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)
116 BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
120 TDB *pTask = TASK_GetPtr( hTask );
121 if (!pTask) return FALSE;
123 switch (WINPROC_MapMsg16To32W( 0, msg, wparam, &msg32, &wparam32, &lparam ))
126 return PostThreadMessageW( (DWORD)pTask->teb->tid, msg32, wparam32, lparam );
128 ERR( "16-bit message %x contains pointer, cannot post\n", msg );
136 /***********************************************************************
137 * InSendMessage (USER.192)
139 BOOL16 WINAPI InSendMessage16(void)
141 return InSendMessage();
145 /***********************************************************************
146 * ReplyMessage (USER.115)
148 void WINAPI ReplyMessage16( LRESULT result )
150 ReplyMessage( result );
154 /***********************************************************************
155 * PeekMessage32 (USER.819)
157 BOOL16 WINAPI PeekMessage32_16( MSG32_16 *msg16, HWND16 hwnd16,
158 UINT16 first, UINT16 last, UINT16 flags,
159 BOOL16 wHaveParamHigh )
162 HWND hwnd = WIN_Handle32( hwnd16 );
164 if(USER16_AlertableWait)
165 MsgWaitForMultipleObjectsEx( 0, NULL, 1, 0, MWMO_ALERTABLE );
166 if (!PeekMessageW( &msg, hwnd, first, last, flags )) return FALSE;
168 msg16->msg.hwnd = HWND_16( msg.hwnd );
169 msg16->msg.lParam = msg.lParam;
170 msg16->msg.time = msg.time;
171 msg16->msg.pt.x = (INT16)msg.pt.x;
172 msg16->msg.pt.y = (INT16)msg.pt.y;
173 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
175 return (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
176 &msg16->msg.message, &msg16->msg.wParam,
177 &msg16->msg.lParam ) != -1);
181 /***********************************************************************
182 * PeekMessage (USER.109)
184 BOOL16 WINAPI PeekMessage16( MSG16 *msg, HWND16 hwnd,
185 UINT16 first, UINT16 last, UINT16 flags )
187 return PeekMessage32_16( (MSG32_16 *)msg, hwnd, first, last, flags, FALSE );
191 /***********************************************************************
192 * GetMessage32 (USER.820)
194 BOOL16 WINAPI GetMessage32_16( MSG32_16 *msg16, HWND16 hwnd16, UINT16 first,
195 UINT16 last, BOOL16 wHaveParamHigh )
198 HWND hwnd = WIN_Handle32( hwnd16 );
202 if(USER16_AlertableWait)
203 MsgWaitForMultipleObjectsEx( 0, NULL, INFINITE, 0, MWMO_ALERTABLE );
204 GetMessageW( &msg, hwnd, first, last );
205 msg16->msg.hwnd = HWND_16( msg.hwnd );
206 msg16->msg.lParam = msg.lParam;
207 msg16->msg.time = msg.time;
208 msg16->msg.pt.x = (INT16)msg.pt.x;
209 msg16->msg.pt.y = (INT16)msg.pt.y;
210 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
212 while (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
213 &msg16->msg.message, &msg16->msg.wParam,
214 &msg16->msg.lParam ) == -1);
216 TRACE( "message %04x, hwnd %04x, filter(%04x - %04x)\n",
217 msg16->msg.message, hwnd, first, last );
219 return msg16->msg.message != WM_QUIT;
223 /***********************************************************************
224 * GetMessage (USER.108)
226 BOOL16 WINAPI GetMessage16( MSG16 *msg, HWND16 hwnd, UINT16 first, UINT16 last )
228 return GetMessage32_16( (MSG32_16 *)msg, hwnd, first, last, FALSE );
232 /***********************************************************************
233 * TranslateMessage32 (USER.821)
235 BOOL16 WINAPI TranslateMessage32_16( const MSG32_16 *msg, BOOL16 wHaveParamHigh )
239 msg32.hwnd = WIN_Handle32( msg->msg.hwnd );
240 msg32.message = msg->msg.message;
241 msg32.wParam = MAKEWPARAM( msg->msg.wParam, wHaveParamHigh ? msg->wParamHigh : 0 );
242 msg32.lParam = msg->msg.lParam;
243 return TranslateMessage( &msg32 );
247 /***********************************************************************
248 * TranslateMessage (USER.113)
250 BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
252 return TranslateMessage32_16( (MSG32_16 *)msg, FALSE );
256 /***********************************************************************
257 * DispatchMessage (USER.114)
259 LONG WINAPI DispatchMessage16( const MSG16* msg )
265 HWND hwnd = WIN_Handle32( msg->hwnd );
267 /* Process timer messages */
268 if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
272 /* before calling window proc, verify whether timer is still valid;
273 there's a slim chance that the application kills the timer
274 between GetMessage and DispatchMessage API calls */
275 if (!TIMER_IsTimerValid(hwnd, (UINT) msg->wParam, (HWINDOWPROC) msg->lParam))
276 return 0; /* invalid winproc */
278 return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
279 msg->message, msg->wParam, GetTickCount() );
283 if (!(wndPtr = WIN_GetPtr( HWND_32(msg->hwnd) )))
285 if (msg->hwnd) SetLastError( ERROR_INVALID_WINDOW_HANDLE );
288 if (wndPtr == WND_OTHER_PROCESS)
290 if (IsWindow16( msg->hwnd ))
291 ERR( "cannot dispatch msg to other process window %x\n", msg->hwnd );
292 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
296 if (!(winproc = (WNDPROC16)wndPtr->winproc))
298 WIN_ReleasePtr( wndPtr );
301 painting = (msg->message == WM_PAINT);
302 if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
303 WIN_ReleasePtr( wndPtr );
305 SPY_EnterMessage( SPY_DISPATCHMESSAGE16, hwnd, msg->message, msg->wParam, msg->lParam );
306 retval = CallWindowProc16( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam );
307 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg->message, retval, msg->wParam, msg->lParam );
309 if (painting && (wndPtr = WIN_GetPtr( hwnd )) && (wndPtr != WND_OTHER_PROCESS))
311 BOOL validate = ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate);
312 wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
313 WIN_ReleasePtr( wndPtr );
316 ERR( "BeginPaint not called on WM_PAINT for hwnd %04x!\n", msg->hwnd );
317 /* Validate the update region to avoid infinite WM_PAINT loop */
318 RedrawWindow( hwnd, NULL, 0,
319 RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT );
326 /***********************************************************************
327 * DispatchMessage32 (USER.822)
329 LONG WINAPI DispatchMessage32_16( const MSG32_16 *msg16, BOOL16 wHaveParamHigh )
331 if (wHaveParamHigh == FALSE)
332 return DispatchMessage16( &msg16->msg );
337 msg.hwnd = WIN_Handle32( msg16->msg.hwnd );
338 msg.message = msg16->msg.message;
339 msg.wParam = MAKEWPARAM( msg16->msg.wParam, msg16->wParamHigh );
340 msg.lParam = msg16->msg.lParam;
341 msg.time = msg16->msg.time;
342 msg.pt.x = msg16->msg.pt.x;
343 msg.pt.y = msg16->msg.pt.y;
344 return DispatchMessageA( &msg );
349 /***********************************************************************
350 * IsDialogMessage (USER.90)
352 BOOL16 WINAPI IsDialogMessage16( HWND16 hwndDlg, MSG16 *msg16 )
356 switch(msg16->message)
361 msg.hwnd = WIN_Handle32(msg16->hwnd);
362 msg.lParam = msg16->lParam;
363 WINPROC_MapMsg16To32W( msg.hwnd, msg16->message, msg16->wParam,
364 &msg.message, &msg.wParam, &msg.lParam );
365 /* these messages don't need an unmap */
366 return IsDialogMessageW( WIN_Handle32(hwndDlg), &msg );
368 TranslateMessage16( msg16 );
369 DispatchMessage16( msg16 );
374 /***********************************************************************
375 * MsgWaitForMultipleObjects (USER.640)
377 DWORD WINAPI MsgWaitForMultipleObjects16( DWORD count, CONST HANDLE *handles,
378 BOOL wait_all, DWORD timeout, DWORD mask )
380 return MsgWaitForMultipleObjectsEx( count, handles, timeout, mask,
381 wait_all ? MWMO_WAITALL : 0 );
385 /**********************************************************************
386 * SetDoubleClickTime (USER.20)
388 void WINAPI SetDoubleClickTime16( UINT16 interval )
390 SetDoubleClickTime( interval );
394 /**********************************************************************
395 * GetDoubleClickTime (USER.21)
397 UINT16 WINAPI GetDoubleClickTime16(void)
399 return GetDoubleClickTime();
403 /***********************************************************************
404 * PostQuitMessage (USER.6)
406 void WINAPI PostQuitMessage16( INT16 exitCode )
408 PostQuitMessage( exitCode );
412 /***********************************************************************
413 * SetMessageQueue (USER.266)
415 BOOL16 WINAPI SetMessageQueue16( INT16 size )
417 return SetMessageQueue( size );
421 /***********************************************************************
422 * GetQueueStatus (USER.334)
424 DWORD WINAPI GetQueueStatus16( UINT16 flags )
426 return GetQueueStatus( flags );
430 /***********************************************************************
431 * GetInputState (USER.335)
433 BOOL16 WINAPI GetInputState16(void)
435 return GetInputState();
439 /**********************************************************************
440 * TranslateAccelerator (USER.178)
442 INT16 WINAPI TranslateAccelerator16( HWND16 hwnd, HACCEL16 hAccel, LPMSG16 msg )
447 msg32.message = msg->message;
448 /* msg32.hwnd not used */
449 msg32.wParam = msg->wParam;
450 msg32.lParam = msg->lParam;
451 return TranslateAccelerator( WIN_Handle32(hwnd), HACCEL_32(hAccel), &msg32 );
455 /**********************************************************************
456 * TranslateMDISysAccel (USER.451)
458 BOOL16 WINAPI TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg )
460 if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
463 msg32.hwnd = WIN_Handle32(msg->hwnd);
464 msg32.message = msg->message;
465 msg32.wParam = msg->wParam;
466 msg32.lParam = msg->lParam;
467 /* MDICLIENTINFO is still the same for win32 and win16 ... */
468 return TranslateMDISysAccel( WIN_Handle32(hwndClient), &msg32 );