user32: Add support for SPI_GETFOCUSBORDERWIDTH and SPI_GETFOCUSBORDERHEIGHT.
[wine] / dlls / user32 / 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 "wine/debug.h"
27
28 WINE_DEFAULT_DEBUG_CHANNEL(msg);
29
30 DWORD USER16_AlertableWait = 0;
31
32 static LRESULT cwp_hook_callback( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
33                                   LRESULT *result, void *arg )
34 {
35     CWPSTRUCT cwp;
36
37     cwp.hwnd    = hwnd;
38     cwp.message = msg;
39     cwp.wParam  = wp;
40     cwp.lParam  = lp;
41     *result = 0;
42     return HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp, FALSE );
43 }
44
45 static LRESULT send_message_callback( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
46                                       LRESULT *result, void *arg )
47 {
48     *result = SendMessageA( hwnd, msg, wp, lp );
49     return *result;
50 }
51
52 static LRESULT post_message_callback( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
53                                       LRESULT *result, void *arg )
54 {
55     *result = 0;
56     return PostMessageA( hwnd, msg, wp, lp );
57 }
58
59 static LRESULT post_thread_message_callback( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
60                                              LRESULT *result, void *arg )
61 {
62     DWORD_PTR tid = (DWORD_PTR)arg;
63     *result = 0;
64     return PostThreadMessageA( tid, msg, wp, lp );
65 }
66
67 static LRESULT get_message_callback( HWND16 hwnd, UINT16 msg, WPARAM16 wp, LPARAM lp,
68                                      LRESULT *result, void *arg )
69 {
70     MSG16 *msg16 = arg;
71
72     msg16->hwnd    = hwnd;
73     msg16->message = msg;
74     msg16->wParam  = wp;
75     msg16->lParam  = lp;
76     *result = 0;
77     return 0;
78 }
79
80
81 /***********************************************************************
82  *              SendMessage  (USER.111)
83  */
84 LRESULT WINAPI SendMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
85 {
86     LRESULT result;
87     HWND hwnd = WIN_Handle32( hwnd16 );
88
89     if (hwnd != HWND_BROADCAST && WIN_IsCurrentThread(hwnd))
90     {
91         /* call 16-bit window proc directly */
92         WNDPROC16 winproc;
93
94         /* first the WH_CALLWNDPROC hook */
95         if (HOOK_IsHooked( WH_CALLWNDPROC ))
96             WINPROC_CallProc16To32A( cwp_hook_callback, hwnd16, msg, wparam, lparam, &result, NULL );
97
98         if (!(winproc = (WNDPROC16)GetWindowLong16( hwnd16, GWLP_WNDPROC ))) return 0;
99
100         SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wparam, lparam );
101         result = CallWindowProc16( winproc, hwnd16, msg, wparam, lparam );
102         SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, result, wparam, lparam );
103     }
104     else  /* map to 32-bit unicode for inter-thread/process message */
105     {
106         WINPROC_CallProc16To32A( send_message_callback, hwnd16, msg, wparam, lparam, &result, NULL );
107     }
108     return result;
109 }
110
111
112 /***********************************************************************
113  *              PostMessage  (USER.110)
114  */
115 BOOL16 WINAPI PostMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
116 {
117     LRESULT unused;
118     return WINPROC_CallProc16To32A( post_message_callback, hwnd, msg, wparam, lparam, &unused, NULL );
119 }
120
121
122 /***********************************************************************
123  *              PostAppMessage (USER.116)
124  */
125 BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
126 {
127     LRESULT unused;
128     DWORD_PTR tid = HTASK_32( hTask );
129
130     if (!tid) return FALSE;
131     return WINPROC_CallProc16To32A( post_thread_message_callback, 0, msg, wparam, lparam,
132                                     &unused, (void *)tid );
133 }
134
135
136 /***********************************************************************
137  *              InSendMessage  (USER.192)
138  */
139 BOOL16 WINAPI InSendMessage16(void)
140 {
141     return InSendMessage();
142 }
143
144
145 /***********************************************************************
146  *              ReplyMessage  (USER.115)
147  */
148 void WINAPI ReplyMessage16( LRESULT result )
149 {
150     ReplyMessage( result );
151 }
152
153
154 /***********************************************************************
155  *              PeekMessage32 (USER.819)
156  */
157 BOOL16 WINAPI PeekMessage32_16( MSG32_16 *msg16, HWND16 hwnd16,
158                                 UINT16 first, UINT16 last, UINT16 flags,
159                                 BOOL16 wHaveParamHigh )
160 {
161     MSG msg;
162     LRESULT unused;
163     HWND hwnd = WIN_Handle32( hwnd16 );
164
165     if(USER16_AlertableWait)
166         MsgWaitForMultipleObjectsEx( 0, NULL, 0, 0, MWMO_ALERTABLE );
167     if (!PeekMessageA( &msg, hwnd, first, last, flags )) return FALSE;
168
169     msg16->msg.time    = msg.time;
170     msg16->msg.pt.x    = (INT16)msg.pt.x;
171     msg16->msg.pt.y    = (INT16)msg.pt.y;
172     if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
173     WINPROC_CallProc32ATo16( get_message_callback, msg.hwnd, msg.message, msg.wParam, msg.lParam,
174                              &unused, &msg16->msg );
175     return TRUE;
176 }
177
178
179 /***********************************************************************
180  *              DefWindowProc (USER.107)
181  */
182 LRESULT WINAPI DefWindowProc16( HWND16 hwnd16, UINT16 msg, WPARAM16 wParam, LPARAM lParam )
183 {
184     LRESULT result;
185     HWND hwnd = WIN_Handle32( hwnd16 );
186
187     SPY_EnterMessage( SPY_DEFWNDPROC16, hwnd, msg, wParam, lParam );
188
189     switch(msg)
190     {
191     case WM_NCCREATE:
192         {
193             CREATESTRUCT16 *cs16 = MapSL(lParam);
194             CREATESTRUCTA cs32;
195
196             cs32.lpCreateParams = ULongToPtr(cs16->lpCreateParams);
197             cs32.hInstance      = HINSTANCE_32(cs16->hInstance);
198             cs32.hMenu          = HMENU_32(cs16->hMenu);
199             cs32.hwndParent     = WIN_Handle32(cs16->hwndParent);
200             cs32.cy             = cs16->cy;
201             cs32.cx             = cs16->cx;
202             cs32.y              = cs16->y;
203             cs32.x              = cs16->x;
204             cs32.style          = cs16->style;
205             cs32.dwExStyle      = cs16->dwExStyle;
206             cs32.lpszName       = MapSL(cs16->lpszName);
207             cs32.lpszClass      = MapSL(cs16->lpszClass);
208             result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)&cs32 );
209         }
210         break;
211
212     case WM_NCCALCSIZE:
213         {
214             RECT16 *rect16 = MapSL(lParam);
215             RECT rect32;
216
217             rect32.left    = rect16->left;
218             rect32.top     = rect16->top;
219             rect32.right   = rect16->right;
220             rect32.bottom  = rect16->bottom;
221
222             result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)&rect32 );
223
224             rect16->left   = rect32.left;
225             rect16->top    = rect32.top;
226             rect16->right  = rect32.right;
227             rect16->bottom = rect32.bottom;
228         }
229         break;
230
231     case WM_WINDOWPOSCHANGING:
232     case WM_WINDOWPOSCHANGED:
233         {
234             WINDOWPOS16 *pos16 = MapSL(lParam);
235             WINDOWPOS pos32;
236
237             pos32.hwnd             = WIN_Handle32(pos16->hwnd);
238             pos32.hwndInsertAfter  = WIN_Handle32(pos16->hwndInsertAfter);
239             pos32.x                = pos16->x;
240             pos32.y                = pos16->y;
241             pos32.cx               = pos16->cx;
242             pos32.cy               = pos16->cy;
243             pos32.flags            = pos16->flags;
244
245             result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)&pos32 );
246
247             pos16->hwnd            = HWND_16(pos32.hwnd);
248             pos16->hwndInsertAfter = HWND_16(pos32.hwndInsertAfter);
249             pos16->x               = pos32.x;
250             pos16->y               = pos32.y;
251             pos16->cx              = pos32.cx;
252             pos16->cy              = pos32.cy;
253             pos16->flags           = pos32.flags;
254         }
255         break;
256
257     case WM_GETTEXT:
258     case WM_SETTEXT:
259         result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)MapSL(lParam) );
260         break;
261
262     default:
263         result = DefWindowProcA( hwnd, msg, wParam, lParam );
264         break;
265     }
266
267     SPY_ExitMessage( SPY_RESULT_DEFWND16, hwnd, msg, result, wParam, lParam );
268     return result;
269 }
270
271
272 /***********************************************************************
273  *              PeekMessage  (USER.109)
274  */
275 BOOL16 WINAPI PeekMessage16( MSG16 *msg, HWND16 hwnd,
276                              UINT16 first, UINT16 last, UINT16 flags )
277 {
278     return PeekMessage32_16( (MSG32_16 *)msg, hwnd, first, last, flags, FALSE );
279 }
280
281
282 /***********************************************************************
283  *              GetMessage32  (USER.820)
284  */
285 BOOL16 WINAPI GetMessage32_16( MSG32_16 *msg16, HWND16 hwnd16, UINT16 first,
286                                UINT16 last, BOOL16 wHaveParamHigh )
287 {
288     MSG msg;
289     LRESULT unused;
290     HWND hwnd = WIN_Handle32( hwnd16 );
291
292     if(USER16_AlertableWait)
293         MsgWaitForMultipleObjectsEx( 0, NULL, INFINITE, 0, MWMO_ALERTABLE );
294     GetMessageA( &msg, hwnd, first, last );
295     msg16->msg.time    = msg.time;
296     msg16->msg.pt.x    = (INT16)msg.pt.x;
297     msg16->msg.pt.y    = (INT16)msg.pt.y;
298     if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
299     WINPROC_CallProc32ATo16( get_message_callback, msg.hwnd, msg.message, msg.wParam, msg.lParam,
300                              &unused, &msg16->msg );
301
302     TRACE( "message %04x, hwnd %p, filter(%04x - %04x)\n",
303            msg16->msg.message, hwnd, first, last );
304
305     return msg16->msg.message != WM_QUIT;
306 }
307
308
309 /***********************************************************************
310  *              GetMessage  (USER.108)
311  */
312 BOOL16 WINAPI GetMessage16( MSG16 *msg, HWND16 hwnd, UINT16 first, UINT16 last )
313 {
314     return GetMessage32_16( (MSG32_16 *)msg, hwnd, first, last, FALSE );
315 }
316
317
318 /***********************************************************************
319  *              TranslateMessage32 (USER.821)
320  */
321 BOOL16 WINAPI TranslateMessage32_16( const MSG32_16 *msg, BOOL16 wHaveParamHigh )
322 {
323     MSG msg32;
324
325     msg32.hwnd    = WIN_Handle32( msg->msg.hwnd );
326     msg32.message = msg->msg.message;
327     msg32.wParam  = MAKEWPARAM( msg->msg.wParam, wHaveParamHigh ? msg->wParamHigh : 0 );
328     msg32.lParam  = msg->msg.lParam;
329     return TranslateMessage( &msg32 );
330 }
331
332
333 /***********************************************************************
334  *              TranslateMessage (USER.113)
335  */
336 BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
337 {
338     return TranslateMessage32_16( (const MSG32_16 *)msg, FALSE );
339 }
340
341
342 /***********************************************************************
343  *              DispatchMessage (USER.114)
344  */
345 LONG WINAPI DispatchMessage16( const MSG16* msg )
346 {
347     WND * wndPtr;
348     WNDPROC16 winproc;
349     LONG retval;
350     HWND hwnd = WIN_Handle32( msg->hwnd );
351
352       /* Process timer messages */
353     if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
354     {
355         if (msg->lParam)
356             return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
357                                      msg->message, msg->wParam, GetTickCount() );
358     }
359
360     if (!(wndPtr = WIN_GetPtr( hwnd )))
361     {
362         if (msg->hwnd) SetLastError( ERROR_INVALID_WINDOW_HANDLE );
363         return 0;
364     }
365     if (wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP)
366     {
367         if (IsWindow( hwnd )) SetLastError( ERROR_MESSAGE_SYNC_ONLY );
368         else SetLastError( ERROR_INVALID_WINDOW_HANDLE );
369         return 0;
370     }
371     winproc = WINPROC_GetProc16( wndPtr->winproc, wndPtr->flags & WIN_ISUNICODE );
372     WIN_ReleasePtr( wndPtr );
373
374     SPY_EnterMessage( SPY_DISPATCHMESSAGE16, hwnd, msg->message, msg->wParam, msg->lParam );
375     retval = CallWindowProc16( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam );
376     SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg->message, retval, msg->wParam, msg->lParam );
377
378     return retval;
379 }
380
381
382 /***********************************************************************
383  *              DispatchMessage32 (USER.822)
384  */
385 LONG WINAPI DispatchMessage32_16( const MSG32_16 *msg16, BOOL16 wHaveParamHigh )
386 {
387     if (wHaveParamHigh == FALSE)
388         return DispatchMessage16( &msg16->msg );
389     else
390     {
391         MSG msg;
392
393         msg.hwnd    = WIN_Handle32( msg16->msg.hwnd );
394         msg.message = msg16->msg.message;
395         msg.wParam  = MAKEWPARAM( msg16->msg.wParam, msg16->wParamHigh );
396         msg.lParam  = msg16->msg.lParam;
397         msg.time    = msg16->msg.time;
398         msg.pt.x    = msg16->msg.pt.x;
399         msg.pt.y    = msg16->msg.pt.y;
400         return DispatchMessageA( &msg );
401     }
402 }
403
404
405 /***********************************************************************
406  *              IsDialogMessage (USER.90)
407  */
408 BOOL16 WINAPI IsDialogMessage16( HWND16 hwndDlg, MSG16 *msg16 )
409 {
410     MSG msg;
411     HWND hwndDlg32;
412
413     msg.hwnd  = WIN_Handle32(msg16->hwnd);
414     hwndDlg32 = WIN_Handle32(hwndDlg);
415
416     switch(msg16->message)
417     {
418     case WM_KEYDOWN:
419     case WM_CHAR:
420     case WM_SYSCHAR:
421         msg.message = msg16->message;
422         msg.wParam  = msg16->wParam;
423         msg.lParam  = msg16->lParam;
424         return IsDialogMessageA( hwndDlg32, &msg );
425     }
426
427     if ((hwndDlg32 != msg.hwnd) && !IsChild( hwndDlg32, msg.hwnd )) return FALSE;
428     TranslateMessage16( msg16 );
429     DispatchMessage16( msg16 );
430     return TRUE;
431 }
432
433
434 /***********************************************************************
435  *              MsgWaitForMultipleObjects  (USER.640)
436  */
437 DWORD WINAPI MsgWaitForMultipleObjects16( DWORD count, CONST HANDLE *handles,
438                                           BOOL wait_all, DWORD timeout, DWORD mask )
439 {
440     return MsgWaitForMultipleObjectsEx( count, handles, timeout, mask,
441                                         wait_all ? MWMO_WAITALL : 0 );
442 }
443
444
445 /**********************************************************************
446  *              SetDoubleClickTime (USER.20)
447  */
448 void WINAPI SetDoubleClickTime16( UINT16 interval )
449 {
450     SetDoubleClickTime( interval );
451 }
452
453
454 /**********************************************************************
455  *              GetDoubleClickTime (USER.21)
456  */
457 UINT16 WINAPI GetDoubleClickTime16(void)
458 {
459     return GetDoubleClickTime();
460 }
461
462
463 /***********************************************************************
464  *              PostQuitMessage (USER.6)
465  */
466 void WINAPI PostQuitMessage16( INT16 exitCode )
467 {
468     PostQuitMessage( exitCode );
469 }
470
471
472 /**********************************************************************
473  *              GetKeyState (USER.106)
474  */
475 INT16 WINAPI GetKeyState16(INT16 vkey)
476 {
477     return GetKeyState(vkey);
478 }
479
480
481 /**********************************************************************
482  *              GetKeyboardState (USER.222)
483  */
484 BOOL WINAPI GetKeyboardState16( LPBYTE state )
485 {
486     return GetKeyboardState( state );
487 }
488
489
490 /**********************************************************************
491  *              SetKeyboardState (USER.223)
492  */
493 BOOL WINAPI SetKeyboardState16( LPBYTE state )
494 {
495     return SetKeyboardState( state );
496 }
497
498
499 /***********************************************************************
500  *              SetMessageQueue (USER.266)
501  */
502 BOOL16 WINAPI SetMessageQueue16( INT16 size )
503 {
504     return SetMessageQueue( size );
505 }
506
507
508 /***********************************************************************
509  *              GetQueueStatus (USER.334)
510  */
511 DWORD WINAPI GetQueueStatus16( UINT16 flags )
512 {
513     return GetQueueStatus( flags );
514 }
515
516
517 /***********************************************************************
518  *              GetInputState (USER.335)
519  */
520 BOOL16 WINAPI GetInputState16(void)
521 {
522     return GetInputState();
523 }
524
525
526 /**********************************************************************
527  *           TranslateAccelerator      (USER.178)
528  */
529 INT16 WINAPI TranslateAccelerator16( HWND16 hwnd, HACCEL16 hAccel, LPMSG16 msg )
530 {
531     MSG msg32;
532
533     if (!msg) return 0;
534     msg32.message = msg->message;
535     /* msg32.hwnd not used */
536     msg32.wParam  = msg->wParam;
537     msg32.lParam  = msg->lParam;
538     return TranslateAcceleratorW( WIN_Handle32(hwnd), HACCEL_32(hAccel), &msg32 );
539 }
540
541
542 /**********************************************************************
543  *              TranslateMDISysAccel (USER.451)
544  */
545 BOOL16 WINAPI TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg )
546 {
547     if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
548     {
549         MSG msg32;
550         msg32.hwnd    = WIN_Handle32(msg->hwnd);
551         msg32.message = msg->message;
552         msg32.wParam  = msg->wParam;
553         msg32.lParam  = msg->lParam;
554         /* MDICLIENTINFO is still the same for win32 and win16 ... */
555         return TranslateMDISysAccel( WIN_Handle32(hwndClient), &msg32 );
556     }
557     return 0;
558 }