1 /* $Id: message.c,v 1.9 2002/08/26 23:20:54 dwelch Exp $
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(LPMSG 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
);
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
,
334 NtUserPostThreadMessage(DWORD idThread
,
345 NtUserQuerySendMessage(DWORD Unknown0
)
353 W32kSendMessage(HWND hWnd
,
361 PWINDOW_OBJECT Window
;
363 /* FIXME: Check for a broadcast or topmost destination. */
365 /* FIXME: Call hooks. */
368 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation
->HandleTable
,
372 if (!NT_SUCCESS(Status
))
377 /* FIXME: Check for an exiting window. */
379 if (Window
->MessageQueue
== PsGetWin32Thread()->MessageQueue
)
383 Result
= W32kCallTrampolineWindowProc(NULL
, hWnd
, Msg
, wParam
,
389 Result
= W32kCallWindowProc(NULL
, hWnd
, Msg
, wParam
, lParam
);
395 PUSER_SENT_MESSAGE Message
;
396 PKEVENT CompletionEvent
;
398 CompletionEvent
= ExAllocatePool(NonPagedPool
, sizeof(KEVENT
));
399 KeInitializeEvent(CompletionEvent
, NotificationEvent
, FALSE
);
401 Message
= ExAllocatePool(NonPagedPool
, sizeof(USER_SENT_MESSAGE
));
402 Message
->Msg
.hwnd
= hWnd
;
403 Message
->Msg
.message
= Msg
;
404 Message
->Msg
.wParam
= wParam
;
405 Message
->Msg
.lParam
= lParam
;
406 Message
->CompletionEvent
= CompletionEvent
;
407 Message
->Result
= &Result
;
408 Message
->CompletionQueue
= NULL
;
409 Message
->CompletionCallback
= NULL
;
410 MsqSendMessage(Window
->MessageQueue
, Message
);
412 ObmDereferenceObject(Window
);
413 Status
= KeWaitForSingleObject(CompletionEvent
,
418 if (Status
== STATUS_WAIT_0
)
430 NtUserSendMessage(HWND hWnd
,
435 return(W32kSendMessage(hWnd
, Msg
, wParam
, lParam
, FALSE
));
439 NtUserSendMessageCallback(HWND hWnd
,
443 SENDASYNCPROC lpCallBack
,
450 NtUserSendNotifyMessage(HWND hWnd
,
461 NtUserWaitMessage(VOID
)