系统事件 EVENT_SYSTEM_SWITCHSTART 和 EVENT_SYSTEM_SWITCHEND 在 Windows 7 中有效,但在 Windows 10 中无效
The system events EVENT_SYSTEM_SWITCHSTART and EVENT_SYSTEM_SWITCHEND works in Windows 7 but not in Windows 10
添加信息:
当我在 Windows 7 中使用我的 .exe 文件时,一切正常。它在 Windows 10 中不起作用。我不明白为什么。
原版post:
可能我只是需要更多的咖啡... ...但我正在尝试编写一个小程序来监听 Alt+Tab 事件。所以我添加了 SetWinEventHook 来监听 EVENT_SYSTEM_SWITCHSTART 和 EVENT_SYSTEM_SWITCHEND。因为这就是我认为根据 MSDN 执行此操作的方法:SetWinEventHook, WinEventProc callback, Event constants
出于某种原因,这些事件似乎从未触发过。但更有可能我遗漏了什么。
当我没有让它在我的实际应用程序中工作时,我创建了这个小应用程序来测试它。它在那里也不起作用。但其他事件确实有效。 EVENT_SYSTEM_FOREGROUND、EVENT_OBJECT_CREATE 和
EVENT_OBJECT_DESTROY 经常发生。
我的小测试应用程序的代码:
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
namespace
{
HWINEVENTHOOK sTabHook;
HWINEVENTHOOK sFocusHook;
HWINEVENTHOOK sCreateHook;
}
void CALLBACK tabEventProc(HWINEVENTHOOK hook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
printf("Never happens!");
if (EVENT_SYSTEM_SWITCHSTART == event)
{
printf("Tab start\n");
}
else if (EVENT_SYSTEM_SWITCHEND == event)
{
printf("Tab end\n");
}
}
void CALLBACK focusEventProc(HWINEVENTHOOK hook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
printf("Window focused\n");
}
void CALLBACK createEventProc(HWINEVENTHOOK hook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
if (EVENT_OBJECT_CREATE == event)
{
printf("Object created\n");
}
else if (EVENT_OBJECT_DESTROY == event)
{
printf("Object destroyed\n");
}
}
DWORD WINAPI threadProc()
{
sTabHook = SetWinEventHook(EVENT_SYSTEM_SWITCHSTART, EVENT_SYSTEM_SWITCHEND, nullptr, tabEventProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); //no ice, no napkins, no soda, no salt, no pepper... no quaso, NOTHING!
sFocusHook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, nullptr, focusEventProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
sCreateHook = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_DESTROY, nullptr, createEventProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
MSG message;
while (GetMessage(&message, nullptr, 0, 0)) {
TranslateMessage(&message);
DispatchMessage(&message);
}
UnhookWinEvent(sTabHook);
UnhookWinEvent(sFocusHook);
UnhookWinEvent(sCreateHook);
return 0;
}
int main()
{
HANDLE threadHandle;
DWORD thread;
threadHandle = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)threadProc, 0, 0, &thread);
if (threadHandle)
{
return WaitForSingleObject(threadHandle, INFINITE);
}
else
{
return 1;
}
return 0;
}
当我点击 windows 和 opening/closing windows。但是当 alt+tab 到其他应用程序时,tabEventProc 没有打印输出。
如果我在方法中放置断点,情况相同。它从不在 tabEventProc 内部中断,但在其他两种方法中始终如此。
有人可以告诉我我做错了什么吗?因为 Google Wan Kenobi 无法帮助我。我真的很困惑。
我使用的是 Windows 10 和 Visual Studio 2017 社区版。该项目是从 Visual Studios "create new project" 模板创建的标准 C++ 控制台项目。
好的。所以我想你必须遵守丑陋的黑客才能使 Alt-Tab 检测在 Windows 10.
上工作
这是我最终得到的丑陋解决方案:
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <string>
namespace
{
HINSTANCE sInstance = GetModuleHandle(nullptr);
HHOOK sTabHook;
HWINEVENTHOOK sFocusHook;
bool sAltTabHappend = false;
}
LRESULT CALLBACK tabEventProc(int nCode, WPARAM wParam, LPARAM lParam)
{
auto kbdLlHookStruct = (KBDLLHOOKSTRUCT*)lParam;
switch (nCode)
{
case HC_ACTION:
{
if (kbdLlHookStruct->vkCode == VK_TAB && kbdLlHookStruct->flags & LLKHF_ALTDOWN)
{
printf("Alt-Tab\n");
sAltTabHappend = true;
}
}
}
return CallNextHookEx(sTabHook, nCode, wParam, lParam);
}
void CALLBACK focusEventProc(HWINEVENTHOOK hook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
if (!sAltTabHappend)
{
return;
}
char windowTitleOut[256];
GetWindowTextA(hwnd, windowTitleOut, sizeof(windowTitleOut));
std::string windowTitle(windowTitleOut);
if (windowTitle.empty() || 0 == windowTitle.compare("Task Switching"))
{
return;
}
printf("You just canged to %s by Alt-tabbing... yeah...\n", windowTitleOut);
sAltTabHappend = false;
}
DWORD WINAPI threadProc()
{
sTabHook = SetWindowsHookEx(WH_KEYBOARD_LL, tabEventProc, sInstance, 0);
sFocusHook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, nullptr, focusEventProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
MSG message;
while (GetMessage(&message, nullptr, 0, 0)) {
TranslateMessage(&message);
DispatchMessage(&message);
}
UnhookWindowsHookEx(sTabHook);
UnhookWinEvent(sFocusHook);
return 0;
}
int main()
{
HANDLE threadHandle;
DWORD thread;
threadHandle = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)threadProc, 0, 0, &thread);
if (threadHandle)
{
return WaitForSingleObject(threadHandle, INFINITE);
}
else
{
return 1;
}
return 0;
}
因此,我没有连接到 EVENT_SYSTEM_SWITCHSTART 和 EVENT_SYSTEM_SWITCHEND,而是连接到 WH_KEYBOARD_LL 与 SetWindowsHookEx。然后我检查 Alt+Tab 按键组合。如果发生这种情况,我将其保存到静态变量并在 EVENT_SYSTEM_FOREGROUND 处检查之前是否发生过 Alt+Tab 然后 assume我们 Alt+Tab 切换到 window.
我真的很讨厌这个解决方案,因为它不能保证焦点 window 是我们切换到的那个。必须有更好的方法。
它没有回答为什么 EVENT_SYSTEM_SWITCHSTART 和 EVENT_SYSTEM_SWITCHEND 对 Windows10.
添加信息:
当我在 Windows 7 中使用我的 .exe 文件时,一切正常。它在 Windows 10 中不起作用。我不明白为什么。
原版post:
可能我只是需要更多的咖啡... ...但我正在尝试编写一个小程序来监听 Alt+Tab 事件。所以我添加了 SetWinEventHook 来监听 EVENT_SYSTEM_SWITCHSTART 和 EVENT_SYSTEM_SWITCHEND。因为这就是我认为根据 MSDN 执行此操作的方法:SetWinEventHook, WinEventProc callback, Event constants
出于某种原因,这些事件似乎从未触发过。但更有可能我遗漏了什么。
当我没有让它在我的实际应用程序中工作时,我创建了这个小应用程序来测试它。它在那里也不起作用。但其他事件确实有效。 EVENT_SYSTEM_FOREGROUND、EVENT_OBJECT_CREATE 和 EVENT_OBJECT_DESTROY 经常发生。
我的小测试应用程序的代码:
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
namespace
{
HWINEVENTHOOK sTabHook;
HWINEVENTHOOK sFocusHook;
HWINEVENTHOOK sCreateHook;
}
void CALLBACK tabEventProc(HWINEVENTHOOK hook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
printf("Never happens!");
if (EVENT_SYSTEM_SWITCHSTART == event)
{
printf("Tab start\n");
}
else if (EVENT_SYSTEM_SWITCHEND == event)
{
printf("Tab end\n");
}
}
void CALLBACK focusEventProc(HWINEVENTHOOK hook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
printf("Window focused\n");
}
void CALLBACK createEventProc(HWINEVENTHOOK hook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
if (EVENT_OBJECT_CREATE == event)
{
printf("Object created\n");
}
else if (EVENT_OBJECT_DESTROY == event)
{
printf("Object destroyed\n");
}
}
DWORD WINAPI threadProc()
{
sTabHook = SetWinEventHook(EVENT_SYSTEM_SWITCHSTART, EVENT_SYSTEM_SWITCHEND, nullptr, tabEventProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); //no ice, no napkins, no soda, no salt, no pepper... no quaso, NOTHING!
sFocusHook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, nullptr, focusEventProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
sCreateHook = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_DESTROY, nullptr, createEventProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
MSG message;
while (GetMessage(&message, nullptr, 0, 0)) {
TranslateMessage(&message);
DispatchMessage(&message);
}
UnhookWinEvent(sTabHook);
UnhookWinEvent(sFocusHook);
UnhookWinEvent(sCreateHook);
return 0;
}
int main()
{
HANDLE threadHandle;
DWORD thread;
threadHandle = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)threadProc, 0, 0, &thread);
if (threadHandle)
{
return WaitForSingleObject(threadHandle, INFINITE);
}
else
{
return 1;
}
return 0;
}
当我点击 windows 和 opening/closing windows。但是当 alt+tab 到其他应用程序时,tabEventProc 没有打印输出。
如果我在方法中放置断点,情况相同。它从不在 tabEventProc 内部中断,但在其他两种方法中始终如此。
有人可以告诉我我做错了什么吗?因为 Google Wan Kenobi 无法帮助我。我真的很困惑。
我使用的是 Windows 10 和 Visual Studio 2017 社区版。该项目是从 Visual Studios "create new project" 模板创建的标准 C++ 控制台项目。
好的。所以我想你必须遵守丑陋的黑客才能使 Alt-Tab 检测在 Windows 10.
上工作这是我最终得到的丑陋解决方案:
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <string>
namespace
{
HINSTANCE sInstance = GetModuleHandle(nullptr);
HHOOK sTabHook;
HWINEVENTHOOK sFocusHook;
bool sAltTabHappend = false;
}
LRESULT CALLBACK tabEventProc(int nCode, WPARAM wParam, LPARAM lParam)
{
auto kbdLlHookStruct = (KBDLLHOOKSTRUCT*)lParam;
switch (nCode)
{
case HC_ACTION:
{
if (kbdLlHookStruct->vkCode == VK_TAB && kbdLlHookStruct->flags & LLKHF_ALTDOWN)
{
printf("Alt-Tab\n");
sAltTabHappend = true;
}
}
}
return CallNextHookEx(sTabHook, nCode, wParam, lParam);
}
void CALLBACK focusEventProc(HWINEVENTHOOK hook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
if (!sAltTabHappend)
{
return;
}
char windowTitleOut[256];
GetWindowTextA(hwnd, windowTitleOut, sizeof(windowTitleOut));
std::string windowTitle(windowTitleOut);
if (windowTitle.empty() || 0 == windowTitle.compare("Task Switching"))
{
return;
}
printf("You just canged to %s by Alt-tabbing... yeah...\n", windowTitleOut);
sAltTabHappend = false;
}
DWORD WINAPI threadProc()
{
sTabHook = SetWindowsHookEx(WH_KEYBOARD_LL, tabEventProc, sInstance, 0);
sFocusHook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, nullptr, focusEventProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
MSG message;
while (GetMessage(&message, nullptr, 0, 0)) {
TranslateMessage(&message);
DispatchMessage(&message);
}
UnhookWindowsHookEx(sTabHook);
UnhookWinEvent(sFocusHook);
return 0;
}
int main()
{
HANDLE threadHandle;
DWORD thread;
threadHandle = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)threadProc, 0, 0, &thread);
if (threadHandle)
{
return WaitForSingleObject(threadHandle, INFINITE);
}
else
{
return 1;
}
return 0;
}
因此,我没有连接到 EVENT_SYSTEM_SWITCHSTART 和 EVENT_SYSTEM_SWITCHEND,而是连接到 WH_KEYBOARD_LL 与 SetWindowsHookEx。然后我检查 Alt+Tab 按键组合。如果发生这种情况,我将其保存到静态变量并在 EVENT_SYSTEM_FOREGROUND 处检查之前是否发生过 Alt+Tab 然后 assume我们 Alt+Tab 切换到 window.
我真的很讨厌这个解决方案,因为它不能保证焦点 window 是我们切换到的那个。必须有更好的方法。
它没有回答为什么 EVENT_SYSTEM_SWITCHSTART 和 EVENT_SYSTEM_SWITCHEND 对 Windows10.