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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "wine/winuser16.h"
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(msg
);
32 DWORD USER16_AlertableWait
= 0;
34 /***********************************************************************
35 * SendMessage (USER.111)
37 LRESULT WINAPI
SendMessage16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
42 HWND hwnd
= WIN_Handle32( hwnd16
);
44 if (hwnd
!= HWND_BROADCAST
&& WIN_IsCurrentThread(hwnd
))
46 /* call 16-bit window proc directly */
49 /* first the WH_CALLWNDPROC hook */
50 if (HOOK_IsHooked( WH_CALLWNDPROC
))
52 LPARAM lparam32
= lparam
;
54 if (WINPROC_MapMsg16To32A( hwnd
, msg
, wparam
, &msg32
, &wparam32
, &lparam32
) != -1)
60 cwp
.wParam
= wparam32
;
61 cwp
.lParam
= lparam32
;
62 HOOK_CallHooks( WH_CALLWNDPROC
, HC_ACTION
, 1, (LPARAM
)&cwp
, FALSE
);
63 WINPROC_UnmapMsg16To32A( hwnd
, msg32
, wparam32
, lparam32
, 0 );
64 /* FIXME: should reflect changes back into the message we send */
68 if (!(winproc
= (WNDPROC16
)GetWindowLong16( hwnd16
, GWL_WNDPROC
))) return 0;
70 SPY_EnterMessage( SPY_SENDMESSAGE16
, hwnd
, msg
, wparam
, lparam
);
71 result
= CallWindowProc16( (WNDPROC16
)winproc
, hwnd16
, msg
, wparam
, lparam
);
72 SPY_ExitMessage( SPY_RESULT_OK16
, hwnd
, msg
, result
, wparam
, lparam
);
74 else /* map to 32-bit unicode for inter-thread/process message */
76 if (WINPROC_MapMsg16To32W( hwnd
, msg
, wparam
, &msg32
, &wparam32
, &lparam
) == -1)
78 result
= WINPROC_UnmapMsg16To32W( hwnd
, msg32
, wparam32
, lparam
,
79 SendMessageW( hwnd
, msg32
, wparam32
, lparam
) );
85 /***********************************************************************
86 * PostMessage (USER.110)
88 BOOL16 WINAPI
PostMessage16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
92 HWND hwnd
= WIN_Handle32( hwnd16
);
94 switch (WINPROC_MapMsg16To32W( hwnd
, msg
, wparam
, &msg32
, &wparam32
, &lparam
))
97 return PostMessageW( hwnd
, msg32
, wparam32
, lparam
);
99 ERR( "16-bit message 0x%04x contains pointer, cannot post\n", msg
);
107 /***********************************************************************
108 * PostAppMessage (USER.116)
110 BOOL16 WINAPI
PostAppMessage16( HTASK16 hTask
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
114 DWORD tid
= HTASK_32( hTask
);
115 if (!tid
) return FALSE
;
117 switch (WINPROC_MapMsg16To32W( 0, msg
, wparam
, &msg32
, &wparam32
, &lparam
))
120 return PostThreadMessageW( tid
, msg32
, wparam32
, lparam
);
122 ERR( "16-bit message %x contains pointer, cannot post\n", msg
);
130 /***********************************************************************
131 * InSendMessage (USER.192)
133 BOOL16 WINAPI
InSendMessage16(void)
135 return InSendMessage();
139 /***********************************************************************
140 * ReplyMessage (USER.115)
142 void WINAPI
ReplyMessage16( LRESULT result
)
144 ReplyMessage( result
);
148 /***********************************************************************
149 * PeekMessage32 (USER.819)
151 BOOL16 WINAPI
PeekMessage32_16( MSG32_16
*msg16
, HWND16 hwnd16
,
152 UINT16 first
, UINT16 last
, UINT16 flags
,
153 BOOL16 wHaveParamHigh
)
156 HWND hwnd
= WIN_Handle32( hwnd16
);
158 if(USER16_AlertableWait
)
159 MsgWaitForMultipleObjectsEx( 0, NULL
, 1, 0, MWMO_ALERTABLE
);
160 if (!PeekMessageW( &msg
, hwnd
, first
, last
, flags
)) return FALSE
;
162 msg16
->msg
.hwnd
= HWND_16( msg
.hwnd
);
163 msg16
->msg
.lParam
= msg
.lParam
;
164 msg16
->msg
.time
= msg
.time
;
165 msg16
->msg
.pt
.x
= (INT16
)msg
.pt
.x
;
166 msg16
->msg
.pt
.y
= (INT16
)msg
.pt
.y
;
167 if (wHaveParamHigh
) msg16
->wParamHigh
= HIWORD(msg
.wParam
);
169 return (WINPROC_MapMsg32WTo16( msg
.hwnd
, msg
.message
, msg
.wParam
,
170 &msg16
->msg
.message
, &msg16
->msg
.wParam
,
171 &msg16
->msg
.lParam
) != -1);
175 /***********************************************************************
176 * PeekMessage (USER.109)
178 BOOL16 WINAPI
PeekMessage16( MSG16
*msg
, HWND16 hwnd
,
179 UINT16 first
, UINT16 last
, UINT16 flags
)
181 return PeekMessage32_16( (MSG32_16
*)msg
, hwnd
, first
, last
, flags
, FALSE
);
185 /***********************************************************************
186 * GetMessage32 (USER.820)
188 BOOL16 WINAPI
GetMessage32_16( MSG32_16
*msg16
, HWND16 hwnd16
, UINT16 first
,
189 UINT16 last
, BOOL16 wHaveParamHigh
)
192 HWND hwnd
= WIN_Handle32( hwnd16
);
196 if(USER16_AlertableWait
)
197 MsgWaitForMultipleObjectsEx( 0, NULL
, INFINITE
, 0, MWMO_ALERTABLE
);
198 GetMessageW( &msg
, hwnd
, first
, last
);
199 msg16
->msg
.hwnd
= HWND_16( msg
.hwnd
);
200 msg16
->msg
.lParam
= msg
.lParam
;
201 msg16
->msg
.time
= msg
.time
;
202 msg16
->msg
.pt
.x
= (INT16
)msg
.pt
.x
;
203 msg16
->msg
.pt
.y
= (INT16
)msg
.pt
.y
;
204 if (wHaveParamHigh
) msg16
->wParamHigh
= HIWORD(msg
.wParam
);
206 while (WINPROC_MapMsg32WTo16( msg
.hwnd
, msg
.message
, msg
.wParam
,
207 &msg16
->msg
.message
, &msg16
->msg
.wParam
,
208 &msg16
->msg
.lParam
) == -1);
210 TRACE( "message %04x, hwnd %p, filter(%04x - %04x)\n",
211 msg16
->msg
.message
, hwnd
, first
, last
);
213 return msg16
->msg
.message
!= WM_QUIT
;
217 /***********************************************************************
218 * GetMessage (USER.108)
220 BOOL16 WINAPI
GetMessage16( MSG16
*msg
, HWND16 hwnd
, UINT16 first
, UINT16 last
)
222 return GetMessage32_16( (MSG32_16
*)msg
, hwnd
, first
, last
, FALSE
);
226 /***********************************************************************
227 * TranslateMessage32 (USER.821)
229 BOOL16 WINAPI
TranslateMessage32_16( const MSG32_16
*msg
, BOOL16 wHaveParamHigh
)
233 msg32
.hwnd
= WIN_Handle32( msg
->msg
.hwnd
);
234 msg32
.message
= msg
->msg
.message
;
235 msg32
.wParam
= MAKEWPARAM( msg
->msg
.wParam
, wHaveParamHigh
? msg
->wParamHigh
: 0 );
236 msg32
.lParam
= msg
->msg
.lParam
;
237 return TranslateMessage( &msg32
);
241 /***********************************************************************
242 * TranslateMessage (USER.113)
244 BOOL16 WINAPI
TranslateMessage16( const MSG16
*msg
)
246 return TranslateMessage32_16( (MSG32_16
*)msg
, FALSE
);
250 /***********************************************************************
251 * DispatchMessage (USER.114)
253 LONG WINAPI
DispatchMessage16( const MSG16
* msg
)
259 HWND hwnd
= WIN_Handle32( msg
->hwnd
);
261 /* Process timer messages */
262 if ((msg
->message
== WM_TIMER
) || (msg
->message
== WM_SYSTIMER
))
266 /* before calling window proc, verify whether timer is still valid;
267 there's a slim chance that the application kills the timer
268 between GetMessage and DispatchMessage API calls */
269 if (!TIMER_IsTimerValid(hwnd
, (UINT
) msg
->wParam
, (WNDPROC
)msg
->lParam
))
270 return 0; /* invalid winproc */
272 return CallWindowProc16( (WNDPROC16
)msg
->lParam
, msg
->hwnd
,
273 msg
->message
, msg
->wParam
, GetTickCount() );
277 if (!(wndPtr
= WIN_GetPtr( hwnd
)))
279 if (msg
->hwnd
) SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
282 if (wndPtr
== WND_OTHER_PROCESS
)
284 if (IsWindow( hwnd
))
285 ERR( "cannot dispatch msg to other process window %p\n", hwnd
);
286 SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
290 if (!(winproc
= (WNDPROC16
)wndPtr
->winproc
))
292 WIN_ReleasePtr( wndPtr
);
295 painting
= (msg
->message
== WM_PAINT
);
296 if (painting
) wndPtr
->flags
|= WIN_NEEDS_BEGINPAINT
;
297 WIN_ReleasePtr( wndPtr
);
299 SPY_EnterMessage( SPY_DISPATCHMESSAGE16
, hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
300 retval
= CallWindowProc16( winproc
, msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
301 SPY_ExitMessage( SPY_RESULT_OK16
, hwnd
, msg
->message
, retval
, msg
->wParam
, msg
->lParam
);
303 if (painting
&& (wndPtr
= WIN_GetPtr( hwnd
)) && (wndPtr
!= WND_OTHER_PROCESS
))
305 BOOL validate
= ((wndPtr
->flags
& WIN_NEEDS_BEGINPAINT
) && wndPtr
->hrgnUpdate
);
306 wndPtr
->flags
&= ~WIN_NEEDS_BEGINPAINT
;
307 WIN_ReleasePtr( wndPtr
);
310 ERR( "BeginPaint not called on WM_PAINT for hwnd %p!\n", hwnd
);
311 /* Validate the update region to avoid infinite WM_PAINT loop */
312 RedrawWindow( hwnd
, NULL
, 0,
313 RDW_NOFRAME
| RDW_VALIDATE
| RDW_NOCHILDREN
| RDW_NOINTERNALPAINT
);
320 /***********************************************************************
321 * DispatchMessage32 (USER.822)
323 LONG WINAPI
DispatchMessage32_16( const MSG32_16
*msg16
, BOOL16 wHaveParamHigh
)
325 if (wHaveParamHigh
== FALSE
)
326 return DispatchMessage16( &msg16
->msg
);
331 msg
.hwnd
= WIN_Handle32( msg16
->msg
.hwnd
);
332 msg
.message
= msg16
->msg
.message
;
333 msg
.wParam
= MAKEWPARAM( msg16
->msg
.wParam
, msg16
->wParamHigh
);
334 msg
.lParam
= msg16
->msg
.lParam
;
335 msg
.time
= msg16
->msg
.time
;
336 msg
.pt
.x
= msg16
->msg
.pt
.x
;
337 msg
.pt
.y
= msg16
->msg
.pt
.y
;
338 return DispatchMessageA( &msg
);
343 /***********************************************************************
344 * IsDialogMessage (USER.90)
346 BOOL16 WINAPI
IsDialogMessage16( HWND16 hwndDlg
, MSG16
*msg16
)
350 switch(msg16
->message
)
355 msg
.hwnd
= WIN_Handle32(msg16
->hwnd
);
356 msg
.lParam
= msg16
->lParam
;
357 WINPROC_MapMsg16To32W( msg
.hwnd
, msg16
->message
, msg16
->wParam
,
358 &msg
.message
, &msg
.wParam
, &msg
.lParam
);
359 /* these messages don't need an unmap */
360 return IsDialogMessageW( WIN_Handle32(hwndDlg
), &msg
);
362 TranslateMessage16( msg16
);
363 DispatchMessage16( msg16
);
368 /***********************************************************************
369 * MsgWaitForMultipleObjects (USER.640)
371 DWORD WINAPI
MsgWaitForMultipleObjects16( DWORD count
, CONST HANDLE
*handles
,
372 BOOL wait_all
, DWORD timeout
, DWORD mask
)
374 return MsgWaitForMultipleObjectsEx( count
, handles
, timeout
, mask
,
375 wait_all
? MWMO_WAITALL
: 0 );
379 /**********************************************************************
380 * SetDoubleClickTime (USER.20)
382 void WINAPI
SetDoubleClickTime16( UINT16 interval
)
384 SetDoubleClickTime( interval
);
388 /**********************************************************************
389 * GetDoubleClickTime (USER.21)
391 UINT16 WINAPI
GetDoubleClickTime16(void)
393 return GetDoubleClickTime();
397 /***********************************************************************
398 * PostQuitMessage (USER.6)
400 void WINAPI
PostQuitMessage16( INT16 exitCode
)
402 PostQuitMessage( exitCode
);
406 /**********************************************************************
407 * GetKeyState (USER.106)
409 INT16 WINAPI
GetKeyState16(INT16 vkey
)
411 return GetKeyState(vkey
);
415 /**********************************************************************
416 * GetKeyboardState (USER.222)
418 BOOL WINAPI
GetKeyboardState16( LPBYTE state
)
420 return GetKeyboardState( state
);
424 /**********************************************************************
425 * SetKeyboardState (USER.223)
427 BOOL WINAPI
SetKeyboardState16( LPBYTE state
)
429 return SetKeyboardState( state
);
433 /***********************************************************************
434 * SetMessageQueue (USER.266)
436 BOOL16 WINAPI
SetMessageQueue16( INT16 size
)
438 return SetMessageQueue( size
);
442 /***********************************************************************
443 * GetQueueStatus (USER.334)
445 DWORD WINAPI
GetQueueStatus16( UINT16 flags
)
447 return GetQueueStatus( flags
);
451 /***********************************************************************
452 * GetInputState (USER.335)
454 BOOL16 WINAPI
GetInputState16(void)
456 return GetInputState();
460 /**********************************************************************
461 * TranslateAccelerator (USER.178)
463 INT16 WINAPI
TranslateAccelerator16( HWND16 hwnd
, HACCEL16 hAccel
, LPMSG16 msg
)
468 msg32
.message
= msg
->message
;
469 /* msg32.hwnd not used */
470 msg32
.wParam
= msg
->wParam
;
471 msg32
.lParam
= msg
->lParam
;
472 return TranslateAccelerator( WIN_Handle32(hwnd
), HACCEL_32(hAccel
), &msg32
);
476 /**********************************************************************
477 * TranslateMDISysAccel (USER.451)
479 BOOL16 WINAPI
TranslateMDISysAccel16( HWND16 hwndClient
, LPMSG16 msg
)
481 if (msg
->message
== WM_KEYDOWN
|| msg
->message
== WM_SYSKEYDOWN
)
484 msg32
.hwnd
= WIN_Handle32(msg
->hwnd
);
485 msg32
.message
= msg
->message
;
486 msg32
.wParam
= msg
->wParam
;
487 msg32
.lParam
= msg
->lParam
;
488 /* MDICLIENTINFO is still the same for win32 and win16 ... */
489 return TranslateMDISysAccel( WIN_Handle32(hwndClient
), &msg32
);