Author: jimtabor
Date: Sat Nov 19 05:33:26 2011
New Revision: 54428

URL: http://svn.reactos.org/svn/reactos?rev=54428&view=rev
Log:
[User32]
- Updating MsgiAnsiToUnicodeReply fixed bug 4856 and 6650. Mirrored with it's 
counterpart. More work is needed.
- Adding some future DBCS char support.
- Miscellaneous changes.

Modified:
    trunk/reactos/dll/win32/user32/windows/message.c

Modified: trunk/reactos/dll/win32/user32/windows/message.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/message.c?rev=54428&r1=54427&r2=54428&view=diff
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/message.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/windows/message.c [iso-8859-1] Sat Nov 19 
05:33:26 2011
@@ -90,6 +90,20 @@
 
 #undef SET
 
+/* check whether a combobox expects strings or ids in 
CB_ADDSTRING/CB_INSERTSTRING */
+static BOOL FASTCALL combobox_has_strings( HWND hwnd )
+{
+    DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
+    return (!(style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) || (style 
& CBS_HASSTRINGS));
+}
+
+/* check whether a listbox expects strings or ids in 
LB_ADDSTRING/LB_INSERTSTRING */
+static BOOL FASTCALL listbox_has_strings( HWND hwnd )
+{
+    DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
+    return (!(style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) || (style 
& LBS_HASSTRINGS));
+}
+
 /* DDE message exchange
  *
  * - Session initialization
@@ -234,24 +248,24 @@
         {
           PKMDDELPARAM DdeLparam;
           DdeLparam = HeapAlloc(GetProcessHeap(), 0, sizeof(KMDDELPARAM));
-          if (NULL == DdeLparam || !UnpackDDElParam(
-               UMMsg->message, UMMsg->lParam,
-               &DdeLparam->uiLo, &DdeLparam->uiHi)) return FALSE;
-          /*
-               If this is a reply to WM_DDE_EXECUTE then
-               uiHi will contain a hMem, hence >= 0x10000.
-               Otherwise, it will be be an atom, a 16-bit value.
+          if (!DdeLparam ||
+              !UnpackDDElParam( UMMsg->message, UMMsg->lParam, 
&DdeLparam->uiLo, &DdeLparam->uiHi))
+             return FALSE;
+         /*
+             If this is a reply to WM_DDE_EXECUTE then
+             uiHi will contain a hMem, hence >= 0x10000.
+             Otherwise, it will be be an atom, a 16-bit value.
           */
-          if(DdeLparam->uiHi >= 0x10000)
-            {
-              HGLOBAL h = DdeGetPair((HGLOBAL)(ULONG_PTR)DdeLparam->uiHi);
-                  if (NULL != h)
-                    {
-                  GlobalFree((HGLOBAL)(ULONG_PTR)DdeLparam->uiHi);
-                  DdeLparam->uiHi = (UINT_PTR) h;
-                    }
-                }
-              FreeDDElParam(UMMsg->message, UMMsg->lParam);
+          if (!IS_ATOM(DdeLparam->uiHi))
+          {
+             HGLOBAL h = DdeGetPair((HGLOBAL)(ULONG_PTR)DdeLparam->uiHi);
+             if (h)
+             {
+                GlobalFree((HGLOBAL)(ULONG_PTR)DdeLparam->uiHi);
+                DdeLparam->uiHi = (UINT_PTR) h;
+             }
+          }
+          FreeDDElParam(UMMsg->message, UMMsg->lParam);
           KMMsg->lParam = (LPARAM) DdeLparam;
         }
         break;
@@ -264,17 +278,17 @@
 
           Size = GlobalSize((HGLOBAL) UMMsg->lParam);
           Data = GlobalLock((HGLOBAL) UMMsg->lParam);
