1 /* $Id: message.c,v 1.36 2004/03/11 14:47:43 weiden Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: lib/user32/windows/message.c
7 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
9 * 06-06-2001 CSH Created
21 GetMessageExtraInfo(VOID
)
23 return (LPARAM
)NtUserCallNoParam(NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO
);
34 PUSER32_THREAD_DATA ThreadData
= User32GetThreadData();
35 return(MAKELONG(ThreadData
->LastMessage
.pt
.x
, ThreadData
->LastMessage
.pt
.y
));
45 PUSER32_THREAD_DATA ThreadData
= User32GetThreadData();
46 return(ThreadData
->LastMessage
.time
);
57 /* return(NtUserGetThreadState(THREADSTATE_INSENDMESSAGE) != ISMEX_NOSEND); */
71 /* return NtUserGetThreadState(THREADSTATE_INSENDMESSAGE); */
98 return NtUserSetMessageExtraInfo(lParam
);
103 MsgiAnsiToUnicodeMessage(LPMSG UnicodeMsg
, LPMSG AnsiMsg
)
105 *UnicodeMsg
= *AnsiMsg
;
106 switch (AnsiMsg
->message
)
109 case WM_ASKCBFORMATNAME
:
111 LPWSTR Buffer
= HeapAlloc(GetProcessHeap(), 0,
112 AnsiMsg
->wParam
* sizeof(WCHAR
));
117 UnicodeMsg
->lParam
= (LPARAM
)Buffer
;
121 /* AnsiMsg->lParam is string (0-terminated) */
123 case WM_WININICHANGE
:
124 case WM_DEVMODECHANGE
:
130 UNICODE_STRING UnicodeString
;
131 RtlCreateUnicodeStringFromAsciiz(&UnicodeString
, (LPSTR
)AnsiMsg
->lParam
);
132 UnicodeMsg
->lParam
= (LPARAM
)UnicodeString
.Buffer
;
139 UNICODE_STRING UnicodeBuffer
;
142 CREATESTRUCTW cs
; /* new structure */
143 LPCWSTR lpszName
; /* allocated Name */
144 LPCWSTR lpszClass
; /* allocated Class */
146 struct s
*xs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(struct s
));
151 xs
->cs
= *(CREATESTRUCTW
*)AnsiMsg
->lParam
;
152 if (HIWORD(xs
->cs
.lpszName
))
154 RtlCreateUnicodeStringFromAsciiz(&UnicodeBuffer
, (LPSTR
)xs
->cs
.lpszName
);
155 xs
->lpszName
= xs
->cs
.lpszName
= UnicodeBuffer
.Buffer
;
157 if (HIWORD(xs
->cs
.lpszClass
))
159 RtlCreateUnicodeStringFromAsciiz(&UnicodeBuffer
, (LPSTR
)xs
->cs
.lpszClass
);
160 xs
->lpszClass
= xs
->cs
.lpszClass
= UnicodeBuffer
.Buffer
;
162 UnicodeMsg
->lParam
= (LPARAM
)xs
;
168 UNICODE_STRING UnicodeBuffer
;
169 MDICREATESTRUCTW
*cs
=
170 (MDICREATESTRUCTW
*)HeapAlloc(GetProcessHeap(), 0, sizeof(*cs
));
177 *cs
= *(MDICREATESTRUCTW
*)AnsiMsg
->lParam
;
179 if (HIWORD(cs
->szClass
))
181 RtlCreateUnicodeStringFromAsciiz(&UnicodeBuffer
, (LPSTR
)cs
->szClass
);
182 cs
->szClass
= UnicodeBuffer
.Buffer
;
185 RtlCreateUnicodeStringFromAsciiz(&UnicodeBuffer
, (LPSTR
)cs
->szTitle
);
186 cs
->szTitle
= UnicodeBuffer
.Buffer
;
188 UnicodeMsg
->lParam
= (LPARAM
)cs
;
198 MsgiAnsiToUnicodeCleanup(LPMSG UnicodeMsg
, LPMSG AnsiMsg
)
200 switch (AnsiMsg
->message
)
203 case WM_ASKCBFORMATNAME
:
205 HeapFree(GetProcessHeap(), 0, (PVOID
) UnicodeMsg
->lParam
);
210 case WM_WININICHANGE
:
211 case WM_DEVMODECHANGE
:
217 UNICODE_STRING UnicodeString
;
218 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)UnicodeMsg
->lParam
);
219 RtlFreeUnicodeString(&UnicodeString
);
226 UNICODE_STRING UnicodeString
;
229 CREATESTRUCTW cs
; /* new structure */
230 LPWSTR lpszName
; /* allocated Name */
231 LPWSTR lpszClass
; /* allocated Class */
233 struct s
*xs
= (struct s
*)UnicodeMsg
->lParam
;
236 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)xs
->lpszName
);
237 RtlFreeUnicodeString(&UnicodeString
);
241 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)xs
->lpszClass
);
242 RtlFreeUnicodeString(&UnicodeString
);
244 HeapFree(GetProcessHeap(), 0, xs
);
250 UNICODE_STRING UnicodeString
;
251 MDICREATESTRUCTW
*cs
= (MDICREATESTRUCTW
*)UnicodeMsg
->lParam
;
252 if (HIWORD(cs
->szTitle
))
254 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)cs
->szTitle
);
255 RtlFreeUnicodeString(&UnicodeString
);
257 if (HIWORD(cs
->szClass
))
259 RtlInitUnicodeString(&UnicodeString
, (PCWSTR
)cs
->szClass
);
260 RtlFreeUnicodeString(&UnicodeString
);
262 HeapFree(GetProcessHeap(), 0, cs
);
271 MsgiAnsiToUnicodeReply(LPMSG UnicodeMsg
, LPMSG AnsiMsg
, LRESULT
*Result
)
273 switch (AnsiMsg
->message
)
276 case WM_ASKCBFORMATNAME
:
278 LPWSTR Buffer
= (LPWSTR
)UnicodeMsg
->lParam
;
279 LPSTR AnsiBuffer
= (LPSTR
)AnsiMsg
->lParam
;
280 if (UnicodeMsg
->wParam
> 0 &&
281 !WideCharToMultiByte(CP_ACP
, 0, Buffer
, -1,
282 AnsiBuffer
, UnicodeMsg
->wParam
, NULL
, NULL
))
284 AnsiBuffer
[UnicodeMsg
->wParam
- 1] = 0;
289 case WM_GETTEXTLENGTH
:
290 case CB_GETLBTEXTLEN
:
293 /* FIXME: There may be one DBCS char for each Unicode char */
299 MsgiAnsiToUnicodeCleanup(UnicodeMsg
, AnsiMsg
);
306 User32ConvertToAsciiMessage(UINT
* Msg
, WPARAM
* wParam
, LPARAM
* lParam
)
315 UNICODE_STRING UString
;
318 CsW
= (CREATESTRUCTW
*)(*lParam
);
319 CsA
= RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(CREATESTRUCTA
));
320 memcpy(CsA
, CsW
, sizeof(CREATESTRUCTW
));
322 RtlInitUnicodeString(&UString
, CsW
->lpszName
);
323 RtlUnicodeStringToAnsiString(&AString
, &UString
, TRUE
);
324 CsA
->lpszName
= AString
.Buffer
;
325 if (HIWORD((ULONG
)CsW
->lpszClass
) != 0)
327 RtlInitUnicodeString(&UString
, CsW
->lpszClass
);
328 RtlUnicodeStringToAnsiString(&AString
, &UString
, TRUE
);
329 CsA
->lpszClass
= AString
.Buffer
;
331 (*lParam
) = (LPARAM
)CsA
;
336 ANSI_STRING AnsiString
;
337 UNICODE_STRING UnicodeString
;
338 RtlInitUnicodeString(&UnicodeString
, (PWSTR
) *lParam
);
339 if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiString
,
343 *lParam
= (LPARAM
) AnsiString
.Buffer
;
352 User32FreeAsciiConvertedMessage(UINT Msg
, WPARAM wParam
, LPARAM lParam
)
358 ANSI_STRING AnsiString
;
359 UNICODE_STRING UnicodeString
;
362 InString
= (LPSTR
)lParam
;
363 TempString
= RtlAllocateHeap(RtlGetProcessHeap(), 0, strlen(InString
) + 1);
364 strcpy(TempString
, InString
);
365 RtlInitAnsiString(&AnsiString
, TempString
);
366 UnicodeString
.Length
= wParam
* sizeof(WCHAR
);
367 UnicodeString
.MaximumLength
= wParam
* sizeof(WCHAR
);
368 UnicodeString
.Buffer
= (PWSTR
)lParam
;
369 if (! NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicodeString
,
375 UnicodeString
.Buffer
[0] = L
'\0';
378 RtlFreeHeap(RtlGetProcessHeap(), 0, TempString
);
383 ANSI_STRING AnsiString
;
384 RtlInitAnsiString(&AnsiString
, (PSTR
) lParam
);
385 RtlFreeAnsiString(&AnsiString
);
393 Cs
= (CREATESTRUCTA
*)lParam
;
394 RtlFreeHeap(RtlGetProcessHeap(), 0, (LPSTR
)Cs
->lpszName
);
395 if (HIWORD((ULONG
)Cs
->lpszClass
) != 0)
397 RtlFreeHeap(RtlGetProcessHeap(), 0, (LPSTR
)Cs
->lpszClass
);
399 RtlFreeHeap(RtlGetProcessHeap(), 0, Cs
);
406 IntCallWindowProcW(BOOL IsAnsiProc
,
417 User32ConvertToAsciiMessage(&Msg
, &wParam
, &lParam
);
418 Result
= WndProc(hWnd
, Msg
, wParam
, lParam
);
419 User32FreeAsciiConvertedMessage(Msg
, wParam
, lParam
);
424 return WndProc(hWnd
, Msg
, wParam
, lParam
);
428 STATIC LRESULT FASTCALL
429 IntCallWindowProcA(BOOL IsAnsiProc
,
442 return WndProc(hWnd
, Msg
, wParam
, lParam
);
447 AnsiMsg
.message
= Msg
;
448 AnsiMsg
.wParam
= wParam
;
449 AnsiMsg
.lParam
= lParam
;
450 if (! MsgiAnsiToUnicodeMessage(&UnicodeMsg
, &AnsiMsg
))
454 Result
= WndProc(UnicodeMsg
.hwnd
, UnicodeMsg
.message
,
455 UnicodeMsg
.wParam
, UnicodeMsg
.lParam
);
456 if (! MsgiAnsiToUnicodeReply(&UnicodeMsg
, &AnsiMsg
, &Result
))
469 CallWindowProcA(WNDPROC lpPrevWndFunc
,
476 WndProcHandle wphData
;
478 IsHandle
= NtUserDereferenceWndProcHandle(lpPrevWndFunc
,&wphData
);
481 return IntCallWindowProcA(TRUE
, lpPrevWndFunc
, hWnd
, Msg
, wParam
, lParam
);
485 return IntCallWindowProcA(! wphData
.IsUnicode
, wphData
.WindowProc
,
486 hWnd
, Msg
, wParam
, lParam
);
495 CallWindowProcW(WNDPROC lpPrevWndFunc
,
502 WndProcHandle wphData
;
504 IsHandle
= NtUserDereferenceWndProcHandle(lpPrevWndFunc
,&wphData
);
507 return IntCallWindowProcW(FALSE
, lpPrevWndFunc
, hWnd
, Msg
, wParam
, lParam
);
511 return IntCallWindowProcW(! wphData
.IsUnicode
, wphData
.WindowProc
,
512 hWnd
, Msg
, wParam
, lParam
);
521 DispatchMessageA(CONST MSG
*lpmsg
)
523 return(NtUserDispatchMessage(lpmsg
));
531 DispatchMessageW(CONST MSG
*lpmsg
)
533 return(NtUserDispatchMessage((LPMSG
)lpmsg
));
541 GetMessageA(LPMSG lpMsg
,
547 PUSER32_THREAD_DATA ThreadData
= User32GetThreadData();
549 Res
= NtUserGetMessage(lpMsg
, hWnd
, wMsgFilterMin
, wMsgFilterMax
);
550 if (Res
&& lpMsg
->message
!= WM_PAINT
&& lpMsg
->message
!= WM_QUIT
)
552 ThreadData
->LastMessage
= *lpMsg
;
562 GetMessageW(LPMSG lpMsg
,
568 PUSER32_THREAD_DATA ThreadData
= User32GetThreadData();
570 Res
= NtUserGetMessage(lpMsg
, hWnd
, wMsgFilterMin
, wMsgFilterMax
);
571 if (Res
&& lpMsg
->message
!= WM_PAINT
&& lpMsg
->message
!= WM_QUIT
)
573 ThreadData
->LastMessage
= *lpMsg
;
583 PeekMessageA(LPMSG lpMsg
,
590 PUSER32_THREAD_DATA ThreadData
= User32GetThreadData();
592 Res
= NtUserPeekMessage(lpMsg
, hWnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
593 if (Res
&& lpMsg
->message
!= WM_PAINT
&& lpMsg
->message
!= WM_QUIT
)
595 ThreadData
->LastMessage
= *lpMsg
;
614 PUSER32_THREAD_DATA ThreadData
= User32GetThreadData();
616 Res
= NtUserPeekMessage(lpMsg
, hWnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
617 if (Res
&& lpMsg
->message
!= WM_PAINT
&& lpMsg
->message
!= WM_QUIT
)
619 ThreadData
->LastMessage
= *lpMsg
;
636 return NtUserPostMessage(hWnd
, Msg
, wParam
, lParam
);
651 return NtUserPostMessage(hWnd
, Msg
, wParam
, lParam
);
663 (void) NtUserPostMessage(NULL
, WM_QUIT
, nExitCode
, 0);
678 return NtUserPostThreadMessage(idThread
, Msg
, wParam
, lParam
);
693 return NtUserPostThreadMessage(idThread
, Msg
, wParam
, lParam
);
701 SendMessageW(HWND Wnd
,
706 NTUSERSENDMESSAGEINFO Info
;
710 Result
= NtUserSendMessage(Wnd
, Msg
, wParam
, lParam
, &Info
);
711 if (! Info
.HandledByKernel
)
713 /* We need to send the message ourselves */
714 Result
= IntCallWindowProcW(Info
.Ansi
, Info
.Proc
, Wnd
, Msg
, wParam
, lParam
);
725 SendMessageA(HWND Wnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
730 NTUSERSENDMESSAGEINFO Info
;
733 AnsiMsg
.message
= Msg
;
734 AnsiMsg
.wParam
= wParam
;
735 AnsiMsg
.lParam
= lParam
;
736 if (! MsgiAnsiToUnicodeMessage(&UcMsg
, &AnsiMsg
))
742 Result
= NtUserSendMessage(UcMsg
.hwnd
, UcMsg
.message
,
743 UcMsg
.wParam
, UcMsg
.lParam
, &Info
);
744 if (! Info
.HandledByKernel
)
746 /* We need to send the message ourselves */
749 /* Ansi message and Ansi window proc, that's easy. Clean up
750 the Unicode message though */
751 MsgiAnsiToUnicodeCleanup(&UcMsg
, &AnsiMsg
);
752 Result
= IntCallWindowProcA(Info
.Ansi
, Info
.Proc
, Wnd
, Msg
, wParam
, lParam
);
756 /* Unicode winproc. Although we started out with an Ansi message we
757 already converted it to Unicode for the kernel call. Reuse that
758 message to avoid another conversion */
759 Result
= IntCallWindowProcW(Info
.Ansi
, Info
.Proc
, UcMsg
.hwnd
,
760 UcMsg
.message
, UcMsg
.wParam
, UcMsg
.lParam
);
761 if (! MsgiAnsiToUnicodeReply(&UcMsg
, &AnsiMsg
, &Result
))
769 /* Message sent by kernel. Convert back to Ansi */
770 if (! MsgiAnsiToUnicodeReply(&UcMsg
, &AnsiMsg
, &Result
))
785 SendMessageCallbackA(
790 SENDASYNCPROC lpCallBack
,
793 return NtUserSendMessageCallback(
808 SendMessageCallbackW(
813 SENDASYNCPROC lpCallBack
,
816 return NtUserSendMessageCallback(
838 PDWORD_PTR lpdwResult
)
843 NTUSERSENDMESSAGEINFO Info
;
846 AnsiMsg
.message
= Msg
;
847 AnsiMsg
.wParam
= wParam
;
848 AnsiMsg
.lParam
= lParam
;
849 if (! MsgiAnsiToUnicodeMessage(&UcMsg
, &AnsiMsg
))
855 Result
= NtUserSendMessageTimeout(UcMsg
.hwnd
, UcMsg
.message
,
856 UcMsg
.wParam
, UcMsg
.lParam
,
857 fuFlags
, uTimeout
, (ULONG_PTR
*)lpdwResult
, &Info
);
862 if (! Info
.HandledByKernel
)
864 /* We need to send the message ourselves */
867 /* Ansi message and Ansi window proc, that's easy. Clean up
868 the Unicode message though */
869 MsgiAnsiToUnicodeCleanup(&UcMsg
, &AnsiMsg
);
870 Result
= IntCallWindowProcA(Info
.Ansi
, Info
.Proc
, hWnd
, Msg
, wParam
, lParam
);
874 /* Unicode winproc. Although we started out with an Ansi message we
875 already converted it to Unicode for the kernel call. Reuse that
876 message to avoid another conversion */
877 Result
= IntCallWindowProcW(Info
.Ansi
, Info
.Proc
, UcMsg
.hwnd
,
878 UcMsg
.message
, UcMsg
.wParam
, UcMsg
.lParam
);
879 if (! MsgiAnsiToUnicodeReply(&UcMsg
, &AnsiMsg
, &Result
))
885 *lpdwResult
= Result
;
890 /* Message sent by kernel. Convert back to Ansi */
891 if (! MsgiAnsiToUnicodeReply(&UcMsg
, &AnsiMsg
, &Result
))
913 PDWORD_PTR lpdwResult
)
915 NTUSERSENDMESSAGEINFO Info
;
919 Result
= NtUserSendMessageTimeout(hWnd
, Msg
, wParam
, lParam
, fuFlags
, uTimeout
,
921 if (! Info
.HandledByKernel
)
923 /* We need to send the message ourselves */
924 Result
= IntCallWindowProcW(Info
.Ansi
, Info
.Proc
, hWnd
, Msg
, wParam
, lParam
);
926 *lpdwResult
= Result
;
970 TranslateMessage(CONST MSG
*lpMsg
)
972 return(TranslateMessageEx((LPMSG
)lpMsg
, 0));
979 TranslateMessageEx(CONST MSG
*lpMsg
, DWORD unk
)
981 return(NtUserTranslateMessage((LPMSG
)lpMsg
, (HKL
)unk
));
992 return NtUserWaitMessage();
1000 RegisterWindowMessageA(LPCSTR lpString
)
1002 UNICODE_STRING String
;
1006 Result
= RtlCreateUnicodeStringFromAsciiz(&String
, (PCSZ
)lpString
);
1011 Atom
= NtUserRegisterWindowMessage(&String
);
1012 RtlFreeUnicodeString(&String
);
1021 RegisterWindowMessageW(LPCWSTR lpString
)
1023 UNICODE_STRING String
;
1025 RtlInitUnicodeString(&String
, lpString
);
1026 return(NtUserRegisterWindowMessage(&String
));
1033 SetCapture(HWND hWnd
)
1035 return(NtUserSetCapture(hWnd
));
1044 return(NtUserGetCapture());
1051 ReleaseCapture(VOID
)
1053 NtUserSetCapture(NULL
);
1063 RealGetQueueStatus(UINT flags
)
1066 WORD changed_bits
, wake_bits
;
1068 #if 0 /* wine stuff. don't know what it does... */
1070 /* check for pending X events */
1071 if (USER_Driver
.pMsgWaitForMultipleObjectsEx
)
1072 USER_Driver
.pMsgWaitForMultipleObjectsEx( 0, NULL
, 0, 0, 0 );
1075 ret
= NtUserGetQueueStatus(TRUE
/*ClearChanges*/);
1077 changed_bits
= LOWORD(ret
);
1078 wake_bits
= HIWORD(ret
);
1080 return MAKELONG(changed_bits
& flags
, wake_bits
& flags
);
1087 BOOL STDCALL
GetInputState(VOID
)
1092 #if 0 /* wine stuff. don't know what it does... */
1094 /* check for pending X events */
1095 if (USER_Driver
.pMsgWaitForMultipleObjectsEx
)
1096 USER_Driver
.pMsgWaitForMultipleObjectsEx( 0, NULL
, 0, 0, 0 );
1099 ret
= NtUserGetQueueStatus(FALSE
/*ClearChanges*/);
1101 wake_bits
= HIWORD(ret
);
1103 return wake_bits
& (QS_KEY
| QS_MOUSEBUTTON
);
1109 BOOL STDCALL
SetMessageQueue(int cMessagesMax
)
1111 /* Function does nothing on 32 bit windows */
1114 typedef DWORD (WINAPI
* RealGetQueueStatusProc
)(UINT flags
);
1115 typedef DWORD (WINAPI
* RealMsgWaitForMultipleObjectsExProc
)(DWORD nCount
, LPHANDLE lpHandles
, DWORD dwMilliseconds
, DWORD dwWakeMask
, DWORD dwFlags
);
1117 typedef struct _USER_MESSAGE_PUMP_ADDRESSES
{
1119 //NtUserRealInternalGetMessageProc NtUserRealInternalGetMessage;
1120 //NtUserRealWaitMessageExProc NtUserRealWaitMessageEx;
1121 RealGetQueueStatusProc RealGetQueueStatus
;
1122 RealMsgWaitForMultipleObjectsExProc RealMsgWaitForMultipleObjectsEx
;
1123 } USER_MESSAGE_PUMP_ADDRESSES
, * PUSER_MESSAGE_PUMP_ADDRESSES
;
1127 RealMsgWaitForMultipleObjectsEx(
1130 DWORD dwMilliseconds
,
1134 typedef BOOL (WINAPI
* MESSAGEPUMPHOOKPROC
)(BOOL Unregistering
,PUSER_MESSAGE_PUMP_ADDRESSES MessagePumpAddresses
);
1136 RTL_CRITICAL_SECTION gcsMPH
;
1137 MESSAGEPUMPHOOKPROC gpfnInitMPH
;
1138 DWORD gcLoadMPH
= 0;
1139 USER_MESSAGE_PUMP_ADDRESSES gmph
= {sizeof(USER_MESSAGE_PUMP_ADDRESSES
),
1140 //NtUserRealInternalGetMessage,
1141 //NtUserRealInternalWaitMessageEx,
1143 RealMsgWaitForMultipleObjectsEx
1146 DWORD gfMessagePumpHook
= 0;
1148 BOOL WINAPI
IsInsideMessagePumpHook()
1150 if(!gfMessagePumpHook
)
1153 /* Since our TEB doesnt match that of real windows, testing this value is useless until we know what it does
1154 PUCHAR NtTeb = (PUCHAR)NtCurrentTeb();
1156 if(!*(PLONG*)&NtTeb[0x708])
1159 if(**(PLONG*)&NtTeb[0x708] <= 0)
1165 void WINAPI
ResetMessagePumpHook(PUSER_MESSAGE_PUMP_ADDRESSES Addresses
)
1167 Addresses
->cbSize
= sizeof(USER_MESSAGE_PUMP_ADDRESSES
);
1168 //Addresses->NtUserRealInternalGetMessage = (NtUserRealInternalGetMessageProc)NtUserRealInternalGetMessage;
1169 //Addresses->NtUserRealWaitMessageEx = (NtUserRealWaitMessageExProc)NtUserRealInternalWaitMessageEx;
1170 Addresses
->RealGetQueueStatus
= RealGetQueueStatus
;
1171 Addresses
->RealMsgWaitForMultipleObjectsEx
= RealMsgWaitForMultipleObjectsEx
;
1174 BOOL WINAPI
RegisterMessagePumpHook(MESSAGEPUMPHOOKPROC Hook
)
1176 RtlEnterCriticalSection(&gcsMPH
);
1178 SetLastError(ERROR_INVALID_PARAMETER
);
1179 RtlLeaveCriticalSection(&gcsMPH
);
1183 USER_MESSAGE_PUMP_ADDRESSES Addresses
;
1185 ResetMessagePumpHook(&Addresses
);
1186 if(!Hook(FALSE
, &Addresses
) || !Addresses
.cbSize
) {
1187 RtlLeaveCriticalSection(&gcsMPH
);
1190 memcpy(&gmph
, &Addresses
, Addresses
.cbSize
);
1192 if(gpfnInitMPH
!= Hook
) {
1193 RtlLeaveCriticalSection(&gcsMPH
);
1197 if(NtUserCallNoParam(NOPARAM_ROUTINE_INIT_MESSAGE_PUMP
)) {
1198 RtlLeaveCriticalSection(&gcsMPH
);
1202 InterlockedExchange(&gfMessagePumpHook
, 1);
1204 RtlLeaveCriticalSection(&gcsMPH
);
1208 BOOL WINAPI
UnregisterMessagePumpHook(VOID
)
1210 RtlEnterCriticalSection(&gcsMPH
);
1212 if(NtUserCallNoParam(NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP
)) {
1215 InterlockedExchange(&gfMessagePumpHook
, 0);
1216 gpfnInitMPH(TRUE
, NULL
);
1217 ResetMessagePumpHook(&gmph
);
1220 RtlLeaveCriticalSection(&gcsMPH
);
1224 RtlLeaveCriticalSection(&gcsMPH
);
1228 DWORD WINAPI
GetQueueStatus(UINT flags
)
1230 return IsInsideMessagePumpHook() ? gmph
.RealGetQueueStatus(flags
) : RealGetQueueStatus(flags
);
1233 DWORD WINAPI
MsgWaitForMultipleObjectsEx(DWORD nCount
, LPHANDLE lpHandles
, DWORD dwMilliseconds
, DWORD dwWakeMask
, DWORD dwFlags
)
1235 return IsInsideMessagePumpHook() ? gmph
.RealMsgWaitForMultipleObjectsEx(nCount
, lpHandles
,dwMilliseconds
, dwWakeMask
, dwFlags
) : RealMsgWaitForMultipleObjectsEx(nCount
, lpHandles
,dwMilliseconds
, dwWakeMask
, dwFlags
);