0

I'm new to rust and the windows API and I'm trying to use the PostMessage function using the windows-rs crate. However, I'm not sure what data type WPARAM expects. I've tried guessing since the windows-rs documentation doesn't seem to say. The official microsoft docs for C++ seem to expect the constants found below.. but I get an error when I try using them with the rust crate.

https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes

https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/UI/WindowsAndMessaging/fn.PostMessageA.html

https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postmessagea

use windows::{
    Win32::System::Threading::*, Win32::UI::WindowsAndMessaging::*, Win32::UI::Input::KeyboardAndMouse::*
};

fn main() {
    unsafe {
        Sleep(1000);
        let wh = GetActiveWindow();
        PostMessageA(wh, WM_KEYDOWN, VK_ADD, None);
    }
}

I get an error telling me that WPARAM doesn't have an implementation for "VIRTUAL_KEY". I've also tried using the hexdecimal for VK_ADD in various ways.. but each one throws errors about WPARAM not implementing the type I try to use.

PostMessageA(wh, WM_KEYDOWN, 0x6B, None);
PostMessageA(wh, WM_KEYDOWN, "0x6B", None);
let hex: u32 = 0x6B;
PostMessageA(wh, WM_KEYDOWN, hex, None);

I'm also not sure how to send the hexadecimal properly formatted either, so I'm probably doing that incorrectly. Does anyone have any ideas, or could anyone with a better understanding of rust check out the source code of the crate?

https://github.com/microsoft/windows-rs

Paul Dempsey
  • 639
  • 3
  • 19
herroh
  • 3
  • 3

1 Answers1

0

As @Jmb said in his comment, using WPARAM(VK_ADD.0 as _) should work, but you would also need to pass the LPARAM argument as required by the WM_KEYDOWN message, but if you simply want to send keyboard input then its better and easier to use SendInput

  • Thanks to both of you @Jmb and Ahmad. I'm able to compile now with the WPARAM as suggested. Is the LPARAM similar as well? ``` – herroh Dec 15 '21 at 07:23
  • And I have read about SendInput but I don't believe it's able to send input to windows that aren't active. – herroh Dec 15 '21 at 07:33
  • In the docs you linked it says LPARAM takes bits? So I guess it's a bitwise operator? I'm not sure how to pass that though. I'm still trying to figure that part out. – herroh Dec 15 '21 at 14:04
  • Yes the LPARAM is similar, just harder to do manually, as you will have to fill the required data bit by bit. There is a good chance that PostMessage will not work as intended (as it doesn't simulate a keypress perfectly), so you might need to used SendInput in the end depending on your use case, in that case you would to change the foreground window to the desired input window temporarily and then use SendInput. – Ahmad AlHallak Dec 15 '21 at 14:17
  • To fill the LPARAM you would need something like: `let l_param = repeat_count | (scan_code << 16) | (extended << 24) | (context_code << 29) | (previous_state << 30) | (transition_state << 31)` Note that I have not tested this, so be wary. And remember to send a `WM_KEYUP` message later, and keep in mind that `PostMessage` is asynchronous (unlike `SendMessage`), that means that your code won't wait for the message to process before continuing execution. – Ahmad AlHallak Dec 15 '21 at 14:25