9 #define MSQ_SENTNOWAIT 0x80000000
11 typedef struct _USER_MESSAGE
15 } USER_MESSAGE
, *PUSER_MESSAGE
;
17 struct _USER_MESSAGE_QUEUE
;
19 typedef struct _USER_SENT_MESSAGE
23 PKEVENT CompletionEvent
;
25 struct _USER_MESSAGE_QUEUE
* SenderQueue
;
26 SENDASYNCPROC CompletionCallback
;
27 ULONG_PTR CompletionCallbackContext
;
28 /* entry in the dispatching list of the sender's message queue */
29 LIST_ENTRY DispatchingListEntry
;
32 } USER_SENT_MESSAGE
, *PUSER_SENT_MESSAGE
;
34 typedef struct _USER_SENT_MESSAGE_NOTIFY
36 SENDASYNCPROC CompletionCallback
;
37 ULONG_PTR CompletionCallbackContext
;
42 } USER_SENT_MESSAGE_NOTIFY
, *PUSER_SENT_MESSAGE_NOTIFY
;
44 typedef struct _USER_MESSAGE_QUEUE
46 /* Reference counter, only access this variable with interlocked functions! */
49 /* Owner of the message queue */
50 struct _ETHREAD
*Thread
;
51 /* Queue of messages sent to the queue. */
52 LIST_ENTRY SentMessagesListHead
;
53 /* Queue of messages posted to the queue. */
54 LIST_ENTRY PostedMessagesListHead
;
55 /* Queue of sent-message notifies for the queue. */
56 LIST_ENTRY NotifyMessagesListHead
;
57 /* Queue for hardware messages for the queue. */
58 LIST_ENTRY HardwareMessagesListHead
;
59 /* Lock for the hardware message list. */
61 /* Pointer to the current WM_MOUSEMOVE message */
62 PUSER_MESSAGE MouseMoveMsg
;
63 /* True if a WM_QUIT message is pending. */
65 /* The quit exit code. */
67 /* Set if there are new messages specified by WakeMask in any of the queues. */
69 /* Handle for the above event (in the context of the process owning the queue). */
70 HANDLE NewMessagesHandle
;
71 /* Last time PeekMessage() was called. */
73 /* Current window with focus (ie. receives keyboard input) for this queue. */
75 /* Count of paints pending. */
77 /* Current active window for this queue. */
79 /* Current capture window for this queue. */
81 /* Current move/size window for this queue */
83 /* Current menu owner window for this queue */
85 /* Identifes the menu state */
87 /* Caret information for this queue */
88 PTHRDCARETINFO CaretInfo
;
90 /* queue state tracking */
95 /* extra message information */
98 /* messages that are currently dispatched by other threads */
99 LIST_ENTRY DispatchingMessagesHead
;
100 /* messages that are currently dispatched by this message queue, required for cleanup */
101 LIST_ENTRY LocalDispatchingMessagesHead
;
103 /* Desktop that the message queue is attached to */
104 struct _DESKTOP
*Desktop
;
105 } USER_MESSAGE_QUEUE
, *PUSER_MESSAGE_QUEUE
;
108 MsqIsHung(PUSER_MESSAGE_QUEUE MessageQueue
);
110 co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue
,
111 HWND Wnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
,
112 UINT uTimeout
, BOOL Block
, INT HookMessage
,
114 PUSER_MESSAGE FASTCALL
115 MsqCreateMessage(LPMSG Msg
);
117 MsqDestroyMessage(PUSER_MESSAGE Message
);
119 MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue
,
120 MSG
* Msg
, BOOLEAN HardwareMessage
, DWORD MessageBits
);
122 MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue
, ULONG ExitCode
);
124 co_MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue
,
128 IN UINT MsgFilterLow
,
129 IN UINT MsgFilterHigh
,
130 OUT PUSER_MESSAGE
* Message
);
132 MsqInitializeMessageQueue(struct _ETHREAD
*Thread
, PUSER_MESSAGE_QUEUE MessageQueue
);
134 MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue
);
135 PUSER_MESSAGE_QUEUE FASTCALL
136 MsqCreateMessageQueue(struct _ETHREAD
*Thread
);
138 MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue
);
139 PUSER_MESSAGE_QUEUE FASTCALL
140 MsqGetHardwareMessageQueue(VOID
);
142 MsqInitializeImpl(VOID
);
144 co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue
);
146 co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue
, PWND WndFilter
,
147 UINT MsgFilterMin
, UINT MsgFilterMax
);
149 MsqSendNotifyMessage(PUSER_MESSAGE_QUEUE MessageQueue
,
150 PUSER_SENT_MESSAGE_NOTIFY NotifyMessage
);
152 MsqIncPaintCountQueue(PUSER_MESSAGE_QUEUE Queue
);
154 MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue
);
156 co_IntSendMessage(HWND hWnd
,
161 co_IntPostOrSendMessage(HWND hWnd
,
166 co_IntSendMessageTimeout(HWND hWnd
,
174 LRESULT FASTCALL
co_IntSendMessageNoWait(HWND hWnd
,
179 co_IntSendMessageWithCallBack(HWND hWnd
,
183 SENDASYNCPROC CompletionCallback
,
184 ULONG_PTR CompletionCallbackContext
,
188 IntDispatchMessage(MSG
* Msg
);
190 IntTranslateKbdMessage(LPMSG lpMsg
, UINT flags
);
193 co_MsqPostKeyboardMessage(UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
195 MsqPostHotKeyMessage(PVOID Thread
, HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
197 MsqInsertSystemMessage(MSG
* Msg
);
199 MsqIsClkLck(LPMSG Msg
, BOOL Remove
);
201 MsqIsDblClk(LPMSG Msg
, BOOL Remove
);
203 MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue
, ULONG Type
, HWND hWnd
);
205 __inline BOOL
MsqIsSignaled( PUSER_MESSAGE_QUEUE queue
);
206 __inline VOID
MsqSetQueueBits( PUSER_MESSAGE_QUEUE queue
, WORD bits
);
207 __inline VOID
MsqClearQueueBits( PUSER_MESSAGE_QUEUE queue
, WORD bits
);
208 BOOL APIENTRY
IntInitMessagePumpHook();
209 BOOL APIENTRY
IntUninitMessagePumpHook();
210 #define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF))
212 LPARAM FASTCALL
MsqSetMessageExtraInfo(LPARAM lParam
);
213 LPARAM FASTCALL
MsqGetMessageExtraInfo(VOID
);
214 VOID APIENTRY
MsqRemoveWindowMessagesFromQueue(PVOID pWindow
); /* F*(&$ headers, will be gone in the rewrite! */
216 #define IntLockHardwareMessageQueue(MsgQueue) \
217 KeWaitForMutexObject(&(MsgQueue)->HardwareLock, UserRequest, KernelMode, FALSE, NULL)
219 #define IntUnLockHardwareMessageQueue(MsgQueue) \
220 KeReleaseMutex(&(MsgQueue)->HardwareLock, FALSE)
222 #define IntReferenceMessageQueue(MsgQueue) \
223 InterlockedIncrement(&(MsgQueue)->References)
225 #define IntDereferenceMessageQueue(MsgQueue) \
227 if(InterlockedDecrement(&(MsgQueue)->References) == 0) \
229 DPRINT("Free message queue 0x%x\n", (MsgQueue)); \
230 if ((MsgQueue)->NewMessages != NULL) \
231 ObDereferenceObject((MsgQueue)->NewMessages); \
232 if ((MsgQueue)->NewMessagesHandle != NULL) \
233 ZwClose((MsgQueue)->NewMessagesHandle); \
234 ExFreePool((MsgQueue)); \
238 #define IS_BTN_MESSAGE(message,code) \
239 ((message) == WM_LBUTTON##code || \
240 (message) == WM_MBUTTON##code || \
241 (message) == WM_RBUTTON##code || \
242 (message) == WM_XBUTTON##code || \
243 (message) == WM_NCLBUTTON##code || \
244 (message) == WM_NCMBUTTON##code || \
245 (message) == WM_NCRBUTTON##code || \
246 (message) == WM_NCXBUTTON##code )
248 #define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
249 #define WM_NCMOUSELAST (WM_NCMOUSEFIRST+(WM_MOUSELAST-WM_MOUSEFIRST))
251 #define IS_MOUSE_MESSAGE(message) \
252 ((message >= WM_NCMOUSEFIRST && message <= WM_NCMOUSELAST) || \
253 (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST))
255 #define IS_KBD_MESSAGE(message) \
256 (message == WM_KEYDOWN || message == WM_KEYUP)
259 IntMsqSetWakeMask(DWORD WakeMask
);
262 IntMsqClearWakeMask(VOID
);
265 MsqCalculateMessageTime(IN PLARGE_INTEGER TickCount
)
267 return (LONG
)(TickCount
->QuadPart
* (KeQueryTimeIncrement() / 10000));