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/us... ============================================================================== --- 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/de... ============================================================================== --- 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/ntus... ============================================================================== --- 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/inc... ============================================================================== --- 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/ntu... ============================================================================== --- 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/ntu... ============================================================================== --- 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/ntu... ============================================================================== --- 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))) {