Fixed typo.
[wine.git] / dlls / user / msg16.c
blob1aafce0e8377cb34472143dc41e0d18aa9795188
1 /*
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"
22 #include "wownt32.h"
23 #include "winerror.h"
24 #include "message.h"
25 #include "win.h"
26 #include "winproc.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(msg);
31 DWORD USER16_AlertableWait = 0;
33 /***********************************************************************
34 * SendMessage (USER.111)
36 LRESULT WINAPI SendMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
38 LRESULT result;
39 UINT msg32;
40 WPARAM wparam32;
41 HWND hwnd = WIN_Handle32( hwnd16 );
43 if (hwnd != HWND_BROADCAST && WIN_IsCurrentThread(hwnd))
45 /* call 16-bit window proc directly */
46 WNDPROC16 winproc;
48 /* first the WH_CALLWNDPROC hook */
49 if (HOOK_IsHooked( WH_CALLWNDPROC ))
51 LPARAM lparam32 = lparam;
53 if (WINPROC_MapMsg16To32A( hwnd, msg, wparam, &msg32, &wparam32, &lparam32 ) != -1)
55 CWPSTRUCT cwp;
57 cwp.hwnd = hwnd;
58 cwp.message = msg32;
59 cwp.wParam = wparam32;
60 cwp.lParam = lparam32;
61 HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp, FALSE );
62 WINPROC_UnmapMsg16To32A( hwnd, msg32, wparam32, lparam32, 0 );
63 /* FIXME: should reflect changes back into the message we send */
67 if (!(winproc = (WNDPROC16)GetWindowLong16( hwnd16, GWL_WNDPROC ))) return 0;
69 SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wparam, lparam );
70 result = CallWindowProc16( (WNDPROC16)winproc, hwnd16, msg, wparam, lparam );
71 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, result, wparam, lparam );
73 else /* map to 32-bit unicode for inter-thread/process message */
75 if (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ) == -1)
76 return 0;
77 result = WINPROC_UnmapMsg16To32W( hwnd, msg32, wparam32, lparam,
78 SendMessageW( hwnd, msg32, wparam32, lparam ) );
80 return result;
84 /***********************************************************************
85 * PostMessage (USER.110)
87 BOOL16 WINAPI PostMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
89 WPARAM wparam32;
90 UINT msg32;
91 HWND hwnd = WIN_Handle32( hwnd16 );
93 switch (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ))
95 case 0:
96 return PostMessageW( hwnd, msg32, wparam32, lparam );
97 case 1:
98 ERR( "16-bit message 0x%04x contains pointer, cannot post\n", msg );
99 return FALSE;
100 default:
101 return FALSE;
106 /***********************************************************************
107 * PostAppMessage (USER.116)
109 BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
111 WPARAM wparam32;
112 UINT msg32;
113 DWORD tid = HTASK_32( hTask );
114 if (!tid) return FALSE;
116 switch (WINPROC_MapMsg16To32W( 0, msg, wparam, &msg32, &wparam32, &lparam ))
118 case 0:
119 return PostThreadMessageW( tid, msg32, wparam32, lparam );
120 case 1:
121 ERR( "16-bit message %x contains pointer, cannot post\n", msg );
122 return FALSE;
123 default:
124 return FALSE;
129 /***********************************************************************
130 * InSendMessage (USER.192)
132 BOOL16 WINAPI InSendMessage16(void)
134 return InSendMessage();
138 /***********************************************************************
139 * ReplyMessage (USER.115)
141 void WINAPI ReplyMessage16( LRESULT result )
143 ReplyMessage( result );
147 /***********************************************************************
148 * PeekMessage32 (USER.819)
150 BOOL16 WINAPI PeekMessage32_16( MSG32_16 *msg16, HWND16 hwnd16,
151 UINT16 first, UINT16 last, UINT16 flags,
152 BOOL16 wHaveParamHigh )
154 MSG msg;
155 HWND hwnd = WIN_Handle32( hwnd16 );
157 if(USER16_AlertableWait)
158 MsgWaitForMultipleObjectsEx( 0, NULL, 1, 0, MWMO_ALERTABLE );
159 if (!PeekMessageW( &msg, hwnd, first, last, flags )) return FALSE;
161 msg16->msg.hwnd = HWND_16( msg.hwnd );
162 msg16->msg.lParam = msg.lParam;
163 msg16->msg.time = msg.time;
164 msg16->msg.pt.x = (INT16)msg.pt.x;
165 msg16->msg.pt.y = (INT16)msg.pt.y;
166 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
168 return (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
169 &msg16->msg.message, &msg16->msg.wParam,
170 &msg16->msg.lParam ) != -1);
174 /***********************************************************************
175 * PeekMessage (USER.109)
177 BOOL16 WINAPI PeekMessage16( MSG16 *msg, HWND16 hwnd,
178 UINT16 first, UINT16 last, UINT16 flags )
180 return PeekMessage32_16( (MSG32_16 *)msg, hwnd, first, last, flags, FALSE );
184 /***********************************************************************
185 * GetMessage32 (USER.820)
187 BOOL16 WINAPI GetMessage32_16( MSG32_16 *msg16, HWND16 hwnd16, UINT16 first,
188 UINT16 last, BOOL16 wHaveParamHigh )
190 MSG msg;
191 HWND hwnd = WIN_Handle32( hwnd16 );
195 if(USER16_AlertableWait)
196 MsgWaitForMultipleObjectsEx( 0, NULL, INFINITE, 0, MWMO_ALERTABLE );
197 GetMessageW( &msg, hwnd, first, last );
198 msg16->msg.hwnd = HWND_16( msg.hwnd );
199 msg16->msg.lParam = msg.lParam;
200 msg16->msg.time = msg.time;
201 msg16->msg.pt.x = (INT16)msg.pt.x;
202 msg16->msg.pt.y = (INT16)msg.pt.y;
203 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
205 while (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
206 &msg16->msg.message, &msg16->msg.wParam,
207 &msg16->msg.lParam ) == -1);
209 TRACE( "message %04x, hwnd %p, filter(%04x - %04x)\n",
210 msg16->msg.message, hwnd, first, last );
212 return msg16->msg.message != WM_QUIT;
216 /***********************************************************************
217 * GetMessage (USER.108)
219 BOOL16 WINAPI GetMessage16( MSG16 *msg, HWND16 hwnd, UINT16 first, UINT16 last )
221 return GetMessage32_16( (MSG32_16 *)msg, hwnd, first, last, FALSE );
225 /***********************************************************************
226 * TranslateMessage32 (USER.821)
228 BOOL16 WINAPI TranslateMessage32_16( const MSG32_16 *msg, BOOL16 wHaveParamHigh )
230 MSG msg32;
232 msg32.hwnd = WIN_Handle32( msg->msg.hwnd );
233 msg32.message = msg->msg.message;
234 msg32.wParam = MAKEWPARAM( msg->msg.wParam, wHaveParamHigh ? msg->wParamHigh : 0 );
235 msg32.lParam = msg->msg.lParam;
236 return TranslateMessage( &msg32 );
240 /***********************************************************************
241 * TranslateMessage (USER.113)
243 BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
245 return TranslateMessage32_16( (MSG32_16 *)msg, FALSE );
249 /***********************************************************************
250 * DispatchMessage (USER.114)
252 LONG WINAPI DispatchMessage16( const MSG16* msg )
254 WND * wndPtr;
255 WNDPROC16 winproc;
256 LONG retval;
257 int painting;
258 HWND hwnd = WIN_Handle32( msg->hwnd );
260 /* Process timer messages */
261 if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
263 if (msg->lParam)
265 /* before calling window proc, verify whether timer is still valid;
266 there's a slim chance that the application kills the timer
267 between GetMessage and DispatchMessage API calls */
268 if (!TIMER_IsTimerValid(hwnd, (UINT) msg->wParam, (WNDPROC)msg->lParam))
269 return 0; /* invalid winproc */
271 return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
272 msg->message, msg->wParam, GetTickCount() );
276 if (!(wndPtr = WIN_GetPtr( hwnd )))
278 if (msg->hwnd) SetLastError( ERROR_INVALID_WINDOW_HANDLE );
279 return 0;
281 if (wndPtr == WND_OTHER_PROCESS)
283 if (IsWindow( hwnd ))
284 ERR( "cannot dispatch msg to other process window %p\n", hwnd );
285 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
286 return 0;
289 if (!(winproc = (WNDPROC16)wndPtr->winproc))
291 WIN_ReleasePtr( wndPtr );
292 return 0;
294 painting = (msg->message == WM_PAINT);
295 if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
296 WIN_ReleasePtr( wndPtr );
298 SPY_EnterMessage( SPY_DISPATCHMESSAGE16, hwnd, msg->message, msg->wParam, msg->lParam );
299 retval = CallWindowProc16( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam );
300 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg->message, retval, msg->wParam, msg->lParam );
302 if (painting && (wndPtr = WIN_GetPtr( hwnd )) && (wndPtr != WND_OTHER_PROCESS))
304 BOOL validate = ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate);
305 wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
306 WIN_ReleasePtr( wndPtr );
307 if (validate)
309 ERR( "BeginPaint not called on WM_PAINT for hwnd %p!\n", hwnd );
310 /* Validate the update region to avoid infinite WM_PAINT loop */
311 RedrawWindow( hwnd, NULL, 0,
312 RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT );
315 return retval;
319 /***********************************************************************
320 * DispatchMessage32 (USER.822)
322 LONG WINAPI DispatchMessage32_16( const MSG32_16 *msg16, BOOL16 wHaveParamHigh )
324 if (wHaveParamHigh == FALSE)
325 return DispatchMessage16( &msg16->msg );
326 else
328 MSG msg;
330 msg.hwnd = WIN_Handle32( msg16->msg.hwnd );
331 msg.message = msg16->msg.message;
332 msg.wParam = MAKEWPARAM( msg16->msg.wParam, msg16->wParamHigh );
333 msg.lParam = msg16->msg.lParam;
334 msg.time = msg16->msg.time;
335 msg.pt.x = msg16->msg.pt.x;
336 msg.pt.y = msg16->msg.pt.y;
337 return DispatchMessageA( &msg );
342 /***********************************************************************
343 * IsDialogMessage (USER.90)
345 BOOL16 WINAPI IsDialogMessage16( HWND16 hwndDlg, MSG16 *msg16 )
347 MSG msg;
348 HWND hwndDlg32;
350 msg.hwnd = WIN_Handle32(msg16->hwnd);
351 hwndDlg32 = WIN_Handle32(hwndDlg);
353 switch(msg16->message)
355 case WM_KEYDOWN:
356 case WM_CHAR:
357 case WM_SYSCHAR:
358 msg.lParam = msg16->lParam;
359 WINPROC_MapMsg16To32W( msg.hwnd, msg16->message, msg16->wParam,
360 &msg.message, &msg.wParam, &msg.lParam );
361 /* these messages don't need an unmap */
362 return IsDialogMessageW( hwndDlg32, &msg );
365 if ((hwndDlg32 != msg.hwnd) && !IsChild( hwndDlg32, msg.hwnd )) return FALSE;
366 TranslateMessage16( msg16 );
367 DispatchMessage16( msg16 );
368 return TRUE;
372 /***********************************************************************
373 * MsgWaitForMultipleObjects (USER.640)
375 DWORD WINAPI MsgWaitForMultipleObjects16( DWORD count, CONST HANDLE *handles,
376 BOOL wait_all, DWORD timeout, DWORD mask )
378 return MsgWaitForMultipleObjectsEx( count, handles, timeout, mask,
379 wait_all ? MWMO_WAITALL : 0 );
383 /**********************************************************************
384 * SetDoubleClickTime (USER.20)
386 void WINAPI SetDoubleClickTime16( UINT16 interval )
388 SetDoubleClickTime( interval );
392 /**********************************************************************
393 * GetDoubleClickTime (USER.21)
395 UINT16 WINAPI GetDoubleClickTime16(void)
397 return GetDoubleClickTime();
401 /***********************************************************************
402 * PostQuitMessage (USER.6)
404 void WINAPI PostQuitMessage16( INT16 exitCode )
406 PostQuitMessage( exitCode );
410 /**********************************************************************
411 * GetKeyState (USER.106)
413 INT16 WINAPI GetKeyState16(INT16 vkey)
415 return GetKeyState(vkey);
419 /**********************************************************************
420 * GetKeyboardState (USER.222)
422 BOOL WINAPI GetKeyboardState16( LPBYTE state )
424 return GetKeyboardState( state );
428 /**********************************************************************
429 * SetKeyboardState (USER.223)
431 BOOL WINAPI SetKeyboardState16( LPBYTE state )
433 return SetKeyboardState( state );
437 /***********************************************************************
438 * SetMessageQueue (USER.266)
440 BOOL16 WINAPI SetMessageQueue16( INT16 size )
442 return SetMessageQueue( size );
446 /***********************************************************************
447 * GetQueueStatus (USER.334)
449 DWORD WINAPI GetQueueStatus16( UINT16 flags )
451 return GetQueueStatus( flags );
455 /***********************************************************************
456 * GetInputState (USER.335)
458 BOOL16 WINAPI GetInputState16(void)
460 return GetInputState();
464 /**********************************************************************
465 * TranslateAccelerator (USER.178)
467 INT16 WINAPI TranslateAccelerator16( HWND16 hwnd, HACCEL16 hAccel, LPMSG16 msg )
469 MSG msg32;
471 if (!msg) return 0;
472 msg32.message = msg->message;
473 /* msg32.hwnd not used */
474 msg32.wParam = msg->wParam;
475 msg32.lParam = msg->lParam;
476 return TranslateAcceleratorW( WIN_Handle32(hwnd), HACCEL_32(hAccel), &msg32 );
480 /**********************************************************************
481 * TranslateMDISysAccel (USER.451)
483 BOOL16 WINAPI TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg )
485 if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
487 MSG msg32;
488 msg32.hwnd = WIN_Handle32(msg->hwnd);
489 msg32.message = msg->message;
490 msg32.wParam = msg->wParam;
491 msg32.lParam = msg->lParam;
492 /* MDICLIENTINFO is still the same for win32 and win16 ... */
493 return TranslateMDISysAccel( WIN_Handle32(hwndClient), &msg32 );
495 return 0;