首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Windows上运行正式的SetWinEventHook示例代码?

如何在Windows上运行正式的SetWinEventHook示例代码?
EN

Stack Overflow用户
提问于 2022-03-16 13:43:51
回答 1查看 523关注 0票数 0

我想试着运行在https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwineventhook上给出的官方的https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwineventhook示例

代码语言:javascript
运行
复制
// Global variable.
HWINEVENTHOOK g_hook;

// Initializes COM and sets up the event hook.
//
void InitializeMSAA()
{
    CoInitialize(NULL);
    g_hook = SetWinEventHook(
        EVENT_SYSTEM_MENUSTART, EVENT_SYSTEM_MENUEND,  // Range of events (4 to 5).
        NULL,                                          // Handle to DLL.
        HandleWinEvent,                                // The callback.
        0, 0,              // Process and thread IDs of interest (0 = all)
        WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); // Flags.
}

// Unhooks the event and shuts down COM.
//
void ShutdownMSAA()
{
    UnhookWinEvent(g_hook);
    CoUninitialize();
}

// Callback function that handles events.
//
void CALLBACK HandleWinEvent(HWINEVENTHOOK hook, DWORD event, HWND hwnd,
                             LONG idObject, LONG idChild,
                             DWORD dwEventThread, DWORD dwmsEventTime)
{
    IAccessible* pAcc = NULL;
    VARIANT varChild;
    HRESULT hr = AccessibleObjectFromEvent(hwnd, idObject, idChild, &pAcc, &varChild);  
    if ((hr == S_OK) && (pAcc != NULL))
    {
        BSTR bstrName;
        pAcc->get_accName(varChild, &bstrName);
        if (event == EVENT_SYSTEM_MENUSTART)
        {
            printf("Begin: ");
        }
        else if (event == EVENT_SYSTEM_MENUEND)
        {
            printf("End:   ");
        }
        printf("%S\n", bstrName);
        SysFreeString(bstrName);
        pAcc->Release();
    }
}

我想使用Visual编译并运行这个程序,所以我创建了一个包含内容的Windows Console Application Project

代码语言:javascript
运行
复制
#include <windows.h>
#include <iostream>
#include <conio.h>
#include <oleacc.h>

// Global variable.
HWINEVENTHOOK g_hook;

// Initializes COM and sets up the event hook.
//
void HandleWinEvent(HWINEVENTHOOK, DWORD, HWND,
    LONG, LONG,
    DWORD, DWORD);

void InitializeMSAA()
{
    HRESULT hrCoInit = CoInitialize(NULL);
    g_hook = SetWinEventHook(
        EVENT_SYSTEM_MENUSTART, EVENT_SYSTEM_MENUEND,  // Range of events (4 to 5).
        NULL,                                          // Handle to DLL.
        HandleWinEvent,                                // The callback.
        0, 0,              // Process and thread IDs of interest (0 = all)
        WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); // Flags.
}

// Unhooks the event and shuts down COM.
//
void ShutdownMSAA()
{
    UnhookWinEvent(g_hook);
    CoUninitialize();
}

// Callback function that handles events.
//
void CALLBACK HandleWinEvent(HWINEVENTHOOK hook, DWORD event, HWND hwnd,
    LONG idObject, LONG idChild,
    DWORD dwEventThread, DWORD dwmsEventTime)
{
    IAccessible* pAcc = NULL;
    VARIANT varChild;
    HRESULT hr = AccessibleObjectFromEvent(hwnd, idObject, idChild, &pAcc, &varChild);
    if ((hr == S_OK) && (pAcc != NULL))
    {
        BSTR bstrName;
        pAcc->get_accName(varChild, &bstrName);
        if (event == EVENT_SYSTEM_MENUSTART)
        {
            printf("Begin: ");
        }
        else if (event == EVENT_SYSTEM_MENUEND)
        {
            printf("End:   ");
        }
        printf("%S\n", bstrName);
        SysFreeString(bstrName);
        pAcc->Release();
    }
}

int main()
{
    std::cout << "Hello World!\n";
    InitializeMSAA();
    MSG msg;
    
    while (1) {
        //if (_getch() == 'q') {
        //    break;
        //}
        GetMessage(&msg, NULL, 0, 0);
        TranslateMessage(&msg);
        DispatchMessage(&msg);
     }
    ShutdownMSAA();
    return 0;
}

此代码运行良好,但未检测到事件。我试图通过打开和关闭“开始”菜单来生成事件。

如何使这个示例代码工作?

EN

回答 1

Stack Overflow用户

发布于 2022-03-29 02:40:49

根据EVENT_SYSTEM_MENUSTART和EVENT_SYSTEM_MENUEND在正式文件中的解释。

系统将此事件发送给标准菜单,这些菜单由HMENU、使用菜单模板资源创建的或Win32菜单API元素标识。

正如@Remy所说,“运行一个单独的有菜单的GUI应用程序”。

控制台程序启动后,可以使用菜单运行Win32桌面应用程序。

我修改了您的代码以在VS2019中运行。在HandleWinEvent前面添加了回调。

代码语言:javascript
运行
复制
#pragma comment(lib,"Oleacc.lib")
// Global variable.
HWINEVENTHOOK g_hook;

// Initializes COM and sets up the event hook.
//
void CALLBACK HandleWinEvent(HWINEVENTHOOK, DWORD, HWND, LONG, LONG, DWORD, DWORD);

这是我的测试结果

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71498135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档