Native Windows GUI: Low level events

Winapi implements a bazillion of events and applications are free to define their own. There's no way for NWG to catch wrap them all. As a solution, NWG lets you use bind_raw_event_handler to hook the system event queue without parsing the parameters.

Using raw events handlers

fn log_resize(window: &Window) {
    use winapi::um::winuser::WM_SIZE;
    use winapi::shared::minwindef::{HIWORD, LOWORD};
    
    const MY_UNIQUE_RAW_HANDLER_ID: usize = 45776;

    bind_raw_event_handler(&window.handle, MY_UNIQUE_RAW_HANDLER_ID, |_hwnd, msg, _w, l| {
        match msg {
            WM_SIZE => {
                println!("w: {}, h: {}", LOWORD(l as u32), HIWORD(l as u32));
            },
            _ => {}
        }
    
        None
    });
}


Raw event handlers work in similar way as default events handers. It works by adding a callback to a window control. This callback then gets called everytime the control receives an event.

The parameters: The return value:

RawEventHandler works the same way as the normal event handler. This object is an opaque handle over the event hook and ignoring this value means that the callback and all its data will be leaked.

The callback:

The callback takes 4 arguments: HWND, MSG, WPARAM, and LPARAM which are the same value passed to the window procedures. This guide assumes you already know how to use them.

The callback also lets you pass a value back to the OS. If None is returned, the internal handler will use DefSubclassProc and execute the next event handler on the control. If a Some value is returned, this value will be returned by the internal handler and the following handlers will not be called.

Events handlers are always executed from last added to first added. Ie, user hooks will be executed before any NWG hooks.

Freeing raw handlers

To free a raw event handler call: nwg::unbind_raw_event_handler(&handler)

Calling unbind twice or trying to unbind an handler after destroying its parent will cause the function to panic.

Checking if a raw handler is bound

If you are not sure if a raw event handler is bound and you don't want your application to panic, use the nwg::has_raw_handler(&handle, handler_id) method. Example:
let handler = bind_raw_event_handler(&handle, 9001, move |_hwnd, _msg, _w, _l| {
    None
});

assert!(has_raw_handler(&handle, 9001) == true);