Bletch <npwoods@mess.org>

- Implements the Encoding field when you save, allowing the user to save as
  ANSI, Unicode or UTF-8
- Invoking 'Save As' after saving or loading a file will default to the
  earlier filename
(minor changes by GvG, so mistakes are mine).

svn path=/trunk/; revision=17820
This commit is contained in:
Gé van Geldorp 2005-09-12 17:10:00 +00:00
parent 5fbac4d9e6
commit 6ceb694074
4 changed files with 220 additions and 37 deletions

View file

@ -94,6 +94,17 @@ PUSHBUTTON "Cancel", 0x152, 180, 21, 40, 15, WS_TABSTOP
PUSHBUTTON "&Help", 0x153, 180, 39, 40, 15, WS_TABSTOP
}
/* Dialog `Encoding' */
DIALOG_ENCODING DIALOG 0, 0, 256, 26
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS |
WS_CAPTION | WS_SYSMENU
FONT 8, "MS Shell Dlg"
CAPTION "Encoding"
{
COMBOBOX ID_ENCODING,54,0,156,80,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Encoding:",0x155,5,2,41,12
}
STRINGTABLE DISCARDABLE
{
STRING_PAGESETUP_HEADERVALUE, "&n" /* FIXME */
@ -125,5 +136,8 @@ STRING_NOTFOUND, "'%s' can not be found."
STRING_OUT_OF_MEMORY, "Not enough memory to complete this \
task. \nClose one or more applications to increase the amount of \nfree \
memory."
STRING_ANSI, "ANSI"
STRING_UNICODE, "Unicode"
STRING_UNICODE_BE, "Unicode (big endian)"
STRING_UTF8, "UTF-8"
}

View file

