Made all 16<->32 HWND conversions use explicit functions instead of
[wine] / dlls / user / msg16.c
1 /*
2  * 16-bit messaging support
3  *
4  * Copyright 2001 Alexandre Julliard
5  */
6
7 #include "wine/winuser16.h"
8 #include "heap.h"
9 #include "hook.h"
10 #include "message.h"
11 #include "spy.h"
12 #include "task.h"
13 #include "thread.h"
14 #include "win.h"
15 #include "debugtools.h"
16
17 DEFAULT_DEBUG_CHANNEL(msg);
18
19
20 /***********************************************************************
21  *              SendMessage  (USER.111)
22  */
23 LRESULT WINAPI SendMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
24 {
25     LRESULT result;
26     HWND hwnd = WIN_Handle32( hwnd16 );
27
28     if (hwnd != HWND_BROADCAST &&
29         GetWindowThreadProcessId( hwnd, NULL ) == GetCurrentThreadId())
30     {
31         /* call 16-bit window proc directly */
32         WNDPROC16 winproc;
33
34         /* first the WH_CALLWNDPROC hook */
35         if (HOOK_IsHooked( WH_CALLWNDPROC ))
36         {
37             CWPSTRUCT16 *cwp;
38
39             if ((cwp = SEGPTR_NEW(CWPSTRUCT16)))
40             {
41                 cwp->hwnd    = hwnd16;
42                 cwp->message = msg;
43                 cwp->wParam  = wparam;
44                 cwp->lParam  = lparam;
45                 HOOK_CallHooks16( WH_CALLWNDPROC, HC_ACTION, 1, SEGPTR_GET(cwp) );
46                 if (cwp->hwnd != hwnd16)
47                 {
48                     hwnd16 = cwp->hwnd;
49                     hwnd = WIN_Handle32( hwnd16 );
50                 }
51                 msg    = cwp->message;
52                 wparam = cwp->wParam;
53                 lparam = cwp->lParam;
54                 SEGPTR_FREE( cwp );
55             }
56         }
57
58         if (!(winproc = (WNDPROC16)GetWindowLong16( hwnd16, GWL_WNDPROC ))) return 0;
59
60         SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wparam, lparam );
61         result = CallWindowProc16( (WNDPROC16)winproc, hwnd16, msg, wparam, lparam );
62         SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, result, wparam, lparam );
63     }
64     else  /* map to 32-bit unicode for inter-thread/process message */
65     {
66         UINT msg32;
67         WPARAM wparam32;
68
69         if (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ) == -1)
70             return 0;
71         result = WINPROC_UnmapMsg16To32W( hwnd, msg32, wparam32, lparam,
72                                           SendMessageW( hwnd, msg32, wparam32, lparam ) );
73     }
74     return result;
75 }
76
77
78 /***********************************************************************
79  *              PostMessage  (USER.110)
80  */
81 BOOL16 WINAPI PostMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
82 {
83     WPARAM wparam32;
84     UINT msg32;
85     HWND hwnd = WIN_Handle32( hwnd16 );
86
87     switch (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ))
88     {
89     case 0:
90         return PostMessageW( hwnd, msg32, wparam32, lparam );
91     case 1:
92         ERR( "16-bit message %x contains pointer, cannot post\n", msg );
93         return FALSE;
94     default:
95         return FALSE;
96     }
97 }
98
99
100 /***********************************************************************
101  *              PostAppMessage (USER.116)
102  *              PostAppMessage16 (USER32.@)
103  */
104 BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
105 {
106     WPARAM wparam32;
107     UINT msg32;
108     TDB *pTask = TASK_GetPtr( hTask );
109     if (!pTask) return FALSE;
110
111     switch (WINPROC_MapMsg16To32W( 0, msg, wparam, &msg32, &wparam32, &lparam ))
112     {
113     case 0:
114         return PostThreadMessageW( (DWORD)pTask->teb->tid, msg32, wparam32, lparam );
115     case 1:
116         ERR( "16-bit message %x contains pointer, cannot post\n", msg );
117         return FALSE;
118     default:
119         return FALSE;
120     }
121 }
122
123
124 /***********************************************************************
125  *              InSendMessage  (USER.192)
126  */
127 BOOL16 WINAPI InSendMessage16(void)
128 {
129     return InSendMessage();
130 }
131
132
133 /***********************************************************************
134  *              ReplyMessage  (USER.115)
135  */
136 void WINAPI ReplyMessage16( LRESULT result )
137 {
138     ReplyMessage( result );
139 }
140
141
142 /***********************************************************************
143  *              PeekMessage32 (USER.819)
144  */
145 BOOL16 WINAPI PeekMessage32_16( MSG32_16 *msg16, HWND16 hwnd16,
146                                 UINT16 first, UINT16 last, UINT16 flags,
147                                 BOOL16 wHaveParamHigh )
148 {
149     MSG msg;
150     HWND hwnd = WIN_Handle32( hwnd16 );
151
152     if (!PeekMessageW( &msg, hwnd, first, last, flags )) return FALSE;
153
154     msg16->msg.hwnd    = WIN_Handle16( msg.hwnd );
155     msg16->msg.lParam  = msg.lParam;
156     msg16->msg.time    = msg.time;
157     msg16->msg.pt.x    = (INT16)msg.pt.x;
158     msg16->msg.pt.y    = (INT16)msg.pt.y;
159     if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
160
161     return (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
162                                    &msg16->msg.message, &msg16->msg.wParam,
163                                    &msg16->msg.lParam ) != -1);
164 }
165
166
167 /***********************************************************************
168  *              PeekMessage  (USER.109)
169  */
170 BOOL16 WINAPI PeekMessage16( MSG16 *msg, HWND16 hwnd,
171                              UINT16 first, UINT16 last, UINT16 flags )
172 {
173     return PeekMessage32_16( (MSG32_16 *)msg, hwnd, first, last, flags, FALSE );
174 }
175
176
177 /***********************************************************************
178  *              GetMessage32  (USER.820)
179  */
180 BOOL16 WINAPI GetMessage32_16( MSG32_16 *msg16, HWND16 hwnd16, UINT16 first,
181                                UINT16 last, BOOL16 wHaveParamHigh )
182 {
183     MSG msg;
184     HWND hwnd = WIN_Handle32( hwnd16 );
185
186     do
187     {
188         GetMessageW( &msg, hwnd, first, last );
189         msg16->msg.hwnd    = WIN_Handle16( msg.hwnd );
190         msg16->msg.lParam  = msg.lParam;
191         msg16->msg.time    = msg.time;
192         msg16->msg.pt.x    = (INT16)msg.pt.x;
193         msg16->msg.pt.y    = (INT16)msg.pt.y;
194         if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
195     }
196     while (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
197                                   &msg16->msg.message, &msg16->msg.wParam,
198                                   &msg16->msg.lParam ) == -1);
199
200     TRACE( "message %04x, hwnd %04x, filter(%04x - %04x)\n",
201            msg16->msg.message, hwnd, first, last );
202
203     return msg16->msg.message != WM_QUIT;
204 }
205
206
207 /***********************************************************************
208  *              GetMessage  (USER.108)
209  */
210 BOOL16 WINAPI GetMessage16( MSG16 *msg, HWND16 hwnd, UINT16 first, UINT16 last )
211 {
212     return GetMessage32_16( (MSG32_16 *)msg, hwnd, first, last, FALSE );
213 }
214
215
216 /***********************************************************************
217  *              TranslateMessage32 (USER.821)
218  */
219 BOOL16 WINAPI TranslateMessage32_16( const MSG32_16 *msg, BOOL16 wHaveParamHigh )
220 {
221     MSG msg32;
222
223     msg32.hwnd    = WIN_Handle32( msg->msg.hwnd );
224     msg32.message = msg->msg.message;
225     msg32.wParam  = MAKEWPARAM( msg->msg.wParam, wHaveParamHigh ? msg->wParamHigh : 0 );
226     msg32.lParam  = msg->msg.lParam;
227     return TranslateMessage( &msg32 );
228 }
229
230
231 /***********************************************************************
232  *              TranslateMessage (USER.113)
233  */
234 BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
235 {
236     return TranslateMessage32_16( (MSG32_16 *)msg, FALSE );
237 }
238
239
240 /***********************************************************************
241  *              DispatchMessage (USER.114)
242  */
243 LONG WINAPI DispatchMessage16( const MSG16* msg )
244 {
245     WND * wndPtr;
246     WNDPROC16 winproc;
247     LONG retval;
248     int painting;
249     HWND hwnd = WIN_Handle32( msg->hwnd );
250
251       /* Process timer messages */
252     if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
253     {
254         if (msg->lParam)
255         {
256             /* before calling window proc, verify whether timer is still valid;
257                there's a slim chance that the application kills the timer
258                between GetMessage and DispatchMessage API calls */
259             if (!TIMER_IsTimerValid(hwnd, (UINT) msg->wParam, (HWINDOWPROC) msg->lParam))
260                 return 0; /* invalid winproc */
261
262             return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
263                                      msg->message, msg->wParam, GetTickCount() );
264         }
265     }
266
267     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
268     if (!wndPtr->winproc)
269     {
270         WIN_ReleaseWndPtr( wndPtr );
271         return 0;
272     }
273     winproc = (WNDPROC16)wndPtr->winproc;
274     painting = (msg->message == WM_PAINT);
275     if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
276     WIN_ReleaseWndPtr( wndPtr );
277
278     SPY_EnterMessage( SPY_DISPATCHMESSAGE16, hwnd, msg->message, msg->wParam, msg->lParam );
279     retval = CallWindowProc16( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam );
280     SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg->message, retval, msg->wParam, msg->lParam );
281
282     if (!painting) return retval;
283
284     if ((wndPtr = WIN_FindWndPtr( hwnd )))
285     {
286         if ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
287         {
288             ERR( "BeginPaint not called on WM_PAINT for hwnd %04x!\n", msg->hwnd );
289             wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
290             WIN_ReleaseWndPtr( wndPtr );
291             /* Validate the update region to avoid infinite WM_PAINT loop */
292             RedrawWindow( hwnd, NULL, 0,
293                           RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT );
294         }
295         else WIN_ReleaseWndPtr( wndPtr );
296     }
297     return retval;
298 }
299
300
301 /***********************************************************************
302  *              DispatchMessage32 (USER.822)
303  */
304 LONG WINAPI DispatchMessage32_16( const MSG32_16 *msg16, BOOL16 wHaveParamHigh )
305 {
306     if (wHaveParamHigh == FALSE)
307         return DispatchMessage16( &msg16->msg );
308     else
309     {
310         MSG msg;
311
312         msg.hwnd    = WIN_Handle32( msg16->msg.hwnd );
313         msg.message = msg16->msg.message;
314         msg.wParam  = MAKEWPARAM( msg16->msg.wParam, msg16->wParamHigh );
315         msg.lParam  = msg16->msg.lParam;
316         msg.time    = msg16->msg.time;
317         msg.pt.x    = msg16->msg.pt.x;
318         msg.pt.y    = msg16->msg.pt.y;
319         return DispatchMessageA( &msg );
320     }
321 }
322
323
324 /***********************************************************************
325  *              MsgWaitForMultipleObjects  (USER.640)
326  */
327 DWORD WINAPI MsgWaitForMultipleObjects16( DWORD count, CONST HANDLE *handles,
328                                           BOOL wait_all, DWORD timeout, DWORD mask )
329 {
330     return MsgWaitForMultipleObjectsEx( count, handles, timeout, mask,
331                                         wait_all ? MWMO_WAITALL : 0 );
332 }
333
334
335 /**********************************************************************
336  *              SetDoubleClickTime (USER.20)
337  */
338 void WINAPI SetDoubleClickTime16( UINT16 interval )
339 {
340     SetDoubleClickTime( interval );
341 }
342
343
344 /**********************************************************************
345  *              GetDoubleClickTime (USER.21)
346  */
347 UINT16 WINAPI GetDoubleClickTime16(void)
348 {
349     return GetDoubleClickTime();
350 }
351
352
353 /***********************************************************************
354  *              PostQuitMessage (USER.6)
355  */
356 void WINAPI PostQuitMessage16( INT16 exitCode )
357 {
358     PostQuitMessage( exitCode );
359 }
360
361
362 /***********************************************************************
363  *              SetMessageQueue (USER.266)
364  */
365 BOOL16 WINAPI SetMessageQueue16( INT16 size )
366 {
367     return SetMessageQueue( size );
368 }
369
370
371 /***********************************************************************
372  *              GetQueueStatus (USER.334)
373  */
374 DWORD WINAPI GetQueueStatus16( UINT16 flags )
375 {
376     return GetQueueStatus( flags );
377 }
378
379
380 /***********************************************************************
381  *              GetInputState (USER.335)
382  */
383 BOOL16 WINAPI GetInputState16(void)
384 {
385     return GetInputState();
386 }
387
388
389 /**********************************************************************
390  *           TranslateAccelerator      (USER.178)
391  */
392 INT16 WINAPI TranslateAccelerator16( HWND16 hwnd, HACCEL16 hAccel, LPMSG16 msg )
393 {
394     MSG msg32;
395
396     if (!msg) return 0;
397     msg32.message = msg->message;
398     /* msg32.hwnd not used */
399     msg32.wParam  = msg->wParam;
400     msg32.lParam  = msg->lParam;
401     return TranslateAccelerator( WIN_Handle32(hwnd), hAccel, &msg32 );
402 }
403
404
405 /**********************************************************************
406  *              TranslateMDISysAccel (USER.451)
407  */
408 BOOL16 WINAPI TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg )
409 {
410     if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
411     {
412         MSG msg32;
413         msg32.hwnd    = WIN_Handle32(msg->hwnd);
414         msg32.message = msg->message;
415         msg32.wParam  = msg->wParam;
416         msg32.lParam  = msg->lParam;
417         /* MDICLIENTINFO is still the same for win32 and win16 ... */
418         return TranslateMDISysAccel( WIN_Handle32(hwndClient), &msg32 );
419     }
420     return 0;
421 }