9 #define MSQ_SENTNOWAIT 0x80000000
11 typedef struct _USER_MESSAGE
16 } USER_MESSAGE
, *PUSER_MESSAGE
;
18 struct _USER_MESSAGE_QUEUE
;
20 typedef struct _USER_SENT_MESSAGE
24 PKEVENT CompletionEvent
;
26 struct _USER_MESSAGE_QUEUE
* SenderQueue
;
27 SENDASYNCPROC CompletionCallback
;
28 ULONG_PTR CompletionCallbackContext
;
29 /* entry in the dispatching list of the sender's message queue */
30 LIST_ENTRY DispatchingListEntry
;
33 } USER_SENT_MESSAGE
, *PUSER_SENT_MESSAGE
;
35 typedef struct _USER_SENT_MESSAGE_NOTIFY
37 SENDASYNCPROC CompletionCallback
;
38 ULONG_PTR CompletionCallbackContext
;
43 } USER_SENT_MESSAGE_NOTIFY
, *PUSER_SENT_MESSAGE_NOTIFY
;
45 typedef struct _TIMER_ENTRY
{
47 LARGE_INTEGER ExpiryTime
;
53 } TIMER_ENTRY
, *PTIMER_ENTRY
;
55 typedef struct _USER_MESSAGE_QUEUE
57 /* Reference counter, only access this variable with interlocked functions! */
60 /* Owner of the message queue */
61 struct _ETHREAD
*Thread
;
62 /* Queue of messages sent to the queue. */
63 LIST_ENTRY SentMessagesListHead
;
64 /* Queue of messages posted to the queue. */
65 LIST_ENTRY PostedMessagesListHead
;
66 /* Queue of sent-message notifies for the queue. */
67 LIST_ENTRY NotifyMessagesListHead
;
68 /* Queue for hardware messages for the queue. */
69 LIST_ENTRY HardwareMessagesListHead
;
70 /* List of timers, sorted on expiry time (earliest first) */
71 LIST_ENTRY TimerListHead
;
72 /* Lock for the hardware message list. */
74 /* Pointer to the current WM_MOUSEMOVE message */
75 PUSER_MESSAGE MouseMoveMsg
;
76 /* True if a WM_QUIT message is pending. */
78 /* The quit exit code. */
80 /* Set if there are new messages specified by WakeMask in any of the queues. */
82 /* Handle for the above event (in the context of the process owning the queue). */
83 HANDLE NewMessagesHandle
;
84 /* Last time PeekMessage() was called. */
86 /* Current window with focus (ie. receives keyboard input) for this queue. */
88 /* Count of paints pending. */
90 /* Current active window for this queue. */
92 /* Current capture window for this queue. */
94 /* Current move/size window for this queue */
96 /* Current menu owner window for this queue */
98 /* Identifes the menu state */
100 /* Caret information for this queue */
101 PTHRDCARETINFO CaretInfo
;
106 /* queue state tracking */
111 /* extra message information */
114 /* messages that are currently dispatched by other threads */
115 LIST_ENTRY DispatchingMessagesHead
;
116 /* messages that are currently dispatched by this message queue, required for cleanup */
117 LIST_ENTRY LocalDispatchingMessagesHead
;
119 /* Desktop that the message queue is attached to */
120 struct _DESKTOP
*Desktop
;
121 } USER_MESSAGE_QUEUE
, *PUSER_MESSAGE_QUEUE
;
124 MsqIsHung(PUSER_MESSAGE_QUEUE MessageQueue
);
126 co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue
,
127 HWND Wnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
,
128 UINT uTimeout
, BOOL Block
, INT HookMessage
,
130 PUSER_MESSAGE FASTCALL
131 MsqCreateMessage(LPMSG Msg
, BOOLEAN FreeLParam
);
133 MsqDestroyMessage(PUSER_MESSAGE Message
);
135 MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue
,
136 MSG
* Msg
, BOOLEAN FreeLParam
, DWORD MessageBits
);
138 MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue
, ULONG ExitCode
);
140 co_MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue
,
143 IN PWINDOW_OBJECT Window
,
144 IN UINT MsgFilterLow
,
145 IN UINT MsgFilterHigh
,
146 OUT PUSER_MESSAGE
* Message
);
148 MsqInitializeMessageQueue(struct _ETHREAD
*Thread
, PUSER_MESSAGE_QUEUE MessageQueue
);
150 MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue
);
151 PUSER_MESSAGE_QUEUE FASTCALL
152 MsqCreateMessageQueue(struct _ETHREAD
*Thread
);
154 MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue
);
155 PUSER_MESSAGE_QUEUE FASTCALL
156 MsqGetHardwareMessageQueue(VOID
);
158 MsqInitializeImpl(VOID
);
160 co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue
);
162 co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue
, PWINDOW_OBJECT WndFilter
,
163 UINT MsgFilterMin
, UINT MsgFilterMax
);
165 MsqSendNotifyMessage(PUSER_MESSAGE_QUEUE MessageQueue
,
166 PUSER_SENT_MESSAGE_NOTIFY NotifyMessage
);
168 MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue
);
170 MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue
);
172 co_IntSendMessage(HWND hWnd
,
177 co_IntPostOrSendMessage(HWND hWnd
,
182 co_IntSendMessageTimeout(HWND hWnd
,
190 LRESULT FASTCALL
co_IntSendMessageNoWait(HWND hWnd
,
195 co_IntSendMessageWithCallBack(HWND hWnd
,
199 SENDASYNCPROC CompletionCallback
,
200 ULONG_PTR CompletionCallbackContext
,
204 IntDispatchMessage(MSG
* Msg
);
206 IntTranslateKbdMessage(LPMSG lpMsg
, UINT flags
);
209 co_MsqPostKeyboardMessage(UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
211 MsqPostHotKeyMessage(PVOID Thread
, HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
213 MsqInsertSystemMessage(MSG
* Msg
);
215 MsqIsClkLck(LPMSG Msg
, BOOL Remove
);
217 MsqIsDblClk(LPMSG Msg
, BOOL Remove
);
219 MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue
, ULONG Type
, HWND hWnd
);
221 __inline BOOL
MsqIsSignaled( PUSER_MESSAGE_QUEUE queue
);
222 __inline VOID
MsqSetQueueBits( PUSER_MESSAGE_QUEUE queue
, WORD bits
);
223 __inline VOID
MsqClearQueueBits( PUSER_MESSAGE_QUEUE queue
, WORD bits
);
224 BOOL APIENTRY
IntInitMessagePumpHook();
225 BOOL APIENTRY
IntUninitMessagePumpHook();
226 #define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF))
228 PHOOKTABLE FASTCALL
MsqGetHooks(PUSER_MESSAGE_QUEUE Queue
);
229 VOID FASTCALL
MsqSetHooks(PUSER_MESSAGE_QUEUE Queue
, PHOOKTABLE Hooks
);
231 LPARAM FASTCALL
MsqSetMessageExtraInfo(LPARAM lParam
);
232 LPARAM FASTCALL
MsqGetMessageExtraInfo(VOID
);
233 VOID APIENTRY
MsqRemoveWindowMessagesFromQueue(PVOID pWindow
); /* F*(&$ headers, will be gone in the rewrite! */
235 #define IntLockHardwareMessageQueue(MsgQueue) \
236 KeWaitForMutexObject(&(MsgQueue)->HardwareLock, UserRequest, KernelMode, FALSE, NULL)
238 #define IntUnLockHardwareMessageQueue(MsgQueue) \
239 KeReleaseMutex(&(MsgQueue)->HardwareLock, FALSE)
241 #define IntReferenceMessageQueue(MsgQueue) \
242 InterlockedIncrement(&(MsgQueue)->References)
244 #define IntDereferenceMessageQueue(MsgQueue) \
246 if(InterlockedDecrement(&(MsgQueue)->References) == 0) \
248 DPRINT("Free message queue 0x%x\n", (MsgQueue)); \
249 if ((MsgQueue)->NewMessages != NULL) \
250 ObDereferenceObject((MsgQueue)->NewMessages); \
251 if ((MsgQueue)->NewMessagesHandle != NULL) \
252 ZwClose((MsgQueue)->NewMessagesHandle); \
253 ExFreePool((MsgQueue)); \
257 #define IS_BTN_MESSAGE(message,code) \
258 ((message) == WM_LBUTTON##code || \
259 (message) == WM_MBUTTON##code || \
260 (message) == WM_RBUTTON##code || \
261 (message) == WM_XBUTTON##code || \
262 (message) == WM_NCLBUTTON##code || \
263 (message) == WM_NCMBUTTON##code || \
264 (message) == WM_NCRBUTTON##code || \
265 (message) == WM_NCXBUTTON##code )
267 #define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
268 #define WM_NCMOUSELAST (WM_NCMOUSEFIRST+(WM_MOUSELAST-WM_MOUSEFIRST))
270 #define IS_MOUSE_MESSAGE(message) \
271 ((message >= WM_NCMOUSEFIRST && message <= WM_NCMOUSELAST) || \
272 (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST))
274 #define IS_KBD_MESSAGE(message) \
275 (message == WM_KEYDOWN || message == WM_KEYUP)
278 IntMsqSetWakeMask(DWORD WakeMask
);
281 IntMsqClearWakeMask(VOID
);
284 MsqSetTimer(PUSER_MESSAGE_QUEUE MessageQueue
, HWND Wnd
,
285 UINT_PTR IDEvent
, UINT Period
, TIMERPROC TimerFunc
,
288 MsqKillTimer(PUSER_MESSAGE_QUEUE MessageQueue
, HWND Wnd
,
289 UINT_PTR IDEvent
, UINT Msg
);
291 MsqGetTimerMessage(PUSER_MESSAGE_QUEUE MessageQueue
,
292 PWINDOW_OBJECT WindowFilter
, UINT MsgFilterMin
, UINT MsgFilterMax
,
293 MSG
*Msg
, BOOLEAN Restart
);
295 MsqGetFirstTimerExpiry(PUSER_MESSAGE_QUEUE MessageQueue
,
296 PWINDOW_OBJECT WndFilter
, UINT MsgFilterMin
, UINT MsgFilterMax
,
297 PLARGE_INTEGER FirstTimerExpiry
);
299 MsqRemoveTimersWindow(PUSER_MESSAGE_QUEUE MessageQueue
, HWND Wnd
);
302 MsqCalculateMessageTime(IN PLARGE_INTEGER TickCount
)
304 return (LONG
)(TickCount
->QuadPart
* (KeQueryTimeIncrement() / 10000));