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"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(msg
);
33 DWORD USER16_AlertableWait
= 0;
35 /***********************************************************************
36 * SendMessage (USER.111)
38 LRESULT WINAPI
SendMessage16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
41 HWND hwnd
= WIN_Handle32( hwnd16
);
43 if (hwnd
!= HWND_BROADCAST
&& WIN_IsCurrentThread(hwnd
))
45 /* call 16-bit window proc directly */
48 /* first the WH_CALLWNDPROC hook */
49 if (HOOK_IsHooked( WH_CALLWNDPROC
))
58 seg_cwp
= MapLS( &cwp
);
59 HOOK_CallHooks16( WH_CALLWNDPROC
, HC_ACTION
, 1, seg_cwp
);
61 if (cwp
.hwnd
!= hwnd16
)
64 hwnd
= WIN_Handle32( hwnd16
);
71 if (!(winproc
= (WNDPROC16
)GetWindowLong16( hwnd16
, GWL_WNDPROC
))) return 0;
73 SPY_EnterMessage( SPY_SENDMESSAGE16
, hwnd
, msg
, wparam
, lparam
);
74 result
= CallWindowProc16( (WNDPROC16
)winproc
, hwnd16
, msg
, wparam
, lparam
);
75 SPY_ExitMessage( SPY_RESULT_OK16
, hwnd
, msg
, result
, wparam
, lparam
);
77 else /* map to 32-bit unicode for inter-thread/process message */
82 if (WINPROC_MapMsg16To32W( hwnd
, msg
, wparam
, &msg32
, &wparam32
, &lparam
) == -1)
84 result
= WINPROC_UnmapMsg16To32W( hwnd
, msg32
, wparam32
, lparam
,
85 SendMessageW( hwnd
, msg32
, wparam32
, lparam
) );
91 /***********************************************************************
92 * PostMessage (USER.110)
94 BOOL16 WINAPI
PostMessage16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
98 HWND hwnd
= WIN_Handle32( hwnd16
);
100 switch (WINPROC_MapMsg16To32W( hwnd
, msg
, wparam
, &msg32
, &wparam32
, &lparam
))
103 return PostMessageW( hwnd
, msg32
, wparam32
, lparam
);
105 ERR( "16-bit message 0x%04x contains pointer, cannot post\n", msg
);
113 /***********************************************************************
114 * PostAppMessage (USER.116)
115 * PostAppMessage16 (USER32.@)
117 BOOL16 WINAPI
PostAppMessage16( HTASK16 hTask
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
121 TDB
*pTask
= TASK_GetPtr( hTask
);
122 if (!pTask
) return FALSE
;
124 switch (WINPROC_MapMsg16To32W( 0, msg
, wparam
, &msg32
, &wparam32
, &lparam
))
127 return PostThreadMessageW( (DWORD
)pTask
->teb
->tid
, msg32
, wparam32
, lparam
);
129 ERR( "16-bit message %x contains pointer, cannot post\n", msg
);
137 /***********************************************************************
138 * InSendMessage (USER.192)
140 BOOL16 WINAPI
InSendMessage16(void)
142 return InSendMessage();
146 /***********************************************************************
147 * ReplyMessage (USER.115)
149 void WINAPI
ReplyMessage16( LRESULT result
)
151 ReplyMessage( result
);
155 /***********************************************************************
156 * PeekMessage32 (USER.819)
158 BOOL16 WINAPI
PeekMessage32_16( MSG32_16
*msg16
, HWND16 hwnd16
,
159 UINT16 first
, UINT16 last
, UINT16 flags
,
160 BOOL16 wHaveParamHigh
)
163 HWND hwnd
= WIN_Handle32( hwnd16
);
165 if(USER16_AlertableWait
)
166 MsgWaitForMultipleObjectsEx( 0, NULL
, 1, 0, MWMO_ALERTABLE
);
167 if (!PeekMessageW( &msg
, hwnd
, first
, last
, flags
)) return FALSE
;
169 msg16
->msg
.hwnd
= WIN_Handle16( msg
.hwnd
);
170 msg16
->msg
.lParam
= msg
.lParam
;
171 msg16
->msg
.time
= msg
.time
;
172 msg16
->msg
.pt
.x
= (INT16
)msg
.pt
.x
;
173 msg16
->msg
.pt
.y
= (INT16
)msg
.pt
.y
;
174 if (wHaveParamHigh
) msg16
->wParamHigh
= HIWORD(msg
.wParam
);
176 return (WINPROC_MapMsg32WTo16( msg
.hwnd
, msg
.message
, msg
.wParam
,
177 &msg16
->msg
.message
, &msg16
->msg
.wParam
,
178 &msg16
->msg
.lParam
) != -1);
182 /***********************************************************************
183 * PeekMessage (USER.109)
185 BOOL16 WINAPI
PeekMessage16( MSG16
*msg
, HWND16 hwnd
,
186 UINT16 first
, UINT16 last
, UINT16 flags
)
188 return PeekMessage32_16( (MSG32_16
*)msg
, hwnd
, first
, last
, flags
, FALSE
);
192 /***********************************************************************
193 * GetMessage32 (USER.820)
195 BOOL16 WINAPI
GetMessage32_16( MSG32_16
*msg16
, HWND16 hwnd16
, UINT16 first
,
196 UINT16 last
, BOOL16 wHaveParamHigh
)
199 HWND hwnd
= WIN_Handle32( hwnd16
);
203 if(USER16_AlertableWait
)
204 MsgWaitForMultipleObjectsEx( 0, NULL
, INFINITE
, 0, MWMO_ALERTABLE
);
205 GetMessageW( &msg
, hwnd
, first
, last
);
206 msg16
->msg
.hwnd
= WIN_Handle16( msg
.hwnd
);
207 msg16
->msg
.lParam
= msg
.lParam
;
208 msg16
->msg
.time
= msg
.time
;
209 msg16
->msg
.pt
.x
= (INT16
)msg
.pt
.x
;
210 msg16
->msg
.pt
.y
= (INT16
)msg
.pt
.y
;
211 if (wHaveParamHigh
) msg16
->wParamHigh
= HIWORD(msg
.wParam
);
213 while (WINPROC_MapMsg32WTo16( msg
.hwnd
, msg
.message
, msg
.wParam
,
214 &msg16
->msg
.message
, &msg16
->msg
.wParam
,
215 &msg16
->msg
.lParam
) == -1);
217 TRACE( "message %04x, hwnd %04x, filter(%04x - %04x)\n",
218 msg16
->msg
.message
, hwnd
, first
, last
);
220 return msg16
->msg
.message
!= WM_QUIT
;
224 /***********************************************************************
225 * GetMessage (USER.108)
227 BOOL16 WINAPI
GetMessage16( MSG16
*msg
, HWND16 hwnd
, UINT16 first
, UINT16 last
)
229 return GetMessage32_16( (MSG32_16
*)msg
, hwnd
, first
, last
, FALSE
);
233 /***********************************************************************
234 * TranslateMessage32 (USER.821)
236 BOOL16 WINAPI
TranslateMessage32_16( const MSG32_16
*msg
, BOOL16 wHaveParamHigh
)
240 msg32
.hwnd
= WIN_Handle32( msg
->msg
.hwnd
);
241 msg32
.message
= msg
->msg
.message
;
242 msg32
.wParam
= MAKEWPARAM( msg
->msg
.wParam
, wHaveParamHigh
? msg
->wParamHigh
: 0 );
243 msg32
.lParam
= msg
->msg
.lParam
;
244 return TranslateMessage( &msg32
);
248 /***********************************************************************
249 * TranslateMessage (USER.113)
251 BOOL16 WINAPI
TranslateMessage16( const MSG16
*msg
)
253 return TranslateMessage32_16( (MSG32_16
*)msg
, FALSE
);
257 /***********************************************************************
258 * DispatchMessage (USER.114)
260 LONG WINAPI
DispatchMessage16( const MSG16
* msg
)
266 HWND hwnd
= WIN_Handle32( msg
->hwnd
);
268 /* Process timer messages */
269 if ((msg
->message
== WM_TIMER
) || (msg
->message
== WM_SYSTIMER
))
273 /* before calling window proc, verify whether timer is still valid;
274 there's a slim chance that the application kills the timer
275 between GetMessage and DispatchMessage API calls */
276 if (!TIMER_IsTimerValid(hwnd
, (UINT
) msg
->wParam
, (HWINDOWPROC
) msg
->lParam
))
277 return 0; /* invalid winproc */
279 return CallWindowProc16( (WNDPROC16
)msg
->lParam
, msg
->hwnd
,
280 msg
->message
, msg
->wParam
, GetTickCount() );
284 if (!(wndPtr
= WIN_GetPtr( msg
->hwnd
)))
286 if (msg
->hwnd
) SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
289 if (wndPtr
== WND_OTHER_PROCESS
)
291 if (IsWindow( msg
->hwnd
))
292 ERR( "cannot dispatch msg to other process window %x\n", msg
->hwnd
);
293 SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
297 if (!(winproc
= (WNDPROC16
)wndPtr
->winproc
))
299 WIN_ReleasePtr( wndPtr
);
302 painting
= (msg
->message
== WM_PAINT
);
303 if (painting
) wndPtr
->flags
|= WIN_NEEDS_BEGINPAINT
;
304 WIN_ReleasePtr( wndPtr
);
306 SPY_EnterMessage( SPY_DISPATCHMESSAGE16
, hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
307 retval
= CallWindowProc16( winproc
, msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
308 SPY_ExitMessage( SPY_RESULT_OK16
, hwnd
, msg
->message
, retval
, msg
->wParam
, msg
->lParam
);
310 if (painting
&& (wndPtr
= WIN_GetPtr( hwnd
)) && (wndPtr
!= WND_OTHER_PROCESS
))
312 BOOL validate
= ((wndPtr
->flags
& WIN_NEEDS_BEGINPAINT
) && wndPtr
->hrgnUpdate
);
313 wndPtr
->flags
&= ~WIN_NEEDS_BEGINPAINT
;
314 WIN_ReleasePtr( wndPtr
);
317 ERR( "BeginPaint not called on WM_PAINT for hwnd %04x!\n", msg
->hwnd
);
318 /* Validate the update region to avoid infinite WM_PAINT loop */
319 RedrawWindow( hwnd
, NULL
, 0,
320 RDW_NOFRAME
| RDW_VALIDATE
| RDW_NOCHILDREN
| RDW_NOINTERNALPAINT
);
327 /***********************************************************************
328 * DispatchMessage32 (USER.822)
330 LONG WINAPI
DispatchMessage32_16( const MSG32_16
*msg16
, BOOL16 wHaveParamHigh
)
332 if (wHaveParamHigh
== FALSE
)
333 return DispatchMessage16( &msg16
->msg
);
338 msg
.hwnd
= WIN_Handle32( msg16
->msg
.hwnd
);
339 msg
.message
= msg16
->msg
.message
;
340 msg
.wParam
= MAKEWPARAM( msg16
->msg
.wParam
, msg16
->wParamHigh
);
341 msg
.lParam
= msg16
->msg
.lParam
;
342 msg
.time
= msg16
->msg
.time
;
343 msg
.pt
.x
= msg16
->msg
.pt
.x
;
344 msg
.pt
.y
= msg16
->msg
.pt
.y
;
345 return DispatchMessageA( &msg
);
350 /***********************************************************************
351 * IsDialogMessage (USER.90)
353 BOOL16 WINAPI
IsDialogMessage16( HWND16 hwndDlg
, MSG16
*msg16
)
357 switch(msg16
->message
)
362 msg
.hwnd
= WIN_Handle32(msg16
->hwnd
);
363 msg
.lParam
= msg16
->lParam
;
364 WINPROC_MapMsg16To32W( msg
.hwnd
, msg16
->message
, msg16
->wParam
,
365 &msg
.message
, &msg
.wParam
, &msg
.lParam
);
366 /* these messages don't need an unmap */
367 return IsDialogMessageW( WIN_Handle32(hwndDlg
), &msg
);
369 TranslateMessage16( msg16
);
370 DispatchMessage16( msg16
);
375 /***********************************************************************
376 * MsgWaitForMultipleObjects (USER.640)
378 DWORD WINAPI
MsgWaitForMultipleObjects16( DWORD count
, CONST HANDLE
*handles
,
379 BOOL wait_all
, DWORD timeout
, DWORD mask
)
381 return MsgWaitForMultipleObjectsEx( count
, handles
, timeout
, mask
,
382 wait_all
? MWMO_WAITALL
: 0 );
386 /**********************************************************************
387 * SetDoubleClickTime (USER.20)
389 void WINAPI
SetDoubleClickTime16( UINT16 interval
)
391 SetDoubleClickTime( interval
);
395 /**********************************************************************
396 * GetDoubleClickTime (USER.21)
398 UINT16 WINAPI
GetDoubleClickTime16(void)
400 return GetDoubleClickTime();
404 /***********************************************************************
405 * PostQuitMessage (USER.6)
407 void WINAPI
PostQuitMessage16( INT16 exitCode
)
409 PostQuitMessage( exitCode
);
413 /***********************************************************************
414 * SetMessageQueue (USER.266)
416 BOOL16 WINAPI
SetMessageQueue16( INT16 size
)
418 return SetMessageQueue( size
);
422 /***********************************************************************
423 * GetQueueStatus (USER.334)
425 DWORD WINAPI
GetQueueStatus16( UINT16 flags
)
427 return GetQueueStatus( flags
);
431 /***********************************************************************
432 * GetInputState (USER.335)
434 BOOL16 WINAPI
GetInputState16(void)
436 return GetInputState();
440 /**********************************************************************
441 * TranslateAccelerator (USER.178)
443 INT16 WINAPI
TranslateAccelerator16( HWND16 hwnd
, HACCEL16 hAccel
, LPMSG16 msg
)
448 msg32
.message
= msg
->message
;
449 /* msg32.hwnd not used */
450 msg32
.wParam
= msg
->wParam
;
451 msg32
.lParam
= msg
->lParam
;
452 return TranslateAccelerator( WIN_Handle32(hwnd
), HACCEL_32(hAccel
), &msg32
);
456 /**********************************************************************
457 * TranslateMDISysAccel (USER.451)
459 BOOL16 WINAPI
TranslateMDISysAccel16( HWND16 hwndClient
, LPMSG16 msg
)
461 if (msg
->message
== WM_KEYDOWN
|| msg
->message
== WM_SYSKEYDOWN
)
464 msg32
.hwnd
= WIN_Handle32(msg
->hwnd
);
465 msg32
.message
= msg
->message
;
466 msg32
.wParam
= msg
->wParam
;
467 msg32
.lParam
= msg
->lParam
;
468 /* MDICLIENTINFO is still the same for win32 and win16 ... */
469 return TranslateMDISysAccel( WIN_Handle32(hwndClient
), &msg32
);