[ros-diffs] [weiden] 30611: Implement WM_QUERYUISTATE, WM_CHANGEUISTATE and WM_UPDATEUISTATE

weiden at svn.reactos.org weiden at svn.reactos.org
Wed Nov 21 09:32:47 CET 2007


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/user32.h?rev=30611&r1=30610&r2=30611&view=diff
==============================================================================
--- 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.c?rev=30611&r1=30610&r2=30611&view=diff
==============================================================================
--- 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/defwnd.c?rev=30611&r1=30610&r2=30611&view=diff
==============================================================================
--- 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/ntuser.h?rev=30611&r1=30610&r2=30611&view=diff
==============================================================================
--- 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/include/window.h?rev=30611&r1=30610&r2=30611&view=diff
==============================================================================
--- 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/ntuser/misc.c?rev=30611&r1=30610&r2=30611&view=diff
==============================================================================
--- 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/ntuser/msgqueue.c?rev=30611&r1=30610&r2=30611&view=diff
==============================================================================
--- 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/ntuser/window.c?rev=30611&r1=30610&r2=30611&view=diff
==============================================================================
--- 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)))
    {




More information about the Ros-diffs mailing list