Use V_* macros.
[wine/wine64.git] / dlls / user / msg16.c
blob60f5df2b7762caf52715b01942682a99b5b7c5de
1 /*
2 * 16-bit messaging support
4 * Copyright 2001 Alexandre Julliard
5 */
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"
17 DEFAULT_DEBUG_CHANNEL(msg);
20 /***********************************************************************
21 * SendMessage (USER.111)
23 LRESULT WINAPI SendMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
25 LRESULT result;
27 if (hwnd != HWND_BROADCAST &&
28 GetWindowThreadProcessId( hwnd, NULL ) == GetCurrentThreadId())
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;
38 if ((cwp = SEGPTR_NEW(CWPSTRUCT16)))
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 );
53 if (!(winproc = (WNDPROC16)GetWindowLong16( hwnd, GWL_WNDPROC ))) return 0;
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 );
59 else /* map to 32-bit unicode for inter-thread/process message */
61 UINT msg32;
62 WPARAM wparam32;
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 ) );
69 return result;
73 /***********************************************************************
74 * PostMessage (USER.110)
76 BOOL16 WINAPI PostMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
78 WPARAM wparam32;
79 UINT msg32;
81 switch (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ))
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;
94 /***********************************************************************
95 * PostAppMessage (USER.116)
96 * PostAppMessage16 (USER32.@)
98 BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
100 WPARAM wparam32;
101 UINT msg32;
102 TDB *pTask = TASK_GetPtr( hTask );
103 if (!pTask) return FALSE;
105 switch (WINPROC_MapMsg16To32W( 0, msg, wparam, &msg32, &wparam32, &lparam ))
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;
118 /***********************************************************************
119 * InSendMessage (USER.192)
121 BOOL16 WINAPI InSendMessage16(void)
123 return InSendMessage();
127 /***********************************************************************
128 * ReplyMessage (USER.115)
130 void WINAPI ReplyMessage16( LRESULT result )
132 ReplyMessage( result );
136 /***********************************************************************
137 * PeekMessage32 (USER.819)
139 BOOL16 WINAPI PeekMessage32_16( MSG32_16 *msg16, HWND16 hwnd,
140 UINT16 first, UINT16 last, UINT16 flags,
141 BOOL16 wHaveParamHigh )
143 MSG msg;
145 if (!PeekMessageW( &msg, hwnd, first, last, flags )) return FALSE;
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);
154 return (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
155 &msg16->msg.message, &msg16->msg.wParam,
156 &msg16->msg.lParam ) != -1);
160 /***********************************************************************
161 * PeekMessage (USER.109)
163 BOOL16 WINAPI PeekMessage16( MSG16 *msg, HWND16 hwnd,
164 UINT16 first, UINT16 last, UINT16 flags )
166 return PeekMessage32_16( (MSG32_16 *)msg, hwnd, first, last, flags, FALSE );
170 /***********************************************************************
171 * GetMessage32 (USER.820)
173 BOOL16 WINAPI GetMessage32_16( MSG32_16 *msg16, HWND16 hwnd, UINT16 first,
174 UINT16 last, BOOL16 wHaveParamHigh )
176 MSG msg;
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);
188 while (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
189 &msg16->msg.message, &msg16->msg.wParam,
190 &msg16->msg.lParam ) == -1);
192 TRACE( "message %04x, hwnd %04x, filter(%04x - %04x)\n",
193 msg16->msg.message, hwnd, first, last );
195 return msg16->msg.message != WM_QUIT;
199 /***********************************************************************
200 * GetMessage (USER.108)
202 BOOL16 WINAPI GetMessage16( MSG16 *msg, HWND16 hwnd, UINT16 first, UINT16 last )
204 return GetMessage32_16( (MSG32_16 *)msg, hwnd, first, last, FALSE );
208 /***********************************************************************
209 * TranslateMessage32 (USER.821)
211 BOOL16 WINAPI TranslateMessage32_16( const MSG32_16 *msg, BOOL16 wHaveParamHigh )
213 MSG msg32;
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 );
223 /***********************************************************************
224 * TranslateMessage (USER.113)
226 BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
228 return TranslateMessage32_16( (MSG32_16 *)msg, FALSE );
232 /***********************************************************************
233 * DispatchMessage (USER.114)
235 LONG WINAPI DispatchMessage16( const MSG16* msg )
237 WND * wndPtr;
238 WNDPROC16 winproc;
239 LONG retval;
240 int painting;
242 /* Process timer messages */
243 if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
245 if (msg->lParam)
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 */
253 return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
254 msg->message, msg->wParam, GetTickCount() );
258 if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
259 if (!wndPtr->winproc)
261 WIN_ReleaseWndPtr( wndPtr );
262 return 0;
264 winproc = (WNDPROC16)wndPtr->winproc;
265 painting = (msg->message == WM_PAINT);
266 if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
267 WIN_ReleaseWndPtr( wndPtr );
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 );
273 if (!painting) return retval;
275 if ((wndPtr = WIN_FindWndPtr( msg->hwnd )))
277 if ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
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 );
285 WIN_ReleaseWndPtr( wndPtr );
287 return retval;
291 /***********************************************************************
292 * DispatchMessage32 (USER.822)
294 LONG WINAPI DispatchMessage32_16( const MSG32_16 *msg16, BOOL16 wHaveParamHigh )
296 if (wHaveParamHigh == FALSE)
297 return DispatchMessage16( &msg16->msg );
298 else
300 MSG msg;
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 );
314 /***********************************************************************
315 * MsgWaitForMultipleObjects (USER.640)
317 DWORD WINAPI MsgWaitForMultipleObjects16( DWORD count, CONST HANDLE *handles,
318 BOOL wait_all, DWORD timeout, DWORD mask )
320 return MsgWaitForMultipleObjectsEx( count, handles, timeout, mask,
321 wait_all ? MWMO_WAITALL : 0 );
325 /**********************************************************************
326 * SetDoubleClickTime (USER.20)
328 void WINAPI SetDoubleClickTime16( UINT16 interval )
330 SetDoubleClickTime( interval );
334 /**********************************************************************
335 * GetDoubleClickTime (USER.21)
337 UINT16 WINAPI GetDoubleClickTime16(void)
339 return GetDoubleClickTime();
343 /***********************************************************************
344 * PostQuitMessage (USER.6)
346 void WINAPI PostQuitMessage16( INT16 exitCode )
348 PostQuitMessage( exitCode );
352 /***********************************************************************
353 * SetMessageQueue (USER.266)
355 BOOL16 WINAPI SetMessageQueue16( INT16 size )
357 return SetMessageQueue( size );
361 /***********************************************************************
362 * GetQueueStatus (USER.334)
364 DWORD WINAPI GetQueueStatus16( UINT16 flags )
366 return GetQueueStatus( flags );
370 /***********************************************************************
371 * GetInputState (USER.335)
373 BOOL16 WINAPI GetInputState16(void)
375 return GetInputState();