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/m…
==============================================================================
--- 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;