Rust winapi RegisterHotKey

Hi,

I'm trying to use Rust along with the winapi = {version = "0.3", features = ["winuser"]} crate in order to register a hotkey

I've got this following code setup

use std::{
    ptr,
    thread,
    sync::{atomic::{AtomicBool, Ordering}, Arc},
};
use winapi::{
    shared::minwindef::{LPARAM, WPARAM},
    um::{winuser::{
        RegisterHotKey, TranslateMessage, DispatchMessageW, PeekMessageW,
        PM_REMOVE, MSG, MOD_WIN, MOD_NOREPEAT, WM_HOTKEY,
    }, errhandlingapi::GetLastError},
};

fn register_global_hotkey(stop_flag: Arc<AtomicBool>) {
    unsafe {
        let registered = RegisterHotKey(
            ptr::null_mut(),
            1,
            (MOD_WIN | MOD_NOREPEAT) as u32,
            's' as u32,
        );
        if registered == 0{
            println!("failed to register hotkey {}", GetLastError());
        }

        let mut msg = MSG {
            hwnd: ptr::null_mut(),
            message: 0,
            wParam: 0,
            lParam: 0,
            time: 0,
            pt: std::mem::zeroed(),
        };

        while !stop_flag.load(Ordering::Relaxed) {
            let peek_value = PeekMessageW(&mut msg, ptr::null_mut(), 0, 0, PM_REMOVE);
            if  peek_value != 0 {
                TranslateMessage(&msg);
                DispatchMessageW(&msg);

                if msg.message == WM_HOTKEY {
                    println!("Win + s pressed!");
                }
            }
            println!("Peek value {} Message Value: {:?}",peek_value, msg.message);
        }
    }
}

fn main() {
    let stop_flag = Arc::new(AtomicBool::new(false));
    let hotkey_thread = thread::spawn({
        let stop_flag = Arc::clone(&stop_flag);
        move || {
            register_global_hotkey(stop_flag);
        }
    });
    hotkey_thread.join().unwrap();
    return;
}

I'm not getting any errors but the output of

println!("Peek value {} Message Value: {}",peek_value, msg.message);

Is always

Peek value 0 Message Value: 0

Even if I'm pressing keys/clicking etc.

Does anyone have any idea what I have setup wrong here?

Thanks!

Try the other case.

Tested with the other case -

let registered = RegisterHotKey(
            ptr::null_mut(),
            1,
            (MOD_WIN | MOD_NOREPEAT) as u32,
            'S' as u32,
        );

But still have the same result

Peek value 0 Message Value: 0
Peek value 0 Message Value: 0
Peek value 0 Message Value: 0
Peek value 0 Message Value: 0
Peek value 0 Message Value: 0
Peek value 0 Message Value: 0
Peek value 0 Message Value: 0

I believe that 1 is a mistake. The code I have uses AddAtom to create a globally unique identifier.

This lead me down the right path, it ended up being the combination of characters I was using...

I swapped to [Win + Shift + 'Y'] and it is working!

let registered = RegisterHotKey(
            ptr::null_mut(),
            1,
            (MOD_WIN | MOD_SHIFT) as u32,
            'Y' as u32,
        );

So it must have been a conflict with a system hotkey maybe?

Fully working register_global_hotkey function -

fn register_global_hotkey(stop_flag: Arc<AtomicBool>) {
    unsafe {
        let registered = RegisterHotKey(
            ptr::null_mut(),
            1,
            (MOD_WIN | MOD_SHIFT) as u32,
            'Y' as u32,
        );
        if registered == 0{
            println!("failed to register hotkey {}", GetLastError());
        }

        let mut msg = MSG {
            hwnd: ptr::null_mut(),
            message: 0,
            wParam: 0,
            lParam: 0,
            time: 0,
            pt: std::mem::zeroed(),
        };

        while !stop_flag.load(Ordering::Relaxed) {
            let peek_value = PeekMessageW(&mut msg, ptr::null_mut(), 0, 0, PM_REMOVE);
            if  peek_value > 0 {
                TranslateMessage(&msg);
                DispatchMessageW(&msg);

                if msg.message == WM_HOTKEY {
                    println!("Win + s pressed!");
                }
                println!("Peek value {} Message Value: {}",peek_value, msg.message);
            }
        }
    }
}
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.