2 * 16-bit messaging support
4 * Copyright 2001 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/winuser16.h"
25 #include "user_private.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(msg);
30 DWORD USER16_AlertableWait = 0;
32 static LRESULT cwp_hook_callback( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
33 LRESULT *result, void *arg )
42 return HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp, FALSE );
45 static LRESULT send_message_callback( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
46 LRESULT *result, void *arg )
48 *result = SendMessageA( hwnd, msg, wp, lp );
52 static LRESULT post_message_callback( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
53 LRESULT *result, void *arg )
56 return PostMessageA( hwnd, msg, wp, lp );
59 static LRESULT post_thread_message_callback( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
60 LRESULT *result, void *arg )
62 DWORD_PTR tid = (DWORD_PTR)arg;
64 return PostThreadMessageA( tid, msg, wp, lp );
67 static LRESULT get_message_callback( HWND16 hwnd, UINT16 msg, WPARAM16 wp, LPARAM lp,
68 LRESULT *result, void *arg )
80 static LRESULT defdlg_proc_callback( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
81 LRESULT *result, void *arg )
83 *result = DefDlgProcA( hwnd, msg, wp, lp );
88 /***********************************************************************
89 * SendMessage (USER.111)
91 LRESULT WINAPI SendMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
94 HWND hwnd = WIN_Handle32( hwnd16 );
96 if (hwnd != HWND_BROADCAST && WIN_IsCurrentThread(hwnd))
98 /* call 16-bit window proc directly */
101 /* first the WH_CALLWNDPROC hook */
102 if (HOOK_IsHooked( WH_CALLWNDPROC ))
103 WINPROC_CallProc16To32A( cwp_hook_callback, hwnd16, msg, wparam, lparam, &result, NULL );
105 if (!(winproc = (WNDPROC16)GetWindowLong16( hwnd16, GWLP_WNDPROC ))) return 0;
107 SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wparam, lparam );
108 result = CallWindowProc16( winproc, hwnd16, msg, wparam, lparam );
109 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, result, wparam, lparam );
111 else /* map to 32-bit unicode for inter-thread/process message */
113 WINPROC_CallProc16To32A( send_message_callback, hwnd16, msg, wparam, lparam, &result, NULL );
119 /***********************************************************************
120 * PostMessage (USER.110)
122 BOOL16 WINAPI PostMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
125 return WINPROC_CallProc16To32A( post_message_callback, hwnd, msg, wparam, lparam, &unused, NULL );
129 /***********************************************************************
130 * PostAppMessage (USER.116)
132 BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
135 DWORD_PTR tid = HTASK_32( hTask );
137 if (!tid) return FALSE;
138 return WINPROC_CallProc16To32A( post_thread_message_callback, 0, msg, wparam, lparam,
139 &unused, (void *)tid );
143 /***********************************************************************
144 * InSendMessage (USER.192)
146 BOOL16 WINAPI InSendMessage16(void)
148 return InSendMessage();
152 /***********************************************************************
153 * ReplyMessage (USER.115)
155 void WINAPI ReplyMessage16( LRESULT result )
157 ReplyMessage( result );
161 /***********************************************************************
162 * PeekMessage32 (USER.819)
164 BOOL16 WINAPI PeekMessage32_16( MSG32_16 *msg16, HWND16 hwnd16,
165 UINT16 first, UINT16 last, UINT16 flags,
166 BOOL16 wHaveParamHigh )
170 HWND hwnd = WIN_Handle32( hwnd16 );
172 if(USER16_AlertableWait)
173 MsgWaitForMultipleObjectsEx( 0, NULL, 0, 0, MWMO_ALERTABLE );
174 if (!PeekMessageA( &msg, hwnd, first, last, flags )) return FALSE;
176 msg16->msg.time = msg.time;
177 msg16->msg.pt.x = (INT16)msg.pt.x;
178 msg16->msg.pt.y = (INT16)msg.pt.y;
179 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
180 WINPROC_CallProc32ATo16( get_message_callback, msg.hwnd, msg.message, msg.wParam, msg.lParam,
181 &unused, &msg16->msg );
186 /***********************************************************************
187 * DefWindowProc (USER.107)
189 LRESULT WINAPI DefWindowProc16( HWND16 hwnd16, UINT16 msg, WPARAM16 wParam, LPARAM lParam )
192 HWND hwnd = WIN_Handle32( hwnd16 );
194 SPY_EnterMessage( SPY_DEFWNDPROC16, hwnd, msg, wParam, lParam );
200 CREATESTRUCT16 *cs16 = MapSL(lParam);
203 cs32.lpCreateParams = ULongToPtr(cs16->lpCreateParams);
204 cs32.hInstance = HINSTANCE_32(cs16->hInstance);
205 cs32.hMenu = HMENU_32(cs16->hMenu);
206 cs32.hwndParent = WIN_Handle32(cs16->hwndParent);
211 cs32.style = cs16->style;
212 cs32.dwExStyle = cs16->dwExStyle;
213 cs32.lpszName = MapSL(cs16->lpszName);
214 cs32.lpszClass = MapSL(cs16->lpszClass);
215 result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)&cs32 );
221 RECT16 *rect16 = MapSL(lParam);
224 rect32.left = rect16->left;
225 rect32.top = rect16->top;
226 rect32.right = rect16->right;
227 rect32.bottom = rect16->bottom;
229 result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)&rect32 );
231 rect16->left = rect32.left;
232 rect16->top = rect32.top;
233 rect16->right = rect32.right;
234 rect16->bottom = rect32.bottom;
238 case WM_WINDOWPOSCHANGING:
239 case WM_WINDOWPOSCHANGED:
241 WINDOWPOS16 *pos16 = MapSL(lParam);
244 pos32.hwnd = WIN_Handle32(pos16->hwnd);
245 pos32.hwndInsertAfter = WIN_Handle32(pos16->hwndInsertAfter);
248 pos32.cx = pos16->cx;
249 pos32.cy = pos16->cy;
250 pos32.flags = pos16->flags;
252 result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)&pos32 );
254 pos16->hwnd = HWND_16(pos32.hwnd);
255 pos16->hwndInsertAfter = HWND_16(pos32.hwndInsertAfter);
258 pos16->cx = pos32.cx;
259 pos16->cy = pos32.cy;
260 pos16->flags = pos32.flags;
266 result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)MapSL(lParam) );
270 result = DefWindowProcA( hwnd, msg, wParam, lParam );
274 SPY_ExitMessage( SPY_RESULT_DEFWND16, hwnd, msg, result, wParam, lParam );
279 /***********************************************************************
280 * DefDlgProc (USER.308)
282 LRESULT WINAPI DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam )
285 WINPROC_CallProc16To32A( defdlg_proc_callback, hwnd, msg, wParam, lParam, &result, 0 );
290 /***********************************************************************
291 * PeekMessage (USER.109)
293 BOOL16 WINAPI PeekMessage16( MSG16 *msg, HWND16 hwnd,
294 UINT16 first, UINT16 last, UINT16 flags )
296 return PeekMessage32_16( (MSG32_16 *)msg, hwnd, first, last, flags, FALSE );
300 /***********************************************************************
301 * GetMessage32 (USER.820)
303 BOOL16 WINAPI GetMessage32_16( MSG32_16 *msg16, HWND16 hwnd16, UINT16 first,
304 UINT16 last, BOOL16 wHaveParamHigh )
308 HWND hwnd = WIN_Handle32( hwnd16 );
310 if(USER16_AlertableWait)
311 MsgWaitForMultipleObjectsEx( 0, NULL, INFINITE, 0, MWMO_ALERTABLE );
312 GetMessageA( &msg, hwnd, first, last );
313 msg16->msg.time = msg.time;
314 msg16->msg.pt.x = (INT16)msg.pt.x;
315 msg16->msg.pt.y = (INT16)msg.pt.y;
316 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
317 WINPROC_CallProc32ATo16( get_message_callback, msg.hwnd, msg.message, msg.wParam, msg.lParam,
318 &unused, &msg16->msg );
320 TRACE( "message %04x, hwnd %p, filter(%04x - %04x)\n",
321 msg16->msg.message, hwnd, first, last );
323 return msg16->msg.message != WM_QUIT;
327 /***********************************************************************
328 * GetMessage (USER.108)
330 BOOL16 WINAPI GetMessage16( MSG16 *msg, HWND16 hwnd, UINT16 first, UINT16 last )
332 return GetMessage32_16( (MSG32_16 *)msg, hwnd, first, last, FALSE );
336 /***********************************************************************
337 * TranslateMessage32 (USER.821)
339 BOOL16 WINAPI TranslateMessage32_16( const MSG32_16 *msg, BOOL16 wHaveParamHigh )
343 msg32.hwnd = WIN_Handle32( msg->msg.hwnd );
344 msg32.message = msg->msg.message;
345 msg32.wParam = MAKEWPARAM( msg->msg.wParam, wHaveParamHigh ? msg->wParamHigh : 0 );
346 msg32.lParam = msg->msg.lParam;
347 return TranslateMessage( &msg32 );
351 /***********************************************************************
352 * TranslateMessage (USER.113)
354 BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
356 return TranslateMessage32_16( (const MSG32_16 *)msg, FALSE );
360 /***********************************************************************
361 * DispatchMessage (USER.114)
363 LONG WINAPI DispatchMessage16( const MSG16* msg )
368 HWND hwnd = WIN_Handle32( msg->hwnd );
370 /* Process timer messages */
371 if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
374 return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
375 msg->message, msg->wParam, GetTickCount() );
378 if (!(wndPtr = WIN_GetPtr( hwnd )))
380 if (msg->hwnd) SetLastError( ERROR_INVALID_WINDOW_HANDLE );
383 if (wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP)
385 if (IsWindow( hwnd )) SetLastError( ERROR_MESSAGE_SYNC_ONLY );
386 else SetLastError( ERROR_INVALID_WINDOW_HANDLE );
389 winproc = WINPROC_GetProc16( wndPtr->winproc, wndPtr->flags & WIN_ISUNICODE );
390 WIN_ReleasePtr( wndPtr );
392 SPY_EnterMessage( SPY_DISPATCHMESSAGE16, hwnd, msg->message, msg->wParam, msg->lParam );
393 retval = CallWindowProc16( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam );
394 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg->message, retval, msg->wParam, msg->lParam );
400 /***********************************************************************
401 * DispatchMessage32 (USER.822)
403 LONG WINAPI DispatchMessage32_16( const MSG32_16 *msg16, BOOL16 wHaveParamHigh )
405 if (wHaveParamHigh == FALSE)
406 return DispatchMessage16( &msg16->msg );
411 msg.hwnd = WIN_Handle32( msg16->msg.hwnd );
412 msg.message = msg16->msg.message;
413 msg.wParam = MAKEWPARAM( msg16->msg.wParam, msg16->wParamHigh );
414 msg.lParam = msg16->msg.lParam;
415 msg.time = msg16->msg.time;
416 msg.pt.x = msg16->msg.pt.x;
417 msg.pt.y = msg16->msg.pt.y;
418 return DispatchMessageA( &msg );
423 /***********************************************************************
424 * IsDialogMessage (USER.90)
426 BOOL16 WINAPI IsDialogMessage16( HWND16 hwndDlg, MSG16 *msg16 )
431 msg.hwnd = WIN_Handle32(msg16->hwnd);
432 hwndDlg32 = WIN_Handle32(hwndDlg);
434 switch(msg16->message)
439 msg.message = msg16->message;
440 msg.wParam = msg16->wParam;
441 msg.lParam = msg16->lParam;
442 return IsDialogMessageA( hwndDlg32, &msg );
445 if ((hwndDlg32 != msg.hwnd) && !IsChild( hwndDlg32, msg.hwnd )) return FALSE;
446 TranslateMessage16( msg16 );
447 DispatchMessage16( msg16 );
452 /***********************************************************************
453 * MsgWaitForMultipleObjects (USER.640)
455 DWORD WINAPI MsgWaitForMultipleObjects16( DWORD count, CONST HANDLE *handles,
456 BOOL wait_all, DWORD timeout, DWORD mask )
458 return MsgWaitForMultipleObjectsEx( count, handles, timeout, mask,
459 wait_all ? MWMO_WAITALL : 0 );
463 /**********************************************************************
464 * SetDoubleClickTime (USER.20)
466 void WINAPI SetDoubleClickTime16( UINT16 interval )
468 SetDoubleClickTime( interval );
472 /**********************************************************************
473 * GetDoubleClickTime (USER.21)
475 UINT16 WINAPI GetDoubleClickTime16(void)
477 return GetDoubleClickTime();
481 /***********************************************************************
482 * PostQuitMessage (USER.6)
484 void WINAPI PostQuitMessage16( INT16 exitCode )
486 PostQuitMessage( exitCode );
490 /**********************************************************************
491 * GetKeyState (USER.106)
493 INT16 WINAPI GetKeyState16(INT16 vkey)
495 return GetKeyState(vkey);
499 /**********************************************************************
500 * GetKeyboardState (USER.222)
502 BOOL WINAPI GetKeyboardState16( LPBYTE state )
504 return GetKeyboardState( state );
508 /**********************************************************************
509 * SetKeyboardState (USER.223)
511 BOOL WINAPI SetKeyboardState16( LPBYTE state )
513 return SetKeyboardState( state );
517 /***********************************************************************
518 * SetMessageQueue (USER.266)
520 BOOL16 WINAPI SetMessageQueue16( INT16 size )
522 return SetMessageQueue( size );
526 /***********************************************************************
527 * UserYield (USER.332)
529 void WINAPI UserYield16(void)
532 PeekMessageW( &msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE );
536 /***********************************************************************
537 * GetQueueStatus (USER.334)
539 DWORD WINAPI GetQueueStatus16( UINT16 flags )
541 return GetQueueStatus( flags );
545 /***********************************************************************
546 * GetInputState (USER.335)
548 BOOL16 WINAPI GetInputState16(void)
550 return GetInputState();
554 /**********************************************************************
555 * TranslateAccelerator (USER.178)
557 INT16 WINAPI TranslateAccelerator16( HWND16 hwnd, HACCEL16 hAccel, LPMSG16 msg )
562 msg32.message = msg->message;
563 /* msg32.hwnd not used */
564 msg32.wParam = msg->wParam;
565 msg32.lParam = msg->lParam;
566 return TranslateAcceleratorW( WIN_Handle32(hwnd), HACCEL_32(hAccel), &msg32 );
570 /**********************************************************************
571 * TranslateMDISysAccel (USER.451)
573 BOOL16 WINAPI TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg )
575 if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
578 msg32.hwnd = WIN_Handle32(msg->hwnd);
579 msg32.message = msg->message;
580 msg32.wParam = msg->wParam;
581 msg32.lParam = msg->lParam;
582 /* MDICLIENTINFO is still the same for win32 and win16 ... */
583 return TranslateMDISysAccel( WIN_Handle32(hwndClient), &msg32 );