From 0331caa800b4c882ebc6feef776b8f5e189fc80c Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Tue, 11 Nov 2003 22:17:18 +0000 Subject: [PATCH] 1.added a simple test application for hotkeys 2.some fixes on hotkeys svn path=/trunk/; revision=6623 --- reactos/apps/tests/Makefile | 4 +- reactos/apps/tests/hotkey/.cvsignore | 6 + reactos/apps/tests/hotkey/hotkey.c | 116 +++++++++++++++++++ reactos/apps/tests/hotkey/makefile | 21 ++++ reactos/ntoskrnl/include/internal/ex.h | 2 + reactos/subsys/win32k/include/hotkey.h | 21 +++- reactos/subsys/win32k/main/dllmain.c | 9 +- reactos/subsys/win32k/ntuser/hotkey.c | 154 ++++++++++++++++--------- reactos/subsys/win32k/ntuser/input.c | 5 +- reactos/subsys/win32k/ntuser/window.c | 4 +- reactos/subsys/win32k/ntuser/winsta.c | 7 +- 11 files changed, 277 insertions(+), 72 deletions(-) create mode 100644 reactos/apps/tests/hotkey/.cvsignore create mode 100644 reactos/apps/tests/hotkey/hotkey.c create mode 100644 reactos/apps/tests/hotkey/makefile diff --git a/reactos/apps/tests/Makefile b/reactos/apps/tests/Makefile index 77d51049d12..8c9436745e5 100644 --- a/reactos/apps/tests/Makefile +++ b/reactos/apps/tests/Makefile @@ -10,8 +10,8 @@ include $(PATH_TO_TOP)/rules.mak TEST_APPS = SampleWindow alive apc args atomtest bench bitblt button \ button2 capclock carets cliarea combo consume copymove count dibtest \ dump_shared_data edit enumwnd event file gditest global_mem hello \ -hivetest icontest isotest lineclip linetest lock lpc messagebox mktime \ -mstest multiwin mutex nptest patblt pipe primitives pteb regtest \ +hivetest hotkey icontest isotest lineclip linetest lock lpc messagebox \ +mktime mstest multiwin mutex nptest patblt pipe primitives pteb regtest \ sectest sertest shaptest shm statst statst2 stretchblt suspend \ tcpsvr terminate txtscale thread thread_msg tokentest vmtest \ winhello winhello2 wm_erasebkgnd wm_paint eventpair threadwait \ diff --git a/reactos/apps/tests/hotkey/.cvsignore b/reactos/apps/tests/hotkey/.cvsignore new file mode 100644 index 00000000000..d63774a7353 --- /dev/null +++ b/reactos/apps/tests/hotkey/.cvsignore @@ -0,0 +1,6 @@ +*.o +*.d +*.exe +*.coff +*.sym +*.map diff --git a/reactos/apps/tests/hotkey/hotkey.c b/reactos/apps/tests/hotkey/hotkey.c new file mode 100644 index 00000000000..ba805b7fe2c --- /dev/null +++ b/reactos/apps/tests/hotkey/hotkey.c @@ -0,0 +1,116 @@ +#include +#include + +//HFONT tf; +LRESULT WINAPI MainWndProc(HWND, UINT, WPARAM, LPARAM); + +int WINAPI +WinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpszCmdLine, + int nCmdShow) +{ + WNDCLASS wc; + MSG msg; + HWND hWnd; + + wc.lpszClassName = "HotkeyTestClass"; + wc.lpfnWndProc = MainWndProc; + wc.style = CS_VREDRAW | CS_HREDRAW; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, (LPCTSTR)IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, (LPCTSTR)IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); + wc.lpszMenuName = NULL; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + if (RegisterClass(&wc) == 0) + { + fprintf(stderr, "RegisterClass failed (last error 0x%X)\n", + GetLastError()); + return(1); + } + + hWnd = CreateWindow("HotkeyTestClass", + "Hotkeys Test", + WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL, + 0, + 0, + CW_USEDEFAULT, + CW_USEDEFAULT, + NULL, + NULL, + hInstance, + NULL); + if (hWnd == NULL) + { + fprintf(stderr, "CreateWindow failed (last error 0x%X)\n", + GetLastError()); + return(1); + } + + //tf = CreateFontA(14, 0, 0, TA_BASELINE, FW_NORMAL, FALSE, FALSE, FALSE, + // ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + // DEFAULT_QUALITY, FIXED_PITCH|FF_DONTCARE, "Timmons"); + + ShowWindow(hWnd, nCmdShow); + + while(GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + //DeleteObject(tf); + + return msg.wParam; +} + + +#define CTRLC 1 +#define ALTF1 2 +LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + PAINTSTRUCT ps; + HDC hDC; + RECT clr, wir; + char spr[100], sir[100]; + + switch(msg) + { + case WM_PAINT: + hDC = BeginPaint(hWnd, &ps); + TextOut(hDC, 10, 10, "Press Ctrl+C or Ctrl+Alt+F1", + strlen("Press Ctrl+C or Ctrl+Alt+F1")); + EndPaint(hWnd, &ps); + break; + + case WM_HOTKEY: + switch(wParam) + { + case CTRLC: + MessageBox(hWnd, "You just pressed Ctrl+C", "Hotkey", MB_OK | MB_ICONINFORMATION); + break; + case ALTF1: + MessageBox(hWnd, "You just pressed Ctrl+Alt+F1", "Hotkey", MB_OK | MB_ICONINFORMATION); + break; + } + break; + + case WM_DESTROY: + UnregisterHotKey(hWnd, CTRLC); + UnregisterHotKey(hWnd, ALTF1); + PostQuitMessage(0); + break; + + case WM_CREATE: + /* Register a Ctrl+Alt+C hotkey*/ + RegisterHotKey(hWnd, CTRLC, MOD_CONTROL, VK_C); + RegisterHotKey(hWnd, ALTF1, MOD_CONTROL | MOD_ALT, VK_F1); + break; + + default: + return DefWindowProc(hWnd, msg, wParam, lParam); + } + return 0; +} diff --git a/reactos/apps/tests/hotkey/makefile b/reactos/apps/tests/hotkey/makefile new file mode 100644 index 00000000000..60fed36a2fa --- /dev/null +++ b/reactos/apps/tests/hotkey/makefile @@ -0,0 +1,21 @@ +# $Id: makefile,v 1.1 2003/11/11 22:17:18 weiden Exp $ + +PATH_TO_TOP = ../../.. + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = windows + +TARGET_NAME = hotkey + +TARGET_SDKLIBS = kernel32.a gdi32.a ntdll.a + +TARGET_OBJECTS = $(TARGET_NAME).o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/reactos/ntoskrnl/include/internal/ex.h b/reactos/ntoskrnl/include/internal/ex.h index da4a00798ac..b1f5bdbfa5e 100644 --- a/reactos/ntoskrnl/include/internal/ex.h +++ b/reactos/ntoskrnl/include/internal/ex.h @@ -60,6 +60,8 @@ typedef struct _WINSTATION_OBJECT SYSTEM_CURSORINFO SystemCursor; struct _DESKTOP_OBJECT* ActiveDesktop; /* FIXME: Clipboard */ + LIST_ENTRY HotKeyListHead; + FAST_MUTEX HotKeyListLock; } WINSTATION_OBJECT, *PWINSTATION_OBJECT; typedef struct _DESKTOP_OBJECT diff --git a/reactos/subsys/win32k/include/hotkey.h b/reactos/subsys/win32k/include/hotkey.h index baaa493cb65..32c1f08ed49 100644 --- a/reactos/subsys/win32k/include/hotkey.h +++ b/reactos/subsys/win32k/include/hotkey.h @@ -3,22 +3,35 @@ #include #include +#include +#include + +typedef struct _HOT_KEY_ITEM +{ + LIST_ENTRY ListEntry; + struct _ETHREAD *Thread; + HWND hWnd; + int id; + UINT fsModifiers; + UINT vk; +} HOT_KEY_ITEM, *PHOT_KEY_ITEM; NTSTATUS FASTCALL -InitHotKeyImpl (VOID); +InitHotKeys(PWINSTATION_OBJECT WinStaObject); NTSTATUS FASTCALL -CleanupHotKeyImpl (VOID); +CleanupHotKeys(PWINSTATION_OBJECT WinStaObject); BOOL -GetHotKey (UINT fsModifiers, +GetHotKey (PWINSTATION_OBJECT WinStaObject, + UINT fsModifiers, UINT vk, struct _ETHREAD **Thread, HWND *hWnd, int *id); VOID -UnregisterWindowHotKeys(HWND hWnd); +UnregisterWindowHotKeys(PWINDOW_OBJECT Window); VOID UnregisterThreadHotKeys(struct _ETHREAD *Thread); diff --git a/reactos/subsys/win32k/main/dllmain.c b/reactos/subsys/win32k/main/dllmain.c index 884075c9b87..ab5b5228183 100644 --- a/reactos/subsys/win32k/main/dllmain.c +++ b/reactos/subsys/win32k/main/dllmain.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: dllmain.c,v 1.49 2003/11/11 20:28:21 gvg Exp $ +/* $Id: dllmain.c,v 1.50 2003/11/11 22:17:18 weiden Exp $ * * Entry Point for win32k.sys */ @@ -230,13 +230,6 @@ DllMain ( return STATUS_UNSUCCESSFUL; } - Status = InitHotKeyImpl(); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Failed to initialize hot key implementation!\n"); - return STATUS_UNSUCCESSFUL; - } - Status = InitInputImpl(); if (!NT_SUCCESS(Status)) { diff --git a/reactos/subsys/win32k/ntuser/hotkey.c b/reactos/subsys/win32k/ntuser/hotkey.c index 4d90e405d44..2a0f3324911 100644 --- a/reactos/subsys/win32k/ntuser/hotkey.c +++ b/reactos/subsys/win32k/ntuser/hotkey.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: hotkey.c,v 1.2 2003/11/03 18:52:21 ekohl Exp $ +/* $Id: hotkey.c,v 1.3 2003/11/11 22:17:18 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -32,7 +32,11 @@ #include #include #include +#include +#include +#include #include +#include #define NDEBUG #include @@ -40,35 +44,20 @@ /* GLOBALS *******************************************************************/ -typedef struct _HOT_KEY_ITEM -{ - LIST_ENTRY ListEntry; - struct _ETHREAD *Thread; - HWND hWnd; - int id; - UINT fsModifiers; - UINT vk; -} HOT_KEY_ITEM, *PHOT_KEY_ITEM; - - -static LIST_ENTRY HotKeyListHead; -static FAST_MUTEX HotKeyListLock; - - /* FUNCTIONS *****************************************************************/ NTSTATUS FASTCALL -InitHotKeyImpl(VOID) +InitHotKeys(PWINSTATION_OBJECT WinStaObject) { - InitializeListHead(&HotKeyListHead); - ExInitializeFastMutex(&HotKeyListLock); + InitializeListHead(&WinStaObject->HotKeyListHead); + ExInitializeFastMutex(&WinStaObject->HotKeyListLock); return STATUS_SUCCESS; } NTSTATUS FASTCALL -CleanupHotKeyImpl(VOID) +CleanupHotKeys(PWINSTATION_OBJECT WinStaObject) { return STATUS_SUCCESS; @@ -76,7 +65,8 @@ CleanupHotKeyImpl(VOID) BOOL -GetHotKey (UINT fsModifiers, +GetHotKey (PWINSTATION_OBJECT WinStaObject, + UINT fsModifiers, UINT vk, struct _ETHREAD **Thread, HWND *hWnd, @@ -85,10 +75,10 @@ GetHotKey (UINT fsModifiers, PLIST_ENTRY Entry; PHOT_KEY_ITEM HotKeyItem; - ExAcquireFastMutex (&HotKeyListLock); + ExAcquireFastMutex (&WinStaObject->HotKeyListLock); - Entry = HotKeyListHead.Flink; - while (Entry != &HotKeyListHead) + Entry = WinStaObject->HotKeyListHead.Flink; + while (Entry != &WinStaObject->HotKeyListHead) { HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD(Entry, HOT_KEY_ITEM, @@ -105,7 +95,7 @@ GetHotKey (UINT fsModifiers, if (id != NULL) *id = HotKeyItem->id; - ExReleaseFastMutex (&HotKeyListLock); + ExReleaseFastMutex (&WinStaObject->HotKeyListLock); return TRUE; } @@ -113,35 +103,43 @@ GetHotKey (UINT fsModifiers, Entry = Entry->Flink; } - ExReleaseFastMutex (&HotKeyListLock); + ExReleaseFastMutex (&WinStaObject->HotKeyListLock); return FALSE; } VOID -UnregisterWindowHotKeys(HWND hWnd) +UnregisterWindowHotKeys(PWINDOW_OBJECT Window) { PLIST_ENTRY Entry; PHOT_KEY_ITEM HotKeyItem; + PWINSTATION_OBJECT WinStaObject = NULL; + + if(Window->OwnerThread && Window->OwnerThread->ThreadsProcess && + Window->OwnerThread->ThreadsProcess->Win32Process) + WinStaObject = Window->OwnerThread->ThreadsProcess->Win32Process->WindowStation; - ExAcquireFastMutex (&HotKeyListLock); + if(!WinStaObject) + return; - Entry = HotKeyListHead.Flink; - while (Entry != &HotKeyListHead) + ExAcquireFastMutex (&WinStaObject->HotKeyListLock); + + Entry = WinStaObject->HotKeyListHead.Flink; + while (Entry != &WinStaObject->HotKeyListHead) { HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry, HOT_KEY_ITEM, ListEntry); Entry = Entry->Flink; - if (HotKeyItem->hWnd == hWnd) + if (HotKeyItem->hWnd == Window->Self) { RemoveEntryList (&HotKeyItem->ListEntry); ExFreePool (HotKeyItem); } } - ExReleaseFastMutex (&HotKeyListLock); + ExReleaseFastMutex (&WinStaObject->HotKeyListLock); } @@ -150,11 +148,18 @@ UnregisterThreadHotKeys(struct _ETHREAD *Thread) { PLIST_ENTRY Entry; PHOT_KEY_ITEM HotKeyItem; + PWINSTATION_OBJECT WinStaObject = NULL; + + if(Thread->ThreadsProcess && Thread->ThreadsProcess->Win32Process) + WinStaObject = Thread->ThreadsProcess->Win32Process->WindowStation; + + if(!WinStaObject) + return; + + ExAcquireFastMutex (&WinStaObject->HotKeyListLock); - ExAcquireFastMutex (&HotKeyListLock); - - Entry = HotKeyListHead.Flink; - while (Entry != &HotKeyListHead) + Entry = WinStaObject->HotKeyListHead.Flink; + while (Entry != &WinStaObject->HotKeyListHead) { HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry, HOT_KEY_ITEM, @@ -167,19 +172,20 @@ UnregisterThreadHotKeys(struct _ETHREAD *Thread) } } - ExReleaseFastMutex (&HotKeyListLock); + ExReleaseFastMutex (&WinStaObject->HotKeyListLock); } static BOOL -IsHotKey (UINT fsModifiers, +IsHotKey (PWINSTATION_OBJECT WinStaObject, + UINT fsModifiers, UINT vk) { PLIST_ENTRY Entry; PHOT_KEY_ITEM HotKeyItem; - Entry = HotKeyListHead.Flink; - while (Entry != &HotKeyListHead) + Entry = WinStaObject->HotKeyListHead.Flink; + while (Entry != &WinStaObject->HotKeyListHead) { HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry, HOT_KEY_ITEM, @@ -204,18 +210,40 @@ NtUserRegisterHotKey(HWND hWnd, UINT vk) { PHOT_KEY_ITEM HotKeyItem; + PWINDOW_OBJECT Window; + PWINSTATION_OBJECT WinStaObject = NULL; + + Window = IntGetWindowObject(hWnd); + if(!Window) + { + SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); + return FALSE; + } + + if(Window->OwnerThread->ThreadsProcess && Window->OwnerThread->ThreadsProcess->Win32Process) + WinStaObject = Window->OwnerThread->ThreadsProcess->Win32Process->WindowStation; + + if(!WinStaObject) + { + IntReleaseWindowObject(Window); + return FALSE; + } - ExAcquireFastMutex (&HotKeyListLock); + ExAcquireFastMutex (&WinStaObject->HotKeyListLock); /* Check for existing hotkey */ - if (IsHotKey (fsModifiers, vk)) + if (IsHotKey (WinStaObject, fsModifiers, vk)) + { + IntReleaseWindowObject(Window); return FALSE; + } HotKeyItem = ExAllocatePool (PagedPool, sizeof(HOT_KEY_ITEM)); if (HotKeyItem == NULL) { - ExReleaseFastMutex (&HotKeyListLock); + ExReleaseFastMutex (&WinStaObject->HotKeyListLock); + IntReleaseWindowObject(Window); return FALSE; } @@ -225,11 +253,12 @@ NtUserRegisterHotKey(HWND hWnd, HotKeyItem->fsModifiers = fsModifiers; HotKeyItem->vk = vk; - InsertHeadList (&HotKeyListHead, + InsertHeadList (&WinStaObject->HotKeyListHead, &HotKeyItem->ListEntry); - ExReleaseFastMutex (&HotKeyListLock); - + ExReleaseFastMutex (&WinStaObject->HotKeyListLock); + + IntReleaseWindowObject(Window); return TRUE; } @@ -240,11 +269,29 @@ NtUserUnregisterHotKey(HWND hWnd, { PLIST_ENTRY Entry; PHOT_KEY_ITEM HotKeyItem; + PWINDOW_OBJECT Window; + PWINSTATION_OBJECT WinStaObject = NULL; + + Window = IntGetWindowObject(hWnd); + if(!Window) + { + SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); + return FALSE; + } + + if(Window->OwnerThread->ThreadsProcess && Window->OwnerThread->ThreadsProcess->Win32Process) + WinStaObject = Window->OwnerThread->ThreadsProcess->Win32Process->WindowStation; + + if(!WinStaObject) + { + IntReleaseWindowObject(Window); + return FALSE; + } - ExAcquireFastMutex (&HotKeyListLock); + ExAcquireFastMutex (&WinStaObject->HotKeyListLock); - Entry = HotKeyListHead.Flink; - while (Entry != &HotKeyListHead) + Entry = WinStaObject->HotKeyListHead.Flink; + while (Entry != &WinStaObject->HotKeyListHead) { HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry, HOT_KEY_ITEM, @@ -254,15 +301,18 @@ NtUserUnregisterHotKey(HWND hWnd, { RemoveEntryList (&HotKeyItem->ListEntry); ExFreePool (HotKeyItem); - ExReleaseFastMutex (&HotKeyListLock); + ExReleaseFastMutex (&WinStaObject->HotKeyListLock); + + IntReleaseWindowObject(Window); return TRUE; } Entry = Entry->Flink; } - ExReleaseFastMutex (&HotKeyListLock); - + ExReleaseFastMutex (&WinStaObject->HotKeyListLock); + + IntReleaseWindowObject(Window); return FALSE; } diff --git a/reactos/subsys/win32k/ntuser/input.c b/reactos/subsys/win32k/ntuser/input.c index de25bfa8aa5..fdab8237763 100644 --- a/reactos/subsys/win32k/ntuser/input.c +++ b/reactos/subsys/win32k/ntuser/input.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: input.c,v 1.17 2003/11/03 18:52:21 ekohl Exp $ +/* $Id: input.c,v 1.18 2003/11/11 22:17:18 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -144,7 +144,8 @@ KeyboardThreadMain(PVOID StartContext) /* FIXME: Support MOD_WIN */ - if (GetHotKey(fsModifiers, + if (GetHotKey(InputWindowStation, + fsModifiers, KeyEvent.wVirtualKeyCode, &Thread, &hWnd, diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index 9a1ed6b6d64..01c66f93286 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: window.c,v 1.133 2003/11/11 21:04:55 navaraf Exp $ +/* $Id: window.c,v 1.134 2003/11/11 22:17:18 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -372,7 +372,7 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window, hwndShellListView = 0; /* Unregister hot keys */ - UnregisterWindowHotKeys (Window->Self); + UnregisterWindowHotKeys (Window); /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */ diff --git a/reactos/subsys/win32k/ntuser/winsta.c b/reactos/subsys/win32k/ntuser/winsta.c index 51dd718fd40..bc3808c6e91 100644 --- a/reactos/subsys/win32k/ntuser/winsta.c +++ b/reactos/subsys/win32k/ntuser/winsta.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: winsta.c,v 1.41 2003/11/11 20:28:21 gvg Exp $ +/* $Id: winsta.c,v 1.42 2003/11/11 22:17:18 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -49,6 +49,7 @@ #include #include #include +#include #define NDEBUG #include @@ -372,7 +373,9 @@ NtUserCreateWindowStation(PUNICODE_STRING lpszWindowStationName, SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); return((HWINSTA)0); } - + + InitHotKeys(WinStaObject); + ExInitializeFastMutex(&WinStaObject->SystemCursor.CursorMutex); WinStaObject->SystemCursor.Enabled = FALSE; WinStaObject->SystemCursor.ButtonsDown = 0;