我尝试用rust编写一个简单的windows应用程序,使用windows-rs crate。我想在Counter结构中封装一个状态,并将其传递给window_proc函数。它成功地检索指针并通过GWLP_USERDATA索引存储它。我的问题是,为什么它在WM_CREATE msg中没有错误地增加,但在WM_COMMAND msg中不起作用?
struct Counter {
counter: i32
}
fn main() -> Result<()> {
let lparam: *mut Counter = Box::leak(Box::new(Counter{
counter: 1
}));
unsafe {
let mut instance = Default::default();
GetModuleHandleExW(0, None, &mut instance)?;
let wnd_class = WNDCLASSEXW {
// ... ...
};
let atom = RegisterClassExW(&wnd_class);
debug_assert!(atom != 0);
let hwnd = CreateWindowExW(
// ... ...
Some(lparam as *mut c_void),
);
// ... ...
}
}
fn increase_and_print(parent: HWND) {
unsafe {
let ptr = GetWindowLongPtrW(parent, GWLP_USERDATA);
println!("GetWindowLongPtrW: {}", ptr);
let ptr = GetWindowLongPtrW(parent, GWLP_USERDATA) as *mut Box<Counter>;
debug_assert!(!ptr.is_null());
let c = &mut *ptr;
c.counter += 1;
println!("counter: {}", c.counter);
}
}
extern "system" fn window_proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT {
unsafe {
match msg {
WM_CREATE => {
// Create a click button
// Retrieve the pointer to your state and store it in the window's user data
SetWindowLongPtrW(hwnd, GWLP_USERDATA, lparam.0 as isize);
increase_and_print(hwnd);
LRESULT(0)
},
WM_DESTROY => {
PostQuitMessage(0);
LRESULT(0)
},
WM_COMMAND => {
increase_and_print(hwnd);
return LRESULT(0);
},
_ => DefWindowProcW(hwnd, msg, wparam, lparam)
}
}
}
字符串
计数器初始化为1,然后在WM_CREATE msg中增加到2。我希望它在单击按钮后打印3(即调用WM_COMMAND msg)控制台中的输出
GetWindowLongPtrW: 359815702944
counter: 2
GetWindowLongPtrW: 359815702944
thread 'main' panicked at 'misaligned pointer dereference: address must be a multiple of 0x4 but is 0xb', apps\counter\src\main.rs:73:9
1条答案
按热度按时间qni6mghb1#
我在GitHub上搜索由windows-rs创建的应用程序,最后我得到了这个robmikh/minesweeper-rs windows.rs。
将计数器设置为用户数据
字符串
计数器并更新其值
型
由于我是Rust的新手,如果有人能详细解释这一点,我将不胜感激。