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
);