2 * 16-bit messaging support
4 * Copyright 2001 Alexandre Julliard
7 #include "wine/winuser16.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
)
26 HWND hwnd
= WIN_Handle32( hwnd16
);
28 if (hwnd
!= HWND_BROADCAST
&& WIN_IsCurrentThread(hwnd
))
30 /* call 16-bit window proc directly */
33 /* first the WH_CALLWNDPROC hook */
34 if (HOOK_IsHooked( WH_CALLWNDPROC
))
43 seg_cwp
= MapLS( &cwp
);
44 HOOK_CallHooks16( WH_CALLWNDPROC
, HC_ACTION
, 1, seg_cwp
);
46 if (cwp
.hwnd
!= hwnd16
)
49 hwnd
= WIN_Handle32( hwnd16
);
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 */
67 if (WINPROC_MapMsg16To32W( hwnd
, msg
, wparam
, &msg32
, &wparam32
, &lparam
) == -1)
69 result
= WINPROC_UnmapMsg16To32W( hwnd
, msg32
, wparam32
, lparam
,
70 SendMessageW( hwnd
, msg32
, wparam32
, lparam
) );
76 /***********************************************************************
77 * PostMessage (USER.110)
79 BOOL16 WINAPI
PostMessage16( HWND16 hwnd16
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
83 HWND hwnd
= WIN_Handle32( hwnd16
);
85 switch (WINPROC_MapMsg16To32W( hwnd
, msg
, wparam
, &msg32
, &wparam32
, &lparam
))
88 return PostMessageW( hwnd
, msg32
, wparam32
, lparam
);
90 ERR( "16-bit message %x contains pointer, cannot post\n", msg
);
98 /***********************************************************************
99 * PostAppMessage (USER.116)
100 * PostAppMessage16 (USER32.@)
102 BOOL16 WINAPI
PostAppMessage16( HTASK16 hTask
, UINT16 msg
, WPARAM16 wparam
, LPARAM lparam
)
106 TDB
*pTask
= TASK_GetPtr( hTask
);
107 if (!pTask
) return FALSE
;
109 switch (WINPROC_MapMsg16To32W( 0, msg
, wparam
, &msg32
, &wparam32
, &lparam
))
112 return PostThreadMessageW( (DWORD
)pTask
->teb
->tid
, msg32
, wparam32
, lparam
);
114 ERR( "16-bit message %x contains pointer, cannot post\n", msg
);
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
)
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
)
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
)
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
)
247 HWND hwnd
= WIN_Handle32( msg
->hwnd
);
249 /* Process timer messages */
250 if ((msg
->message
== WM_TIMER
) || (msg
->message
== WM_SYSTIMER
))
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
);
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
);
278 if (!(winproc
= (WNDPROC16
)wndPtr
->winproc
))
280 WIN_ReleasePtr( wndPtr
);
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
);
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
);
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
);
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
)
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
)
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
);