[2/4] notepad: Remember the encoding of files when they are opened, and use the same encoding when saving.

Alexander Scott-Johns alexander.scott.johns at googlemail.com
Mon Jun 29 19:25:07 CDT 2009


---
 programs/notepad/dialog.c |   90 ++++++++++++++++++++++++++++++++++----------
 programs/notepad/main.c   |    9 +++-
 programs/notepad/main.h   |    3 +-
 3 files changed, 77 insertions(+), 25 deletions(-)
-------------- next part --------------
From 26694ed6ddb74204d7521388fc86b773d317376a Mon Sep 17 00:00:00 2001
From: Alexander Scott-Johns <alexander.scott.johns at googlemail.com>
Date: Mon, 29 Jun 2009 23:03:53 +0100
Subject: notepad: Remember the encoding of files when they are opened, and use
 the same encoding when saving.

---
 programs/notepad/dialog.c |   90 ++++++++++++++++++++++++++++++++++----------
 programs/notepad/main.c   |    9 +++-
 programs/notepad/main.h   |    3 +-
 3 files changed, 77 insertions(+), 25 deletions(-)

diff --git a/programs/notepad/dialog.c b/programs/notepad/dialog.c
index 606b777..10d4ddd 100644
--- a/programs/notepad/dialog.c
+++ b/programs/notepad/dialog.c
@@ -137,39 +137,84 @@ BOOL FileExists(LPCWSTR szFilename)
 }
 
 
-static VOID DoSaveFile(VOID)
+static VOID DoSaveFile(LPCWSTR szFileName, ENCODING enc)
 {
+    int lenW;
+    WCHAR* textW;
     HANDLE hFile;
     DWORD dwNumWrite;
-    LPSTR pTemp;
+    PVOID pBytes;
     DWORD size;
 
-    hFile = CreateFileW(Globals.szFileName, GENERIC_WRITE, FILE_SHARE_WRITE,
-                       NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
-    if(hFile == INVALID_HANDLE_VALUE)
+    /* lenW includes the byte-order mark, but not the \0. */
+    lenW = GetWindowTextLengthW(Globals.hEdit) + 1;
+    textW = HeapAlloc(GetProcessHeap(), 0, (lenW+1) * sizeof(WCHAR));
+    if (!textW)
     {
         ShowLastError();
         return;
     }
+    textW[0] = (WCHAR) 0xfeff;
+    lenW = GetWindowTextW(Globals.hEdit, textW+1, lenW) + 1;
 
-    size = GetWindowTextLengthA(Globals.hEdit) + 1;
-    pTemp = HeapAlloc(GetProcessHeap(), 0, size);
-    if (!pTemp)
+    switch (enc)
+    {
+    case ENCODING_UTF16BE:
+        byteswap_wide_string(textW, lenW);
+        /* fall through */
+
+    case ENCODING_UTF16LE:
+        size = lenW * sizeof(WCHAR);
+        pBytes = textW;
+        break;
+
+    case ENCODING_UTF8:
+        size = WideCharToMultiByte(CP_UTF8, 0, textW, lenW, NULL, 0, NULL, NULL);
+        pBytes = HeapAlloc(GetProcessHeap(), 0, size);
+        if (!pBytes)
+        {
+            ShowLastError();
+            HeapFree(GetProcessHeap(), 0, textW);
+            return;
+        }
+        WideCharToMultiByte(CP_UTF8, 0, textW, lenW, pBytes, size, NULL, NULL);
+        HeapFree(GetProcessHeap(), 0, textW);
+        break;
+
+    default:
+        size = WideCharToMultiByte(CP_ACP, 0, textW+1, lenW-1, NULL, 0, NULL, NULL);
+        pBytes = HeapAlloc(GetProcessHeap(), 0, size);
+        if (!pBytes)
+        {
+            ShowLastError();
+            HeapFree(GetProcessHeap(), 0, textW);
+            return;
+        }
+        WideCharToMultiByte(CP_ACP, 0, textW+1, lenW-1, pBytes, size, NULL, NULL);
+        HeapFree(GetProcessHeap(), 0, textW);
+        break;
+    }
+
+    hFile = CreateFileW(szFileName, GENERIC_WRITE, FILE_SHARE_WRITE,
+                       NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (hFile == INVALID_HANDLE_VALUE)
     {
-	CloseHandle(hFile);
         ShowLastError();
+        HeapFree(GetProcessHeap(), 0, pBytes);
         return;
     }
-    size = GetWindowTextA(Globals.hEdit, pTemp, size);
-
-    if (!WriteFile(hFile, pTemp, size, &dwNumWrite, NULL))
+    if (!WriteFile(hFile, pBytes, size, &dwNumWrite, NULL))
+    {
         ShowLastError();
-    else
-        SendMessageW(Globals.hEdit, EM_SETMODIFY, FALSE, 0);
-
+        CloseHandle(hFile);
+        HeapFree(GetProcessHeap(), 0, pBytes);
+        return;
+    }
     SetEndOfFile(hFile);
     CloseHandle(hFile);
-    HeapFree(GetProcessHeap(), 0, pTemp);
+    HeapFree(GetProcessHeap(), 0, pBytes);
+
+    SendMessageW(Globals.hEdit, EM_SETMODIFY, FALSE, 0);
 }
 
 /**
@@ -197,7 +242,7 @@ BOOL DoCloseFile(void)
         } /* switch */
     } /* if */
 
-    SetFileName(empty_strW);
+    SetFileNameAndEncoding(empty_strW, ENCODING_ANSI);
 
     UpdateWindowCaption();
     return(TRUE);
@@ -303,6 +348,9 @@ void DoOpenFile(LPCWSTR szFileName, ENCODING enc)
     {
     case ENCODING_UTF16BE:
         byteswap_wide_string((WCHAR*) pTemp, size/sizeof(WCHAR));
+        /* Forget whether the file is BE or LE, like native Notepad. */
+        enc = ENCODING_UTF16LE;
+
         /* fall through */
 
     case ENCODING_UTF16LE:
@@ -348,7 +396,7 @@ void DoOpenFile(LPCWSTR szFileName, ENCODING enc)
         SendMessageW(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)lfW);
     }
 
