行业知识
rust - windows窗口消息循环处理
2025-11-08 05:06:11
来源:互联网转载
���文给出了一个通用的windows窗口消息循环的实现,示例如下
()定义窗口类
use windows::{ core::*, Win32::Foundation::*, Win32::System::DataExchange::*, Win32::System::LibraryLoader::GetModuleHandleA, Win32::UI::WindowsAndMessaging::*, Win32_UI_WindowsAndMessaging,};struct Window { handle: HWND, // 窗口句柄 // todo 可以定义一些消息处理需要的参数}impl Window { pub fn new() -> Result { Ok(Window { handle: HWND(0) }) } pub fn run(&mut self) -> Result { unsafe { // 检索指定模块的模块句柄 let instance = GetModuleHandleA(None)?; debug_assert!(instance.0 != 0); let window_class = s!("WindowsDemo"); // 窗口类属性 let wc = WNDCLASSA { // 实例的句柄,该实例包含类的窗口过程。 hInstance: instance.into(), // HMODULE -> HINSTANCE // 窗口类名 lpszClassName: window_class, // 指向窗口过程的指针。 必须使用 CallWindowProc 函数调用窗口过程。 lpfnWndProc: Some(Self::wndproc), ..Default::default() }; // 注册一个窗口类 let atom = RegisterClassA(&wc); debug_assert!(atom != 0); let handle = CreateWindowExA( WINDOW_EX_STYLE::default(), window_class, s!("Demo"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, None, None, instance, Some(self as *mut _ as _), // 用于窗口内全局变量共享 ); debug_assert!(handle.0 != 0); debug_assert!(handle == self.handle); // 从调用线程的消息队列中检索消息 let mut msg = MSG::default(); // 从线程消息中取出一条消息 while GetMessageA(&mut msg, HWND(0), 0, 0).into() { // 把取出的消息发送到目的窗口 TranslateMessage(&msg); DispatchMessageA(&msg); } Ok(()) } Ok(()) } 定义当前窗口的处理过程
extern "system" fn wndproc( window: HWND, message: u32, wparam: WPARAM, lparam: LPARAM, ) -> LRESULT { unsafe { if message == WM_NCCREATE { // 获得窗口创建参数 let cs = lparam.0 as *const CREATESTRUCTA; let this = (*cs).lpCreateParams as *mut Self; (*this).handle = window; // 设置与窗口关联的用户数据 SetWindowLongPtrA(window, GWLP_USERDATA, this as _); } else if message == WM_PAINT { // todo 自行处理窗口绘制 _ = ValidateRect(window, None); } else { // 获得窗口关联的用户数据 let this = GetWindowLongPtrA(window, GWLP_USERDATA) as *mut Self; // 处理接收到的窗口消息 if !this.is_null() { return (*this).message_handler(message, wparam, lparam); } } // 调用默认窗口过程,为应用程序不处理的任何窗口消息提供默认处理。 DefWindowProcA(window, message, wparam, lparam) } } 定义业务逻辑相关的消息处理函数
fn message_handler( &mut self, message: u32, wparam: WPARAM, lparam: LPARAM, ) -> LRESULT { unsafe { match message { WM_CREATE => { // todo 添加业务逻辑 } WM_DESTROY => { PostQuitMessage(0) } WM_CLOSE => { return DefWindowProcA( self.handle, message, wparam, lparam, ); } // todo 添加其它的消息处理逻辑 _ => { return DefWindowProcA( self.handle, message, wparam, lparam, ); } } } LRESULT(0) } 参考
https://github.com/microsoft/windows-rs/tree/master/crates/tests
()