2 * 16-bit messaging support
4 * Copyright 2001 Alexandre Julliard
7 #include "wine/winuser16.h"
15 #include "debugtools.h"
17 DEFAULT_DEBUG_CHANNEL(msg);
19 DWORD USER16_AlertableWait = 0;
21 /***********************************************************************
22 * SendMessage (USER.111)
24 LRESULT WINAPI SendMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
27 HWND hwnd = WIN_Handle32( hwnd16 );
29 if (hwnd != HWND_BROADCAST && WIN_IsCurrentThread(hwnd))
31 /* call 16-bit window proc directly */
34 /* first the WH_CALLWNDPROC hook */
35 if (HOOK_IsHooked( WH_CALLWNDPROC ))
44 seg_cwp = MapLS( &cwp );
45 HOOK_CallHooks16( WH_CALLWNDPROC, HC_ACTION, 1, seg_cwp );
47 if (cwp.hwnd != hwnd16)
50 hwnd = WIN_Handle32( hwnd16 );
57 if (!(winproc = (WNDPROC16)GetWindowLong16( hwnd16, GWL_WNDPROC ))) return 0;
59 SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wparam, lparam );
60 result = CallWindowProc16( (WNDPROC16)winproc, hwnd16, msg, wparam, lparam );
61 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, result, wparam, lparam );
63 else /* map to 32-bit unicode for inter-thread/process message */
68 if (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ) == -1)
70 result = WINPROC_UnmapMsg16To32W( hwnd, msg32, wparam32, lparam,
71 SendMessageW( hwnd, msg32, wparam32, lparam ) );
77 /***********************************************************************
78 * PostMessage (USER.110)
80 BOOL16 WINAPI PostMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
84 HWND hwnd = WIN_Handle32( hwnd16 );
86 switch (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ))
89 return PostMessageW( hwnd, msg32, wparam32, lparam );
91 ERR( "16-bit message %x contains pointer, cannot post\n", msg );
99 /***********************************************************************
100 * PostAppMessage (USER.116)
101 * PostAppMessage16 (USER32.@)
103 BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
107 TDB *pTask = TASK_GetPtr( hTask );
108 if (!pTask) return FALSE;
110 switch (WINPROC_MapMsg16To32W( 0, msg, wparam, &msg32, &wparam32, &lparam ))
113 return PostThreadMessageW( (DWORD)pTask->teb->tid, msg32, wparam32, lparam );
115 ERR( "16-bit message %x contains pointer, cannot post\n", msg );
123 /***********************************************************************
124 * InSendMessage (USER.192)
126 BOOL16 WINAPI InSendMessage16(void)
128 return InSendMessage();
132 /***********************************************************************
133 * ReplyMessage (USER.115)
135 void WINAPI ReplyMessage16( LRESULT result )
137 ReplyMessage( result );
141 /***********************************************************************
142 * PeekMessage32 (USER.819)
144 BOOL16 WINAPI PeekMessage32_16( MSG32_16 *msg16, HWND16 hwnd16,
145 UINT16 first, UINT16 last, UINT16 flags,
146 BOOL16 wHaveParamHigh )
149 HWND hwnd = WIN_Handle32( hwnd16 );
151 if(USER16_AlertableWait)
152 MsgWaitForMultipleObjectsEx( 0, NULL, 1, 0, MWMO_ALERTABLE );
153 if (!PeekMessageW( &msg, hwnd, first, last, flags )) return FALSE;
155 msg16->msg.hwnd = WIN_Handle16( msg.hwnd );
156 msg16->msg.lParam = msg.lParam;
157 msg16->msg.time = msg.time;
158 msg16->msg.pt.x = (INT16)msg.pt.x;
159 msg16->msg.pt.y = (INT16)msg.pt.y;
160 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
162 return (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
163 &msg16->msg.message, &msg16->msg.wParam,
164 &msg16->msg.lParam ) != -1);
168 /***********************************************************************
169 * PeekMessage (USER.109)
171 BOOL16 WINAPI PeekMessage16( MSG16 *msg, HWND16 hwnd,
172 UINT16 first, UINT16 last, UINT16 flags )
174 return PeekMessage32_16( (MSG32_16 *)msg, hwnd, first, last, flags, FALSE );
178 /***********************************************************************
179 * GetMessage32 (USER.820)
181 BOOL16 WINAPI GetMessage32_16( MSG32_16 *msg16, HWND16 hwnd16, UINT16 first,
182 UINT16 last, BOOL16 wHaveParamHigh )
185 HWND hwnd = WIN_Handle32( hwnd16 );
189 if(USER16_AlertableWait)
190 MsgWaitForMultipleObjectsEx( 0, NULL, INFINITE, 0, MWMO_ALERTABLE );
191 GetMessageW( &msg, hwnd, first, last );
192 msg16->msg.hwnd = WIN_Handle16( msg.hwnd );
193 msg16->msg.lParam = msg.lParam;
194 msg16->msg.time = msg.time;
195 msg16->msg.pt.x = (INT16)msg.pt.x;
196 msg16->msg.pt.y = (INT16)msg.pt.y;
197 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
199 while (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
200 &msg16->msg.message, &msg16->msg.wParam,
201 &msg16->msg.lParam ) == -1);
203 TRACE( "message %04x, hwnd %04x, filter(%04x - %04x)\n",
204 msg16->msg.message, hwnd, first, last );
206 return msg16->msg.message != WM_QUIT;
210 /***********************************************************************
211 * GetMessage (USER.108)
213 BOOL16 WINAPI GetMessage16( MSG16 *msg, HWND16 hwnd, UINT16 first, UINT16 last )
215 return GetMessage32_16( (MSG32_16 *)msg, hwnd, first, last, FALSE );
219 /***********************************************************************
220 * TranslateMessage32 (USER.821)
222 BOOL16 WINAPI TranslateMessage32_16( const MSG32_16 *msg, BOOL16 wHaveParamHigh )
226 msg32.hwnd = WIN_Handle32( msg->msg.hwnd );
227 msg32.message = msg->msg.message;
228 msg32.wParam = MAKEWPARAM( msg->msg.wParam, wHaveParamHigh ? msg->wParamHigh : 0 );
229 msg32.lParam = msg->msg.lParam;
230 return TranslateMessage( &msg32 );
234 /***********************************************************************
235 * TranslateMessage (USER.113)
237 BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
239 return TranslateMessage32_16( (MSG32_16 *)msg, FALSE );
243 /***********************************************************************
244 * DispatchMessage (USER.114)
246 LONG WINAPI DispatchMessage16( const MSG16* msg )
252 HWND hwnd = WIN_Handle32( msg->hwnd );
254 /* Process timer messages */
255 if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
259 /* before calling window proc, verify whether timer is still valid;
260 there's a slim chance that the application kills the timer
261 between GetMessage and DispatchMessage API calls */
262 if (!TIMER_IsTimerValid(hwnd, (UINT) msg->wParam, (HWINDOWPROC) msg->lParam))
263 return 0; /* invalid winproc */
265 return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
266 msg->message, msg->wParam, GetTickCount() );
270 if (!(wndPtr = WIN_GetPtr( msg->hwnd )))
272 if (msg->hwnd) SetLastError( ERROR_INVALID_WINDOW_HANDLE );
275 if (wndPtr == WND_OTHER_PROCESS)
277 if (IsWindow( msg->hwnd ))
278 ERR( "cannot dispatch msg to other process window %x\n", msg->hwnd );
279 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
283 if (!(winproc = (WNDPROC16)wndPtr->winproc))
285 WIN_ReleasePtr( wndPtr );
288 painting = (msg->message == WM_PAINT);
289 if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
290 WIN_ReleasePtr( wndPtr );
292 SPY_EnterMessage( SPY_DISPATCHMESSAGE16, hwnd, msg->message, msg->wParam, msg->lParam );
293 retval = CallWindowProc16( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam );
294 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg->message, retval, msg->wParam, msg->lParam );
296 if (painting && (wndPtr = WIN_GetPtr( hwnd )) && (wndPtr != WND_OTHER_PROCESS))
298 BOOL validate = ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate);
299 wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
300 WIN_ReleasePtr( wndPtr );
303 ERR( "BeginPaint not called on WM_PAINT for hwnd %04x!\n", msg->hwnd );
304 /* Validate the update region to avoid infinite WM_PAINT loop */
305 RedrawWindow( hwnd, NULL, 0,
306 RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT );
313 /***********************************************************************
314 * DispatchMessage32 (USER.822)
316 LONG WINAPI DispatchMessage32_16( const MSG32_16 *msg16, BOOL16 wHaveParamHigh )
318 if (wHaveParamHigh == FALSE)
319 return DispatchMessage16( &msg16->msg );
324 msg.hwnd = WIN_Handle32( msg16->msg.hwnd );
325 msg.message = msg16->msg.message;
326 msg.wParam = MAKEWPARAM( msg16->msg.wParam, msg16->wParamHigh );
327 msg.lParam = msg16->msg.lParam;
328 msg.time = msg16->msg.time;
329 msg.pt.x = msg16->msg.pt.x;
330 msg.pt.y = msg16->msg.pt.y;
331 return DispatchMessageA( &msg );
336 /***********************************************************************
337 * MsgWaitForMultipleObjects (USER.640)
339 DWORD WINAPI MsgWaitForMultipleObjects16( DWORD count, CONST HANDLE *handles,
340 BOOL wait_all, DWORD timeout, DWORD mask )
342 return MsgWaitForMultipleObjectsEx( count, handles, timeout, mask,
343 wait_all ? MWMO_WAITALL : 0 );
347 /**********************************************************************
348 * SetDoubleClickTime (USER.20)
350 void WINAPI SetDoubleClickTime16( UINT16 interval )
352 SetDoubleClickTime( interval );
356 /**********************************************************************
357 * GetDoubleClickTime (USER.21)
359 UINT16 WINAPI GetDoubleClickTime16(void)
361 return GetDoubleClickTime();
365 /***********************************************************************
366 * PostQuitMessage (USER.6)
368 void WINAPI PostQuitMessage16( INT16 exitCode )
370 PostQuitMessage( exitCode );
374 /***********************************************************************
375 * SetMessageQueue (USER.266)
377 BOOL16 WINAPI SetMessageQueue16( INT16 size )
379 return SetMessageQueue( size );
383 /***********************************************************************
384 * GetQueueStatus (USER.334)
386 DWORD WINAPI GetQueueStatus16( UINT16 flags )
388 return GetQueueStatus( flags );
392 /***********************************************************************
393 * GetInputState (USER.335)
395 BOOL16 WINAPI GetInputState16(void)
397 return GetInputState();
401 /**********************************************************************
402 * TranslateAccelerator (USER.178)
404 INT16 WINAPI TranslateAccelerator16( HWND16 hwnd, HACCEL16 hAccel, LPMSG16 msg )
409 msg32.message = msg->message;
410 /* msg32.hwnd not used */
411 msg32.wParam = msg->wParam;
412 msg32.lParam = msg->lParam;
413 return TranslateAccelerator( WIN_Handle32(hwnd), hAccel, &msg32 );
417 /**********************************************************************
418 * TranslateMDISysAccel (USER.451)
420 BOOL16 WINAPI TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg )
422 if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
425 msg32.hwnd = WIN_Handle32(msg->hwnd);
426 msg32.message = msg->message;
427 msg32.wParam = msg->wParam;
428 msg32.lParam = msg->lParam;
429 /* MDICLIENTINFO is still the same for win32 and win16 ... */
430 return TranslateMDISysAccel( WIN_Handle32(hwndClient), &msg32 );