2 * 16-bit messaging support
4 * Copyright 2001 Alexandre Julliard
7 #include "wine/winuser16.h"
15 #include "debugtools.h"
17 DEFAULT_DEBUG_CHANNEL(msg);
20 /***********************************************************************
21 * SendMessage (USER.111)
23 LRESULT WINAPI SendMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
26 HWND hwnd = WIN_Handle32( hwnd16 );
28 if (hwnd != HWND_BROADCAST && WIN_IsCurrentThread(hwnd))
30 /* call 16-bit window proc directly */
33 /* first the WH_CALLWNDPROC hook */
34 if (HOOK_IsHooked( WH_CALLWNDPROC ))
38 if ((cwp = SEGPTR_NEW(CWPSTRUCT16)))
44 HOOK_CallHooks16( WH_CALLWNDPROC, HC_ACTION, 1, SEGPTR_GET(cwp) );
45 if (cwp->hwnd != hwnd16)
48 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 (!PeekMessageW( &msg, hwnd, first, last, flags )) return FALSE;
153 msg16->msg.hwnd = WIN_Handle16( msg.hwnd );
154 msg16->msg.lParam = msg.lParam;
155 msg16->msg.time = msg.time;
156 msg16->msg.pt.x = (INT16)msg.pt.x;
157 msg16->msg.pt.y = (INT16)msg.pt.y;
158 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
160 return (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
161 &msg16->msg.message, &msg16->msg.wParam,
162 &msg16->msg.lParam ) != -1);
166 /***********************************************************************
167 * PeekMessage (USER.109)
169 BOOL16 WINAPI PeekMessage16( MSG16 *msg, HWND16 hwnd,
170 UINT16 first, UINT16 last, UINT16 flags )
172 return PeekMessage32_16( (MSG32_16 *)msg, hwnd, first, last, flags, FALSE );
176 /***********************************************************************
177 * GetMessage32 (USER.820)
179 BOOL16 WINAPI GetMessage32_16( MSG32_16 *msg16, HWND16 hwnd16, UINT16 first,
180 UINT16 last, BOOL16 wHaveParamHigh )
183 HWND hwnd = WIN_Handle32( hwnd16 );
187 GetMessageW( &msg, hwnd, first, last );
188 msg16->msg.hwnd = WIN_Handle16( msg.hwnd );
189 msg16->msg.lParam = msg.lParam;
190 msg16->msg.time = msg.time;
191 msg16->msg.pt.x = (INT16)msg.pt.x;
192 msg16->msg.pt.y = (INT16)msg.pt.y;
193 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
195 while (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
196 &msg16->msg.message, &msg16->msg.wParam,
197 &msg16->msg.lParam ) == -1);
199 TRACE( "message %04x, hwnd %04x, filter(%04x - %04x)\n",
200 msg16->msg.message, hwnd, first, last );
202 return msg16->msg.message != WM_QUIT;
206 /***********************************************************************
207 * GetMessage (USER.108)
209 BOOL16 WINAPI GetMessage16( MSG16 *msg, HWND16 hwnd, UINT16 first, UINT16 last )
211 return GetMessage32_16( (MSG32_16 *)msg, hwnd, first, last, FALSE );
215 /***********************************************************************
216 * TranslateMessage32 (USER.821)
218 BOOL16 WINAPI TranslateMessage32_16( const MSG32_16 *msg, BOOL16 wHaveParamHigh )
222 msg32.hwnd = WIN_Handle32( msg->msg.hwnd );
223 msg32.message = msg->msg.message;
224 msg32.wParam = MAKEWPARAM( msg->msg.wParam, wHaveParamHigh ? msg->wParamHigh : 0 );
225 msg32.lParam = msg->msg.lParam;
226 return TranslateMessage( &msg32 );
230 /***********************************************************************
231 * TranslateMessage (USER.113)
233 BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
235 return TranslateMessage32_16( (MSG32_16 *)msg, FALSE );
239 /***********************************************************************
240 * DispatchMessage (USER.114)
242 LONG WINAPI DispatchMessage16( const MSG16* msg )
248 HWND hwnd = WIN_Handle32( msg->hwnd );
250 /* Process timer messages */
251 if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
255 /* before calling window proc, verify whether timer is still valid;
256 there's a slim chance that the application kills the timer
257 between GetMessage and DispatchMessage API calls */
258 if (!TIMER_IsTimerValid(hwnd, (UINT) msg->wParam, (HWINDOWPROC) msg->lParam))
259 return 0; /* invalid winproc */
261 return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
262 msg->message, msg->wParam, GetTickCount() );
266 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
267 if (!wndPtr->winproc)
269 WIN_ReleaseWndPtr( wndPtr );
272 winproc = (WNDPROC16)wndPtr->winproc;
273 painting = (msg->message == WM_PAINT);
274 if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
275 WIN_ReleaseWndPtr( wndPtr );
277 SPY_EnterMessage( SPY_DISPATCHMESSAGE16, hwnd, msg->message, msg->wParam, msg->lParam );
278 retval = CallWindowProc16( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam );
279 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg->message, retval, msg->wParam, msg->lParam );
281 if (!painting) return retval;
283 if ((wndPtr = WIN_FindWndPtr( hwnd )))
285 if ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
287 ERR( "BeginPaint not called on WM_PAINT for hwnd %04x!\n", msg->hwnd );
288 wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
289 WIN_ReleaseWndPtr( wndPtr );
290 /* Validate the update region to avoid infinite WM_PAINT loop */
291 RedrawWindow( hwnd, NULL, 0,
292 RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT );
294 else WIN_ReleaseWndPtr( wndPtr );
300 /***********************************************************************
301 * DispatchMessage32 (USER.822)
303 LONG WINAPI DispatchMessage32_16( const MSG32_16 *msg16, BOOL16 wHaveParamHigh )
305 if (wHaveParamHigh == FALSE)
306 return DispatchMessage16( &msg16->msg );
311 msg.hwnd = WIN_Handle32( msg16->msg.hwnd );
312 msg.message = msg16->msg.message;
313 msg.wParam = MAKEWPARAM( msg16->msg.wParam, msg16->wParamHigh );
314 msg.lParam = msg16->msg.lParam;
315 msg.time = msg16->msg.time;
316 msg.pt.x = msg16->msg.pt.x;
317 msg.pt.y = msg16->msg.pt.y;
318 return DispatchMessageA( &msg );
323 /***********************************************************************
324 * MsgWaitForMultipleObjects (USER.640)
326 DWORD WINAPI MsgWaitForMultipleObjects16( DWORD count, CONST HANDLE *handles,
327 BOOL wait_all, DWORD timeout, DWORD mask )
329 return MsgWaitForMultipleObjectsEx( count, handles, timeout, mask,
330 wait_all ? MWMO_WAITALL : 0 );
334 /**********************************************************************
335 * SetDoubleClickTime (USER.20)
337 void WINAPI SetDoubleClickTime16( UINT16 interval )
339 SetDoubleClickTime( interval );
343 /**********************************************************************
344 * GetDoubleClickTime (USER.21)
346 UINT16 WINAPI GetDoubleClickTime16(void)
348 return GetDoubleClickTime();
352 /***********************************************************************
353 * PostQuitMessage (USER.6)
355 void WINAPI PostQuitMessage16( INT16 exitCode )
357 PostQuitMessage( exitCode );
361 /***********************************************************************
362 * SetMessageQueue (USER.266)
364 BOOL16 WINAPI SetMessageQueue16( INT16 size )
366 return SetMessageQueue( size );
370 /***********************************************************************
371 * GetQueueStatus (USER.334)
373 DWORD WINAPI GetQueueStatus16( UINT16 flags )
375 return GetQueueStatus( flags );
379 /***********************************************************************
380 * GetInputState (USER.335)
382 BOOL16 WINAPI GetInputState16(void)
384 return GetInputState();
388 /**********************************************************************
389 * TranslateAccelerator (USER.178)
391 INT16 WINAPI TranslateAccelerator16( HWND16 hwnd, HACCEL16 hAccel, LPMSG16 msg )
396 msg32.message = msg->message;
397 /* msg32.hwnd not used */
398 msg32.wParam = msg->wParam;
399 msg32.lParam = msg->lParam;
400 return TranslateAccelerator( WIN_Handle32(hwnd), hAccel, &msg32 );
404 /**********************************************************************
405 * TranslateMDISysAccel (USER.451)
407 BOOL16 WINAPI TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg )
409 if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
412 msg32.hwnd = WIN_Handle32(msg->hwnd);
413 msg32.message = msg->message;
414 msg32.wParam = msg->wParam;
415 msg32.lParam = msg->lParam;
416 /* MDICLIENTINFO is still the same for win32 and win16 ... */
417 return TranslateMDISysAccel( WIN_Handle32(hwndClient), &msg32 );