replaced keyboard hook

This commit is contained in:
seraphima 2023-10-23 22:55:07 +02:00
parent 4573865575
commit 6427d0a454
4 changed files with 52 additions and 121 deletions

View File

@ -32,14 +32,6 @@ FancyZonesApp::~FancyZonesApp()
m_app->Destroy();
m_app = nullptr;
if (s_llKeyboardHook)
{
if (UnhookWindowsHookEx(s_llKeyboardHook))
{
s_llKeyboardHook = nullptr;
}
}
m_staticWinEventHooks.erase(std::remove_if(begin(m_staticWinEventHooks),
end(m_staticWinEventHooks),
[](const HWINEVENTHOOK hook) {
@ -66,24 +58,6 @@ void FancyZonesApp::Run()
void FancyZonesApp::InitHooks()
{
#if defined(DISABLE_LOWLEVEL_HOOKS_WHEN_DEBUGGED)
const bool hook_disabled = IsDebuggerPresent();
#else
const bool hook_disabled = false;
#endif
if (!hook_disabled)
{
s_llKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), NULL);
if (!s_llKeyboardHook)
{
DWORD errorCode = GetLastError();
show_last_error_message(L"SetWindowsHookEx", errorCode, GET_RESOURCE_STRING(IDS_POWERTOYS_FANCYZONES).c_str());
auto errorMessage = get_last_error_message(errorCode);
Trace::FancyZones::Error(errorCode, errorMessage.has_value() ? errorMessage.value() : L"", L"enable.SetWindowsHookEx");
}
}
std::array<DWORD, 6> events_to_subscribe = {
EVENT_SYSTEM_MOVESIZESTART,
EVENT_SYSTEM_MOVESIZEEND,
@ -174,8 +148,3 @@ void FancyZonesApp::HandleWinHookEvent(WinHookEvent* data) noexcept
break;
}
}
intptr_t FancyZonesApp::HandleKeyboardHookEvent(LowlevelKeyboardEvent* data) noexcept
{
return m_app.as<IFancyZonesCallback>()->OnKeyDown(data->lParam);
}

View File

@ -14,7 +14,6 @@ public:
private:
static inline FancyZonesApp* s_instance = nullptr;
static inline HHOOK s_llKeyboardHook = nullptr;
winrt::com_ptr<IFancyZones> m_app;
HWINEVENTHOOK m_objectLocationWinEventHook = nullptr;
@ -25,25 +24,6 @@ private:
void InitHooks();
void HandleWinHookEvent(WinHookEvent* data) noexcept;
intptr_t HandleKeyboardHookEvent(LowlevelKeyboardEvent* data) noexcept;
static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
LowlevelKeyboardEvent event;
if (nCode == HC_ACTION && wParam == WM_KEYDOWN)
{
event.lParam = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
event.wParam = wParam;
if (s_instance)
{
if (s_instance->HandleKeyboardHookEvent(&event) == 1)
{
return 1;
}
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
static void CALLBACK WinHookProc(HWINEVENTHOOK winEventHook,
DWORD event,

View File

@ -133,8 +133,6 @@ public:
IFACEMETHODIMP_(void)
VirtualDesktopChanged() noexcept;
IFACEMETHODIMP_(bool)
OnKeyDown(PKBDLLHOOKSTRUCT info) noexcept;
void MoveSizeStart(HWND window, HMONITOR monitor);
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen);
@ -461,64 +459,6 @@ void FancyZones::WindowCreated(HWND window) noexcept
}
}
// IFancyZonesCallback
IFACEMETHODIMP_(bool)
FancyZones::OnKeyDown(PKBDLLHOOKSTRUCT info) noexcept
{
// Return true to swallow the keyboard event
bool const shift = GetAsyncKeyState(VK_SHIFT) & 0x8000;
bool const win = GetAsyncKeyState(VK_LWIN) & 0x8000 || GetAsyncKeyState(VK_RWIN) & 0x8000;
bool const alt = GetAsyncKeyState(VK_MENU) & 0x8000;
bool const ctrl = GetAsyncKeyState(VK_CONTROL) & 0x8000;
if ((win && !shift && !ctrl) || (win && ctrl && alt))
{
if ((info->vkCode == VK_RIGHT) || (info->vkCode == VK_LEFT) || (info->vkCode == VK_UP) || (info->vkCode == VK_DOWN))
{
if (ShouldProcessSnapHotkey(info->vkCode))
{
Trace::FancyZones::OnKeyDown(info->vkCode, win, ctrl, false /*inMoveSize*/);
// Win+Left, Win+Right will cycle through Zones in the active ZoneSet when WM_PRIV_SNAP_HOTKEY's handled
PostMessageW(m_window, WM_PRIV_SNAP_HOTKEY, 0, info->vkCode);
return true;
}
}
}
if (FancyZonesSettings::settings().quickLayoutSwitch)
{
int digitPressed = -1;
if ('0' <= info->vkCode && info->vkCode <= '9')
{
digitPressed = info->vkCode - '0';
}
else if (VK_NUMPAD0 <= info->vkCode && info->vkCode <= VK_NUMPAD9)
{
digitPressed = info->vkCode - VK_NUMPAD0;
}
bool dragging = m_draggingState.IsDragging();
bool changeLayoutWhileNotDragging = !dragging && !shift && win && ctrl && alt && digitPressed != -1;
bool changeLayoutWhileDragging = dragging && digitPressed != -1;
if (changeLayoutWhileNotDragging || changeLayoutWhileDragging)
{
auto layoutId = LayoutHotkeys::instance().GetLayoutId(digitPressed);
if (layoutId.has_value())
{
PostMessageW(m_window, WM_PRIV_QUICK_LAYOUT_KEY, 0, static_cast<LPARAM>(digitPressed));
Trace::FancyZones::QuickLayoutSwitched(changeLayoutWhileNotDragging);
return true;
}
}
}
if (m_draggingState.IsDragging() && shift)
{
return true;
}
return false;
}
void FancyZones::ToggleEditor() noexcept
{
_TRACER_;
@ -739,19 +679,70 @@ void FancyZones::OnKeyboardInput(WPARAM /*flags*/, HRAWINPUT hInput) noexcept
return;
}
switch (input.value().vkKey)
USHORT key = input.value().vkKey;
switch (key)
{
case VK_SHIFT:
{
m_draggingState.SetShiftState(input.value().pressed);
}
break;
case VK_CONTROL:
{
m_draggingState.SetCtrlState(input.value().pressed);
}
break;
case VK_RIGHT:
case VK_LEFT:
case VK_UP:
case VK_DOWN:
{
bool const win = GetAsyncKeyState(VK_LWIN) & 0x8000 || GetAsyncKeyState(VK_RWIN) & 0x8000;
bool const ctrl = GetAsyncKeyState(VK_CONTROL) & 0x8000;
if (win && ShouldProcessSnapHotkey(key))
{
Trace::FancyZones::OnKeyDown(key, win, ctrl, false /*inMoveSize*/);
// Win+Left, Win+Right will cycle through Zones in the active ZoneSet when WM_PRIV_SNAP_HOTKEY's handled
PostMessageW(m_window, WM_PRIV_SNAP_HOTKEY, 0, key);
}
}
break;
default:
{
if (FancyZonesSettings::settings().quickLayoutSwitch && input.value().pressed)
{
int digitPressed = -1;
if ('0' <= key && key <= '9')
{
digitPressed = key - '0';
}
else if (VK_NUMPAD0 <= key && key <= VK_NUMPAD9)
{
digitPressed = key - VK_NUMPAD0;
}
bool const shift = GetAsyncKeyState(VK_SHIFT) & 0x8000;
bool const win = GetAsyncKeyState(VK_LWIN) & 0x8000 || GetAsyncKeyState(VK_RWIN) & 0x8000;
bool const alt = GetAsyncKeyState(VK_MENU) & 0x8000;
bool const ctrl = GetAsyncKeyState(VK_CONTROL) & 0x8000;
bool dragging = m_draggingState.IsDragging();
bool changeLayoutWhileNotDragging = !dragging && !shift && win && ctrl && alt && digitPressed != -1;
bool changeLayoutWhileDragging = dragging && digitPressed != -1;
if (changeLayoutWhileNotDragging || changeLayoutWhileDragging)
{
auto layoutId = LayoutHotkeys::instance().GetLayoutId(digitPressed);
if (layoutId.has_value())
{
PostMessageW(m_window, WM_PRIV_QUICK_LAYOUT_KEY, 0, static_cast<LPARAM>(digitPressed));
Trace::FancyZones::QuickLayoutSwitched(changeLayoutWhileNotDragging);
}
}
}
}
break;
}
}

View File

@ -37,15 +37,6 @@ interface __declspec(uuid("{2CB37E8F-87E6-4AEC-B4B2-E0FDC873343F}")) IFancyZones
*/
IFACEMETHOD_(void, HandleWinHookEvent)
(const WinHookEvent* data) = 0;
/**
* Process keyboard event.
*
* @param info Information about low level keyboard event.
* @returns Boolean indicating if this event should be passed on further to other applications
* in event chain, or should it be suppressed.
*/
IFACEMETHOD_(bool, OnKeyDown)
(PKBDLLHOOKSTRUCT info) = 0;
};
winrt::com_ptr<IFancyZones> MakeFancyZones(HINSTANCE hinstance, std::function<void()> disableCallback) noexcept;