小工具知识网

当前位置: 首页 > 行业知识 > rust - windows窗口消息循环处理

行业知识

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

()

上一篇:揭秘双眼皮手术费用真相,全方位了解价格与性价比!

下一篇:被套安装全攻略,视频教程助你轻松掌握安装技巧