Use MapLS/UnMapLS instead of SEGPTR_* macros.
[wine/wine-kai.git] / dlls / user / msg16.c
blobc0873a8602b4b028539b601ea34e0057622887f4
1 /*
2 * 16-bit messaging support
4 * Copyright 2001 Alexandre Julliard
5 */
7 #include "wine/winuser16.h"
8 #include "winerror.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"
17 DEFAULT_DEBUG_CHANNEL(msg);
20 /***********************************************************************
21 * SendMessage (USER.111)
23 LRESULT WINAPI SendMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
25 LRESULT result;
26 HWND hwnd = WIN_Handle32( hwnd16 );
28 if (hwnd != HWND_BROADCAST && WIN_IsCurrentThread(hwnd))
30 /* call 16-bit window proc directly */
31 WNDPROC16 winproc;
33 /* first the WH_CALLWNDPROC hook */
34 if (HOOK_IsHooked( WH_CALLWNDPROC ))
36 CWPSTRUCT16 cwp;
37 SEGPTR seg_cwp;
39 cwp.hwnd = hwnd16;
40 cwp.message = msg;
41 cwp.wParam = wparam;
42 cwp.lParam = lparam;
43 seg_cwp = MapLS( &cwp );
44 HOOK_CallHooks16( WH_CALLWNDPROC, HC_ACTION, 1, seg_cwp );
45 UnMapLS( seg_cwp );
46 if (cwp.hwnd != hwnd16)
48 hwnd16 = cwp.hwnd;
49 hwnd = WIN_Handle32( hwnd16 );
51 msg = cwp.message;
52 wparam = cwp.wParam;
53 lparam = cwp.lParam;
56 if (!(winproc = (WNDPROC16)GetWindowLong16( hwnd16, GWL_WNDPROC ))) return 0;
58 SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wparam, lparam );
59 result = CallWindowProc16( (WNDPROC16)winproc, hwnd16, msg, wparam, lparam );
60 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, result, wparam, lparam );
62 else /* map to 32-bit unicode for inter-thread/process message */
64 UINT msg32;
65 WPARAM wparam32;
67 if (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ) == -1)
68 return 0;
69 result = WINPROC_UnmapMsg16To32W( hwnd, msg32, wparam32, lparam,
70 SendMessageW( hwnd, msg32, wparam32, lparam ) );
72 return result;
76 /***********************************************************************
77 * PostMessage (USER.110)
79 BOOL16 WINAPI PostMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
81 WPARAM wparam32;
82 UINT msg32;
83 HWND hwnd = WIN_Handle32( hwnd16 );
85 switch (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ))
87 case 0:
88 return PostMessageW( hwnd, msg32, wparam32, lparam );
89 case 1:
90 ERR( "16-bit message %x contains pointer, cannot post\n", msg );
91 return FALSE;
92 default:
93 return FALSE;
98 /***********************************************************************
99 * PostAppMessage (USER.116)
100 * PostAppMessage16 (USER32.@)
102 BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
104 WPARAM wparam32;
105 UINT msg32;
106 TDB *pTask = TASK_GetPtr( hTask );
107 if (!pTask) return FALSE;
109 switch (WINPROC_MapMsg16To32W( 0, msg, wparam, &msg32, &wparam32, &lparam ))
111 case 0:
112 return PostThreadMessageW( (DWORD)pTask->teb->tid, msg32, wparam32, lparam );
113 case 1:
114 ERR( "16-bit message %x contains pointer, cannot post\n", msg );
115 return FALSE;
116 default:
117 return FALSE;
122 /***********************************************************************
123 * InSendMessage (USER.192)
125 BOOL16 WINAPI InSendMessage16(void)
127 return InSendMessage();
131 /***********************************************************************
132 * ReplyMessage (USER.115)
134 void WINAPI ReplyMessage16( LRESULT result )
136 ReplyMessage( result );
140 /***********************************************************************
141 * PeekMessage32 (USER.819)
143 BOOL16 WINAPI PeekMessage32_16( MSG32_16 *msg16, HWND16 hwnd16,
144 UINT16 first, UINT16 last, UINT16 flags,
145 BOOL16 wHaveParamHigh )
147 MSG msg;
148 HWND hwnd = WIN_Handle32( hwnd16 );
150 if (!PeekMessageW( &msg, hwnd, first, last, flags )) return FALSE;
152 msg16->msg.hwnd = WIN_Handle16( msg.hwnd );
153 msg16->msg.lParam = msg.lParam;
154 msg16->msg.time = msg.time;
155 msg16->msg.pt.x = (INT16)msg.pt.x;
156 msg16->msg.pt.y = (INT16)msg.pt.y;
157 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
159 return (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
160 &msg16->msg.message, &msg16->msg.wParam,
161 &msg16->msg.lParam ) != -1);
165 /***********************************************************************
166 * PeekMessage (USER.109)
168 BOOL16 WINAPI PeekMessage16( MSG16 *msg, HWND16 hwnd,
169 UINT16 first, UINT16 last, UINT16 flags )
171 return PeekMessage32_16( (MSG32_16 *)msg, hwnd, first, last, flags, FALSE );
175 /***********************************************************************
176 * GetMessage32 (USER.820)
178 BOOL16 WINAPI GetMessage32_16( MSG32_16 *msg16, HWND16 hwnd16, UINT16 first,
179 UINT16 last, BOOL16 wHaveParamHigh )
181 MSG msg;
182 HWND hwnd = WIN_Handle32( hwnd16 );
186 GetMessageW( &msg, hwnd, first, last );
187 msg16->msg.hwnd = WIN_Handle16( msg.hwnd );
188 msg16->msg.lParam = msg.lParam;
189 msg16->msg.time = msg.time;
190 msg16->msg.pt.x = (INT16)msg.pt.x;
191 msg16->msg.pt.y = (INT16)msg.pt.y;
192 if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
194 while (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
195 &msg16->msg.message, &msg16->msg.wParam,
196 &msg16->msg.lParam ) == -1);
198 TRACE( "message %04x, hwnd %04x, filter(%04x - %04x)\n",
199 msg16->msg.message, hwnd, first, last );
201 return msg16->msg.message != WM_QUIT;
205 /***********************************************************************
206 * GetMessage (USER.108)
208 BOOL16 WINAPI GetMessage16( MSG16 *msg, HWND16 hwnd, UINT16 first, UINT16 last )
210 return GetMessage32_16( (MSG32_16 *)msg, hwnd, first, last, FALSE );
214 /***********************************************************************
215 * TranslateMessage32 (USER.821)
217 BOOL16 WINAPI TranslateMessage32_16( const MSG32_16 *msg, BOOL16 wHaveParamHigh )
219 MSG msg32;
221 msg32.hwnd = WIN_Handle32( msg->msg.hwnd );
222 msg32.message = msg->msg.message;
223 msg32.wParam = MAKEWPARAM( msg->msg.wParam, wHaveParamHigh ? msg->wParamHigh : 0 );
224 msg32.lParam = msg->msg.lParam;
225 return TranslateMessage( &msg32 );
229 /***********************************************************************
230 * TranslateMessage (USER.113)
232 BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
234 return TranslateMessage32_16( (MSG32_16 *)msg, FALSE );
238 /***********************************************************************
239 * DispatchMessage (USER.114)
241 LONG WINAPI DispatchMessage16( const MSG16* msg )
243 WND * wndPtr;
244 WNDPROC16 winproc;
245 LONG retval;
246 int painting;
247 HWND hwnd = WIN_Handle32( msg->hwnd );
249 /* Process timer messages */
250 if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
252 if (msg->lParam)
254 /* before calling window proc, verify whether timer is still valid;
255 there's a slim chance that the application kills the timer
256 between GetMessage and DispatchMessage API calls */
257 if (!TIMER_IsTimerValid(hwnd, (UINT) msg->wParam, (HWINDOWPROC) msg->lParam))
258 return 0; /* invalid winproc */
260 return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
261 msg->message, msg->wParam, GetTickCount() );
265 if (!(wndPtr = WIN_GetPtr( msg->hwnd )))
267 if (msg->hwnd) SetLastError( ERROR_INVALID_WINDOW_HANDLE );
268 return 0;
270 if (wndPtr == WND_OTHER_PROCESS)
272 if (IsWindow( msg->hwnd ))
273 ERR( "cannot dispatch msg to other process window %x\n", msg->hwnd );
274 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
275 return 0;
278 if (!(winproc = (WNDPROC16)wndPtr->winproc))
280 WIN_ReleasePtr( wndPtr );
281 return 0;
283 painting = (msg->message == WM_PAINT);
284 if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
285 WIN_ReleasePtr( wndPtr );
287 SPY_EnterMessage( SPY_DISPATCHMESSAGE16, hwnd, msg->message, msg->wParam, msg->lParam );
288 retval = CallWindowProc16( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam );
289 SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg->message, retval, msg->wParam, msg->lParam );
291 if (painting && (wndPtr = WIN_GetPtr( hwnd )) && (wndPtr != WND_OTHER_PROCESS))
293 BOOL validate = ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate);
294 wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
295 WIN_ReleasePtr( wndPtr );
296 if (validate)
298 ERR( "BeginPaint not called on WM_PAINT for hwnd %04x!\n", msg->hwnd );
299 /* Validate the update region to avoid infinite WM_PAINT loop */
300 RedrawWindow( hwnd, NULL, 0,
301 RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT );
304 return retval;
308 /***********************************************************************
309 * DispatchMessage32 (USER.822)
311 LONG WINAPI DispatchMessage32_16( const MSG32_16 *msg16, BOOL16 wHaveParamHigh )
313 if (wHaveParamHigh == FALSE)
314 return DispatchMessage16( &msg16->msg );
315 else
317 MSG msg;
319 msg.hwnd = WIN_Handle32( msg16->msg.hwnd );
320 msg.message = msg16->msg.message;
321 msg.wParam = MAKEWPARAM( msg16->msg.wParam, msg16->wParamHigh );
322 msg.lParam = msg16->msg.lParam;
323 msg.time = msg16->msg.time;
324 msg.pt.x = msg16->msg.pt.x;
325 msg.pt.y = msg16->msg.pt.y;
326 return DispatchMessageA( &msg );
331 /***********************************************************************
332 * MsgWaitForMultipleObjects (USER.640)
334 DWORD WINAPI MsgWaitForMultipleObjects16( DWORD count, CONST HANDLE *handles,
335 BOOL wait_all, DWORD timeout, DWORD mask )
337 return MsgWaitForMultipleObjectsEx( count, handles, timeout, mask,
338 wait_all ? MWMO_WAITALL : 0 );
342 /**********************************************************************
343 * SetDoubleClickTime (USER.20)
345 void WINAPI SetDoubleClickTime16( UINT16 interval )
347 SetDoubleClickTime( interval );
351 /**********************************************************************
352 * GetDoubleClickTime (USER.21)
354 UINT16 WINAPI GetDoubleClickTime16(void)
356 return GetDoubleClickTime();
360 /***********************************************************************
361 * PostQuitMessage (USER.6)
363 void WINAPI PostQuitMessage16( INT16 exitCode )
365 PostQuitMessage( exitCode );
369 /***********************************************************************
370 * SetMessageQueue (USER.266)
372 BOOL16 WINAPI SetMessageQueue16( INT16 size )
374 return SetMessageQueue( size );
378 /***********************************************************************
379 * GetQueueStatus (USER.334)
381 DWORD WINAPI GetQueueStatus16( UINT16 flags )
383 return GetQueueStatus( flags );
387 /***********************************************************************
388 * GetInputState (USER.335)
390 BOOL16 WINAPI GetInputState16(void)
392 return GetInputState();
396 /**********************************************************************
397 * TranslateAccelerator (USER.178)
399 INT16 WINAPI TranslateAccelerator16( HWND16 hwnd, HACCEL16 hAccel, LPMSG16 msg )
401 MSG msg32;
403 if (!msg) return 0;
404 msg32.message = msg->message;
405 /* msg32.hwnd not used */
406 msg32.wParam = msg->wParam;
407 msg32.lParam = msg->lParam;
408 return TranslateAccelerator( WIN_Handle32(hwnd), hAccel, &msg32 );
412 /**********************************************************************
413 * TranslateMDISysAccel (USER.451)
415 BOOL16 WINAPI TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg )
417 if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
419 MSG msg32;
420 msg32.hwnd = WIN_Handle32(msg->hwnd);
421 msg32.message = msg->message;
422 msg32.wParam = msg->wParam;
423 msg32.lParam = msg->lParam;
424 /* MDICLIENTINFO is still the same for win32 and win16 ... */
425 return TranslateMDISysAccel( WIN_Handle32(hwndClient), &msg32 );
427 return 0;