0

So I setup windows hook for EVENT_SYSTEM_FOREGROUND event then in order to receive events from windows there must be message loop in the same thread, this requires setting up a window or using GetMessage()(this is not really an option for this case, because I listen for all windows, not just one). When I create message box with MessageBoxW() everything works fine, but this method is kinda ugly because box appears on the screen. I found out that I can create hidden window with CreateWindowExW(), after a while of experiments window was finally created but no events were passed to callback. I tried to create HWND_MESSAGE window which as described in Windows docs should be used for only messaging window, as well as random dummy window, but neither of them works.
Here's how it looks like:

...
// setting up event hook
let hook = unsafe {
    SetWinEventHook(
        EVENT_SYSTEM_FOREGROUND,
        EVENT_SYSTEM_FOREGROUND,
        None,
        Some(win_event_hook_callback),
        0,
        0,
        0,
    )
};

if hook.0 == 0 {
    panic!("Could not setup WinEventHook");
}

info!("WinEventHook setup successful!");

// setting up class for window
let mut wc = WNDCLASSW::default();
let class_name = w!("randomclassname123");
wc.lpszClassName = class_name;
wc.lpfnWndProc = Some(window_proc);
wc.style = CS_GLOBALCLASS;
let wc_ptr: *const WNDCLASSW = &wc;

// registering class
let result = unsafe { RegisterClassW(wc_ptr) };

info!("RESULT: {:#?}", result);

// creating window
let hwnd: HWND = unsafe {
    CreateWindowExW(
        WS_EX_TOOLWINDOW,
        wc.lpszClassName,
        w!("TITLE"),
        WS_OVERLAPPEDWINDOW,
        0,
        0,
        1000,
        1000,
        None,
        None,
        None,
        None,
    )
};
info!("HWND: {:#?}", &hwnd);

// sleeping to not to close thread immediately
std::thread::sleep(Duration::from_millis(40000));
...
dalvi
  • 27
  • 5
  • 1
    The OS makes the callback on the same thread that called SetWinEventHook(). Very nice, but can't happen when you make that thread catatonic on that sleep() call. The window is quite dead as well. Message loop required, call GetMessage/DispatchMessage(). – Hans Passant Jul 01 '23 at 12:04
  • Hmmm. Now I set things up in the main thread, without sleep(), but poiling function as future along with server future. I can get one message, and then after a few seconds app crashes with `STATUS_STACK_BUFFER_OVERRUN` error on, as I see with `RUST_BACKTRACE` `GetMessageW` call – dalvi Jul 01 '23 at 12:55
  • 1
    Something wrong with win_event_hook_callback(), probably. I can't see it. Must be stdcall in 32-bit code. – Hans Passant Jul 01 '23 at 13:20
  • this callback was working absolutely fine with `MessageBoxW()`, can it really be the problem? – dalvi Jul 01 '23 at 13:25
  • Actually you are right. Because in `win_event_hook_callback()` I send my event to another place with unbounded channel, but before setting hook up I forgot to store unbounded sender in local thread storage. Now when I fixed that it works! Thank you! – dalvi Jul 01 '23 at 13:29

0 Answers0