我正在编写一个函数来创建一个窗口,并且我提供了下面不起作用的代码。此代码使用 windows 板条箱和最新版本的 rust(在编写 rustc 1.74.0 时。
pub fn create_window() -> errors::Result<()> {
let h_instance: HINSTANCE = match unsafe { GetModuleHandleW(None) } {
Ok(h) => h.into(),
Err(e) => return make_error!("{}", e),
};
let lp_sz_class_name = w!("window_class");
let lp_sz_window_name = w!("window_title");
let window_class: WNDCLASSW = 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 {
match unsafe { GetLastError() } {
Err(e) => {
return make_error!("failed to register window class > {}", e);
}
_ => {}
}
};
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) {
match unsafe { GetLastError() } {
Err(e) => {
return make_error!("failed to create window > {}", e); // ERROR OCCURS HERE!!
}
_ => {}
};
}
Ok(())
}
当此代码运行时,它会生成错误“无法创建窗口 > 参数不正确。(0x80070057)”。指示函数
CreateWindowExW
的参数无效。
我尝试将参数一一隔离,但所有参数都有数据,并且我无法找到无效参数。我想知道是否有人可以看一下我是否错过了什么?
我期望成功注册窗口类,并创建不成功的窗口句柄。
warning: unreachable pattern
--> src/main.rs:82:9
|
77 | WM_CLOSE => {
| -------- matches any value
...
82 | WM_DESTROY => {
| ^^^^^^^^^^ unreachable pattern
|
= note: `#[warn(unreachable_patterns)]` on by default
相关代码在
window_proc
是这样的:
match msg {
WM_CLOSE => { /*... */ ; LRESULT(0) }
WM_DESTROY => { ... }
_ => DefWindowProcW(hwnd, msg, wparam, lparam),
}
但是常量
WM_*
对于 Rust 编译器来说是未知的,所以这实际上等价于:
match msg {
_ => { /*... */ ; LRESULT(0) }
/* blah, blah DefWindowProcW something that is never run */
}
也就是说,无论正在处理什么消息,该函数始终返回
LRESULT(0)
。正如我之前评论的,即使在
CreateWindow
返回之前,窗口函数收到的第一条消息也是 WM_NCCREATE
。但是返回该消息的
0
将中止窗口创建。 GetLastError()
返回的值将是您使用 SetLastError()
设置的值,但您没有调用它,因此您会得到毫无意义的错误代码。解决方案很简单,只需导入消息常量即可:
unsafe extern "system" fn window_proc(
hwnd: HWND,
msg: u32,
wparam: WPARAM,
lparam: LPARAM,
) -> LRESULT {
use windows::Win32::UI::WindowsAndMessaging::*; // <---- Here!
match msg {
WM_CLOSE => { ...
这就是为什么你永远不应该忽略 Rust 编译器警告。以及为什么您应该始终在 StackOverflow 问题中添加 MRE!