我正在写一个函数来创建一个窗口,我提供了下面不能工作的代码。此代码使用windows crate和最新版本的rust(在编写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) },
}
}
字符串
当这段代码运行时,它会产生一个错误“创建窗口失败>参数不正确。(0x80070057)"。这表明函数CreateWindowExW
的参数无效。
我尝试了逐个隔离参数,但都有数据,我无法找到无效参数。我想知道是否有人可以看看,看看我是否错过了什么?
我期望窗口类注册成功,而窗口句柄创建失败。
1条答案
按热度按时间gpfsuwkq1#
我编译了你粘贴的MRE,它产生了这个警告,这是一个大红旗:
字符串
window_proc
中的相关代码是这样的:型
但是常量
WM_*
对于Rust编译器来说是未知的,所以这实际上等价于:型
也就是说,这个函数总是返回
LRESULT(0)
,不管处理的是什么消息。正如我之前评论的,窗口函数得到的第一条消息之一,甚至在CreateWindow
返回之前,是WM_NCCREATE
。但是为该消息返回0
将中止窗口创建。GetLastError()
返回的值将是您使用SetLastError()
设置的任何值,但是您没有调用它,所以你得到了无意义的错误代码。解决方案很简单,只需导入消息常量:
型
这就是为什么你永远不应该忽略Rust编译器的警告,以及为什么你应该总是在StackOverflow问题中添加一个MRE!