Author: jimtabor
Date: Mon Apr 25 15:18:39 2011
New Revision: 51450
URL:
http://svn.reactos.org/svn/reactos?rev=51450&view=rev
Log:
[User32|Win32k]
- Isolated Alt-Tab/Esc issues. Placed update_input_key_state when posting to a queue like
wine. This fixed the shift key checks. The Alt-Space is handled after a Translate Message
call (WM_SYSCHAR), developers need to check application code to help support it
(ConCtrl32). Will move AltSwitch.c from win32csr and port patch from bug 5378 to User32.
ReactOS registers the Switch Class in Win32k and it is not used.
- Implemented the rest of HotKey Support. ReactOS Explorer does not save hotkey actions.
- See related bugs 1091.
Modified:
trunk/reactos/dll/win32/user32/windows/defwnd.c
trunk/reactos/subsystems/win32/win32k/include/hotkey.h
trunk/reactos/subsystems/win32/win32k/ntuser/defwnd.c
trunk/reactos/subsystems/win32/win32k/ntuser/hotkey.c
trunk/reactos/subsystems/win32/win32k/ntuser/message.c
trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c
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 [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/windows/defwnd.c [iso-8859-1] Mon Apr 25 15:18:39 2011
@@ -753,12 +753,12 @@
{
WINDOWPLACEMENT wp;
POINT Pt;
+ LRESULT lResult;
if (!IsWindowEnabled( hWnd )) return 0;
if (ISITHOOKED(WH_CBT))
{
- LRESULT lResult;
NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult,
FNID_DEFWINDOWPROC, FALSE);
if (lResult) return 0;
}
@@ -795,7 +795,7 @@
break;
case SC_CLOSE:
return SendMessageW(hWnd, WM_CLOSE, 0, 0);
-
+// case SC_DEFAULT:
case SC_MOUSEMENU:
{
Pt.x = (short)LOWORD(lParam);
@@ -815,9 +815,40 @@
}
break;
+ case SC_SCREENSAVE:
+ NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult,
FNID_DEFWINDOWPROC, FALSE);
+ break;
+
+ case SC_NEXTWINDOW:
+ case SC_PREVWINDOW:
+ FIXME("Implement Alt-Tab!!! wParam 0x%x lParam 0x%x\n",wParam,lParam);
+ break;
+
+ case SC_HOTKEY:
+ {
+ HWND hwnd, hWndLastActive;
+
+ hwnd = (HWND)lParam;
+ PWND pWnd = ValidateHwnd(hwnd);
+ if (pWnd)
+ {
+ hWndLastActive = GetLastActivePopup(hwnd);
+ if (hWndLastActive)
+ {
+ hwnd = hWndLastActive;
+ pWnd = ValidateHwnd(hwnd);
+ }
+ SetForegroundWindow(hwnd);
+ if (pWnd->style & WS_MINIMIZE)
+ {
+ PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
+ }
+ }
+ }
+ break;
+
default:
- /* FIXME: Implement */
- UNIMPLEMENTED;
+ FIXME("Unimplemented DefWndHandleSysCommand wParam 0x%x\n",wParam);
break;
}
@@ -1380,39 +1411,49 @@
if(wParam == VK_F10) iF10Key = VK_F10;
break;
- /* FIXME: This is also incomplete. */
case WM_SYSKEYDOWN:
{
if (HIWORD(lParam) & KEYDATA_ALT)
- {
- HWND top = GetAncestor(hWnd, GA_ROOT);
- /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
- if ( (wParam == VK_MENU || wParam == VK_LMENU
- || wParam == VK_RMENU) && !iMenuSysKey )
- iMenuSysKey = 1;
- else
- iMenuSysKey = 0;
+ { /* Previous state, if the key was down before this message,
+ this is a cheap way to ignore autorepeat keys. */
+ if ( !(HIWORD(lParam) & KEYDATA_PREVSTATE) )
+ {
+ if ( ( wParam == VK_MENU ||
+ wParam == VK_LMENU ||
+ wParam == VK_RMENU ) && !iMenuSysKey )
+ iMenuSysKey = 1;
+ else
+ iMenuSysKey = 0;
+ }
iF10Key = 0;
if (wParam == VK_F4) /* Try to close the window */
{
- if (!(GetClassLongPtrW(top, GCL_STYLE) & CS_NOCLOSE))
- {
- if (bUnicode)
- PostMessageW(top, WM_SYSCOMMAND, SC_CLOSE, 0);
- else
- PostMessageA(top, WM_SYSCOMMAND, SC_CLOSE, 0);
- }
+ HWND top = GetAncestor(hWnd, GA_ROOT);
+ if (!(GetClassLongPtrW(top, GCL_STYLE) & CS_NOCLOSE))
+ PostMessageW(top, WM_SYSCOMMAND, SC_CLOSE, 0);
}
- else if (wParam == VK_SNAPSHOT)
+ else if (wParam == VK_SNAPSHOT) // Alt-VK_SNAPSHOT?
{
- HWND hwnd = hWnd;
- while (GetParent(hwnd) != NULL)
- {
- hwnd = GetParent(hwnd);
- }
- DefWndScreenshot(hwnd);
+ HWND hwnd = hWnd;
+ while (GetParent(hwnd) != NULL)
+ {
+ hwnd = GetParent(hwnd);
+ }
+ DefWndScreenshot(hwnd);
+ }
+ else if ( wParam == VK_ESCAPE || wParam == VK_TAB ) // Alt-Tab/ESC
Alt-Shift-Tab/ESC
+ {
+ WPARAM wParamTmp;
+ HWND Active = GetActiveWindow(); // Noticed MDI problem.
+ if (!Active)
+ {
+ FIXME("WM_SYSKEYDOWN VK_ESCAPE no active\n");
+ break;
+ }
+ wParamTmp = GetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW :
SC_NEXTWINDOW;
+ SendMessageW( Active, WM_SYSCOMMAND, wParamTmp, wParam );
}
}
else if( wParam == VK_F10 )
@@ -1421,8 +1462,6 @@
SendMessageW( hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, MAKELPARAM(-1, -1)
);
iF10Key = 1;
}
- else if( wParam == VK_ESCAPE && (GetKeyState(VK_SHIFT) &
0x8000))
- SendMessageW( hWnd, WM_SYSCOMMAND, SC_KEYMENU, ' ' );
break;
}
@@ -1440,36 +1479,22 @@
case WM_SYSCHAR:
{
iMenuSysKey = 0;
- if (wParam == '\r' && IsIconic(hWnd))
+ if (wParam == VK_RETURN && IsIconic(hWnd))
{
PostMessageW( hWnd, WM_SYSCOMMAND, SC_RESTORE, 0L );
break;
}
if ((HIWORD(lParam) & KEYDATA_ALT) && wParam)
{
- if (wParam == '\t' || wParam == '\x1b') break;
- if (wParam == ' ' && (GetWindowLongPtrW( hWnd, GWL_STYLE
) & WS_CHILD))
+ if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
+ if (wParam == VK_SPACE && (GetWindowLongPtrW( hWnd, GWL_STYLE )
& WS_CHILD))
SendMessageW( GetParent(hWnd), Msg, wParam, lParam );
else
SendMessageW( hWnd, WM_SYSCOMMAND, SC_KEYMENU, wParam );
}
else /* check for Ctrl-Esc */
- if (wParam != '\x1b') MessageBeep(0);
- break;
- }
-
- case WM_SHOWWINDOW:
- {
- if (lParam) // Call when it is necessary.
- NtUserMessageCall( hWnd, Msg, wParam, lParam, 0, FNID_DEFWINDOWPROC,
FALSE);
- break;
- }
-
- case WM_CLIENTSHUTDOWN:
- {
- LRESULT lResult;
- NtUserMessageCall( hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult,
FNID_DEFWINDOWPROC, FALSE);
- return lResult;
+ if (wParam != VK_ESCAPE) MessageBeep(0);
+ break;
}
case WM_CANCELMODE:
@@ -1800,6 +1825,17 @@
break;
}
+/* Move to win32k !*/
+ case WM_SHOWWINDOW:
+ if (!lParam) break; // Call when it is necessary.
+ case WM_CLIENTSHUTDOWN:
+ case WM_GETHOTKEY:
+ case WM_SETHOTKEY:
+ {
+ LRESULT lResult;
+ NtUserMessageCall( hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult,
FNID_DEFWINDOWPROC, !bUnicode);
+ return lResult;
+ }
}
return 0;
}
Modified: trunk/reactos/subsystems/win32/win32k/include/hotkey.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/hotkey.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/hotkey.h [iso-8859-1] Mon Apr 25
15:18:39 2011
@@ -12,6 +12,8 @@
UINT fsModifiers;
UINT vk;
} HOT_KEY_ITEM, *PHOT_KEY_ITEM;
+
+#define IDHOT_REACTOS (-9)
INIT_FUNCTION
NTSTATUS
@@ -33,5 +35,9 @@
VOID FASTCALL
UnregisterThreadHotKeys(struct _ETHREAD *Thread);
+UINT FASTCALL
+DefWndGetHotKey(HWND hwnd);
+INT FASTCALL
+DefWndSetHotKey( PWND pWnd, WPARAM wParam);
/* EOF */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/defwnd.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/defwnd.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/defwnd.c [iso-8859-1] Mon Apr 25 15:18:39
2011
@@ -97,6 +97,34 @@
return lResult;
}
+LRESULT FASTCALL
+DefWndHandleSysCommand(PWND pWnd, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT lResult = 0;
+ BOOL Hook = FALSE;
+
+ if (ISITHOOKED(WH_CBT) || (pWnd->head.rpdesk->pDeskInfo->fsHooks &
HOOKID_TO_FLAG(WH_CBT)))
+ {
+ Hook = TRUE;
+ lResult = co_HOOK_CallHooks(WH_CBT, HCBT_SYSCOMMAND, wParam, lParam);
+
+ if (lResult) return lResult;
+ }
+
+ switch (wParam & 0xfff0)
+ {
+ case SC_SCREENSAVE:
+ DPRINT1("Screensaver Called!\n");
+ break;
+
+ default:
+ UNIMPLEMENTED;
+ break;
+ }
+
+ return(Hook ? 1 : 0); // Don't call us again from user space.
+}
+
/*
Win32k counterpart of User DefWindowProc
*/
@@ -117,7 +145,7 @@
case WM_SYSCOMMAND:
{
DPRINT1("hwnd %p WM_SYSCOMMAND %lx %lx\n", Wnd->head.h, wParam,
lParam );
- lResult = co_HOOK_CallHooks(WH_CBT, HCBT_SYSCOMMAND, wParam, lParam);
+ lResult = DefWndHandleSysCommand(Wnd, wParam, lParam);
break;
}
case WM_SHOWWINDOW:
@@ -142,6 +170,12 @@
case WM_CLIENTSHUTDOWN:
return IntClientShutdown(Wnd, wParam, lParam);
+ case WM_GETHOTKEY:
+ return DefWndGetHotKey(UserHMGetHandle(Wnd));
+ case WM_SETHOTKEY:
+ return DefWndSetHotKey(Wnd, wParam);
+
+ /* ReactOS only. */
case WM_CBT:
{
switch (wParam)
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/hotkey.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/hotkey.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/hotkey.c [iso-8859-1] Mon Apr 25 15:18:39
2011
@@ -61,7 +61,6 @@
return STATUS_SUCCESS;
}
-
#if 0 //not used
NTSTATUS FASTCALL
CleanupHotKeys(VOID)
@@ -70,7 +69,6 @@
return STATUS_SUCCESS;
}
#endif
-
BOOL FASTCALL
GetHotKey (UINT fsModifiers,
@@ -102,7 +100,6 @@
return FALSE;
}
-
VOID FASTCALL
UnregisterWindowHotKeys(PWND Window)
{
@@ -119,7 +116,6 @@
}
-
VOID FASTCALL
UnregisterThreadHotKeys(struct _ETHREAD *Thread)
{
@@ -135,7 +131,6 @@
}
}
-
static
BOOL FASTCALL
@@ -154,7 +149,111 @@
return FALSE;
}
-
+//
+// Get/SetHotKey message support.
+//
+UINT FASTCALL
+DefWndGetHotKey( HWND hwnd )
+{
+ PHOT_KEY_ITEM HotKeyItem;
+
+ DPRINT1("DefWndGetHotKey\n");
+
+ if (IsListEmpty(&gHotkeyList)) return 0;
+
+ LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
+ {
+ if ( HotKeyItem->hWnd == hwnd &&
+ HotKeyItem->id == IDHOT_REACTOS )
+ {
+ return MAKELONG(HotKeyItem->vk, HotKeyItem->fsModifiers);
+ }
+ }
+ return 0;
+}
+
+INT FASTCALL
+DefWndSetHotKey( PWND pWnd, WPARAM wParam )
+{
+ UINT fsModifiers, vk;
+ PHOT_KEY_ITEM HotKeyItem;
+ HWND hWnd;
+ BOOL HaveSameWnd = FALSE;
+ INT Ret = 1;
+
+ DPRINT1("DefWndSetHotKey wParam 0x%x\n", wParam);
+
+ // A hot key cannot be associated with a child window.
+ if (pWnd->style & WS_CHILD) return 0;
+
+ // VK_ESCAPE, VK_SPACE, and VK_TAB are invalid hot keys.
+ if ( LOWORD(wParam) == VK_ESCAPE ||
+ LOWORD(wParam) == VK_SPACE ||
+ LOWORD(wParam) == VK_TAB ) return -1;
+
+ vk = LOWORD(wParam);
+ fsModifiers = HIWORD(wParam);
+ hWnd = UserHMGetHandle(pWnd);
+
+ if (wParam)
+ {
+ LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
+ {
+ if ( HotKeyItem->fsModifiers == fsModifiers &&
+ HotKeyItem->vk == vk &&
+ HotKeyItem->id == IDHOT_REACTOS )
+ {
+ if (HotKeyItem->hWnd != hWnd)
+ Ret = 2; // Another window already has the same hot key.
+ break;
+ }
+ }
+ }
+
+ LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
+ {
+ if ( HotKeyItem->hWnd == hWnd &&
+ HotKeyItem->id == IDHOT_REACTOS )
+ {
+ HaveSameWnd = TRUE;
+ break;
+ }
+ }
+
+ if (HaveSameWnd)
+ {
+ if (wParam == 0)
+ { // Setting wParam to NULL removes the hot key associated with a window.
+ UnregisterWindowHotKeys(pWnd);
+ }
+ else
+ { /* A window can only have one hot key. If the window already has a hot key
+ associated with it, the new hot key replaces the old one. */
+ HotKeyItem->fsModifiers = fsModifiers;
+ HotKeyItem->vk = vk;
+ }
+ }
+ else //
+ {
+ if (wParam == 0)
+ return 1; // Do nothing, exit.
+
+ HotKeyItem = ExAllocatePoolWithTag (PagedPool, sizeof(HOT_KEY_ITEM),
USERTAG_HOTKEY);
+ if (HotKeyItem == NULL)
+ {
+ return 0;
+ }
+
+ HotKeyItem->Thread = pWnd->head.pti->pEThread;
+ HotKeyItem->hWnd = hWnd;
+ HotKeyItem->id = IDHOT_REACTOS; // Don't care, these hot keys are unrelated
to the hot keys set by RegisterHotKey.
+ HotKeyItem->fsModifiers = fsModifiers;
+ HotKeyItem->vk = vk;
+
+ InsertHeadList (&gHotkeyList, &HotKeyItem->ListEntry);
+ }
+ return Ret;
+}
/* SYSCALLS *****************************************************************/
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/message.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/message.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/message.c [iso-8859-1] Mon Apr 25
15:18:39 2011
@@ -735,7 +735,8 @@
}
/* Now check for normal messages. */
- if ((ProcessMask & QS_POSTMESSAGE) &&
+ if (( (ProcessMask & QS_POSTMESSAGE) ||
+ (ProcessMask & QS_HOTKEY) ) &&
MsqPeekMessage( ThreadQueue,
RemoveMessages,
Window,
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 [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] Mon Apr 25
15:18:39 2011
@@ -463,6 +463,7 @@
FocusMessageQueue->Desktop->pDeskInfo->LastInputWasKbd = TRUE;
Msg.pt = gpsi->ptCursor;
+ update_input_key_state(FocusMessageQueue, &Msg);
MsqPostMessage(FocusMessageQueue, &Msg, TRUE, QS_KEY);
}
else
@@ -481,6 +482,8 @@
MSG Mesg;
LARGE_INTEGER LargeTickCount;
NTSTATUS Status;
+ INT id;
+ DWORD Type;
Status = ObReferenceObjectByPointer (Thread,
THREAD_ALL_ACCESS,
@@ -503,14 +506,17 @@
return;
}
- Mesg.hwnd = hWnd;
- Mesg.message = WM_HOTKEY;
- Mesg.wParam = wParam;
- Mesg.lParam = lParam;
+ id = wParam; // Check for hot keys unrelated to the hot keys set by RegisterHotKey.
+
+ Mesg.hwnd = hWnd;
+ Mesg.message = id != IDHOT_REACTOS ? WM_HOTKEY : WM_SYSCOMMAND;
+ Mesg.wParam = id != IDHOT_REACTOS ? wParam : SC_HOTKEY;
+ Mesg.lParam = id != IDHOT_REACTOS ? lParam : (LPARAM)hWnd;
+ Type = id != IDHOT_REACTOS ? QS_HOTKEY : QS_POSTMESSAGE;
KeQueryTickCount(&LargeTickCount);
- Mesg.time = MsqCalculateMessageTime(&LargeTickCount);
- Mesg.pt = gpsi->ptCursor;
- MsqPostMessage(Window->head.pti->MessageQueue, &Mesg, FALSE, QS_HOTKEY);
+ Mesg.time = MsqCalculateMessageTime(&LargeTickCount);
+ Mesg.pt = gpsi->ptCursor;
+ MsqPostMessage(Window->head.pti->MessageQueue, &Mesg, FALSE, Type);
UserDereferenceObject(Window);
ObDereferenceObject (Thread);
@@ -543,8 +549,8 @@
{
PUSER_SENT_MESSAGE SaveMsg, Message;
PLIST_ENTRY Entry;
- LRESULT Result;
PTHREADINFO pti;
+ LRESULT Result = 0;
if (IsListEmpty(&MessageQueue->SentMessagesListHead))
{
@@ -1321,6 +1327,10 @@
case VK_LMENU: case VK_RMENU:
Msg->wParam = VK_MENU;
break;
+ case VK_F10:
+ if (Msg->message == WM_KEYUP) Msg->message = WM_SYSKEYUP;
+ if (Msg->message == WM_KEYDOWN) Msg->message = WM_SYSKEYDOWN;
+ break;
}
}
@@ -1450,7 +1460,7 @@
{
update_input_key_state(MessageQueue, pMsg);
RemoveEntryList(&CurrentMessage->ListEntry);
- ClearMsgBitsMask(MessageQueue, QS_INPUT);
+ ClearMsgBitsMask(MessageQueue, CurrentMessage->QS_Flags);
MsqDestroyMessage(CurrentMessage);
}
@@ -1510,7 +1520,7 @@
if (Remove)
{
RemoveEntryList(&CurrentMessage->ListEntry);
- ClearMsgBitsMask(MessageQueue, QS_POSTMESSAGE);
+ ClearMsgBitsMask(MessageQueue, CurrentMessage->QS_Flags);
MsqDestroyMessage(CurrentMessage);
}
return(TRUE);