nexus\api/
wnd_proc.rs

1//! Windows [WNDPROC](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-wndproc).
2
3use crate::{revertible::Revertible, AddonApi, WndProcApi};
4use windows::Win32::Foundation::{HWND, LPARAM, LRESULT, WPARAM};
5
6pub type RawWndProcCallback =
7    extern "C-unwind" fn(h_wnd: HWND, u_msg: u32, w_param: WPARAM, l_param: LPARAM) -> u32;
8
9pub type RawWndProcAddRem = unsafe extern "C-unwind" fn(wnd_proc_callback: RawWndProcCallback);
10
11pub type RawWndProcSendToGame = unsafe extern "C-unwind" fn(
12    h_wnd: HWND,
13    u_msg: u32,
14    w_param: WPARAM,
15    l_param: LPARAM,
16) -> LRESULT;
17
18/// Registers a new [WNDPROC](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-wndproc) callback.
19///
20/// Returns a [`Revertible`] to revert the register.
21pub fn register_wnd_proc(
22    callback: RawWndProcCallback,
23) -> Revertible<impl Fn() + Send + Sync + Clone + 'static> {
24    let WndProcApi {
25        register,
26        deregister,
27        ..
28    } = AddonApi::get().wnd_proc;
29    unsafe { register(callback) };
30    let revert = move || unsafe { deregister(callback) };
31    revert.into()
32}
33
34/// Deregisters an already registered [WNDPROC](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-wndproc) callback.
35pub fn deregister_wnd_proc(callback: RawWndProcCallback) {
36    let WndProcApi { deregister, .. } = AddonApi::get().wnd_proc;
37    unsafe { deregister(callback) }
38}
39
40/// Sends a [WNDPROC](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-wndproc) directly to the game, bypassing other hooks.
41pub fn send_wnd_proc_to_game(h_wnd: HWND, u_msg: u32, w_param: WPARAM, l_param: LPARAM) -> LRESULT {
42    let WndProcApi {
43        send_to_game_only, ..
44    } = AddonApi::get().wnd_proc;
45    unsafe { send_to_game_only(h_wnd, u_msg, w_param, l_param) }
46}