blob: 2ed9979b70bc424175ec6d2227a9b48730aae536 [file] [log] [blame]
Alexandre Julliardd253c582001-08-07 19:19:08 +00001/*
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
17DEFAULT_DEBUG_CHANNEL(msg);
18
19
20/***********************************************************************
21 * SendMessage (USER.111)
22 */
Alexandre Julliardd23a82b2001-09-19 20:37:04 +000023LRESULT WINAPI SendMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
Alexandre Julliardd253c582001-08-07 19:19:08 +000024{
25 LRESULT result;
Alexandre Julliardd23a82b2001-09-19 20:37:04 +000026 HWND hwnd = WIN_Handle32( hwnd16 );
Alexandre Julliardd253c582001-08-07 19:19:08 +000027
Alexandre Julliard7695d692001-09-24 01:19:59 +000028 if (hwnd != HWND_BROADCAST && WIN_IsCurrentThread(hwnd))
Alexandre Julliardd253c582001-08-07 19:19:08 +000029 {
30 /* call 16-bit window proc directly */
Alexandre Julliardd253c582001-08-07 19:19:08 +000031 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 {
Alexandre Julliardd23a82b2001-09-19 20:37:04 +000040 cwp->hwnd = hwnd16;
Alexandre Julliardd253c582001-08-07 19:19:08 +000041 cwp->message = msg;
42 cwp->wParam = wparam;
43 cwp->lParam = lparam;
44 HOOK_CallHooks16( WH_CALLWNDPROC, HC_ACTION, 1, SEGPTR_GET(cwp) );
Alexandre Julliardd23a82b2001-09-19 20:37:04 +000045 if (cwp->hwnd != hwnd16)
46 {
47 hwnd16 = cwp->hwnd;
48 hwnd = WIN_Handle32( hwnd16 );
49 }
Alexandre Julliardd253c582001-08-07 19:19:08 +000050 msg = cwp->message;
51 wparam = cwp->wParam;
52 lparam = cwp->lParam;
53 SEGPTR_FREE( cwp );
54 }
55 }
56
Alexandre Julliardd23a82b2001-09-19 20:37:04 +000057 if (!(winproc = (WNDPROC16)GetWindowLong16( hwnd16, GWL_WNDPROC ))) return 0;
Alexandre Julliardd253c582001-08-07 19:19:08 +000058
59 SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wparam, lparam );
Alexandre Julliardd23a82b2001-09-19 20:37:04 +000060 result = CallWindowProc16( (WNDPROC16)winproc, hwnd16, msg, wparam, lparam );
Alexandre Julliardd253c582001-08-07 19:19:08 +000061 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, result, wparam, lparam );
62 }
63 else /* map to 32-bit unicode for inter-thread/process message */
64 {
65 UINT msg32;
66 WPARAM wparam32;
67
68 if (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ) == -1)
69 return 0;
70 result = WINPROC_UnmapMsg16To32W( hwnd, msg32, wparam32, lparam,
71 SendMessageW( hwnd, msg32, wparam32, lparam ) );
72 }
73 return result;
74}
75
76
77/***********************************************************************
78 * PostMessage (USER.110)
79 */
Alexandre Julliardd23a82b2001-09-19 20:37:04 +000080BOOL16 WINAPI PostMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
Alexandre Julliardd253c582001-08-07 19:19:08 +000081{
82 WPARAM wparam32;
83 UINT msg32;
Alexandre Julliardd23a82b2001-09-19 20:37:04 +000084 HWND hwnd = WIN_Handle32( hwnd16 );
Alexandre Julliardd253c582001-08-07 19:19:08 +000085
86 switch (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ))
87 {
88 case 0:
89 return PostMessageW( hwnd, msg32, wparam32, lparam );
90 case 1:
91 ERR( "16-bit message %x contains pointer, cannot post\n", msg );
92 return FALSE;
93 default:
94 return FALSE;
95 }
96}
97
98
99/***********************************************************************
100 * PostAppMessage (USER.116)
101 * PostAppMessage16 (USER32.@)
102 */
103BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
104{
105 WPARAM wparam32;
106 UINT msg32;
107 TDB *pTask = TASK_GetPtr( hTask );
108 if (!pTask) return FALSE;
109
110 switch (WINPROC_MapMsg16To32W( 0, msg, wparam, &msg32, &wparam32, &lparam ))
111 {
112 case 0:
113 return PostThreadMessageW( (DWORD)pTask->teb->tid, msg32, wparam32, lparam );
114 case 1:
115 ERR( "16-bit message %x contains pointer, cannot post\n", msg );
116 return FALSE;
117 default:
118 return FALSE;
119 }
120}
121
122
123/***********************************************************************
124 * InSendMessage (USER.192)
125 */
126BOOL16 WINAPI InSendMessage16(void)
127{
128 return InSendMessage();
129}
130
131
132/***********************************************************************
133 * ReplyMessage (USER.115)
134 */
135void WINAPI ReplyMessage16( LRESULT result )
136{
137 ReplyMessage( result );
138}
139
140
141/***********************************************************************
142 * PeekMessage32 (USER.819)
143 */
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000144BOOL16 WINAPI PeekMessage32_16( MSG32_16 *msg16, HWND16 hwnd16,
Alexandre Julliardd253c582001-08-07 19:19:08 +0000145 UINT16 first, UINT16 last, UINT16 flags,
146 BOOL16 wHaveParamHigh )
147{
148 MSG msg;
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000149 HWND hwnd = WIN_Handle32( hwnd16 );
Alexandre Julliardd253c582001-08-07 19:19:08 +0000150
151 if (!PeekMessageW( &msg, hwnd, first, last, flags )) return FALSE;
152
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000153 msg16->msg.hwnd = WIN_Handle16( msg.hwnd );
Alexandre Julliardd253c582001-08-07 19:19:08 +0000154 msg16->msg.lParam = msg.lParam;
155 msg16->msg.time = msg.time;
156 msg16->msg.pt.x = (INT16)msg.pt.x;
157 msg16->msg.pt.y = (INT16)msg.pt.y;
158 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
159
160 return (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
161 &msg16->msg.message, &msg16->msg.wParam,
162 &msg16->msg.lParam ) != -1);
163}
164
165
166/***********************************************************************
167 * PeekMessage (USER.109)
168 */
169BOOL16 WINAPI PeekMessage16( MSG16 *msg, HWND16 hwnd,
170 UINT16 first, UINT16 last, UINT16 flags )
171{
172 return PeekMessage32_16( (MSG32_16 *)msg, hwnd, first, last, flags, FALSE );
173}
174
175
176/***********************************************************************
177 * GetMessage32 (USER.820)
178 */
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000179BOOL16 WINAPI GetMessage32_16( MSG32_16 *msg16, HWND16 hwnd16, UINT16 first,
Alexandre Julliardd253c582001-08-07 19:19:08 +0000180 UINT16 last, BOOL16 wHaveParamHigh )
181{
182 MSG msg;
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000183 HWND hwnd = WIN_Handle32( hwnd16 );
Alexandre Julliardd253c582001-08-07 19:19:08 +0000184
185 do
186 {
187 GetMessageW( &msg, hwnd, first, last );
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000188 msg16->msg.hwnd = WIN_Handle16( msg.hwnd );
Alexandre Julliardd253c582001-08-07 19:19:08 +0000189 msg16->msg.lParam = msg.lParam;
190 msg16->msg.time = msg.time;
191 msg16->msg.pt.x = (INT16)msg.pt.x;
192 msg16->msg.pt.y = (INT16)msg.pt.y;
193 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
194 }
195 while (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
196 &msg16->msg.message, &msg16->msg.wParam,
197 &msg16->msg.lParam ) == -1);
198
199 TRACE( "message %04x, hwnd %04x, filter(%04x - %04x)\n",
200 msg16->msg.message, hwnd, first, last );
201
202 return msg16->msg.message != WM_QUIT;
203}
204
205
206/***********************************************************************
207 * GetMessage (USER.108)
208 */
209BOOL16 WINAPI GetMessage16( MSG16 *msg, HWND16 hwnd, UINT16 first, UINT16 last )
210{
211 return GetMessage32_16( (MSG32_16 *)msg, hwnd, first, last, FALSE );
212}
213
214
215/***********************************************************************
216 * TranslateMessage32 (USER.821)
217 */
218BOOL16 WINAPI TranslateMessage32_16( const MSG32_16 *msg, BOOL16 wHaveParamHigh )
219{
220 MSG msg32;
221
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000222 msg32.hwnd = WIN_Handle32( msg->msg.hwnd );
Alexandre Julliardd253c582001-08-07 19:19:08 +0000223 msg32.message = msg->msg.message;
224 msg32.wParam = MAKEWPARAM( msg->msg.wParam, wHaveParamHigh ? msg->wParamHigh : 0 );
225 msg32.lParam = msg->msg.lParam;
226 return TranslateMessage( &msg32 );
227}
228
229
230/***********************************************************************
231 * TranslateMessage (USER.113)
232 */
233BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
234{
235 return TranslateMessage32_16( (MSG32_16 *)msg, FALSE );
236}
237
238
239/***********************************************************************
240 * DispatchMessage (USER.114)
241 */
242LONG WINAPI DispatchMessage16( const MSG16* msg )
243{
244 WND * wndPtr;
245 WNDPROC16 winproc;
246 LONG retval;
247 int painting;
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000248 HWND hwnd = WIN_Handle32( msg->hwnd );
Alexandre Julliardd253c582001-08-07 19:19:08 +0000249
250 /* Process timer messages */
251 if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
252 {
253 if (msg->lParam)
254 {
255 /* before calling window proc, verify whether timer is still valid;
256 there's a slim chance that the application kills the timer
257 between GetMessage and DispatchMessage API calls */
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000258 if (!TIMER_IsTimerValid(hwnd, (UINT) msg->wParam, (HWINDOWPROC) msg->lParam))
Alexandre Julliardd253c582001-08-07 19:19:08 +0000259 return 0; /* invalid winproc */
260
261 return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
262 msg->message, msg->wParam, GetTickCount() );
263 }
264 }
265
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000266 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
Alexandre Julliardd253c582001-08-07 19:19:08 +0000267 if (!wndPtr->winproc)
268 {
269 WIN_ReleaseWndPtr( wndPtr );
270 return 0;
271 }
272 winproc = (WNDPROC16)wndPtr->winproc;
273 painting = (msg->message == WM_PAINT);
274 if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
275 WIN_ReleaseWndPtr( wndPtr );
276
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000277 SPY_EnterMessage( SPY_DISPATCHMESSAGE16, hwnd, msg->message, msg->wParam, msg->lParam );
Alexandre Julliardd253c582001-08-07 19:19:08 +0000278 retval = CallWindowProc16( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam );
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000279 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg->message, retval, msg->wParam, msg->lParam );
Alexandre Julliardd253c582001-08-07 19:19:08 +0000280
281 if (!painting) return retval;
282
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000283 if ((wndPtr = WIN_FindWndPtr( hwnd )))
Alexandre Julliardd253c582001-08-07 19:19:08 +0000284 {
285 if ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
286 {
287 ERR( "BeginPaint not called on WM_PAINT for hwnd %04x!\n", msg->hwnd );
288 wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000289 WIN_ReleaseWndPtr( wndPtr );
Alexandre Julliardd253c582001-08-07 19:19:08 +0000290 /* Validate the update region to avoid infinite WM_PAINT loop */
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000291 RedrawWindow( hwnd, NULL, 0,
Alexandre Julliardd253c582001-08-07 19:19:08 +0000292 RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT );
293 }
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000294 else WIN_ReleaseWndPtr( wndPtr );
Alexandre Julliardd253c582001-08-07 19:19:08 +0000295 }
296 return retval;
297}
298
299
300/***********************************************************************
301 * DispatchMessage32 (USER.822)
302 */
303LONG WINAPI DispatchMessage32_16( const MSG32_16 *msg16, BOOL16 wHaveParamHigh )
304{
305 if (wHaveParamHigh == FALSE)
306 return DispatchMessage16( &msg16->msg );
307 else
308 {
309 MSG msg;
310
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000311 msg.hwnd = WIN_Handle32( msg16->msg.hwnd );
Alexandre Julliardd253c582001-08-07 19:19:08 +0000312 msg.message = msg16->msg.message;
313 msg.wParam = MAKEWPARAM( msg16->msg.wParam, msg16->wParamHigh );
314 msg.lParam = msg16->msg.lParam;
315 msg.time = msg16->msg.time;
316 msg.pt.x = msg16->msg.pt.x;
317 msg.pt.y = msg16->msg.pt.y;
318 return DispatchMessageA( &msg );
319 }
320}
321
322
323/***********************************************************************
324 * MsgWaitForMultipleObjects (USER.640)
325 */
326DWORD WINAPI MsgWaitForMultipleObjects16( DWORD count, CONST HANDLE *handles,
327 BOOL wait_all, DWORD timeout, DWORD mask )
328{
329 return MsgWaitForMultipleObjectsEx( count, handles, timeout, mask,
330 wait_all ? MWMO_WAITALL : 0 );
331}
332
333
334/**********************************************************************
335 * SetDoubleClickTime (USER.20)
336 */
337void WINAPI SetDoubleClickTime16( UINT16 interval )
338{
339 SetDoubleClickTime( interval );
340}
341
342
343/**********************************************************************
344 * GetDoubleClickTime (USER.21)
345 */
346UINT16 WINAPI GetDoubleClickTime16(void)
347{
348 return GetDoubleClickTime();
349}
350
351
352/***********************************************************************
353 * PostQuitMessage (USER.6)
354 */
355void WINAPI PostQuitMessage16( INT16 exitCode )
356{
357 PostQuitMessage( exitCode );
358}
359
360
361/***********************************************************************
362 * SetMessageQueue (USER.266)
363 */
364BOOL16 WINAPI SetMessageQueue16( INT16 size )
365{
366 return SetMessageQueue( size );
367}
368
369
370/***********************************************************************
371 * GetQueueStatus (USER.334)
372 */
373DWORD WINAPI GetQueueStatus16( UINT16 flags )
374{
375 return GetQueueStatus( flags );
376}
377
378
379/***********************************************************************
380 * GetInputState (USER.335)
381 */
382BOOL16 WINAPI GetInputState16(void)
383{
384 return GetInputState();
385}
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000386
387
388/**********************************************************************
389 * TranslateAccelerator (USER.178)
390 */
391INT16 WINAPI TranslateAccelerator16( HWND16 hwnd, HACCEL16 hAccel, LPMSG16 msg )
392{
393 MSG msg32;
394
395 if (!msg) return 0;
396 msg32.message = msg->message;
397 /* msg32.hwnd not used */
398 msg32.wParam = msg->wParam;
399 msg32.lParam = msg->lParam;
400 return TranslateAccelerator( WIN_Handle32(hwnd), hAccel, &msg32 );
401}
402
403
404/**********************************************************************
405 * TranslateMDISysAccel (USER.451)
406 */
407BOOL16 WINAPI TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg )
408{
409 if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
410 {
411 MSG msg32;
412 msg32.hwnd = WIN_Handle32(msg->hwnd);
413 msg32.message = msg->message;
414 msg32.wParam = msg->wParam;
415 msg32.lParam = msg->lParam;
416 /* MDICLIENTINFO is still the same for win32 and win16 ... */
417 return TranslateMDISysAccel( WIN_Handle32(hwndClient), &msg32 );
418 }
419 return 0;
420}