We should always allocate in NdrConformantStringUnmarshal if the
[wine.git] / dlls / user / msg16.c
blob4d79fddf3f0f081dc2f78df525146aa82c11c5bc
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 "win.h"
25 #include "user_private.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, GWLP_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 ),
79 NULL );
81 return result;
85 /***********************************************************************
86 * PostMessage (USER.110)
88 BOOL16 WINAPI PostMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
90 WPARAM wparam32;
91 UINT msg32;
92 HWND hwnd = WIN_Handle32( hwnd16 );
94 switch (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ))
96 case 0:
97 return PostMessageW( hwnd, msg32, wparam32, lparam );
98 case 1:
99 ERR( "16-bit message 0x%04x contains pointer, cannot post\n", msg );
100 return FALSE;
101 default:
102 return FALSE;
107 /***********************************************************************
108 * PostAppMessage (USER.116)
110 BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
112 WPARAM wparam32;
113 UINT msg32;
114 DWORD tid = HTASK_32( hTask );
115 if (!tid) return FALSE;
117 switch (WINPROC_MapMsg16To32W( 0, msg, wparam, &msg32, &wparam32, &lparam ))
119 case 0:
120 return PostThreadMessageW( tid, msg32, wparam32, lparam );
121 case 1:
122 ERR( "16-bit message %x contains pointer, cannot post\n", msg );
123 return FALSE;
124 default:
125 return FALSE;
130 /***********************************************************************
131 * InSendMessage (USER.192)
133 BOOL16 WINAPI InSendMessage16(void)
135 return InSendMessage();
139 /***********************************************************************
140 * ReplyMessage (USER.115)
142 void WINAPI ReplyMessage16( LRESULT result )
144 ReplyMessage( result );
148 /***********************************************************************
149 * PeekMessage32 (USER.819)
151 BOOL16 WINAPI PeekMessage32_16( MSG32_16 *msg16, HWND16 hwnd16,
152 UINT16 first, UINT16 last, UINT16 flags,
153 BOOL16 wHaveParamHigh )
155 MSG msg;
156 HWND hwnd = WIN_Handle32( hwnd16 );
158 if(USER16_AlertableWait)
159 MsgWaitForMultipleObjectsEx( 0, NULL, 1, 0, MWMO_ALERTABLE );
160 if (!PeekMessageW( &msg, hwnd, first, last, flags )) return FALSE;
162 msg16->msg.hwnd = HWND_16( msg.hwnd );
163 msg16->msg.lParam = msg.lParam;
164 msg16->msg.time = msg.time;
165 msg16->msg.pt.x = (INT16)msg.pt.x;
166 msg16->msg.pt.y = (INT16)msg.pt.y;
167 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
169 return (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
170 &msg16->msg.message, &msg16->msg.wParam,
171 &msg16->msg.lParam ) != -1);
175 /***********************************************************************
176 * DefWindowProc (USER.107)
178 LRESULT WINAPI DefWindowProc16( HWND16 hwnd16, UINT16 msg, WPARAM16 wParam, LPARAM lParam )
180 LRESULT result;
181 HWND hwnd = WIN_Handle32( hwnd16 );
183 SPY_EnterMessage( SPY_DEFWNDPROC16, hwnd, msg, wParam, lParam );
185 switch(msg)
187 case WM_NCCREATE:
189 CREATESTRUCT16 *cs16 = MapSL(lParam);
190 CREATESTRUCTA cs32;
192 cs32.lpCreateParams = (LPVOID)cs16->lpCreateParams;
193 cs32.hInstance = HINSTANCE_32(cs16->hInstance);
194 cs32.hMenu = HMENU_32(cs16->hMenu);
195 cs32.hwndParent = WIN_Handle32(cs16->hwndParent);
196 cs32.cy = cs16->cy;
197 cs32.cx = cs16->cx;
198 cs32.y = cs16->y;
199 cs32.x = cs16->x;
200 cs32.style = cs16->style;
201 cs32.dwExStyle = cs16->dwExStyle;
202 cs32.lpszName = MapSL(cs16->lpszName);
203 cs32.lpszClass = MapSL(cs16->lpszClass);
204 result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)&cs32 );
206 break;
208 case WM_NCCALCSIZE:
210 RECT16 *rect16 = MapSL(lParam);
211 RECT rect32;
213 rect32.left = rect16->left;
214 rect32.top = rect16->top;
215 rect32.right = rect16->right;
216 rect32.bottom = rect16->bottom;
218 result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)&rect32 );
220 rect16->left = rect32.left;
221 rect16->top = rect32.top;
222 rect16->right = rect32.right;
223 rect16->bottom = rect32.bottom;
225 break;
227 case WM_WINDOWPOSCHANGING:
228 case WM_WINDOWPOSCHANGED:
230 WINDOWPOS16 *pos16 = MapSL(lParam);
231 WINDOWPOS pos32;
233 pos32.hwnd = WIN_Handle32(pos16->hwnd);
234 pos32.hwndInsertAfter = WIN_Handle32(pos16->hwndInsertAfter);
235 pos32.x = pos16->x;
236 pos32.y = pos16->y;
237 pos32.cx = pos16->cx;
238 pos32.cy = pos16->cy;
239 pos32.flags = pos16->flags;
241 result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)&pos32 );
243 pos16->hwnd = HWND_16(pos32.hwnd);
244 pos16->hwndInsertAfter = HWND_16(pos32.hwndInsertAfter);
245 pos16->x = pos32.x;
246 pos16->y = pos32.y;
247 pos16->cx = pos32.cx;
248 pos16->cy = pos32.cy;
249 pos16->flags = pos32.flags;
251 break;
253 case WM_GETTEXT:
254 case WM_SETTEXT:
255 result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)MapSL(lParam) );
256 break;
258 default:
259 result = DefWindowProcA( hwnd, msg, wParam, lParam );
260 break;
263 SPY_ExitMessage( SPY_RESULT_DEFWND16, hwnd, msg, result, wParam, lParam );
264 return result;
268 /***********************************************************************
269 * PeekMessage (USER.109)
271 BOOL16 WINAPI PeekMessage16( MSG16 *msg, HWND16 hwnd,
272 UINT16 first, UINT16 last, UINT16 flags )
274 return PeekMessage32_16( (MSG32_16 *)msg, hwnd, first, last, flags, FALSE );
278 /***********************************************************************
279 * GetMessage32 (USER.820)
281 BOOL16 WINAPI GetMessage32_16( MSG32_16 *msg16, HWND16 hwnd16, UINT16 first,
282 UINT16 last, BOOL16 wHaveParamHigh )
284 MSG msg;
285 HWND hwnd = WIN_Handle32( hwnd16 );
289 if(USER16_AlertableWait)
290 MsgWaitForMultipleObjectsEx( 0, NULL, INFINITE, 0, MWMO_ALERTABLE );
291 GetMessageW( &msg, hwnd, first, last );
292 msg16->msg.hwnd = HWND_16( msg.hwnd );
293 msg16->msg.lParam = msg.lParam;
294 msg16->msg.time = msg.time;
295 msg16->msg.pt.x = (INT16)msg.pt.x;
296 msg16->msg.pt.y = (INT16)msg.pt.y;
297 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
299 while (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
300 &msg16->msg.message, &msg16->msg.wParam,
301 &msg16->msg.lParam ) == -1);
303 TRACE( "message %04x, hwnd %p, filter(%04x - %04x)\n",
304 msg16->msg.message, hwnd, first, last );
306 return msg16->msg.message != WM_QUIT;
310 /***********************************************************************
311 * GetMessage (USER.108)
313 BOOL16 WINAPI GetMessage16( MSG16 *msg, HWND16 hwnd, UINT16 first, UINT16 last )
315 return GetMessage32_16( (MSG32_16 *)msg, hwnd, first, last, FALSE );
319 /***********************************************************************
320 * TranslateMessage32 (USER.821)
322 BOOL16 WINAPI TranslateMessage32_16( const MSG32_16 *msg, BOOL16 wHaveParamHigh )
324 MSG msg32;
326 msg32.hwnd = WIN_Handle32( msg->msg.hwnd );
327 msg32.message = msg->msg.message;
328 msg32.wParam = MAKEWPARAM( msg->msg.wParam, wHaveParamHigh ? msg->wParamHigh : 0 );
329 msg32.lParam = msg->msg.lParam;
330 return TranslateMessage( &msg32 );
334 /***********************************************************************
335 * TranslateMessage (USER.113)
337 BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
339 return TranslateMessage32_16( (const MSG32_16 *)msg, FALSE );
343 /***********************************************************************
344 * DispatchMessage (USER.114)
346 LONG WINAPI DispatchMessage16( const MSG16* msg )
348 WND * wndPtr;
349 WNDPROC16 winproc;
350 LONG retval;
351 HWND hwnd = WIN_Handle32( msg->hwnd );
353 /* Process timer messages */
354 if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
356 if (msg->lParam)
357 return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
358 msg->message, msg->wParam, GetTickCount() );
361 if (!(wndPtr = WIN_GetPtr( hwnd )))
363 if (msg->hwnd) SetLastError( ERROR_INVALID_WINDOW_HANDLE );
364 return 0;
366 if (wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP)
368 if (IsWindow( hwnd )) SetLastError( ERROR_MESSAGE_SYNC_ONLY );
369 else SetLastError( ERROR_INVALID_WINDOW_HANDLE );
370 return 0;
372 winproc = (WNDPROC16)wndPtr->winproc;
373 WIN_ReleasePtr( wndPtr );
375 SPY_EnterMessage( SPY_DISPATCHMESSAGE16, hwnd, msg->message, msg->wParam, msg->lParam );
376 retval = CallWindowProc16( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam );
377 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg->message, retval, msg->wParam, msg->lParam );
379 return retval;
383 /***********************************************************************
384 * DispatchMessage32 (USER.822)
386 LONG WINAPI DispatchMessage32_16( const MSG32_16 *msg16, BOOL16 wHaveParamHigh )
388 if (wHaveParamHigh == FALSE)
389 return DispatchMessage16( &msg16->msg );
390 else
392 MSG msg;
394 msg.hwnd = WIN_Handle32( msg16->msg.hwnd );
395 msg.message = msg16->msg.message;
396 msg.wParam = MAKEWPARAM( msg16->msg.wParam, msg16->wParamHigh );
397 msg.lParam = msg16->msg.lParam;
398 msg.time = msg16->msg.time;
399 msg.pt.x = msg16->msg.pt.x;
400 msg.pt.y = msg16->msg.pt.y;
401 return DispatchMessageA( &msg );
406 /***********************************************************************
407 * IsDialogMessage (USER.90)
409 BOOL16 WINAPI IsDialogMessage16( HWND16 hwndDlg, MSG16 *msg16 )
411 MSG msg;
412 HWND hwndDlg32;
414 msg.hwnd = WIN_Handle32(msg16->hwnd);
415 hwndDlg32 = WIN_Handle32(hwndDlg);
417 switch(msg16->message)
419 case WM_KEYDOWN:
420 case WM_CHAR:
421 case WM_SYSCHAR:
422 msg.lParam = msg16->lParam;
423 WINPROC_MapMsg16To32W( msg.hwnd, msg16->message, msg16->wParam,
424 &msg.message, &msg.wParam, &msg.lParam );
425 /* these messages don't need an unmap */
426 return IsDialogMessageW( hwndDlg32, &msg );
429 if ((hwndDlg32 != msg.hwnd) && !IsChild( hwndDlg32, msg.hwnd )) return FALSE;
430 TranslateMessage16( msg16 );
431 DispatchMessage16( msg16 );
432 return TRUE;
436 /***********************************************************************
437 * MsgWaitForMultipleObjects (USER.640)
439 DWORD WINAPI MsgWaitForMultipleObjects16( DWORD count, CONST HANDLE *handles,
440 BOOL wait_all, DWORD timeout, DWORD mask )
442 return MsgWaitForMultipleObjectsEx( count, handles, timeout, mask,
443 wait_all ? MWMO_WAITALL : 0 );
447 /**********************************************************************
448 * SetDoubleClickTime (USER.20)
450 void WINAPI SetDoubleClickTime16( UINT16 interval )
452 SetDoubleClickTime( interval );
456 /**********************************************************************
457 * GetDoubleClickTime (USER.21)
459 UINT16 WINAPI GetDoubleClickTime16(void)
461 return GetDoubleClickTime();
465 /***********************************************************************
466 * PostQuitMessage (USER.6)
468 void WINAPI PostQuitMessage16( INT16 exitCode )
470 PostQuitMessage( exitCode );
474 /**********************************************************************
475 * GetKeyState (USER.106)
477 INT16 WINAPI GetKeyState16(INT16 vkey)
479 return GetKeyState(vkey);
483 /**********************************************************************
484 * GetKeyboardState (USER.222)
486 BOOL WINAPI GetKeyboardState16( LPBYTE state )
488 return GetKeyboardState( state );
492 /**********************************************************************
493 * SetKeyboardState (USER.223)
495 BOOL WINAPI SetKeyboardState16( LPBYTE state )
497 return SetKeyboardState( state );
501 /***********************************************************************
502 * SetMessageQueue (USER.266)
504 BOOL16 WINAPI SetMessageQueue16( INT16 size )
506 return SetMessageQueue( size );
510 /***********************************************************************
511 * GetQueueStatus (USER.334)
513 DWORD WINAPI GetQueueStatus16( UINT16 flags )
515 return GetQueueStatus( flags );
519 /***********************************************************************
520 * GetInputState (USER.335)
522 BOOL16 WINAPI GetInputState16(void)
524 return GetInputState();
528 /**********************************************************************
529 * TranslateAccelerator (USER.178)
531 INT16 WINAPI TranslateAccelerator16( HWND16 hwnd, HACCEL16 hAccel, LPMSG16 msg )
533 MSG msg32;
535 if (!msg) return 0;
536 msg32.message = msg->message;
537 /* msg32.hwnd not used */
538 msg32.wParam = msg->wParam;
539 msg32.lParam = msg->lParam;
540 return TranslateAcceleratorW( WIN_Handle32(hwnd), HACCEL_32(hAccel), &msg32 );
544 /**********************************************************************
545 * TranslateMDISysAccel (USER.451)
547 BOOL16 WINAPI TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg )
549 if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
551 MSG msg32;
552 msg32.hwnd = WIN_Handle32(msg->hwnd);
553 msg32.message = msg->message;
554 msg32.wParam = msg->wParam;
555 msg32.lParam = msg->lParam;
556 /* MDICLIENTINFO is still the same for win32 and win16 ... */
557 return TranslateMDISysAccel( WIN_Handle32(hwndClient), &msg32 );
559 return 0;