3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
6 * FILE: subsys/win32k/ntuser/message.c
7 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
9 * 06-06-2001 CSH Created
12 /* INCLUDES ******************************************************************/
14 #include <ddk/ntddk.h>
15 #include <win32k/win32k.h>
16 #include <include/guicheck.h>
17 #include <include/msgqueue.h>
18 #include <include/window.h>
19 #include <include/class.h>
20 #include <include/error.h>
21 #include <include/object.h>
22 #include <include/winsta.h>
23 #include <include/callback.h>
24 #include <include/painting.h>
29 /* FUNCTIONS *****************************************************************/
32 W32kInitMessageImpl(VOID)
34 return(STATUS_SUCCESS);
38 W32kCleanupMessageImpl(VOID)
40 return(STATUS_SUCCESS);
45 NtUserDispatchMessage(CONST MSG* lpMsg)
49 PWINDOW_OBJECT WindowObject;
52 /* Process timer messages. */
53 if (lpMsg->message == WM_TIMER)
57 /* FIXME: Call hooks. */
59 /* FIXME: Check for continuing validity of timer. */
61 return(W32kCallWindowProc((WNDPROC)lpMsg->lParam,
65 0 /* GetTickCount() */));
69 /* Get the window object. */
71 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
74 (PVOID*)&WindowObject);
75 if (!NT_SUCCESS(Status))
80 /* FIXME: Check for paint message. */
81 PaintingFlag = (lpMsg->message == WM_PAINT);
84 WindowObject->Flags |= WINDOWOBJECT_NEED_BEGINPAINT;
87 /* FIXME: Call hook procedures. */
89 /* Call the window procedure. */
90 Result = W32kCallWindowProc(NULL /* WndProc */,
96 if (PaintingFlag && WindowObject->Flags & WINDOWOBJECT_NEED_BEGINPAINT &&
97 WindowObject->UpdateRegion)
106 NtUserGetMessage(LPMSG lpMsg,
111 * FUNCTION: Get a message from the calling thread's message queue.
113 * lpMsg - Pointer to the structure which receives the returned message.
114 * hWnd - Window whose messages are to be retrieved.
115 * wMsgFilterMin - Integer value of the lowest message value to be
117 * wMsgFilterMax - Integer value of the highest message value to be
121 PUSER_MESSAGE_QUEUE ThreadQueue;
123 PUSER_MESSAGE Message;
126 /* Initialize the thread's win32 state if necessary. */
129 ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
133 /* Dispatch sent messages here. */
134 while (MsqDispatchOneSentMessage(ThreadQueue));
136 /* Now look for a quit message. */
137 /* FIXME: WINE checks the message number filter here. */
138 if (ThreadQueue->QuitPosted)
141 lpMsg->message = WM_QUIT;
142 lpMsg->wParam = ThreadQueue->QuitExitCode;
144 ThreadQueue->QuitPosted = FALSE;
148 /* Now check for normal messages. */
149 Present = MsqFindMessage(ThreadQueue,
158 RtlCopyMemory(lpMsg, &Message->Msg, sizeof(MSG));
163 /* Check for hardware events. */
164 Present = MsqFindMessage(ThreadQueue,
173 RtlCopyMemory(lpMsg, &Message->Msg, sizeof(MSG));
178 /* Check for sent messages again. */
179 while (MsqDispatchOneSentMessage(ThreadQueue));
181 /* Check for paint messages. */
182 if (ThreadQueue->PaintPosted)
184 PWINDOW_OBJECT WindowObject;
186 lpMsg->hwnd = PaintingFindWinToRepaint(hWnd, PsGetWin32Thread());
187 lpMsg->message = WM_PAINT;
188 lpMsg->wParam = lpMsg->lParam = 0;
190 WindowObject = W32kGetWindowObject(lpMsg->hwnd);
191 if (WindowObject != NULL)
193 if (WindowObject->Style & WS_MINIMIZE &&
194 (HICON)NtUserGetClassLong(lpMsg->hwnd, GCL_HICON) != NULL)
196 lpMsg->message = WM_PAINTICON;
200 if (lpMsg->hwnd == NULL || lpMsg->hwnd == hWnd ||
201 W32kIsChildWindow(hWnd, lpMsg->hwnd))
203 if (WindowObject->Flags & WINDOWOBJECT_NEED_INTERNALPAINT &&
204 WindowObject->UpdateRegion == NULL)
206 WindowObject->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT;
207 MsqDecPaintCountQueue(WindowObject->MessageQueue);
210 W32kReleaseWindowObject(WindowObject);
216 /* Nothing found so far. Wait for new messages. */
217 Status = MsqWaitForNewMessages(ThreadQueue);
219 while (Status >= STATUS_WAIT_0 && Status <= STATUS_WAIT_63);
220 return((BOOLEAN)(-1));
240 NtUserPeekMessage(LPMSG lpMsg,
246 * FUNCTION: Get a message from the calling thread's message queue.
248 * lpMsg - Pointer to the structure which receives the returned message.
249 * hWnd - Window whose messages are to be retrieved.
250 * wMsgFilterMin - Integer value of the lowest message value to be
252 * wMsgFilterMax - Integer value of the highest message value to be
254 * wRemoveMsg - Specificies whether or not to remove messages from the queue after processing
257 PUSER_MESSAGE_QUEUE ThreadQueue;
259 PUSER_MESSAGE Message;
260 BOOLEAN RemoveMessages;
262 /* Initialize the thread's win32 state if necessary. */
265 ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
267 /* Inspect wRemoveMsg flags */
268 /* FIXME: The only flag we process is PM_REMOVE - processing of others must still be implemented */
269 RemoveMessages = wRemoveMsg & PM_REMOVE;
271 /* FIXME: Dispatch sent messages here. */
273 /* Now look for a quit message. */
274 /* FIXME: WINE checks the message number filter here. */
275 if (ThreadQueue->QuitPosted)
278 lpMsg->message = WM_QUIT;
279 lpMsg->wParam = ThreadQueue->QuitExitCode;
281 ThreadQueue->QuitPosted = FALSE;
285 /* Now check for normal messages. */
286 Present = MsqFindMessage(ThreadQueue,
295 RtlCopyMemory(lpMsg, &Message->Msg, sizeof(MSG));
300 /* Check for hardware events. */
301 Present = MsqFindMessage(ThreadQueue,
310 RtlCopyMemory(lpMsg, &Message->Msg, sizeof(MSG));
315 /* FIXME: Check for sent messages again. */
317 /* FIXME: Check for paint messages. */
319 return((BOOLEAN)(-1));
323 NtUserPostMessage(HWND hWnd,
328 PUSER_MESSAGE_QUEUE ThreadQueue;
332 ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
334 ThreadQueue->QuitPosted = TRUE;
335 ThreadQueue->QuitExitCode = wParam;
348 NtUserPostThreadMessage(DWORD idThread,
359 NtUserQuerySendMessage(DWORD Unknown0)
367 W32kSendMessage(HWND hWnd,
375 PWINDOW_OBJECT Window;
377 /* FIXME: Check for a broadcast or topmost destination. */
379 /* FIXME: Call hooks. */
382 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
386 if (!NT_SUCCESS(Status))
391 /* FIXME: Check for an exiting window. */
393 if (Window->MessageQueue == PsGetWin32Thread()->MessageQueue)
397 Result = W32kCallTrampolineWindowProc(NULL, hWnd, Msg, wParam,
403 Result = W32kCallWindowProc(NULL, hWnd, Msg, wParam, lParam);
409 PUSER_SENT_MESSAGE Message;
410 PKEVENT CompletionEvent;
412 CompletionEvent = ExAllocatePool(NonPagedPool, sizeof(KEVENT));
413 KeInitializeEvent(CompletionEvent, NotificationEvent, FALSE);
415 Message = ExAllocatePool(NonPagedPool, sizeof(USER_SENT_MESSAGE));
416 Message->Msg.hwnd = hWnd;
417 Message->Msg.message = Msg;
418 Message->Msg.wParam = wParam;
419 Message->Msg.lParam = lParam;
420 Message->CompletionEvent = CompletionEvent;
421 Message->Result = &Result;
422 Message->CompletionQueue = NULL;
423 Message->CompletionCallback = NULL;
424 MsqSendMessage(Window->MessageQueue, Message);
426 ObmDereferenceObject(Window);
427 Status = KeWaitForSingleObject(CompletionEvent,
432 if (Status == STATUS_WAIT_0)
444 NtUserSendMessage(HWND hWnd,
449 return(W32kSendMessage(hWnd, Msg, wParam, lParam, FALSE));
453 NtUserSendMessageCallback(HWND hWnd,
457 SENDASYNCPROC lpCallBack,
464 NtUserSendNotifyMessage(HWND hWnd,
475 NtUserWaitMessage(VOID)