Commit 82964f50 authored by Alexandre Julliard's avatar Alexandre Julliard

user32: Added support for the magic WM_CHAR A->W conversions in Send/Post/DispatchMessage.

parent 334ede40
...@@ -251,6 +251,7 @@ static void thread_detach(void) ...@@ -251,6 +251,7 @@ static void thread_detach(void)
WIN_DestroyThreadWindows( get_user_thread_info()->desktop ); WIN_DestroyThreadWindows( get_user_thread_info()->desktop );
CloseHandle( get_user_thread_info()->server_queue ); CloseHandle( get_user_thread_info()->server_queue );
HeapFree( GetProcessHeap(), 0, get_user_thread_info()->wmchar_data );
exiting_thread_id = 0; exiting_thread_id = 0;
} }
......
...@@ -168,6 +168,25 @@ extern void USER_unload_driver(void); ...@@ -168,6 +168,25 @@ extern void USER_unload_driver(void);
struct received_message_info; struct received_message_info;
struct hook16_queue_info; struct hook16_queue_info;
/* type of message-sending functions that need special WM_CHAR handling */
enum wm_char_mapping
{
WMCHAR_MAP_POSTMESSAGE,
WMCHAR_MAP_SENDMESSAGE,
WMCHAR_MAP_SENDMESSAGETIMEOUT,
WMCHAR_MAP_RECVMESSAGE,
WMCHAR_MAP_DISPATCHMESSAGE,
WMCHAR_MAP_CALLWINDOWPROC,
WMCHAR_MAP_COUNT,
WMCHAR_MAP_NOMAPPING = WMCHAR_MAP_COUNT
};
/* data to store state for A/W mappings of WM_CHAR */
struct wm_char_mapping_data
{
BYTE lead_byte[WMCHAR_MAP_COUNT];
};
/* this is the structure stored in TEB->Win32ClientInfo */ /* this is the structure stored in TEB->Win32ClientInfo */
/* no attempt is made to keep the layout compatible with the Windows one */ /* no attempt is made to keep the layout compatible with the Windows one */
struct user_thread_info struct user_thread_info
...@@ -178,6 +197,7 @@ struct user_thread_info ...@@ -178,6 +197,7 @@ struct user_thread_info
HHOOK hook; /* Current hook */ HHOOK hook; /* Current hook */
struct received_message_info *receive_info; /* Message being currently received */ struct received_message_info *receive_info; /* Message being currently received */
struct hook16_queue_info *hook16_info; /* Opaque pointer for 16-bit hook support */ struct hook16_queue_info *hook16_info; /* Opaque pointer for 16-bit hook support */
struct wm_char_mapping_data *wmchar_data; /* Data for WM_CHAR mappings */
DWORD GetMessageTimeVal; /* Value for GetMessageTime */ DWORD GetMessageTimeVal; /* Value for GetMessageTime */
DWORD GetMessagePosVal; /* Value for GetMessagePos */ DWORD GetMessagePosVal; /* Value for GetMessagePos */
ULONG_PTR GetMessageExtraInfoVal; /* Value for GetMessageExtraInfo */ ULONG_PTR GetMessageExtraInfoVal; /* Value for GetMessageExtraInfo */
...@@ -186,7 +206,7 @@ struct user_thread_info ...@@ -186,7 +206,7 @@ struct user_thread_info
UINT active_hooks; /* Bitmap of active hooks */ UINT active_hooks; /* Bitmap of active hooks */
HWND desktop; /* Desktop window */ HWND desktop; /* Desktop window */
ULONG pad[11]; /* Available for more data */ ULONG pad[10]; /* Available for more data */
}; };
struct hook_extra_info struct hook_extra_info
...@@ -215,6 +235,7 @@ extern BOOL FOCUS_MouseActivate( HWND hwnd ); ...@@ -215,6 +235,7 @@ extern BOOL FOCUS_MouseActivate( HWND hwnd );
extern BOOL HOOK_IsHooked( INT id ); extern BOOL HOOK_IsHooked( INT id );
extern void erase_now( HWND hwnd, UINT rdw_flags ); extern void erase_now( HWND hwnd, UINT rdw_flags );
extern LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ); extern LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam );
extern BOOL map_wparam_AtoW( UINT message, WPARAM *wparam, enum wm_char_mapping mapping );
extern LRESULT MSG_SendInternalMessageTimeout( DWORD dest_pid, DWORD dest_tid, extern LRESULT MSG_SendInternalMessageTimeout( DWORD dest_pid, DWORD dest_tid,
UINT msg, WPARAM wparam, LPARAM lparam, UINT msg, WPARAM wparam, LPARAM lparam,
UINT flags, UINT timeout, PDWORD_PTR res_ptr ); UINT flags, UINT timeout, PDWORD_PTR res_ptr );
...@@ -237,7 +258,8 @@ extern WNDPROC WINPROC_AllocProc( WNDPROC funcA, WNDPROC funcW ); ...@@ -237,7 +258,8 @@ extern WNDPROC WINPROC_AllocProc( WNDPROC funcA, WNDPROC funcW );
extern BOOL WINPROC_IsUnicode( WNDPROC proc, BOOL def_val ); extern BOOL WINPROC_IsUnicode( WNDPROC proc, BOOL def_val );
extern LRESULT WINPROC_CallProcAtoW( winproc_callback_t callback, HWND hwnd, UINT msg, extern LRESULT WINPROC_CallProcAtoW( winproc_callback_t callback, HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam, LRESULT *result, void *arg ); WPARAM wParam, LPARAM lParam, LRESULT *result, void *arg,
enum wm_char_mapping mapping );
extern LRESULT WINPROC_CallProc16To32A( winproc_callback_t callback, HWND16 hwnd, UINT16 msg, extern LRESULT WINPROC_CallProc16To32A( winproc_callback_t callback, HWND16 hwnd, UINT16 msg,
WPARAM16 wParam, LPARAM lParam, LRESULT *result, void *arg ); WPARAM16 wParam, LPARAM lParam, LRESULT *result, void *arg );
extern LRESULT WINPROC_CallProc32ATo16( winproc_callback16_t callback, HWND hwnd, UINT msg, extern LRESULT WINPROC_CallProc32ATo16( winproc_callback16_t callback, HWND hwnd, UINT msg,
...@@ -247,7 +269,7 @@ extern INT_PTR WINPROC_CallDlgProc16( DLGPROC16 func, HWND16 hwnd, UINT16 msg, W ...@@ -247,7 +269,7 @@ extern INT_PTR WINPROC_CallDlgProc16( DLGPROC16 func, HWND16 hwnd, UINT16 msg, W
extern INT_PTR WINPROC_CallDlgProcA( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); extern INT_PTR WINPROC_CallDlgProcA( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
extern INT_PTR WINPROC_CallDlgProcW( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); extern INT_PTR WINPROC_CallDlgProcW( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
extern BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, extern BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
LRESULT *result, BOOL unicode ); LRESULT *result, BOOL unicode, enum wm_char_mapping mapping );
/* message spy definitions */ /* message spy definitions */
......
...@@ -441,20 +441,6 @@ static void MDICREATESTRUCT16to32A( const MDICREATESTRUCT16* from, MDICREATESTRU ...@@ -441,20 +441,6 @@ static void MDICREATESTRUCT16to32A( const MDICREATESTRUCT16* from, MDICREATESTRU
to->szClass = MapSL(from->szClass); to->szClass = MapSL(from->szClass);
} }
static WPARAM map_wparam_char_AtoW( WPARAM wParam, DWORD len )
{
CHAR ch[2];
WCHAR wch;
ch[0] = (wParam >> 8);
ch[1] = wParam & 0xff;
if (len > 1 && ch[0])
RtlMultiByteToUnicodeN( &wch, sizeof(wch), NULL, ch, 2 );
else
RtlMultiByteToUnicodeN( &wch, sizeof(wch), NULL, ch + 1, 1 );
return MAKEWPARAM( wch, HIWORD(wParam) );
}
static WPARAM map_wparam_char_WtoA( WPARAM wParam, DWORD len ) static WPARAM map_wparam_char_WtoA( WPARAM wParam, DWORD len )
{ {
WCHAR wch = wParam; WCHAR wch = wParam;
...@@ -602,14 +588,16 @@ static LRESULT call_dialog_proc_Ato16( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ...@@ -602,14 +588,16 @@ static LRESULT call_dialog_proc_Ato16( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp
static LRESULT call_window_proc_AtoW( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp, static LRESULT call_window_proc_AtoW( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
LRESULT *result, void *arg ) LRESULT *result, void *arg )
{ {
return WINPROC_CallProcAtoW( call_window_proc, hwnd, msg, wp, lp, result, arg ); return WINPROC_CallProcAtoW( call_window_proc, hwnd, msg, wp, lp, result,
arg, WMCHAR_MAP_CALLWINDOWPROC );
} }
/* helper callback for 16->32W conversion */ /* helper callback for 16->32W conversion */
static LRESULT call_dialog_proc_AtoW( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp, static LRESULT call_dialog_proc_AtoW( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
LRESULT *result, void *arg ) LRESULT *result, void *arg )
{ {
return WINPROC_CallProcAtoW( call_dialog_proc, hwnd, msg, wp, lp, result, arg ); return WINPROC_CallProcAtoW( call_dialog_proc, hwnd, msg, wp, lp, result,
arg, WMCHAR_MAP_CALLWINDOWPROC );
} }
...@@ -783,7 +771,7 @@ static HANDLE16 convert_handle_32_to_16(UINT_PTR src, unsigned int flags) ...@@ -783,7 +771,7 @@ static HANDLE16 convert_handle_32_to_16(UINT_PTR src, unsigned int flags)
* Call a window procedure, translating args from Ansi to Unicode. * Call a window procedure, translating args from Ansi to Unicode.
*/ */
LRESULT WINPROC_CallProcAtoW( winproc_callback_t callback, HWND hwnd, UINT msg, WPARAM wParam, LRESULT WINPROC_CallProcAtoW( winproc_callback_t callback, HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam, LRESULT *result, void *arg ) LPARAM lParam, LRESULT *result, void *arg, enum wm_char_mapping mapping )
{ {
LRESULT ret = 0; LRESULT ret = 0;
...@@ -979,18 +967,7 @@ LRESULT WINPROC_CallProcAtoW( winproc_callback_t callback, HWND hwnd, UINT msg, ...@@ -979,18 +967,7 @@ LRESULT WINPROC_CallProcAtoW( winproc_callback_t callback, HWND hwnd, UINT msg,
if (lParam) if (lParam)
{ {
MSG newmsg = *(MSG *)lParam; MSG newmsg = *(MSG *)lParam;
switch(newmsg.message) if (map_wparam_AtoW( newmsg.message, &newmsg.wParam, WMCHAR_MAP_NOMAPPING ))
{
case WM_CHAR:
case WM_DEADCHAR:
case WM_SYSCHAR:
case WM_SYSDEADCHAR:
newmsg.wParam = map_wparam_char_AtoW( newmsg.wParam, 1 );
break;
case WM_IME_CHAR:
newmsg.wParam = map_wparam_char_AtoW( newmsg.wParam, 2 );
break;
}
ret = callback( hwnd, msg, wParam, (LPARAM)&newmsg, result, arg ); ret = callback( hwnd, msg, wParam, (LPARAM)&newmsg, result, arg );
} }
else ret = callback( hwnd, msg, wParam, lParam, result, arg ); else ret = callback( hwnd, msg, wParam, lParam, result, arg );
...@@ -1003,11 +980,9 @@ LRESULT WINPROC_CallProcAtoW( winproc_callback_t callback, HWND hwnd, UINT msg, ...@@ -1003,11 +980,9 @@ LRESULT WINPROC_CallProcAtoW( winproc_callback_t callback, HWND hwnd, UINT msg,
case WM_SYSCHAR: case WM_SYSCHAR:
case WM_SYSDEADCHAR: case WM_SYSDEADCHAR:
case EM_SETPASSWORDCHAR: case EM_SETPASSWORDCHAR:
ret = callback( hwnd, msg, map_wparam_char_AtoW(wParam,1), lParam, result, arg );
break;
case WM_IME_CHAR: case WM_IME_CHAR:
ret = callback( hwnd, msg, map_wparam_char_AtoW(wParam,2), lParam, result, arg ); if (map_wparam_AtoW( msg, &wParam, mapping ))
ret = callback( hwnd, msg, wParam, lParam, result, arg );
break; break;
case WM_GETTEXTLENGTH: case WM_GETTEXTLENGTH:
...@@ -1270,9 +1245,20 @@ static LRESULT WINPROC_CallProcWtoA( winproc_callback_t callback, HWND hwnd, UIN ...@@ -1270,9 +1245,20 @@ static LRESULT WINPROC_CallProcWtoA( winproc_callback_t callback, HWND hwnd, UIN
else ret = callback( hwnd, msg, wParam, lParam, result, arg ); else ret = callback( hwnd, msg, wParam, lParam, result, arg );
break; break;
case WM_CHAR:
{
WCHAR wch = wParam;
char ch[2];
DWORD len;
RtlUnicodeToMultiByteN( ch, 2, &len, &wch, sizeof(wch) );
ret = callback( hwnd, msg, (BYTE)ch[0], lParam, result, arg );
if (len == 2) ret = callback( hwnd, msg, (BYTE)ch[1], lParam, result, arg );
}
break;
case WM_CHARTOITEM: case WM_CHARTOITEM:
case WM_MENUCHAR: case WM_MENUCHAR:
case WM_CHAR:
case WM_DEADCHAR: case WM_DEADCHAR:
case WM_SYSCHAR: case WM_SYSCHAR:
case WM_SYSDEADCHAR: case WM_SYSDEADCHAR:
...@@ -2202,7 +2188,7 @@ LRESULT WINPROC_CallProc32ATo16( winproc_callback16_t callback, HWND hwnd, UINT ...@@ -2202,7 +2188,7 @@ LRESULT WINPROC_CallProc32ATo16( winproc_callback16_t callback, HWND hwnd, UINT
* Call the window procedure of the specified window. * Call the window procedure of the specified window.
*/ */
BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
LRESULT *result, BOOL unicode ) LRESULT *result, BOOL unicode, enum wm_char_mapping mapping )
{ {
WND *wndPtr; WND *wndPtr;
WINDOWPROC *proc; WINDOWPROC *proc;
...@@ -2231,7 +2217,7 @@ BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, ...@@ -2231,7 +2217,7 @@ BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
if (proc->procA) if (proc->procA)
call_window_proc( hwnd, msg, wParam, lParam, result, proc->procA ); call_window_proc( hwnd, msg, wParam, lParam, result, proc->procA );
else else
WINPROC_CallProcAtoW( call_window_proc, hwnd, msg, wParam, lParam, result, proc->procW ); WINPROC_CallProcAtoW( call_window_proc, hwnd, msg, wParam, lParam, result, proc->procW, mapping );
} }
return TRUE; return TRUE;
} }
...@@ -2302,7 +2288,8 @@ LRESULT WINAPI CallWindowProcA( ...@@ -2302,7 +2288,8 @@ LRESULT WINAPI CallWindowProcA(
else if (proc->procA) else if (proc->procA)
call_window_proc( hwnd, msg, wParam, lParam, &result, proc->procA ); call_window_proc( hwnd, msg, wParam, lParam, &result, proc->procA );
else if (proc->procW) else if (proc->procW)
WINPROC_CallProcAtoW( call_window_proc, hwnd, msg, wParam, lParam, &result, proc->procW ); WINPROC_CallProcAtoW( call_window_proc, hwnd, msg, wParam, lParam, &result,
proc->procW, WMCHAR_MAP_CALLWINDOWPROC );
else else
WINPROC_CallProc32ATo16( call_window_proc16, hwnd, msg, wParam, lParam, &result, proc->proc16 ); WINPROC_CallProc32ATo16( call_window_proc16, hwnd, msg, wParam, lParam, &result, proc->proc16 );
return result; return result;
...@@ -2386,7 +2373,8 @@ INT_PTR WINPROC_CallDlgProcA( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam, ...@@ -2386,7 +2373,8 @@ INT_PTR WINPROC_CallDlgProcA( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam,
ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc->procA ); ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc->procA );
else if (proc->procW) else if (proc->procW)
{ {
ret = WINPROC_CallProcAtoW( call_dialog_proc, hwnd, msg, wParam, lParam, &result, proc->procW ); ret = WINPROC_CallProcAtoW( call_dialog_proc, hwnd, msg, wParam, lParam, &result,
proc->procW, WMCHAR_MAP_CALLWINDOWPROC );
SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result ); SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result );
} }
else else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment