Reputation: 10544
I want to try and run the official SetWinEventHook()
example given at https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwineventhook:
// 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();
}
}
I wanted to compile and run this using Visual Studio, so I created a Windows Console Application Project
with content:
#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;
}
This code is running fine, but is not detecting events. I am trying to generate events by opening and closing the Start Menu.
How can I make this example code work?
Upvotes: 0
Views: 2360
Reputation: 2979
According to the explanations for EVENT_SYSTEM_MENUSTART and EVENT_SYSTEM_MENUEND in the official documentation.
The system sends this event for standard menus, which are identified by HMENU, created using menu-template resources or Win32 menu API elements.
As @Remy Lebeau said, 'run a separate GUI app that has a menu'.
After your console program starts, you can run a Win32 desktop application with menu.
I modified your code to run in VS2019. Added CALLBACK in front of HandleWinEvent.
#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);
Here are my test results,
Upvotes: 1