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