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 hwnd, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
27 if (hwnd != HWND_BROADCAST &&
28 GetWindowThreadProcessId( hwnd, NULL ) == GetCurrentThreadId())
30 /* 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) );
54 if (!(wndPtr = WIN_FindWndPtr( hwnd )))
56 WARN("invalid hwnd %04x\n", hwnd );
59 winproc = (WNDPROC16)wndPtr->winproc;
60 WIN_ReleaseWndPtr( wndPtr );
62 SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wparam, lparam );
63 result = CallWindowProc16( (WNDPROC16)winproc, hwnd, msg, wparam, lparam );
64 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, result, wparam, lparam );
66 else /* map to 32-bit unicode for inter-thread/process message */
71 if (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ) == -1)
73 result = WINPROC_UnmapMsg16To32W( hwnd, msg32, wparam32, lparam,
74 SendMessageW( hwnd, msg32, wparam32, lparam ) );
80 /***********************************************************************
81 * PostMessage (USER.110)
83 BOOL16 WINAPI PostMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
88 switch (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ))
91 return PostMessageW( hwnd, msg32, wparam32, lparam );
93 ERR( "16-bit message %x contains pointer, cannot post\n", msg );
101 /***********************************************************************
102 * PostAppMessage (USER.116)
103 * PostAppMessage16 (USER32.@)
105 BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
109 TDB *pTask = TASK_GetPtr( hTask );
110 if (!pTask) return FALSE;
112 switch (WINPROC_MapMsg16To32W( 0, msg, wparam, &msg32, &wparam32, &lparam ))
115 return PostThreadMessageW( (DWORD)pTask->teb->tid, msg32, wparam32, lparam );
117 ERR( "16-bit message %x contains pointer, cannot post\n", msg );
125 /***********************************************************************
126 * InSendMessage (USER.192)
128 BOOL16 WINAPI InSendMessage16(void)
130 return InSendMessage();
134 /***********************************************************************
135 * ReplyMessage (USER.115)
137 void WINAPI ReplyMessage16( LRESULT result )
139 ReplyMessage( result );
143 /***********************************************************************
144 * PeekMessage32 (USER.819)
146 BOOL16 WINAPI PeekMessage32_16( MSG32_16 *msg16, HWND16 hwnd,
147 UINT16 first, UINT16 last, UINT16 flags,
148 BOOL16 wHaveParamHigh )
152 if (!PeekMessageW( &msg, hwnd, first, last, flags )) return FALSE;
154 msg16->msg.hwnd = 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 hwnd, UINT16 first,
181 UINT16 last, BOOL16 wHaveParamHigh )
187 GetMessageW( &msg, hwnd, first, last );
188 msg16->msg.hwnd = 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 = 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 )
249 /* Process timer messages */
250 if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
254 /* before calling window proc, verify whether timer is still valid;
255 there's a slim chance that the application kills the timer
256 between GetMessage and DispatchMessage API calls */
257 if (!TIMER_IsTimerValid(msg->hwnd, (UINT) msg->wParam, (HWINDOWPROC) msg->lParam))
258 return 0; /* invalid winproc */
260 return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
261 msg->message, msg->wParam, GetTickCount() );
265 if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
266 if (!wndPtr->winproc)
268 WIN_ReleaseWndPtr( wndPtr );
271 winproc = (WNDPROC16)wndPtr->winproc;
272 painting = (msg->message == WM_PAINT);
273 if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
274 WIN_ReleaseWndPtr( wndPtr );
276 SPY_EnterMessage( SPY_DISPATCHMESSAGE16, msg->hwnd, msg->message, msg->wParam, msg->lParam );
277 retval = CallWindowProc16( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam );
278 SPY_ExitMessage( SPY_RESULT_OK16, msg->hwnd, msg->message, retval, msg->wParam, msg->lParam );
280 if (!painting) return retval;
282 if ((wndPtr = WIN_FindWndPtr( msg->hwnd )))
284 if ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
286 ERR( "BeginPaint not called on WM_PAINT for hwnd %04x!\n", msg->hwnd );
287 wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
288 /* Validate the update region to avoid infinite WM_PAINT loop */
289 RedrawWindow( wndPtr->hwndSelf, NULL, 0,
290 RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT );
292 WIN_ReleaseWndPtr( wndPtr );
298 /***********************************************************************
299 * DispatchMessage32 (USER.822)
301 LONG WINAPI DispatchMessage32_16( const MSG32_16 *msg16, BOOL16 wHaveParamHigh )
303 if (wHaveParamHigh == FALSE)
304 return DispatchMessage16( &msg16->msg );
309 msg.hwnd = msg16->msg.hwnd;
310 msg.message = msg16->msg.message;
311 msg.wParam = MAKEWPARAM( msg16->msg.wParam, msg16->wParamHigh );
312 msg.lParam = msg16->msg.lParam;
313 msg.time = msg16->msg.time;
314 msg.pt.x = msg16->msg.pt.x;
315 msg.pt.y = msg16->msg.pt.y;
316 return DispatchMessageA( &msg );
321 /***********************************************************************
322 * MsgWaitForMultipleObjects (USER.640)
324 DWORD WINAPI MsgWaitForMultipleObjects16( DWORD count, CONST HANDLE *handles,
325 BOOL wait_all, DWORD timeout, DWORD mask )
327 return MsgWaitForMultipleObjectsEx( count, handles, timeout, mask,
328 wait_all ? MWMO_WAITALL : 0 );
332 /**********************************************************************
333 * SetDoubleClickTime (USER.20)
335 void WINAPI SetDoubleClickTime16( UINT16 interval )
337 SetDoubleClickTime( interval );
341 /**********************************************************************
342 * GetDoubleClickTime (USER.21)
344 UINT16 WINAPI GetDoubleClickTime16(void)
346 return GetDoubleClickTime();
350 /***********************************************************************
351 * PostQuitMessage (USER.6)
353 void WINAPI PostQuitMessage16( INT16 exitCode )
355 PostQuitMessage( exitCode );
359 /***********************************************************************
360 * SetMessageQueue (USER.266)
362 BOOL16 WINAPI SetMessageQueue16( INT16 size )
364 return SetMessageQueue( size );
368 /***********************************************************************
369 * GetQueueStatus (USER.334)
371 DWORD WINAPI GetQueueStatus16( UINT16 flags )
373 return GetQueueStatus( flags );
377 /***********************************************************************
378 * GetInputState (USER.335)
380 BOOL16 WINAPI GetInputState16(void)
382 return GetInputState();