使用SetWindowsHookEx观察打开的窗口

约翰尼斯·史翠克(Johannes Stricker)

我正在尝试观察带有全局Windows挂钩的打开和关闭窗口。因此,我试图将回调函数传递给包含钩子过程的DLL。但是,钩子过程本身从未被调用。

/** Handle to this DLL */
HINSTANCE dllModule = 0;
/** Hook procedure */
HHOOK windowHook = 0;
/** Callbacks are called when a new window is opened, or closed. */
HWND_CALLBACK windowOpenCallback = 0;
HWND_CALLBACK windowCloseCallback = 0;

WINDOWHOOK_API int WINAPI DllMain(HINSTANCE hInstance, DWORD reason, LPVOID reserved)
{
    if(reason == DLL_PROCESS_ATTACH)
    {
        dllModule = hInstance;
        std::cout << "Process attached." << std::endl;
    }
    else if (reason == DLL_PROCESS_DETACH)
    {
        std::cout << "Process detached." << std::endl;
    }
    else if (reason == DLL_THREAD_ATTACH)
    {
    }
    else if (reason == DLL_THREAD_DETACH)
    {
    }
    return 1;
}

WINDOWHOOK_API bool setWindowHook(HWND_CALLBACK openCallback, HWND_CALLBACK closeCallback)
{
    if(windowHook != 0 || windowOpenCallback != 0 || windowCloseCallback != 0)
    {
        return false;
    }
    windowOpenCallback = openCallback;
    windowCloseCallback = closeCallback;
    windowHook = SetWindowsHookEx(WH_SHELL, (HOOKPROC)hookCallback, dllModule, 0);

    return windowHook != 0;
}

WINDOWHOOK_API bool releaseWindowHook()
{
    bool result = windowHook != 0 && UnhookWindowsHookEx(windowHook) != 0;

    windowHook = 0;
    windowOpenCallback = 0;
    windowCloseCallback = 0;

    return result;
}

LRESULT CALLBACK hookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
    std::cout << "Hook callback" << std::endl;

    return CallNextHookEx(windowHook, nCode, wParam, lParam);
}

从主程序中,加载库并调用setWindowHook过程。然后,我简单地开始一个无限循环并等待钩子被调用,但是尽管setWindowHook不会失败,但是从不调用该钩子过程。我不明白为什么。

我尝试设置WH_KEYBOARD挂钩。这样,钩子程序就在按键上被调用,但前提是它们在我程序的控制台窗口中。

我正在64位计算机上将其编译为32位。但是,它至少不应该对我所有的32位应用程序都有效吗?

提前致谢。

约翰尼斯·史翠克(Johannes Stricker)

谢谢,我让它可以与DLL和SetWindowsHookEx一起使用,但是SetWinEventHook解决方案可以更好地工作,并且您不需要DLL。唯一的问题是,WINEVENTHOOK没有可将类实例传递给的LPVOID指针属性。因此,如果您正在寻找一种面向对象的方法,并且为此感到吃力,那么此codeproject链接可能会有所帮助。

还要确保,无论您从哪个线程设置钩子,都将发生消息循环,否则您将不会收到任何事件。

while (!stopped)
{
    if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
    {
        // you don't have to do anything here
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用JavaFX打开多个窗口

来自分类Dev

使用窗口打开的Javascript Mailto

来自分类Dev

使用脚本注入打开的窗口

来自分类Dev

使用Java打开终端窗口

来自分类Dev

使用Jquery打开模式窗口

来自分类Dev

使用SwiftUI观察窗口调整大小事件

来自分类Dev

使用jQuery的each()打开下载窗口

来自分类Dev

使用AppleScript打开新的Finder窗口

来自分类Dev

使用jQuery打开侧边栏窗口

来自分类Dev

使用帖子数据打开弹出窗口

来自分类Dev

使用自动对焦打开模式弹出窗口

来自分类Dev

如何使用JQuery打开弹出窗口?

来自分类Dev

使用按钮打开WPF弹出窗口

来自分类Dev

JavaFX使用fxml打开新窗口问题

来自分类Dev

如何使用Selenium Python打开新窗口

来自分类Dev

如何使用ClojureScript打开新窗口?

来自分类Dev

不使用JS怎么打开新窗口

来自分类Dev

Javascript-窗口打开,使用CDN

来自分类Dev

使用AppleScript打开新的Finder窗口

来自分类Dev

使用ffplay在特定窗口位置打开视频

来自分类Dev

使用Python打开sub-cmd窗口

来自分类Dev

使用Shell脚本打开和平铺窗口

来自分类Dev

使用JavaScript打开特定大小的窗口

来自分类Dev

Javascript提示窗口无法使用if语句打开

来自分类Dev

使用javascript .link()方法打开弹出窗口

来自分类Dev

无法使用Javascript打开新窗口

来自分类Dev

使用jQuery的each()打开下载窗口

来自分类Dev

使用Java打开文件的属性窗口

来自分类Dev

散景:使用 CustomJS 打开新窗口