-    SetFileName(szFileName);
+    SetFileNameAndEncoding(szFileName, enc);
     UpdateWindowCaption();
 }
 
@@ -399,7 +447,7 @@ BOOL DIALOG_FileSave(VOID)
     if (Globals.szFileName[0] == '\0')
         return DIALOG_FileSaveAs();
     else
-        DoSaveFile();
+        DoSaveFile(Globals.szFileName, Globals.encFile);
     return TRUE;
 }
 
@@ -428,9 +476,9 @@ BOOL DIALOG_FileSaveAs(VOID)
     saveas.lpstrDefExt       = szDefaultExt;
 
     if (GetSaveFileNameW(&saveas)) {
-        SetFileName(szPath);
+        SetFileNameAndEncoding(szPath, Globals.encFile);
         UpdateWindowCaption();
-        DoSaveFile();
+        DoSaveFile(szPath, Globals.encFile);
         return TRUE;
     }
     return FALSE;
diff --git a/programs/notepad/main.c b/programs/notepad/main.c
index 2156d6b..679ca2c 100644
--- a/programs/notepad/main.c
+++ b/programs/notepad/main.c
@@ -64,15 +64,18 @@ static const WCHAR value_szFooter[]         = {'s','z','T','r','a','i','l','e','
 
 /***********************************************************************
  *
- *           SetFileName
+ *           SetFileNameAndEncoding
  *
- *  Sets Global File Name.
+ *  Sets global file name and encoding (which is used to preselect original
+ *  encoding in Save As dialog, and when saving without using the Save As
+ *  dialog).
  */
-VOID SetFileName(LPCWSTR szFileName)
+VOID SetFileNameAndEncoding(LPCWSTR szFileName, ENCODING enc)
 {
     lstrcpyW(Globals.szFileName, szFileName);
     Globals.szFileTitle[0] = 0;
     GetFileTitleW(szFileName, Globals.szFileTitle, sizeof(Globals.szFileTitle));
+    Globals.encFile = enc;
 }
 
 /******************************************************************************
diff --git a/programs/notepad/main.h b/programs/notepad/main.h
index 465897b..e5662ff 100644
--- a/programs/notepad/main.h
+++ b/programs/notepad/main.h
@@ -47,6 +47,7 @@ typedef struct
   WCHAR    szReplaceText[MAX_PATH];
   WCHAR    szFileName[MAX_PATH];
   WCHAR    szFileTitle[MAX_PATH];
+  ENCODING encFile;
   WCHAR    szFilter[2 * MAX_STRING_LEN + 100];
   INT      iMarginTop;
   INT      iMarginBottom;
@@ -63,6 +64,6 @@ typedef struct
 
 extern NOTEPAD_GLOBALS Globals;
 
-VOID SetFileName(LPCWSTR szFileName);
+VOID SetFileNameAndEncoding(LPCWSTR szFileName, ENCODING enc);
 void NOTEPAD_DoFind(FINDREPLACEW *fr);
 DWORD get_dpi(void);
-- 
1.5.6.3


More information about the wine-patches mailing list