|
-
May 30th, 2017, 06:33 AM
#1
Implementing Alt+Tab functionality using WH_KEYBOARD_LL hook.
I have the following code used in WH_KEYBOARD_LL hook:
Code:
#include <windows.h>
#include <string>
bool WindowSwitcherUIRun = false;
HWND WindowSwitcherUIHandle = 0;
//---------------------------------------------------------------------------
static void ShowErrorMessage(std::string Msg, const DWORD ErrorCode)
{
char ECStr[50] = {0};
itoa(ErrorCode, ECStr, 10);
Msg += ". Error code: " + std::string(ECStr) + ".";
MessageBoxA(0, Msg.c_str(), "AltTabHookInstaller", MB_OK | MB_ICONERROR);
}
//---------------------------------------------------------------------------
static void PressKey(const WORD Key)
{
KEYBDINPUT ki;
ki.wVk = Key;
ki.wScan = MapVirtualKeyA(Key, 0);
ki.dwFlags = 0;
ki.time = 0;
ki.dwExtraInfo = 0;
INPUT Input;
Input.type = INPUT_KEYBOARD;
Input.ki = ki;
SendInput(1, &Input, sizeof(INPUT));
}
//---------------------------------------------------------------------------
static void ReleaseKey(const WORD Key)
{
KEYBDINPUT ki;
ki.wVk = Key;
ki.wScan = MapVirtualKeyA(Key, 0);
ki.dwFlags = KEYEVENTF_KEYUP;
ki.time = 0;
ki.dwExtraInfo = 0;
INPUT Input;
Input.type = INPUT_KEYBOARD;
Input.ki = ki;
SendInput(1, &Input, sizeof(INPUT));
}
//---------------------------------------------------------------------------
static void SendKey(const WORD Key)
{
PressKey(Key);
ReleaseKey(Key);
}
//---------------------------------------------------------------------------
static LRESULT CALLBACK LowLevelKeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
DWORD Msg = wParam;
PKBDLLHOOKSTRUCT hs = (PKBDLLHOOKSTRUCT)lParam;
if ((Msg == WM_SYSKEYDOWN || Msg == WM_SYSKEYUP) && code >= 0 && hs->vkCode == VK_TAB)
{
if (!WindowSwitcherUIRun)
{
WindowSwitcherUIRun = (long long int)ShellExecuteA(
0,
"open",
"C:\\Users\\Default\\AppData\\Roaming\\Microsoft\\Internet Explorer\\Quick Launch\\Window Switcher.lnk",
0,
0,
SW_SHOW) > 32;
if (WindowSwitcherUIRun)
{
WindowSwitcherUIHandle = FindWindowA("TaskSwitcherWnd", 0);
}
}
else if ((hs->flags & LLKHF_UP) == 0)
{
if (SetForegroundWindow(WindowSwitcherUIHandle))
{
SendKey(VK_RIGHT);
}
}
return 1;
}
else if (WindowSwitcherUIRun && ((hs->flags & LLKHF_ALTDOWN) == 0))
{
WindowSwitcherUIRun = false;
ReleaseKey(VK_MENU);
if (SetForegroundWindow(WindowSwitcherUIHandle))
{
SendKey(VK_RETURN);
}
return 1;
}
return CallNextHookEx(0, code, wParam, lParam);
}
//---------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
HHOOK LLKeyHook = 0;
HANDLE Mutex = CreateMutex(0, 0, "AltTabHookInstalleMutex");
MSG Msg;
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
goto Return;
}
if (!(LLKeyHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)&LowLevelKeyboardProc, 0, 0)))
{
ShowErrorMessage("Couldn't install Alt Tab Hook", GetLastError());
goto Return;
}
while (GetMessage(&Msg, NULL, 0, 0) != 0)
{
}
Return:
if (Mutex)
{
CloseHandle(Mutex);
}
if (LLKeyHook)
{
UnhookWindowsHookEx(LLKeyHook);
}
return 0;
}
I run this application on a remote Windows 8 machine when I connect to it via AnyDesk.
Because the Alt+Tab functionality doesn't work when I connect via AnyDesk.
My question is why does SetForegroundWindow(WindowSwitcherUIHandle) fail with "Access is denied" error?
It only fails when the Alt+Tab is first pressed when a window not belonging to Explorer.exe is active/foreground.
Note: the Task Switcher window opened by ShellExecuteA() also belongs to Explorer.exe.
Thanks.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|