kernel: Added a test for QueryDosDeviceA.
[wine] / dlls / user / msg16.c
1 /*
2  * 16-bit messaging support
3  *
4  * Copyright 2001 Alexandre Julliard
5  *
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.
10  *
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.
15  *
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
19  */
20
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"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(msg);
30
31 DWORD USER16_AlertableWait = 0;
32
33 /***********************************************************************
34  *              SendMessage  (USER.111)
35  */
36 LRESULT WINAPI SendMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
37 {
38     LRESULT result;
39     UINT msg32;
40     WPARAM wparam32;
41     HWND hwnd = WIN_Handle32( hwnd16 );
42
43     if (hwnd != HWND_BROADCAST && WIN_IsCurrentThread(hwnd))
44     {
45         /* call 16-bit window proc directly */
46         WNDPROC16 winproc;
47
48         /* first the WH_CALLWNDPROC hook */
49         if (HOOK_IsHooked( WH_CALLWNDPROC ))
50         {
51             LPARAM lparam32 = lparam;
52
53             if (WINPROC_MapMsg16To32A( hwnd, msg, wparam, &msg32, &wparam32, &lparam32 ) != -1)
54             {
55                 CWPSTRUCT cwp;
56
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 */
64             }
65         }
66
67         if (!(winproc = (WNDPROC16)GetWindowLong16( hwnd16, GWLP_WNDPROC ))) return 0;
68
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 );
72     }
73     else  /* map to 32-bit unicode for inter-thread/process message */
74     {
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 );
80     }
81     return result;
82 }
83
84
85 /***********************************************************************
86  *              PostMessage  (USER.110)
87  */
88 BOOL16 WINAPI PostMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
89 {
90     WPARAM wparam32;
91     UINT msg32;
92     HWND hwnd = WIN_Handle32( hwnd16 );
93
94     switch (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ))
95     {
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;
103     }
104 }
105
106
107 /***********************************************************************
108  *              PostAppMessage (USER.116)
109  */
110 BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
111 {
112     WPARAM wparam32;
113     UINT msg32;
114     DWORD tid = HTASK_32( hTask );
115     if (!tid) return FALSE;
116
117     switch (WINPROC_MapMsg16To32W( 0, msg, wparam, &msg32, &wparam32, &lparam ))
118     {
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;
126     }
127 }
128
129
130 /***********************************************************************
131  *              InSendMessage  (USER.192)
132  */
133 BOOL16 WINAPI InSendMessage16(void)
134 {
135     return InSendMessage();
136 }
137
138
139 /***********************************************************************
140  *              ReplyMessage  (USER.115)
141  */
142 void WINAPI ReplyMessage16( LRESULT result )
143 {
144     ReplyMessage( result );
145 }
146
147
148 /***********************************************************************
149  *              PeekMessage32 (USER.819)
150  */
151 BOOL16 WINAPI PeekMessage32_16( MSG32_16 *msg16, HWND16 hwnd16,
152                                 UINT16 first, UINT16 last, UINT16 flags,
153                                 BOOL16 wHaveParamHigh )
154 {
155     MSG msg;
156     HWND hwnd = WIN_Handle32( hwnd16 );
157
158     if(USER16_AlertableWait)
159         MsgWaitForMultipleObjectsEx( 0, NULL, 1, 0, MWMO_ALERTABLE );
160     if (!PeekMessageW( &msg, hwnd, first, last, flags )) return FALSE;
161
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);
168
169     return (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
170                                    &msg16->msg.message, &msg16->msg.wParam,
171                                    &msg16->msg.lParam ) != -1);
172 }
173
174
175 /***********************************************************************
176  *              DefWindowProc (USER.107)
177  */
178 LRESULT WINAPI DefWindowProc16( HWND16 hwnd16, UINT16 msg, WPARAM16 wParam, LPARAM lParam )
179 {
180     LRESULT result;
181     HWND hwnd = WIN_Handle32( hwnd16 );
182
183     SPY_EnterMessage( SPY_DEFWNDPROC16, hwnd, msg, wParam, lParam );
184
185     switch(msg)
186     {
187     case WM_NCCREATE:
188         {
189             CREATESTRUCT16 *cs16 = MapSL(lParam);
190             CREATESTRUCTA cs32;
191
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 );
205         }
206         break;
207
208     case WM_NCCALCSIZE:
209         {
210             RECT16 *rect16 = MapSL(lParam);
211             RECT rect32;
212
213             rect32.left    = rect16->left;
214             rect32.top     = rect16->top;
215             rect32.right   = rect16->right;
216             rect32.bottom  = rect16->bottom;
217
218             result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)&rect32 );
219
220             rect16->left   = rect32.left;
221             rect16->top    = rect32.top;
222             rect16->right  = rect32.right;
223             rect16->bottom = rect32.bottom;
224         }
225         break;
226
227     case WM_WINDOWPOSCHANGING:
228     case WM_WINDOWPOSCHANGED:
229         {
230             WINDOWPOS16 *pos16 = MapSL(lParam);
231             WINDOWPOS pos32;
232
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;
240
241             result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)&pos32 );
242
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;
250         }
251         break;
252
253     case WM_GETTEXT:
254     case WM_SETTEXT:
255         result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)MapSL(lParam) );
256         break;
257
258     default:
259         result = DefWindowProcA( hwnd, msg, wParam, lParam );
260         break;
261     }
262
263     SPY_ExitMessage( SPY_RESULT_DEFWND16, hwnd, msg, result, wParam, lParam );
264     return result;
265 }
266
267
268 /***********************************************************************
269  *              PeekMessage  (USER.109)
270  */
271 BOOL16 WINAPI PeekMessage16( MSG16 *msg, HWND16 hwnd,
272                              UINT16 first, UINT16 last, UINT16 flags )
273 {
274     return PeekMessage32_16( (MSG32_16 *)msg, hwnd, first, last, flags, FALSE );
275 }
276
277
278 /***********************************************************************
279  *              GetMessage32  (USER.820)
280  */
281 BOOL16 WINAPI GetMessage32_16( MSG32_16 *msg16, HWND16 hwnd16, UINT16 first,
282                                UINT16 last, BOOL16 wHaveParamHigh )
283 {
284     MSG msg;
285     HWND hwnd = WIN_Handle32( hwnd16 );
286
287     do
288     {
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);
298     }
299     while (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
300                                   &msg16->msg.message, &msg16->msg.wParam,
301                                   &msg16->msg.lParam ) == -1);
302
303     TRACE( "message %04x, hwnd %p, filter(%04x - %04x)\n",
304            msg16->msg.message, hwnd, first, last );
305
306     return msg16->msg.message != WM_QUIT;
307 }
308
309
310 /***********************************************************************
311  *              GetMessage  (USER.108)
312  */
313 BOOL16 WINAPI GetMessage16( MSG16 *msg, HWND16 hwnd, UINT16 first, UINT16 last )
314 {
315     return GetMessage32_16( (MSG32_16 *)msg, hwnd, first, last, FALSE );
316 }
317
318
319 /***********************************************************************
320  *              TranslateMessage32 (USER.821)
321  */
322 BOOL16 WINAPI TranslateMessage32_16( const MSG32_16 *msg, BOOL16 wHaveParamHigh )
323 {
324     MSG msg32;
325
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 );
331 }
332
333
334 /***********************************************************************
335  *              TranslateMessage (USER.113)
336  */
337 BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
338 {
339     return TranslateMessage32_16( (const MSG32_16 *)msg, FALSE );
340 }
341
342
343 /***********************************************************************
344  *              DispatchMessage (USER.114)
345  */
346 LONG WINAPI DispatchMessage16( const MSG16* msg )
347 {
348     WND * wndPtr;
349     WNDPROC16 winproc;
350     LONG retval;
351     HWND hwnd = WIN_Handle32( msg->hwnd );
352
353       /* Process timer messages */
354     if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
355     {
356         if (msg->lParam)
357             return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
358                                      msg->message, msg->wParam, GetTickCount() );
359     }
360
361     if (!(wndPtr = WIN_GetPtr( hwnd )))
362     {
363         if (msg->hwnd) SetLastError( ERROR_INVALID_WINDOW_HANDLE );
364         return 0;
365     }
366     if (wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP)
367     {
368         if (IsWindow( hwnd )) SetLastError( ERROR_MESSAGE_SYNC_ONLY );
369         else SetLastError( ERROR_INVALID_WINDOW_HANDLE );
370         return 0;
371     }
372     winproc = (WNDPROC16)wndPtr->winproc;
373     WIN_ReleasePtr( wndPtr );
374
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 );
378
379     return retval;
380 }
381
382
383 /***********************************************************************
384  *              DispatchMessage32 (USER.822)
385  */
386 LONG WINAPI DispatchMessage32_16( const MSG32_16 *msg16, BOOL16 wHaveParamHigh )
387 {
388     if (wHaveParamHigh == FALSE)
389         return DispatchMessage16( &msg16->msg );
390     else
391     {
392         MSG msg;
393
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 );
402     }
403 }
404
405
406 /***********************************************************************
407  *              IsDialogMessage (USER.90)
408  */
409 BOOL16 WINAPI IsDialogMessage16( HWND16 hwndDlg, MSG16 *msg16 )
410 {
411     MSG msg;
412     HWND hwndDlg32;
413
414     msg.hwnd  = WIN_Handle32(msg16->hwnd);
415     hwndDlg32 = WIN_Handle32(hwndDlg);
416
417     switch(msg16->message)
418     {
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 );
427     }
428
429     if ((hwndDlg32 != msg.hwnd) && !IsChild( hwndDlg32, msg.hwnd )) return FALSE;
430     TranslateMessage16( msg16 );
431     DispatchMessage16( msg16 );
432     return TRUE;
433 }
434
435
436 /***********************************************************************
437  *              MsgWaitForMultipleObjects  (USER.640)
438  */
439 DWORD WINAPI MsgWaitForMultipleObjects16( DWORD count, CONST HANDLE *handles,
440                                           BOOL wait_all, DWORD timeout, DWORD mask )
441 {
442     return MsgWaitForMultipleObjectsEx( count, handles, timeout, mask,
443                                         wait_all ? MWMO_WAITALL : 0 );
444 }
445
446
447 /**********************************************************************
448  *              SetDoubleClickTime (USER.20)
449  */
450 void WINAPI SetDoubleClickTime16( UINT16 interval )
451 {
452     SetDoubleClickTime( interval );
453 }
454
455
456 /**********************************************************************
457  *              GetDoubleClickTime (USER.21)
458  */
459 UINT16 WINAPI GetDoubleClickTime16(void)
460 {
461     return GetDoubleClickTime();
462 }
463
464
465 /***********************************************************************
466  *              PostQuitMessage (USER.6)
467  */
468 void WINAPI PostQuitMessage16( INT16 exitCode )
469 {
470     PostQuitMessage( exitCode );
471 }
472
473
474 /**********************************************************************
475  *              GetKeyState (USER.106)
476  */
477 INT16 WINAPI GetKeyState16(INT16 vkey)
478 {
479     return GetKeyState(vkey);
480 }
481
482
483 /**********************************************************************
484  *              GetKeyboardState (USER.222)
485  */
486 BOOL WINAPI GetKeyboardState16( LPBYTE state )
487 {
488     return GetKeyboardState( state );
489 }
490
491
492 /**********************************************************************
493  *              SetKeyboardState (USER.223)
494  */
495 BOOL WINAPI SetKeyboardState16( LPBYTE state )
496 {
497     return SetKeyboardState( state );
498 }
499
500
501 /***********************************************************************
502  *              SetMessageQueue (USER.266)
503  */
504 BOOL16 WINAPI SetMessageQueue16( INT16 size )
505 {
506     return SetMessageQueue( size );
507 }
508
509
510 /***********************************************************************
511  *              GetQueueStatus (USER.334)
512  */
513 DWORD WINAPI GetQueueStatus16( UINT16 flags )
514 {
515     return GetQueueStatus( flags );
516 }
517
518
519 /***********************************************************************
520  *              GetInputState (USER.335)
521  */
522 BOOL16 WINAPI GetInputState16(void)
523 {
524     return GetInputState();
525 }
526
527
528 /**********************************************************************
529  *           TranslateAccelerator      (USER.178)
530  */
531 INT16 WINAPI TranslateAccelerator16( HWND16 hwnd, HACCEL16 hAccel, LPMSG16 msg )
532 {
533     MSG msg32;
534
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 );
541 }
542
543
544 /**********************************************************************
545  *              TranslateMDISysAccel (USER.451)
546  */
547 BOOL16 WINAPI TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg )
548 {
549     if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
550     {
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 );
558     }
559     return 0;
560 }