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 &&
29 GetWindowThreadProcessId( hwnd, NULL ) == GetCurrentThreadId())
31 /* call 16-bit window proc directly */
34 /* first the WH_CALLWNDPROC hook */
35 if (HOOK_IsHooked( WH_CALLWNDPROC ))
39 if ((cwp = SEGPTR_NEW(CWPSTRUCT16)))
45 HOOK_CallHooks16( WH_CALLWNDPROC, HC_ACTION, 1, SEGPTR_GET(cwp) );
46 if (cwp->hwnd != hwnd16)
49 hwnd = WIN_Handle32( hwnd16 );
58 if (!(winproc = (WNDPROC16)GetWindowLong16( hwnd16, GWL_WNDPROC ))) return 0;
60 SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wparam, lparam );
61 result = CallWindowProc16( (WNDPROC16)winproc, hwnd16, msg, wparam, lparam );
62 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, result, wparam, lparam );
64 else /* map to 32-bit unicode for inter-thread/process message */
69 if (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ) == -1)
71 result = WINPROC_UnmapMsg16To32W( hwnd, msg32, wparam32, lparam,
72 SendMessageW( hwnd, msg32, wparam32, lparam ) );
78 /***********************************************************************
79 * PostMessage (USER.110)
81 BOOL16 WINAPI PostMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
85 HWND hwnd = WIN_Handle32( hwnd16 );
87 switch (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ))
90 return PostMessageW( hwnd, msg32, wparam32, lparam );
92 ERR( "16-bit message %x contains pointer, cannot post\n", msg );
100 /***********************************************************************
101 * PostAppMessage (USER.116)
102 * PostAppMessage16 (USER32.@)
104 BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
108 TDB *pTask = TASK_GetPtr( hTask );
109 if (!pTask) return FALSE;
111 switch (WINPROC_MapMsg16To32W( 0, msg, wparam, &msg32, &wparam32, &lparam ))
114 return PostThreadMessageW( (DWORD)pTask->teb->tid, msg32, wparam32, lparam );
116 ERR( "16-bit message %x contains pointer, cannot post\n", msg );
124 /***********************************************************************
125 * InSendMessage (USER.192)
127 BOOL16 WINAPI InSendMessage16(void)
129 return InSendMessage();
133 /***********************************************************************
134 * ReplyMessage (USER.115)
136 void WINAPI ReplyMessage16( LRESULT result )
138 ReplyMessage( result );
142 /***********************************************************************
143 * PeekMessage32 (USER.819)
145 BOOL16 WINAPI PeekMessage32_16( MSG32_16 *msg16, HWND16 hwnd16,
146 UINT16 first, UINT16 last, UINT16 flags,
147 BOOL16 wHaveParamHigh )
150 HWND hwnd = WIN_Handle32( hwnd16 );
152 if (!PeekMessageW( &msg, hwnd, first, last, flags )) return FALSE;
154 msg16->msg.hwnd = WIN_Handle16( msg.hwnd );
155 msg16->msg.lParam = msg.lParam;
156 msg16->msg.time = msg.time;
157 msg16->msg.pt.x = (INT16)msg.pt.x;
158 msg16->msg.pt.y = (INT16)msg.pt.y;
159 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
161 return (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
162 &msg16->msg.message, &msg16->msg.wParam,
163 &msg16->msg.lParam ) != -1);
167 /***********************************************************************
168 * PeekMessage (USER.109)
170 BOOL16 WINAPI PeekMessage16( MSG16 *msg, HWND16 hwnd,
171 UINT16 first, UINT16 last, UINT16 flags )
173 return PeekMessage32_16( (MSG32_16 *)msg, hwnd, first, last, flags, FALSE );
177 /***********************************************************************
178 * GetMessage32 (USER.820)
180 BOOL16 WINAPI GetMessage32_16( MSG32_16 *msg16, HWND16 hwnd16, UINT16 first,
181 UINT16 last, BOOL16 wHaveParamHigh )
184 HWND hwnd = WIN_Handle32( hwnd16 );
188 GetMessageW( &msg, hwnd, first, last );
189 msg16->msg.hwnd = WIN_Handle16( msg.hwnd );
190 msg16->msg.lParam = msg.lParam;
191 msg16->msg.time = msg.time;
192 msg16->msg.pt.x = (INT16)msg.pt.x;
193 msg16->msg.pt.y = (INT16)msg.pt.y;
194 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
196 while (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
197 &msg16->msg.message, &msg16->msg.wParam,
198 &msg16->msg.lParam ) == -1);
200 TRACE( "message %04x, hwnd %04x, filter(%04x - %04x)\n",
201 msg16->msg.message, hwnd, first, last );
203 return msg16->msg.message != WM_QUIT;
207 /***********************************************************************
208 * GetMessage (USER.108)
210 BOOL16 WINAPI GetMessage16( MSG16 *msg, HWND16 hwnd, UINT16 first, UINT16 last )
212 return GetMessage32_16( (MSG32_16 *)msg, hwnd, first, last, FALSE );
216 /***********************************************************************
217 * TranslateMessage32 (USER.821)
219 BOOL16 WINAPI TranslateMessage32_16( const MSG32_16 *msg, BOOL16 wHaveParamHigh )
223 msg32.hwnd = WIN_Handle32( msg->msg.hwnd );
224 msg32.message = msg->msg.message;
225 msg32.wParam = MAKEWPARAM( msg->msg.wParam, wHaveParamHigh ? msg->wParamHigh : 0 );
226 msg32.lParam = msg->msg.lParam;
227 return TranslateMessage( &msg32 );
231 /***********************************************************************
232 * TranslateMessage (USER.113)
234 BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
236 return TranslateMessage32_16( (MSG32_16 *)msg, FALSE );
240 /***********************************************************************
241 * DispatchMessage (USER.114)
243 LONG WINAPI DispatchMessage16( const MSG16* msg )
249 HWND hwnd = WIN_Handle32( msg->hwnd );
251 /* Process timer messages */
252 if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
256 /* before calling window proc, verify whether timer is still valid;
257 there's a slim chance that the application kills the timer
258 between GetMessage and DispatchMessage API calls */
259 if (!TIMER_IsTimerValid(hwnd, (UINT) msg->wParam, (HWINDOWPROC) msg->lParam))
260 return 0; /* invalid winproc */
262 return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
263 msg->message, msg->wParam, GetTickCount() );
267 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
268 if (!wndPtr->winproc)
270 WIN_ReleaseWndPtr( wndPtr );
273 winproc = (WNDPROC16)wndPtr->winproc;
274 painting = (msg->message == WM_PAINT);
275 if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
276 WIN_ReleaseWndPtr( wndPtr );
278 SPY_EnterMessage( SPY_DISPATCHMESSAGE16, hwnd, msg->message, msg->wParam, msg->lParam );
279 retval = CallWindowProc16( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam );
280 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg->message, retval, msg->wParam, msg->lParam );
282 if (!painting) return retval;
284 if ((wndPtr = WIN_FindWndPtr( hwnd )))
286 if ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
288 ERR( "BeginPaint not called on WM_PAINT for hwnd %04x!\n", msg->hwnd );
289 wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
290 WIN_ReleaseWndPtr( wndPtr );
291 /* Validate the update region to avoid infinite WM_PAINT loop */
292 RedrawWindow( hwnd, NULL, 0,
293 RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT );
295 else WIN_ReleaseWndPtr( wndPtr );
301 /***********************************************************************
302 * DispatchMessage32 (USER.822)
304 LONG WINAPI DispatchMessage32_16( const MSG32_16 *msg16, BOOL16 wHaveParamHigh )
306 if (wHaveParamHigh == FALSE)
307 return DispatchMessage16( &msg16->msg );
312 msg.hwnd = WIN_Handle32( msg16->msg.hwnd );
313 msg.message = msg16->msg.message;
314 msg.wParam = MAKEWPARAM( msg16->msg.wParam, msg16->wParamHigh );
315 msg.lParam = msg16->msg.lParam;
316 msg.time = msg16->msg.time;
317 msg.pt.x = msg16->msg.pt.x;
318 msg.pt.y = msg16->msg.pt.y;
319 return DispatchMessageA( &msg );
324 /***********************************************************************
325 * MsgWaitForMultipleObjects (USER.640)
327 DWORD WINAPI MsgWaitForMultipleObjects16( DWORD count, CONST HANDLE *handles,
328 BOOL wait_all, DWORD timeout, DWORD mask )
330 return MsgWaitForMultipleObjectsEx( count, handles, timeout, mask,
331 wait_all ? MWMO_WAITALL : 0 );
335 /**********************************************************************
336 * SetDoubleClickTime (USER.20)
338 void WINAPI SetDoubleClickTime16( UINT16 interval )
340 SetDoubleClickTime( interval );
344 /**********************************************************************
345 * GetDoubleClickTime (USER.21)
347 UINT16 WINAPI GetDoubleClickTime16(void)
349 return GetDoubleClickTime();
353 /***********************************************************************
354 * PostQuitMessage (USER.6)
356 void WINAPI PostQuitMessage16( INT16 exitCode )
358 PostQuitMessage( exitCode );
362 /***********************************************************************
363 * SetMessageQueue (USER.266)
365 BOOL16 WINAPI SetMessageQueue16( INT16 size )
367 return SetMessageQueue( size );
371 /***********************************************************************
372 * GetQueueStatus (USER.334)
374 DWORD WINAPI GetQueueStatus16( UINT16 flags )
376 return GetQueueStatus( flags );
380 /***********************************************************************
381 * GetInputState (USER.335)
383 BOOL16 WINAPI GetInputState16(void)
385 return GetInputState();
389 /**********************************************************************
390 * TranslateAccelerator (USER.178)
392 INT16 WINAPI TranslateAccelerator16( HWND16 hwnd, HACCEL16 hAccel, LPMSG16 msg )
397 msg32.message = msg->message;
398 /* msg32.hwnd not used */
399 msg32.wParam = msg->wParam;
400 msg32.lParam = msg->lParam;
401 return TranslateAccelerator( WIN_Handle32(hwnd), hAccel, &msg32 );
405 /**********************************************************************
406 * TranslateMDISysAccel (USER.451)
408 BOOL16 WINAPI TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg )
410 if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
413 msg32.hwnd = WIN_Handle32(msg->hwnd);
414 msg32.message = msg->message;
415 msg32.wParam = msg->wParam;
416 msg32.lParam = msg->lParam;
417 /* MDICLIENTINFO is still the same for win32 and win16 ... */
418 return TranslateMDISysAccel( WIN_Handle32(hwndClient), &msg32 );