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)
WIN_DestroyThreadWindows( get_user_thread_info()->desktop );
CloseHandle( get_user_thread_info()->server_queue );
HeapFree( GetProcessHeap(), 0, get_user_thread_info()->wmchar_data );
exiting_thread_id = 0;
}
......
......@@ -168,6 +168,25 @@ extern void USER_unload_driver(void);
struct received_message_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 */
/* no attempt is made to keep the layout compatible with the Windows one */
struct user_thread_info
......@@ -178,6 +197,7 @@ struct user_thread_info
HHOOK hook; /* Current hook */
struct received_message_info *receive_info; /* Message being currently received */
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 GetMessagePosVal; /* Value for GetMessagePos */
ULONG_PTR GetMessageExtraInfoVal; /* Value for GetMessageExtraInfo */
......@@ -186,7 +206,7 @@ struct user_thread_info
UINT active_hooks; /* Bitmap of active hooks */
HWND desktop; /* Desktop window */
ULONG pad[11]; /* Available for more data */
ULONG pad[10]; /* Available for more data */
};
struct hook_extra_info
......@@ -215,6 +235,7 @@ extern BOOL FOCUS_MouseActivate( HWND hwnd );
extern BOOL HOOK_IsHooked( INT id );
extern void erase_now( HWND hwnd, UINT rdw_flags );
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,
UINT msg, WPARAM wparam, LPARAM lparam,
UINT flags, UINT timeout, PDWORD_PTR res_ptr );
......@@ -237,7 +258,8 @@ extern WNDPROC WINPROC_AllocProc( WNDPROC funcA, WNDPROC funcW );
extern BOOL WINPROC_IsUnicode( WNDPROC proc, BOOL def_val );
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,
WPARAM16 wParam, LPARAM lParam, LRESULT *result, void *arg );
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
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 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 */
......
......@@ -441,20 +441,6 @@ static void MDICREATESTRUCT16to32A( const MDICREATESTRUCT16* from, MDICREATESTRU
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 )
{
WCHAR wch = wParam;
......@@ -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,
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 */
static LRESULT call_dialog_proc_AtoW( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
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)
* Call a window procedure, translating args from Ansi to Unicode.
*/
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;
......@@ -979,19 +967,8 @@ LRESULT WINPROC_CallProcAtoW( winproc_callback_t callback, HWND hwnd, UINT msg,
if (lParam)
{
MSG newmsg = *(MSG *)lParam;
switch(newmsg.message)
{
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 );
if (map_wparam_AtoW( newmsg.message, &newmsg.wParam, WMCHAR_MAP_NOMAPPING ))
ret = callback( hwnd, msg, wParam, (LPARAM)&newmsg, result, arg );
}
else ret = callback( hwnd, msg, wParam, lParam, result, arg );
break;
......@@ -1003,11 +980,9 @@ LRESULT WINPROC_CallProcAtoW( winproc_callback_t callback, HWND hwnd, UINT msg,
case WM_SYSCHAR:
case WM_SYSDEADCHAR:
case EM_SETPASSWORDCHAR:
ret = callback( hwnd, msg, map_wparam_char_AtoW(wParam,1), lParam, result, arg );
break;
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;
case WM_GETTEXTLENGTH:
......@@ -1270,9 +1245,20 @@ static LRESULT WINPROC_CallProcWtoA( winproc_callback_t callback, HWND hwnd, UIN
else ret = callback( hwnd, msg, wParam, lParam, result, arg );
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_MENUCHAR:
case WM_CHAR:
case WM_DEADCHAR:
case WM_SYSCHAR:
case WM_SYSDEADCHAR:
......@@ -2202,7 +2188,7 @@ LRESULT WINPROC_CallProc32ATo16( winproc_callback16_t callback, HWND hwnd, UINT
* Call the window procedure of the specified window.
*/
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;
WINDOWPROC *proc;
......@@ -2231,7 +2217,7 @@ BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
if (proc->procA)
call_window_proc( hwnd, msg, wParam, lParam, result, proc->procA );
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;
}
......@@ -2302,7 +2288,8 @@ LRESULT WINAPI CallWindowProcA(
else if (proc->procA)
call_window_proc( hwnd, msg, wParam, lParam, &result, proc->procA );
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
WINPROC_CallProc32ATo16( call_window_proc16, hwnd, msg, wParam, lParam, &result, proc->proc16 );
return result;
......@@ -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 );
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 );
}
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