-          if (NULL == Data)
-            {
-              SetLastError(ERROR_INVALID_HANDLE);
-              return FALSE;
-            }
+          if (!Data)
+          {
+             SetLastError(ERROR_INVALID_HANDLE);
+             return FALSE;
+          }
           KMDdeExecuteData = HeapAlloc(GetProcessHeap(), 0, 
sizeof(KMDDEEXECUTEDATA) + Size);
-          if (NULL == KMDdeExecuteData)
-            {
-              SetLastError(ERROR_OUTOFMEMORY);
-              return FALSE;
-            }
+          if (!KMDdeExecuteData)
+          {
+             SetLastError(ERROR_OUTOFMEMORY);
+             return FALSE;
+          }
           KMDdeExecuteData->Sender = (HWND) UMMsg->wParam;
           KMDdeExecuteData->ClientMem = (HGLOBAL) UMMsg->lParam;
           memcpy((PVOID) (KMDdeExecuteData + 1), Data, Size);
@@ -291,11 +305,11 @@
 
           pKMCopyData = HeapAlloc(GetProcessHeap(), 0,
                                   sizeof(COPYDATASTRUCT) + 
pUMCopyData->cbData);
-          if (pKMCopyData == NULL)
-            {
+          if (!pKMCopyData)
+          {
               SetLastError(ERROR_OUTOFMEMORY);
               return FALSE;
-            }
+          }
 
           pKMCopyData->dwData = pUMCopyData->dwData;
           pKMCopyData->cbData = pUMCopyData->cbData;
@@ -365,7 +379,7 @@
         {
           PKMDDELPARAM DdeLparam = (PKMDDELPARAM) KMMsg->lParam;
           UMMsg->lParam = PackDDElParam(KMMsg->message, DdeLparam->uiLo, 
DdeLparam->uiHi);
-            }
+        }
         break;
 
       case WM_DDE_EXECUTE:
@@ -376,23 +390,23 @@
 
           KMDdeExecuteData = (PKMDDEEXECUTEDATA) KMMsg->lParam;
           GlobalData = GlobalAlloc(GMEM_MOVEABLE, KMMsg->wParam - 
sizeof(KMDDEEXECUTEDATA));
-          if (NULL == GlobalData)
-            {
-              return FALSE;
-            }
+          if (!GlobalData)
+          {
+             return FALSE;
+          }
           Data = GlobalLock(GlobalData);
-          if (NULL == Data)
-            {
-              GlobalFree(GlobalData);
-              return FALSE;
-            }
+          if (!Data)
+          {
+             GlobalFree(GlobalData);
+             return FALSE;
+          }
           memcpy(Data, (PVOID) (KMDdeExecuteData + 1), KMMsg->wParam - 
sizeof(KMDDEEXECUTEDATA));
           GlobalUnlock(GlobalData);
-          if (! DdeAddPair(KMDdeExecuteData->ClientMem, GlobalData))
-            {
-              GlobalFree(GlobalData);
-              return FALSE;
-            }
+          if (!DdeAddPair(KMDdeExecuteData->ClientMem, GlobalData))
+          {
+             GlobalFree(GlobalData);
+             return FALSE;
+          }
           UMMsg->wParam = (WPARAM) KMDdeExecuteData->Sender;
           UMMsg->lParam = (LPARAM) GlobalData;
         }
@@ -484,9 +498,7 @@
     case LB_FINDSTRINGEXACT:
     case LB_SELECTSTRING:
       {
-        DWORD dwStyle = GetWindowLongPtrW(AnsiMsg->hwnd, GWL_STYLE);
-        if (!(dwStyle & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) &&
-            (dwStyle & LBS_HASSTRINGS))
+        if (listbox_has_strings(AnsiMsg->hwnd))
           {
             RtlCreateUnicodeStringFromAsciiz(&UnicodeString, 
(LPSTR)AnsiMsg->lParam);
             UnicodeMsg->lParam = (LPARAM)UnicodeString.Buffer;
@@ -500,9 +512,7 @@
     case CB_FINDSTRINGEXACT:
     case CB_SELECTSTRING:
       {
-        DWORD dwStyle = GetWindowLongPtrW(AnsiMsg->hwnd, GWL_STYLE);
-        if (!(dwStyle & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) &&
-            (dwStyle & CBS_HASSTRINGS))
+        if (combobox_has_strings(AnsiMsg->hwnd))
           {
             RtlCreateUnicodeStringFromAsciiz(&UnicodeString, 
(LPSTR)AnsiMsg->lParam);
             UnicodeMsg->lParam = (LPARAM)UnicodeString.Buffer;
@@ -579,7 +589,6 @@
   return TRUE;
 }
 
-
 static BOOL FASTCALL
 MsgiAnsiToUnicodeCleanup(LPMSG UnicodeMsg, LPMSG AnsiMsg)
 {
@@ -617,9 +626,7 @@
     case LB_FINDSTRINGEXACT:
     case LB_SELECTSTRING:
       {
-        DWORD dwStyle = GetWindowLongPtrW(AnsiMsg->hwnd, GWL_STYLE);
-        if (!(dwStyle & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) &&
-            (dwStyle & LBS_HASSTRINGS))
+        if (listbox_has_strings(AnsiMsg->hwnd))
           {
             RtlInitUnicodeString(&UnicodeString, (PCWSTR)UnicodeMsg->lParam);
             RtlFreeUnicodeString(&UnicodeString);
@@ -633,9 +640,7 @@
     case CB_FINDSTRINGEXACT:
     case CB_SELECTSTRING:
       {
-        DWORD dwStyle = GetWindowLongPtrW(AnsiMsg->hwnd, GWL_STYLE);
-        if (!(dwStyle & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) &&
-            (dwStyle & CBS_HASSTRINGS))
+        if (combobox_has_strings(AnsiMsg->hwnd))
           {
             RtlInitUnicodeString(&UnicodeString, (PCWSTR)UnicodeMsg->lParam);
             RtlFreeUnicodeString(&UnicodeString);
@@ -686,10 +691,10 @@
   return(TRUE);
 }
 
-
 static BOOL FASTCALL
 MsgiAnsiToUnicodeReply(LPMSG UnicodeMsg, LPMSG AnsiMsg, LRESULT *Result)
 {
+  LRESULT Size;
   switch (AnsiMsg->message)
     {
     case WM_GETTEXT:
@@ -698,20 +703,48 @@
         LPWSTR Buffer = (LPWSTR)UnicodeMsg->lParam;
         LPSTR AnsiBuffer = (LPSTR)AnsiMsg->lParam;
         if (UnicodeMsg->wParam > 0 &&
-            !WideCharToMultiByte(CP_ACP, 0, Buffer, -1,
-            AnsiBuffer, UnicodeMsg->wParam, NULL, NULL))
-          {
+            !WideCharToMultiByte(CP_ACP, 0, Buffer, -1, AnsiBuffer, 
UnicodeMsg->wParam, NULL, NULL))
+        {
             AnsiBuffer[UnicodeMsg->wParam - 1] = 0;
-          }
+        }
         break;
       }
+    case LB_GETTEXT:
+      {
+        LPWSTR Buffer = (LPWSTR) UnicodeMsg->lParam;
+        LPSTR AnsiBuffer = (LPSTR) AnsiMsg->lParam;
+        if (!listbox_has_strings( UnicodeMsg->hwnd )) break;
+        Size = SendMessageW( UnicodeMsg->hwnd, LB_GETTEXTLEN, 
UnicodeMsg->wParam, 0 );
+        if (Size == LB_ERR) break;
+        Size = Size + 1;
+        if (Size > 1 &&
+            !WideCharToMultiByte(CP_ACP, 0, Buffer, -1, AnsiBuffer, Size, 
NULL, NULL))
+        {
+            AnsiBuffer[Size - 1] = 0;
+        }        
+        break;
+      }
+    case CB_GETLBTEXT:
+      {
+        LPWSTR Buffer = (LPWSTR) UnicodeMsg->lParam;
+        LPSTR AnsiBuffer = (LPSTR) AnsiMsg->lParam;
+        if (!combobox_has_strings( UnicodeMsg->hwnd )) break;
+        Size = SendMessageW( UnicodeMsg->hwnd, CB_GETLBTEXTLEN, 
UnicodeMsg->wParam, 0 );
+        if (Size == CB_ERR) break;
+        Size = Size + 1;
+        if (Size > 1 &&
+            !WideCharToMultiByte(CP_ACP, 0, Buffer, -1, AnsiBuffer, Size, 
NULL, NULL))
+        {
+            AnsiBuffer[Size - 1] = 0;
+        }        
+        break;
+      }
     }
 
   MsgiAnsiToUnicodeCleanup(UnicodeMsg, AnsiMsg);
 
   return TRUE;
 }
-
 
 static BOOL FASTCALL
 MsgiUnicodeToAnsiMessage(HWND hwnd, LPMSG AnsiMsg, LPMSG UnicodeMsg)
@@ -809,9 +842,7 @@
       case LB_FINDSTRINGEXACT:
       case LB_SELECTSTRING:
         {
-          DWORD dwStyle = GetWindowLongPtrW(AnsiMsg->hwnd, GWL_STYLE);
-          if (!(dwStyle & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) &&
-              (dwStyle & LBS_HASSTRINGS))
+          if (listbox_has_strings(AnsiMsg->hwnd))
             {
               RtlInitUnicodeString(&UnicodeString, (PWSTR) UnicodeMsg->lParam);
               if (! NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiString,
@@ -831,9 +862,7 @@
       case CB_FINDSTRINGEXACT:
       case CB_SELECTSTRING:
         {
-          DWORD dwStyle = GetWindowLongPtrW(AnsiMsg->hwnd, GWL_STYLE);
-          if (!(dwStyle & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) &&
-               (dwStyle & CBS_HASSTRINGS))
+          if (combobox_has_strings(AnsiMsg->hwnd))
             {
               RtlInitUnicodeString(&UnicodeString, (PWSTR) UnicodeMsg->lParam);
               if (! NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiString,
@@ -896,7 +925,6 @@
   return TRUE;
 }
 
-
 static BOOL FASTCALL
 MsgiUnicodeToAnsiCleanup(LPMSG AnsiMsg, LPMSG UnicodeMsg)
 {
@@ -942,9 +970,7 @@
       case LB_FINDSTRINGEXACT:
       case LB_SELECTSTRING:
         {
-          DWORD dwStyle = GetWindowLongPtrW(AnsiMsg->hwnd, GWL_STYLE);
-          if (!(dwStyle & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) &&
-              (dwStyle & LBS_HASSTRINGS))
+          if (listbox_has_strings(AnsiMsg->hwnd))
             {
               RtlInitAnsiString(&AnsiString, (PSTR) AnsiMsg->lParam);
               RtlFreeAnsiString(&AnsiString);
@@ -987,10 +1013,10 @@
   return TRUE;
 }
 
-
 static BOOL FASTCALL
 MsgiUnicodeToAnsiReply(LPMSG AnsiMsg, LPMSG UnicodeMsg, LRESULT *Result)
 {
+  LRESULT Size;
   switch (UnicodeMsg->message)
     {
     case WM_GETTEXT:
@@ -1000,9 +1026,39 @@
         LPWSTR UBuffer = (LPWSTR) UnicodeMsg->lParam;
         if (0 < AnsiMsg->wParam &&
             ! MultiByteToWideChar(CP_ACP, 0, Buffer, -1, UBuffer, 
UnicodeMsg->wParam))
-          {
+        {
             UBuffer[UnicodeMsg->wParam - 1] = L'\0';
-          }
+        }
+        break;
+      }
+    case LB_GETTEXT:
+      {
+        LPSTR Buffer = (LPSTR) AnsiMsg->lParam;
+        LPWSTR UBuffer = (LPWSTR) UnicodeMsg->lParam;
+        if (!listbox_has_strings( UnicodeMsg->hwnd )) break;
+        Size = SendMessageW( UnicodeMsg->hwnd, LB_GETTEXTLEN, 
UnicodeMsg->wParam, 0 );
+        if (Size == LB_ERR) break;
+        Size = Size + 1;
+        if (1 < Size &&
+            ! MultiByteToWideChar(CP_ACP, 0, Buffer, -1, UBuffer, Size))
+        {
+            UBuffer[Size - 1] = L'\0';
+        }        
+        break;
+      }
+    case CB_GETLBTEXT:
+      {
+        LPSTR Buffer = (LPSTR) AnsiMsg->lParam;
+        LPWSTR UBuffer = (LPWSTR) UnicodeMsg->lParam;
+        if (!combobox_has_strings( UnicodeMsg->hwnd )) break;
+        Size = SendMessageW( UnicodeMsg->hwnd, CB_GETLBTEXTLEN, 
UnicodeMsg->wParam, 0 );
+        if (Size == CB_ERR) break;
+        Size = Size + 1;
+        if (1 < Size &&
+            ! MultiByteToWideChar(CP_ACP, 0, Buffer, -1, UBuffer, Size))
+        {
+            UBuffer[Size - 1] = L'\0';
+        }        
         break;
       }
     }
@@ -1020,34 +1076,83 @@
 static WPARAM
 map_wparam_AtoW( UINT message, WPARAM wparam )
 {
+    char ch[2];
+    WCHAR wch[2];
+
+    wch[0] = wch[1] = 0;
     switch(message)
     {
+    case WM_CHAR:
+        /* WM_CHAR is magic: a DBCS char can be sent/posted as two consecutive 
WM_CHAR
+         * messages, in which case the first char is stored, and the conversion
+         * to Unicode only takes place once the second char is sent/posted.
+         */
+#if 0
+        if (mapping != WMCHAR_MAP_NOMAPPING) // NlsMbCodePageTag
+        {
+            PCLIENTINFO pci = GetWin32ClientInfo();
+
+            struct wm_char_mapping_data *data = 
get_user_thread_info()->wmchar_data;
+
+            BYTE low = LOBYTE(wparam);
+
+            if (HIBYTE(wparam))
+            {
+                ch[0] = low;
+                ch[1] = HIBYTE(wparam);
+                RtlMultiByteToUnicodeN( wch, sizeof(wch), NULL, ch, 2 );
+                TRACE( "map %02x,%02x -> %04x mapping %u\n", (BYTE)ch[0], 
(BYTE)ch[1], wch[0], mapping );
+                if (data) data->lead_byte[mapping] = 0;
+            }
+            else if (data && data->lead_byte[mapping])
+            {
+                ch[0] = data->lead_byte[mapping];
+                ch[1] = low;
+                RtlMultiByteToUnicodeN( wch, sizeof(wch), NULL, ch, 2 );
+                TRACE( "map stored %02x,%02x -> %04x mapping %u\n", 
(BYTE)ch[0], (BYTE)ch[1], wch[0], mapping );
+                data->lead_byte[mapping] = 0;
+            }
+            else if (!IsDBCSLeadByte( low ))
+            {
+                ch[0] = low;
+                RtlMultiByteToUnicodeN( wch, sizeof(wch), NULL, ch, 1 );
+                TRACE( "map %02x -> %04x\n", (BYTE)ch[0], wch[0] );
+                if (data) data->lead_byte[mapping] = 0;
+            }
+            else  /* store it and wait for trail byte */
+            {
+                if (!data)
+                {
+                    if (!(data = HeapAlloc( GetProcessHeap(), 
HEAP_ZERO_MEMORY, sizeof(*data) )))
+                        return FALSE;
+                    get_user_thread_info()->wmchar_data = data;
+                }
+                TRACE( "storing lead byte %02x mapping %u\n", low, mapping );
+                data->lead_byte[mapping] = low;
+                return FALSE;
+            }
+            wparam = MAKEWPARAM(wch[0], wch[1]);
+            break;
+        }
+#endif
+        /* else fall through */
     case WM_CHARTOITEM:
     case EM_SETPASSWORDCHAR:
-    case WM_CHAR:
     case WM_DEADCHAR:
     case WM_SYSCHAR:
     case WM_SYSDEADCHAR:
     case WM_MENUCHAR:
-        {
-            char ch[2];
-            WCHAR wch[2];
-            ch[0] = (wparam & 0xff);
-            ch[1] = (wparam >> 8);
-            MultiByteToWideChar(CP_ACP, 0, ch, 2, wch, 2);
-            wparam = MAKEWPARAM(wch[0], wch[1]);
-        }
+        ch[0] = LOBYTE(wparam);
+        ch[1] = HIBYTE(wparam);
+        RtlMultiByteToUnicodeN( wch, sizeof(wch), NULL, ch, 2 );
+        wparam = MAKEWPARAM(wch[0], wch[1]);
         break;
     case WM_IME_CHAR:
-        {
-            char ch[2];
-            WCHAR wch;
-            ch[0] = (wparam >> 8);
-            ch[1] = (wparam & 0xff);
-            if (ch[0]) MultiByteToWideChar(CP_ACP, 0, ch, 2, &wch, 1);
-            else MultiByteToWideChar(CP_ACP, 0, &ch[1], 1, &wch, 1);
-            wparam = MAKEWPARAM( wch, HIWORD(wparam) );
-        }
+        ch[0] = HIBYTE(wparam);
+        ch[1] = LOBYTE(wparam);
+        if (ch[0]) RtlMultiByteToUnicodeN( wch, sizeof(wch[0]), NULL, ch, 2 );
+        else RtlMultiByteToUnicodeN( wch, sizeof(wch[0]), NULL, ch + 1, 1 );
+        wparam = MAKEWPARAM(wch[0], HIWORD(wparam));
         break;
     }
     return wparam;
@@ -1791,6 +1896,33 @@
     return Ret;
 }
 
+LRESULT
+WINAPI
+DesktopWndProcA( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
+{
+  LRESULT Result;
+  MSG AnsiMsg, UcMsg;
+
+  ERR("Desktop A Class Atom! hWnd 0x%x, Msg %d\n", hwnd, message);
+
+  AnsiMsg.hwnd = hwnd;
+  AnsiMsg.message = message;
+  AnsiMsg.wParam = wParam;
+  AnsiMsg.lParam = lParam;
+
+  // Desktop is always Unicode so convert Ansi here.
+  if (!MsgiAnsiToUnicodeMessage(hwnd, &UcMsg, &AnsiMsg))
+  {
+     return FALSE;
+  }
+
+  Result = DesktopWndProcW(hwnd, message, UcMsg.wParam, UcMsg.lParam);
+
+  MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg);
+
+  return Result;
+}
+
 static VOID
 IntConvertMsgToAnsi(LPMSG lpMsg)
 {
@@ -1818,9 +1950,9 @@
  */
 BOOL WINAPI
 GetMessageA(LPMSG lpMsg,
-               HWND hWnd,
-               UINT wMsgFilterMin,
-               UINT wMsgFilterMax)
+            HWND hWnd,
+            UINT wMsgFilterMin,
+            UINT wMsgFilterMax)
 {
   BOOL Res;
 
@@ -1846,9 +1978,9 @@
  */
 BOOL WINAPI
 GetMessageW(LPMSG lpMsg,
-           HWND hWnd,
-           UINT wMsgFilterMin,
-           UINT wMsgFilterMax)
+            HWND hWnd,
+            UINT wMsgFilterMin,
+            UINT wMsgFilterMax)
 {
   BOOL Res;
 


Reply via email to