Author: weiden
Date: Wed Nov 21 11:32:45 2007
New Revision: 30611
URL:
http://svn.reactos.org/svn/reactos?rev=30611&view=rev
Log:
Implement WM_QUERYUISTATE, WM_CHANGEUISTATE and WM_UPDATEUISTATE
Modified:
trunk/reactos/dll/win32/user32/include/user32.h
trunk/reactos/dll/win32/user32/misc/misc.c
trunk/reactos/dll/win32/user32/windows/defwnd.c
trunk/reactos/include/reactos/win32k/ntuser.h
trunk/reactos/subsystems/win32/win32k/include/window.h
trunk/reactos/subsystems/win32/win32k/ntuser/misc.c
trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c
trunk/reactos/subsystems/win32/win32k/ntuser/window.c
Modified: trunk/reactos/dll/win32/user32/include/user32.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/include/u…
==============================================================================
--- trunk/reactos/dll/win32/user32/include/user32.h (original)
+++ trunk/reactos/dll/win32/user32/include/user32.h Wed Nov 21 11:32:45 2007
@@ -91,6 +91,19 @@
return ti->Hooks != 0;
}
+static __inline PDESKTOP
+GetThreadDesktopInfo(VOID)
+{
+ PW32THREADINFO ti;
+ PDESKTOP di = NULL;
+
+ ti = GetW32ThreadInfo();
+ if (ti != NULL)
+ di = DesktopPtrToUser(ti->Desktop);
+
+ return di;
+}
+
PCALLPROC FASTCALL ValidateCallProc(HANDLE hCallProc);
PWINDOW FASTCALL ValidateHwnd(HWND hwnd);
PWINDOW FASTCALL ValidateHwndOrDesk(HWND hwnd);
Modified: trunk/reactos/dll/win32/user32/misc/misc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/misc/misc…
==============================================================================
--- trunk/reactos/dll/win32/user32/misc/misc.c (original)
+++ trunk/reactos/dll/win32/user32/misc/misc.c Wed Nov 21 11:32:45 2007
@@ -146,19 +146,6 @@
}
return pi;
-}
-
-static PDESKTOP
-GetThreadDesktopInfo(VOID)
-{
- PW32THREADINFO ti;
- PDESKTOP di = NULL;
-
- ti = GetW32ThreadInfo();
- if (ti != NULL)
- di = DesktopPtrToUser(ti->Desktop);
-
- return di;
}
Modified: trunk/reactos/dll/win32/user32/windows/defwnd.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/d…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/defwnd.c (original)
+++ trunk/reactos/dll/win32/user32/windows/defwnd.c Wed Nov 21 11:32:45 2007
@@ -988,6 +988,18 @@
SendMessageW(hwnd, WM_PRINTCLIENT, (WPARAM)hdc, PRF_CLIENT);
}
+static BOOL CALLBACK
+UserSendUiUpdateMsg(HWND hwnd, LPARAM lParam)
+{
+ WPARAM wParam;
+
+ /* Unpack WPARAM */
+ wParam = MAKEWPARAM((lParam >> 3) & 0x3,
+ lParam & (UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE));
+ SendMessageW(hwnd, WM_UPDATEUISTATE, wParam, 0);
+ return TRUE;
+}
+
VOID FASTCALL
DefWndScreenshot(HWND hWnd)
@@ -1590,6 +1602,168 @@
if (wParam) PostQuitMessage(0);
return 0;
+ case WM_QUERYUISTATE:
+ {
+ LRESULT Ret = 0;
+ PWINDOW Wnd = ValidateHwnd(hWnd);
+ if (Wnd != NULL)
+ {
+ if (Wnd->HideFocus)
+ Ret |= UISF_HIDEFOCUS;
+ if (Wnd->HideAccel)
+ Ret |= UISF_HIDEACCEL;
+ }
+ return Ret;
+ }
+
+ case WM_CHANGEUISTATE:
+ {
+ WORD Action = LOWORD(wParam);
+ WORD Flags = HIWORD(wParam);
+ PWINDOW Wnd = ValidateHwnd(hWnd);
+ if (!Wnd || lParam != 0)
+ break;
+
+ if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
+ break;
+
+ if (Flags & UISF_ACTIVE)
+ {
+ WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
+ }
+
+ if (Action == UIS_INITIALIZE)
+ {
+ PDESKTOP Desk = GetThreadDesktopInfo();
+ if (Desk == NULL)
+ break;
+
+ Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
+ Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
+
+ /* We need to update wParam in case we need to send out messages */
+ wParam = MAKEWPARAM(Action, Flags);
+ }
+
+ switch (Action)
+ {
+ case UIS_SET:
+ /* See if we actually need to change something */
+ if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
+ break;
+ if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
+ break;
+
+ /* Don't need to do anything... */
+ return 0;
+
+ case UIS_CLEAR:
+ /* See if we actually need to change something */
+ if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
+ break;
+ if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
+ break;
+
+ /* Don't need to do anything... */
+ return 0;
+
+ default:
+ WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n",
Action);
+ break;
+ }
+
+ if ((Wnd->Style & WS_CHILD) && Wnd->Parent != NULL)
+ {
+ /* We're a child window and we need to pass this message down until
+ we reach the root */
+ hWnd = UserHMGetHandle(Wnd->Parent);
+ }
+ else
+ {
+ /* We're a top level window, we need to change the UI state */
+ Msg = WM_UPDATEUISTATE;
+ }
+
+ if (bUnicode)
+ return SendMessageW(hWnd, Msg, wParam, lParam);
+ else
+ return SendMessageA(hWnd, Msg, wParam, lParam);
+ }
+
+ case WM_UPDATEUISTATE:
+ {
+ BOOL Change = TRUE;
+ WORD Action = LOWORD(wParam);
+ WORD Flags = HIWORD(wParam);
+ PWINDOW Wnd = ValidateHwnd(hWnd);
+ if (!Wnd || lParam != 0)
+ break;
+
+ if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
+ break;
+
+ if (Flags & UISF_ACTIVE)
+ {
+ WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
+ }
+
+ if (Action == UIS_INITIALIZE)
+ {
+ PDESKTOP Desk = GetThreadDesktopInfo();
+ if (Desk == NULL)
+ break;
+
+ Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
+ Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
+
+ /* We need to update wParam for broadcasting the update */
+ wParam = MAKEWPARAM(Action, Flags);
+ }
+
+ switch (Action)
+ {
+ case UIS_SET:
+ /* See if we actually need to change something */
+ if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
+ break;
+ if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
+ break;
+
+ /* Don't need to do anything... */
+ Change = FALSE;
+ break;
+
+ case UIS_CLEAR:
+ /* See if we actually need to change something */
+ if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
+ break;
+ if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
+ break;
+
+ /* Don't need to do anything... */
+ Change = FALSE;
+ break;
+
+ default:
+ WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n",
Action);
+ return 0;
+ }
+
+ /* Pack the information and call win32k */
+ if (Change)
+ {
+ if (!NtUserCallTwoParam((DWORD)hWnd, (DWORD)Flags | ((DWORD)Action
<< 3), TWOPARAM_ROUTINE_ROS_UPDATEUISTATE))
+ break;
+ }
+
+ /* Always broadcast the update to all children */
+ EnumChildWindows(hWnd,
+ UserSendUiUpdateMsg,
+ (LPARAM)Flags | ((LPARAM)Action << 3));
+
+ break;
+ }
+
}
return 0;
}
Modified: trunk/reactos/include/reactos/win32k/ntuser.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntu…
==============================================================================
--- trunk/reactos/include/reactos/win32k/ntuser.h (original)
+++ trunk/reactos/include/reactos/win32k/ntuser.h Wed Nov 21 11:32:45 2007
@@ -35,6 +35,15 @@
HWND hTaskManWindow;
HWND hProgmanWindow;
struct _WINDOW *Wnd;
+
+ union
+ {
+ UINT Dummy;
+ struct
+ {
+ UINT LastInputWasKbd : 1;
+ };
+ };
WCHAR szDesktopName[1];
} DESKTOP, *PDESKTOP;
@@ -154,6 +163,8 @@
/* Indicates whether the window is derived from a system class */
UINT IsSystem : 1;
UINT InternalPosInitialized : 1;
+ UINT HideFocus : 1;
+ UINT HideAccel : 1;
} WINDOW, *PWINDOW;
typedef struct _W32PROCESSINFO
@@ -669,6 +680,7 @@
#define TWOPARAM_ROUTINE_ROS_ISACTIVEICON 0x1001
#define TWOPARAM_ROUTINE_ROS_NCDESTROY 0x1002
#define TWOPARAM_ROUTINE_ROS_REGSYSCLASSES 0x1003
+#define TWOPARAM_ROUTINE_ROS_UPDATEUISTATE 0x1004
DWORD
NTAPI
NtUserCallTwoParam(
Modified: trunk/reactos/subsystems/win32/win32k/include/window.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/window.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/window.h Wed Nov 21 11:32:45 2007
@@ -12,6 +12,8 @@
#include <include/dce.h>
#include <include/prop.h>
#include <include/scroll.h>
+
+BOOL FASTCALL UserUpdateUiState(PWINDOW Wnd, WPARAM wParam);
typedef struct _WINDOW_OBJECT
{
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/misc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/misc.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/misc.c Wed Nov 21 11:32:45 2007
@@ -593,6 +593,19 @@
DPRINT1("ROS_SHOWWINDOW ---> 0x%x\n",Window->Flags);
RETURN( 0 );
}
+
+ case TWOPARAM_ROUTINE_ROS_UPDATEUISTATE:
+ {
+ WPARAM wParam;
+ Window = UserGetWindowObject((HWND)Param1);
+ if (!Window) RETURN(0);
+
+ /* Unpack wParam */
+ wParam = MAKEWPARAM((Param2 >> 3) & 0x3,
+ Param2 & (UISF_HIDEFOCUS | UISF_HIDEACCEL |
UISF_ACTIVE));
+
+ RETURN( UserUpdateUiState(Window->Wnd, wParam) );
+ }
case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW:
UNIMPLEMENTED
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c Wed Nov 21 11:32:45 2007
@@ -478,6 +478,7 @@
NTSTATUS WaitStatus;
DECLARE_RETURN(BOOL);
USER_REFERENCE_ENTRY Ref;
+ PDESKTOP Desk = NULL;
WaitObjects[1] = MessageQueue->NewMessages;
WaitObjects[0] = &HardwareMessageQueueLock;
@@ -499,7 +500,11 @@
DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
- if (DesktopWindow) UserRefObjectCo(DesktopWindow, &Ref);//can DesktopWindow be
NULL?
+ if (DesktopWindow)
+ {
+ UserRefObjectCo(DesktopWindow, &Ref);//can DesktopWindow be NULL?
+ Desk = DesktopWindow->ti->Desktop;
+ }
/* Process messages in the message queue itself. */
IntLockHardwareMessageQueue(MessageQueue);
@@ -512,7 +517,6 @@
if (Current->Msg.message >= WM_MOUSEFIRST &&
Current->Msg.message <= WM_MOUSELAST)
{
-
Accept = co_MsqTranslateMouseMessage(MessageQueue, hWnd, FilterLow, FilterHigh,
@@ -527,6 +531,9 @@
IntUnLockHardwareMessageQueue(MessageQueue);
IntUnLockSystemHardwareMessageQueueLock(FALSE);
*Message = Current;
+
+ if (Desk)
+ Desk->LastInputWasKbd = FALSE;
RETURN(TRUE);
}
@@ -723,6 +730,9 @@
{
Msg.hwnd = FocusMessageQueue->FocusWindow;
DPRINT("Msg.hwnd = %x\n", Msg.hwnd);
+
+ FocusMessageQueue->Desktop->DesktopInfo->LastInputWasKbd = TRUE;
+
IntGetCursorLocation(FocusMessageQueue->Desktop->WindowStation,
&Msg.pt);
MsqPostMessage(FocusMessageQueue, &Msg, FALSE, QS_KEY);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/window.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c Wed Nov 21 11:32:45 2007
@@ -66,6 +66,40 @@
/* HELPER FUNCTIONS ***********************************************************/
+BOOL FASTCALL UserUpdateUiState(PWINDOW Wnd, WPARAM wParam)
+{
+ WORD Action = LOWORD(wParam);
+ WORD Flags = HIWORD(wParam);
+
+ if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ switch (Action)
+ {
+ case UIS_INITIALIZE:
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
+
+ case UIS_SET:
+ if (Flags & UISF_HIDEFOCUS)
+ Wnd->HideFocus = TRUE;
+ if (Flags & UISF_HIDEACCEL)
+ Wnd->HideAccel = TRUE;
+ break;
+
+ case UIS_CLEAR:
+ if (Flags & UISF_HIDEFOCUS)
+ Wnd->HideFocus = FALSE;
+ if (Flags & UISF_HIDEACCEL)
+ Wnd->HideAccel = FALSE;
+ break;
+ }
+
+ return TRUE;
+}
PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd)
{
@@ -1639,6 +1673,11 @@
IntReferenceMessageQueue(Window->MessageQueue);
Window->Parent = ParentWindow;
Wnd->Parent = ParentWindow ? ParentWindow->Wnd : NULL;
+ if (Wnd->Parent != NULL && hWndParent != 0)
+ {
+ Wnd->HideFocus = Wnd->Parent->HideFocus;
+ Wnd->HideAccel = Wnd->Parent->HideAccel;
+ }
if((OwnerWindow = UserGetWindowObject(OwnerWindowHandle)))
{