@ -139,8 +139,14 @@ static VOID DoSaveFile(VOID)
{
HANDLE hFile;
DWORD dwNumWrite;
LPSTR pTemp;
LPWSTR pTemp;
LPVOID pConverted;
DWORD size;
BYTE bom[3];
int iBomSize = 0;
int iCodePage = -1;
int iNewSize;
int i;
hFile = CreateFile(Globals.szFileName, GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
@ -150,23 +156,82 @@ static VOID DoSaveFile(VOID)
return;
}
size = GetWindowTextLengthA(Globals.hEdit) + 1;
pTemp = HeapAlloc(GetProcessHeap(), 0, size);
size = GetWindowTextLengthW(Globals.hEdit) + 1;
pTemp = HeapAlloc(GetProcessHeap(), 0, size * sizeof(*pTemp));
if (!pTemp)
{
CloseHandle(hFile);
CloseHandle(hFile);
ShowLastError();
return;
}
size = GetWindowTextA(Globals.hEdit, pTemp, size);
size = GetWindowTextW(Globals.hEdit, pTemp, size);
if (!WriteFile(hFile, pTemp, size, &dwNumWrite, NULL))
switch(Globals.iEncoding)
{
case ENCODING_ANSI:
iCodePage = CP_ACP;
break;
case ENCODING_UNICODE:
pConverted = pTemp;
iBomSize = 2;
bom[0] = 0xFF;
bom[1] = 0xFE;
break;
case ENCODING_UNICODE_BE:
pConverted = pTemp;
iBomSize = 2;
bom[0] = 0xFE;
bom[1] = 0xFF;
/* flip the endianness */
for (i = 0; i < size; i++)
{
pTemp[i] = ((pTemp[i] & 0x00FF) << 8)
| ((pTemp[i] & 0xFF00) >> 8);
}
break;
case ENCODING_UTF8:
iCodePage = CP_UTF8;
iBomSize = 3;
bom[0] = 0xEF;
bom[1] = 0xBB;
bom[2] = 0xBF;
break;
}
if (iCodePage >= 0)
{
iNewSize = WideCharToMultiByte(iCodePage, 0, pTemp, size, NULL, 0, NULL, NULL);
pConverted = HeapAlloc(GetProcessHeap(), 0, iNewSize);
if (!pConverted)
{
HeapFree(GetProcessHeap(), 0, pTemp);
CloseHandle(hFile);
ShowLastError();
return;
}
WideCharToMultiByte(iCodePage, 0, pTemp, size, pConverted, iNewSize, NULL, NULL);
}
else
{
iNewSize = size * sizeof(WCHAR);
}
if ((iBomSize > 0) && !WriteFile(hFile, bom, iBomSize, &dwNumWrite, NULL))
ShowLastError();
else if (!WriteFile(hFile, pConverted, iNewSize, &dwNumWrite, NULL))
ShowLastError();
else
SendMessage(Globals.hEdit, EM_SETMODIFY, FALSE, 0);
CloseHandle(hFile);
HeapFree(GetProcessHeap(), 0, pTemp);
if (iCodePage >= 0)
HeapFree(GetProcessHeap(), 0, pConverted);
}
/**
@ -208,44 +273,48 @@ void DoOpenFile(LPCWSTR szFileName)
{
HANDLE hFile;
LPSTR pTemp;
LPWSTR pTemp2 = NULL;
DWORD size;
DWORD dwNumRead;
LPWSTR p;
LPBYTE p2;
int iCodePage;
int iNewSize;
/* Close any files and prompt to save changes */
if (!DoCloseFile())
return;
return;
hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
ShowLastError();
return;
ShowLastError();
return;
}
size = GetFileSize(hFile, NULL);
if (size == INVALID_FILE_SIZE)
{
CloseHandle(hFile);
ShowLastError();
return;
CloseHandle(hFile);
ShowLastError();
return;
}
size++;
pTemp = HeapAlloc(GetProcessHeap(), 0, size);
pTemp = HeapAlloc(GetProcessHeap(), 0, size + sizeof(WCHAR));
if (!pTemp)
{
CloseHandle(hFile);
ShowLastError();
return;
CloseHandle(hFile);
ShowLastError();
return;
}
if (!ReadFile(hFile, pTemp, size, &dwNumRead, NULL))
{
CloseHandle(hFile);
HeapFree(GetProcessHeap(), 0, pTemp);
ShowLastError();
return;
CloseHandle(hFile);
HeapFree(GetProcessHeap(), 0, pTemp);
ShowLastError();
return;
}
CloseHandle(hFile);
@ -253,15 +322,55 @@ void DoOpenFile(LPCWSTR szFileName)
if (IsTextUnicode(pTemp, dwNumRead, NULL))
{
LPWSTR p = (LPWSTR)pTemp;
/* We need to strip BOM Unicode character, SetWindowTextW won't do it for us. */
if (*p == 0xFEFF || *p == 0xFFFE) p++;
SetWindowTextW(Globals.hEdit, p);
p = (LPWSTR)pTemp;
p[dwNumRead / 2] = 0;
/* We need to strip BOM Unicode character, SetWindowTextW won't do it for us. */
if (*p == 0xFEFF)
{
Globals.iEncoding = ENCODING_UNICODE_BE;
p++;
}
else if (*p == 0xFFFE)
{
Globals.iEncoding = ENCODING_UNICODE;
p++;
}
}
else
SetWindowTextA(Globals.hEdit, pTemp);
{
p2 = pTemp;
if ((p2[0] == 0xEF) && (p2[1] == 0xBB) && (p2[2] == 0xBF))
{
iCodePage = CP_UTF8;
Globals.iEncoding = ENCODING_UTF8;
p2 += 3;
dwNumRead -= 3;
}
else
{
iCodePage = CP_ACP;
Globals.iEncoding = ENCODING_ANSI;
}
iNewSize = MultiByteToWideChar(iCodePage, 0, p2, dwNumRead, NULL, 0);
pTemp2 = HeapAlloc(GetProcessHeap(), 0, (iNewSize + 1) * sizeof(*pTemp2));
if (!pTemp2)
{
CloseHandle(hFile);
HeapFree(GetProcessHeap(), 0, pTemp);
ShowLastError();
return;
}
MultiByteToWideChar(iCodePage, 0, p2, dwNumRead, pTemp2, iNewSize);
pTemp2[iNewSize] = 0;
p = pTemp2;
}
SetWindowTextW(Globals.hEdit, p);
HeapFree(GetProcessHeap(), 0, pTemp);
if (pTemp2)
HeapFree(GetProcessHeap(), 0, pTemp2);
SendMessage(Globals.hEdit, EM_SETMODIFY, FALSE, 0);
SendMessage(Globals.hEdit, EM_EMPTYUNDOBUFFER, 0, 0);
@ -286,15 +395,18 @@ VOID DIALOG_FileNew(VOID)
VOID DIALOG_FileOpen(VOID)
{
OPENFILENAME openfilename;
WCHAR szPath[MAX_PATH];
WCHAR szDir[MAX_PATH];
WCHAR szPath[MAX_PATH];
static const WCHAR szDefaultExt[] = { 't','x','t',0 };
static const WCHAR txt_files[] = { '*','.','t','x','t',0 };
ZeroMemory(&openfilename, sizeof(openfilename));
GetCurrentDirectory(SIZEOF(szDir), szDir);
lstrcpy(szPath, txt_files);
if (Globals.szFileName[0] == 0)
lstrcpy(szPath, txt_files);
else
lstrcpy(szPath, Globals.szFileName);
openfilename.lStructSize = sizeof(openfilename);
openfilename.hwndOwner = Globals.hMainWnd;
@ -325,18 +437,59 @@ VOID DIALOG_FileSave(VOID)
DoSaveFile();
}
static UINT_PTR CALLBACK DIALOG_FileSaveAs_Hook(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
WCHAR szText[128];
HWND hCombo;
OFNOTIFY *pNotify;
switch(msg)
{
case WM_INITDIALOG:
hCombo = GetDlgItem(hDlg, ID_ENCODING);
LoadString(Globals.hInstance, STRING_ANSI, szText, SIZEOF(szText));
SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szText);
LoadString(Globals.hInstance, STRING_UNICODE, szText, SIZEOF(szText));
SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szText);
LoadString(Globals.hInstance, STRING_UNICODE_BE, szText, SIZEOF(szText));
SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szText);
LoadString(Globals.hInstance, STRING_UTF8, szText, SIZEOF(szText));
SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szText);
SendMessage(hCombo, CB_SETCURSEL, Globals.iEncoding, 0);
break;
case WM_NOTIFY:
if (((NMHDR *) lParam)->code == CDN_FILEOK)
{
pNotify = (OFNOTIFY *) lParam;
hCombo = GetDlgItem(hDlg, ID_ENCODING);
Globals.iEncoding = SendMessage(hCombo, CB_GETCURSEL, 0, 0);
}
break;
}
return 0;
}
VOID DIALOG_FileSaveAs(VOID)
{
OPENFILENAME saveas;
WCHAR szPath[MAX_PATH];
WCHAR szDir[MAX_PATH];
WCHAR szPath[MAX_PATH];
static const WCHAR szDefaultExt[] = { 't','x','t',0 };
static const WCHAR txt_files[] = { '*','.','t','x','t',0 };
ZeroMemory(&saveas, sizeof(saveas));
GetCurrentDirectory(SIZEOF(szDir), szDir);
lstrcpy(szPath, txt_files);
if (Globals.szFileName[0] == 0)
lstrcpy(szPath, txt_files);
else
lstrcpy(szPath, Globals.szFileName);
saveas.lStructSize = sizeof(OPENFILENAME);
saveas.hwndOwner = Globals.hMainWnd;
@ -346,8 +499,10 @@ VOID DIALOG_FileSaveAs(VOID)
saveas.nMaxFile = SIZEOF(szPath);
saveas.lpstrInitialDir = szDir;
saveas.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT |
OFN_HIDEREADONLY;
OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLETEMPLATE | OFN_ENABLEHOOK;
saveas.lpstrDefExt = szDefaultExt;
saveas.lpTemplateName = MAKEINTRESOURCE(DIALOG_ENCODING);
saveas.lpfnHook = DIALOG_FileSaveAs_Hook;
if (GetSaveFileName(&saveas)) {
SetFileName(szPath);
@ -423,14 +578,14 @@ VOID DIALOG_FilePrint(VOID)
cHeightPels = GetDeviceCaps(printer.hDC, VERTRES);
/* Get the file text */
size = GetWindowTextLength(Globals.hEdit) + 1;
size = GetWindowTextLengthW(Globals.hEdit) + 1;
pTemp = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
if (!pTemp)
{
ShowLastError();
return;
}
size = GetWindowText(Globals.hEdit, pTemp, size);
size = GetWindowTextW(Globals.hEdit, pTemp, size);
border = 150;
for (copycount=1; copycount <= printer.nCopies; copycount++) {
@ -700,8 +855,8 @@ static INT_PTR WINAPI DIALOG_PAGESETUP_DlgProc(HWND hDlg, UINT msg, WPARAM wPara
return TRUE;
}
default:
break;
default:
break;
}
break;

View file

@ -25,6 +25,11 @@
#define MAX_STRING_LEN 255
#define ENCODING_ANSI 0
#define ENCODING_UNICODE 1
#define ENCODING_UNICODE_BE 2
#define ENCODING_UTF8 3
typedef struct
{
HANDLE hInstance;
@ -44,6 +49,7 @@ typedef struct
WCHAR szMarginRight[MAX_PATH];
WCHAR szHeader[MAX_PATH];
WCHAR szFooter[MAX_PATH];
int iEncoding;
FINDREPLACE find;
} NOTEPAD_GLOBALS;

View file

@ -22,6 +22,8 @@
#define MAIN_MENU 0x201
#define DIALOG_PAGESETUP 0x202
#define ID_ACCEL 0x203
#define DIALOG_ENCODING 0x204
#define ID_ENCODING 0x205
/* Commands */
#define CMD_NEW 0x100
@ -76,3 +78,9 @@
#define STRING_NOTFOUND 0x17B
#define STRING_OUT_OF_MEMORY 0x17C
#define STRING_ANSI 0x17D
#define STRING_UNICODE 0x17E
#define STRING_UNICODE_BE 0x17F
#define STRING_UTF8 0x180