I am writing a function to create a window and I have provide the code which isn't working below. This code is using the windows crate and the latest version of rust (at time of writing rustc 1.74.0.
use std::ptr;
use windows::{
core::{w, PCWSTR},
Win32::{
Foundation::{GetLastError, HINSTANCE, HWND, LPARAM, LRESULT, WPARAM},
Graphics::Gdi::HBRUSH,
System::LibraryLoader::GetModuleHandleW,
UI::WindowsAndMessaging::{
CreateWindowExW, DefWindowProcW, DestroyWindow, PostQuitMessage, RegisterClassW,
CS_HREDRAW, CS_VREDRAW, CW_USEDEFAULT, HCURSOR, HICON, WINDOW_EX_STYLE, WNDCLASSW,
WS_OVERLAPPEDWINDOW,
},
},
};
fn main() {
match create_window() {
Ok(_) => {}
Err(e) => eprintln!("{}", e),
};
}
pub fn create_window() -> Result<(), Box<dyn std::error::Error>> {
let h_instance: HINSTANCE = unsafe { GetModuleHandleW(None) }?.into();
let lp_sz_class_name = w!("window_class");
let lp_sz_window_name = w!("window_title");
let window_class = WNDCLASSW {
style: CS_HREDRAW | CS_VREDRAW,
lpfnWndProc: Some(window_proc),
cbClsExtra: 0,
cbWndExtra: 0,
hInstance: h_instance,
hIcon: HICON(0),
hCursor: HCURSOR(0),
hbrBackground: HBRUSH(2),
lpszMenuName: PCWSTR(ptr::null_mut()),
lpszClassName: lp_sz_class_name,
};
if unsafe { RegisterClassW(&window_class) } == 0 {
unsafe { GetLastError() }?;
};
let hwnd = unsafe {
CreateWindowExW(
WINDOW_EX_STYLE(0),
window_class.lpszClassName,
lp_sz_window_name,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
None,
None,
window_class.hInstance,
None,
)
};
if hwnd == HWND(0) {
unsafe { GetLastError() }?;
}
Ok(())
}
unsafe extern "system" fn window_proc(
hwnd: HWND,
msg: u32,
wparam: WPARAM,
lparam: LPARAM,
) -> LRESULT {
match msg {
WM_CLOSE => {
unsafe { PostQuitMessage(0) };
unsafe { DestroyWindow(hwnd) };
LRESULT(0)
}
WM_DESTROY => {
unsafe { PostQuitMessage(0) };
LRESULT(0)
}
_ => return unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) },
}
}
When this code is running it produces this as an error "failed to create window > The parameter is incorrect. (0x80070057)". Indicating that a parameter to the function CreateWindowExW
isn't valid.
I've attempted isolate the parameters 1 by 1 but all have data, and I am unable to locate the invalid parameter. I was wondering if anyone can take a look and see if I have missed anything?
I expected the window class to be registered which is successful, and the handle to the window to be created which is unsuccessful.
I compiled the MRE you pasted and it produces this warning that is a big red flag:
The relevant code is in
window_proc
is like this:But the constants
WM_*
are unknown to the Rust compiler so this is actually equivalent to this:That is, this function always returns
LRESULT(0)
, no matter what message is processing. And as I commented before, one of the first messages a window function gets, even beforeCreateWindow
returns, isWM_NCCREATE
. But returning0
for that message will abort the window creation. The value returned byGetLastError()
will be whatever you set withSetLastError()
but you didn't call that, so you get meaningless error code.The solution is easy, just import the message constants:
That is why you should never ignore a Rust compiler warning. And why you should always add an MRE to a StackOverflow question!