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
)
81 /***********************************************************************
82 * SendMessage (USER.111)
84 LRESULT WINAPI
SendMessage16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
87 HWND hwnd
= WIN_Handle32( hwnd16
);
89 if (hwnd
!= HWND_BROADCAST
&& WIN_IsCurrentThread(hwnd
))
91 /* call 16-bit window proc directly */
94 /* first the WH_CALLWNDPROC hook */
95 if (HOOK_IsHooked( WH_CALLWNDPROC
))
96 WINPROC_CallProc16To32A( cwp_hook_callback
, hwnd16
, msg
, wparam
, lparam
, &result
, NULL
);
98 if (!(winproc
= (WNDPROC16
)GetWindowLong16( hwnd16
, GWLP_WNDPROC
))) return 0;
100 SPY_EnterMessage( SPY_SENDMESSAGE16
, hwnd
, msg
, wparam
, lparam
);
101 result
= CallWindowProc16( winproc
, hwnd16
, msg
, wparam
, lparam
);
102 SPY_ExitMessage( SPY_RESULT_OK16
, hwnd
, msg
, result
, wparam
, lparam
);
104 else /* map to 32-bit unicode for inter-thread/process message */
106 WINPROC_CallProc16To32A( send_message_callback
, hwnd16
, msg
, wparam
, lparam
, &result
, NULL
);
112 /***********************************************************************
113 * PostMessage (USER.110)
115 BOOL16 WINAPI
PostMessage16( HWND16 hwnd
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
118 return WINPROC_CallProc16To32A( post_message_callback
, hwnd
, msg
, wparam
, lparam
, &unused
, NULL
);
122 /***********************************************************************
123 * PostAppMessage (USER.116)
125 BOOL16 WINAPI
PostAppMessage16( HTASK16 hTask
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
128 DWORD_PTR tid
= HTASK_32( hTask
);
130 if (!tid
) return FALSE
;
131 return WINPROC_CallProc16To32A( post_thread_message_callback
, 0, msg
, wparam
, lparam
,
132 &unused
, (void *)tid
);
136 /***********************************************************************
137 * InSendMessage (USER.192)
139 BOOL16 WINAPI
InSendMessage16(void)
141 return InSendMessage();
145 /***********************************************************************
146 * ReplyMessage (USER.115)
148 void WINAPI
ReplyMessage16( LRESULT result
)
150 ReplyMessage( result
);
154 /***********************************************************************
155 * PeekMessage32 (USER.819)
157 BOOL16 WINAPI
PeekMessage32_16( MSG32_16
*msg16
, HWND16 hwnd16
,
158 UINT16 first
, UINT16 last
, UINT16 flags
,
159 BOOL16 wHaveParamHigh
)
163 HWND hwnd
= WIN_Handle32( hwnd16
);
165 if(USER16_AlertableWait
)
166 MsgWaitForMultipleObjectsEx( 0, NULL
, 0, 0, MWMO_ALERTABLE
);
167 if (!PeekMessageA( &msg
, hwnd
, first
, last
, flags
)) return FALSE
;
169 msg16
->msg
.time
= msg
.time
;
170 msg16
->msg
.pt
.x
= (INT16
)msg
.pt
.x
;
171 msg16
->msg
.pt
.y
= (INT16
)msg
.pt
.y
;
172 if (wHaveParamHigh
) msg16
->wParamHigh
= HIWORD(msg
.wParam
);
173 WINPROC_CallProc32ATo16( get_message_callback
, msg
.hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
,
174 &unused
, &msg16
->msg
);
179 /***********************************************************************
180 * DefWindowProc (USER.107)
182 LRESULT WINAPI
DefWindowProc16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wParam
, LPARAM lParam
)
185 HWND hwnd
= WIN_Handle32( hwnd16
);
187 SPY_EnterMessage( SPY_DEFWNDPROC16
, hwnd
, msg
, wParam
, lParam
);
193 CREATESTRUCT16
*cs16
= MapSL(lParam
);
196 cs32
.lpCreateParams
= ULongToPtr(cs16
->lpCreateParams
);
197 cs32
.hInstance
= HINSTANCE_32(cs16
->hInstance
);
198 cs32
.hMenu
= HMENU_32(cs16
->hMenu
);
199 cs32
.hwndParent
= WIN_Handle32(cs16
->hwndParent
);
204 cs32
.style
= cs16
->style
;
205 cs32
.dwExStyle
= cs16
->dwExStyle
;
206 cs32
.lpszName
= MapSL(cs16
->lpszName
);
207 cs32
.lpszClass
= MapSL(cs16
->lpszClass
);
208 result
= DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&cs32
);
214 RECT16
*rect16
= MapSL(lParam
);
217 rect32
.left
= rect16
->left
;
218 rect32
.top
= rect16
->top
;
219 rect32
.right
= rect16
->right
;
220 rect32
.bottom
= rect16
->bottom
;
222 result
= DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&rect32
);
224 rect16
->left
= rect32
.left
;
225 rect16
->top
= rect32
.top
;
226 rect16
->right
= rect32
.right
;
227 rect16
->bottom
= rect32
.bottom
;
231 case WM_WINDOWPOSCHANGING
:
232 case WM_WINDOWPOSCHANGED
:
234 WINDOWPOS16
*pos16
= MapSL(lParam
);
237 pos32
.hwnd
= WIN_Handle32(pos16
->hwnd
);
238 pos32
.hwndInsertAfter
= WIN_Handle32(pos16
->hwndInsertAfter
);
241 pos32
.cx
= pos16
->cx
;
242 pos32
.cy
= pos16
->cy
;
243 pos32
.flags
= pos16
->flags
;
245 result
= DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)&pos32
);
247 pos16
->hwnd
= HWND_16(pos32
.hwnd
);
248 pos16
->hwndInsertAfter
= HWND_16(pos32
.hwndInsertAfter
);
251 pos16
->cx
= pos32
.cx
;
252 pos16
->cy
= pos32
.cy
;
253 pos16
->flags
= pos32
.flags
;
259 result
= DefWindowProcA( hwnd
, msg
, wParam
, (LPARAM
)MapSL(lParam
) );
263 result
= DefWindowProcA( hwnd
, msg
, wParam
, lParam
);
267 SPY_ExitMessage( SPY_RESULT_DEFWND16
, hwnd
, msg
, result
, wParam
, lParam
);
272 /***********************************************************************
273 * PeekMessage (USER.109)
275 BOOL16 WINAPI
PeekMessage16( MSG16
*msg
, HWND16 hwnd
,
276 UINT16 first
, UINT16 last
, UINT16 flags
)
278 return PeekMessage32_16( (MSG32_16
*)msg
, hwnd
, first
, last
, flags
, FALSE
);
282 /***********************************************************************
283 * GetMessage32 (USER.820)
285 BOOL16 WINAPI
GetMessage32_16( MSG32_16
*msg16
, HWND16 hwnd16
, UINT16 first
,
286 UINT16 last
, BOOL16 wHaveParamHigh
)
290 HWND hwnd
= WIN_Handle32( hwnd16
);
292 if(USER16_AlertableWait
)
293 MsgWaitForMultipleObjectsEx( 0, NULL
, INFINITE
, 0, MWMO_ALERTABLE
);
294 GetMessageA( &msg
, hwnd
, first
, last
);
295 msg16
->msg
.time
= msg
.time
;
296 msg16
->msg
.pt
.x
= (INT16
)msg
.pt
.x
;
297 msg16
->msg
.pt
.y
= (INT16
)msg
.pt
.y
;
298 if (wHaveParamHigh
) msg16
->wParamHigh
= HIWORD(msg
.wParam
);
299 WINPROC_CallProc32ATo16( get_message_callback
, msg
.hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
,
300 &unused
, &msg16
->msg
);
302 TRACE( "message %04x, hwnd %p, filter(%04x - %04x)\n",
303 msg16
->msg
.message
, hwnd
, first
, last
);
305 return msg16
->msg
.message
!= WM_QUIT
;
309 /***********************************************************************
310 * GetMessage (USER.108)
312 BOOL16 WINAPI
GetMessage16( MSG16
*msg
, HWND16 hwnd
, UINT16 first
, UINT16 last
)
314 return GetMessage32_16( (MSG32_16
*)msg
, hwnd
, first
, last
, FALSE
);
318 /***********************************************************************
319 * TranslateMessage32 (USER.821)
321 BOOL16 WINAPI
TranslateMessage32_16( const MSG32_16
*msg
, BOOL16 wHaveParamHigh
)
325 msg32
.hwnd
= WIN_Handle32( msg
->msg
.hwnd
);
326 msg32
.message
= msg
->msg
.message
;
327 msg32
.wParam
= MAKEWPARAM( msg
->msg
.wParam
, wHaveParamHigh
? msg
->wParamHigh
: 0 );
328 msg32
.lParam
= msg
->msg
.lParam
;
329 return TranslateMessage( &msg32
);
333 /***********************************************************************
334 * TranslateMessage (USER.113)
336 BOOL16 WINAPI
TranslateMessage16( const MSG16
*msg
)
338 return TranslateMessage32_16( (const MSG32_16
*)msg
, FALSE
);
342 /***********************************************************************
343 * DispatchMessage (USER.114)
345 LONG WINAPI
DispatchMessage16( const MSG16
* msg
)
350 HWND hwnd
= WIN_Handle32( msg
->hwnd
);
352 /* Process timer messages */
353 if ((msg
->message
== WM_TIMER
) || (msg
->message
== WM_SYSTIMER
))
356 return CallWindowProc16( (WNDPROC16
)msg
->lParam
, msg
->hwnd
,
357 msg
->message
, msg
->wParam
, GetTickCount() );
360 if (!(wndPtr
= WIN_GetPtr( hwnd
)))
362 if (msg
->hwnd
) SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
365 if (wndPtr
== WND_OTHER_PROCESS
|| wndPtr
== WND_DESKTOP
)
367 if (IsWindow( hwnd
)) SetLastError( ERROR_MESSAGE_SYNC_ONLY
);
368 else SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
371 winproc
= WINPROC_GetProc16( wndPtr
->winproc
, wndPtr
->flags
& WIN_ISUNICODE
);
372 WIN_ReleasePtr( wndPtr
);
374 SPY_EnterMessage( SPY_DISPATCHMESSAGE16
, hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
375 retval
= CallWindowProc16( winproc
, msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
376 SPY_ExitMessage( SPY_RESULT_OK16
, hwnd
, msg
->message
, retval
, msg
->wParam
, msg
->lParam
);
382 /***********************************************************************
383 * DispatchMessage32 (USER.822)
385 LONG WINAPI
DispatchMessage32_16( const MSG32_16
*msg16
, BOOL16 wHaveParamHigh
)
387 if (wHaveParamHigh
== FALSE
)
388 return DispatchMessage16( &msg16
->msg
);
393 msg
.hwnd
= WIN_Handle32( msg16
->msg
.hwnd
);
394 msg
.message
= msg16
->msg
.message
;
395 msg
.wParam
= MAKEWPARAM( msg16
->msg
.wParam
, msg16
->wParamHigh
);
396 msg
.lParam
= msg16
->msg
.lParam
;
397 msg
.time
= msg16
->msg
.time
;
398 msg
.pt
.x
= msg16
->msg
.pt
.x
;
399 msg
.pt
.y
= msg16
->msg
.pt
.y
;
400 return DispatchMessageA( &msg
);
405 /***********************************************************************
406 * IsDialogMessage (USER.90)
408 BOOL16 WINAPI
IsDialogMessage16( HWND16 hwndDlg
, MSG16
*msg16
)
413 msg
.hwnd
= WIN_Handle32(msg16
->hwnd
);
414 hwndDlg32
= WIN_Handle32(hwndDlg
);
416 switch(msg16
->message
)
421 msg
.message
= msg16
->message
;
422 msg
.wParam
= msg16
->wParam
;
423 msg
.lParam
= msg16
->lParam
;
424 return IsDialogMessageA( hwndDlg32
, &msg
);
427 if ((hwndDlg32
!= msg
.hwnd
) && !IsChild( hwndDlg32
, msg
.hwnd
)) return FALSE
;
428 TranslateMessage16( msg16
);
429 DispatchMessage16( msg16
);
434 /***********************************************************************
435 * MsgWaitForMultipleObjects (USER.640)
437 DWORD WINAPI
MsgWaitForMultipleObjects16( DWORD count
, CONST HANDLE
*handles
,
438 BOOL wait_all
, DWORD timeout
, DWORD mask
)
440 return MsgWaitForMultipleObjectsEx( count
, handles
, timeout
, mask
,
441 wait_all
? MWMO_WAITALL
: 0 );
445 /**********************************************************************
446 * SetDoubleClickTime (USER.20)
448 void WINAPI
SetDoubleClickTime16( UINT16 interval
)
450 SetDoubleClickTime( interval
);
454 /**********************************************************************
455 * GetDoubleClickTime (USER.21)
457 UINT16 WINAPI
GetDoubleClickTime16(void)
459 return GetDoubleClickTime();
463 /***********************************************************************
464 * PostQuitMessage (USER.6)
466 void WINAPI
PostQuitMessage16( INT16 exitCode
)
468 PostQuitMessage( exitCode
);
472 /**********************************************************************
473 * GetKeyState (USER.106)
475 INT16 WINAPI
GetKeyState16(INT16 vkey
)
477 return GetKeyState(vkey
);
481 /**********************************************************************
482 * GetKeyboardState (USER.222)
484 BOOL WINAPI
GetKeyboardState16( LPBYTE state
)
486 return GetKeyboardState( state
);
490 /**********************************************************************
491 * SetKeyboardState (USER.223)
493 BOOL WINAPI
SetKeyboardState16( LPBYTE state
)
495 return SetKeyboardState( state
);
499 /***********************************************************************
500 * SetMessageQueue (USER.266)
502 BOOL16 WINAPI
SetMessageQueue16( INT16 size
)
504 return SetMessageQueue( size
);
508 /***********************************************************************
509 * GetQueueStatus (USER.334)
511 DWORD WINAPI
GetQueueStatus16( UINT16 flags
)
513 return GetQueueStatus( flags
);
517 /***********************************************************************
518 * GetInputState (USER.335)
520 BOOL16 WINAPI
GetInputState16(void)
522 return GetInputState();
526 /**********************************************************************
527 * TranslateAccelerator (USER.178)
529 INT16 WINAPI
TranslateAccelerator16( HWND16 hwnd
, HACCEL16 hAccel
, LPMSG16 msg
)
534 msg32
.message
= msg
->message
;
535 /* msg32.hwnd not used */
536 msg32
.wParam
= msg
->wParam
;
537 msg32
.lParam
= msg
->lParam
;
538 return TranslateAcceleratorW( WIN_Handle32(hwnd
), HACCEL_32(hAccel
), &msg32
);
542 /**********************************************************************
543 * TranslateMDISysAccel (USER.451)
545 BOOL16 WINAPI
TranslateMDISysAccel16( HWND16 hwndClient
, LPMSG16 msg
)
547 if (msg
->message
== WM_KEYDOWN
|| msg
->message
== WM_SYSKEYDOWN
)
550 msg32
.hwnd
= WIN_Handle32(msg
->hwnd
);
551 msg32
.message
= msg
->message
;
552 msg32
.wParam
= msg
->wParam
;
553 msg32
.lParam
= msg
->lParam
;
554 /* MDICLIENTINFO is still the same for win32 and win16 ... */
555 return TranslateMDISysAccel( WIN_Handle32(hwndClient
), &msg32
);