gpt4 book ai didi

winapi - 如果我将wndproc函数分配给wndclass,则会发生错误

转载 作者:行者123 更新时间:2023-12-03 11:38:44 24 4
gpt4 key购买 nike

我用rust和winapi编码了简单的窗口应用程序。当我将DefWindowProcW函数分配给lpfnWndProc结构的WndClass字段时,代码可以正常工作。但是,当我分配我定义的WndProc函数时,该窗口不会出现,甚至不会出现用于异常处理的消息框。我想知道为什么它不起作用以及如何解决。
这是我定义的WndClass结构。

    let WndClass = WNDCLASSW {
style: CS_HREDRAW | CS_VREDRAW,
lpfnWndProc: Some( DefWindowProcW ),
cbClsExtra: 0,
cbWndExtra: 0,
hInstance,
hIcon: LoadIconW( null_mut(), IDC_ARROW ),
hCursor: LoadCursorW( null_mut() , IDI_APPLICATION ),
hbrBackground: GetStockObject(WHITE_BRUSH as i32) as HBRUSH,
lpszMenuName: null_mut(),
lpszClassName:lpszClass.as_ptr(),
};
这是完整的代码。
extern crate winapi;

use self::winapi::{
shared::{
windef::{HWND, HBRUSH},
minwindef::{LPARAM, WPARAM, UINT, LRESULT},
},
um::{
wingdi::{GetStockObject, WHITE_BRUSH},
libloaderapi::GetModuleHandleW,
winuser::{
RegisterClassW,
CreateWindowExW,
GetMessageW,
TranslateMessage,
DispatchMessageW,
PostQuitMessage,
DefWindowProcW,
LoadIconW,
LoadCursorW,
MessageBoxW,
ShowWindow,
MSG,
WS_OVERLAPPEDWINDOW,
WS_VISIBLE,
CW_USEDEFAULT,
WNDCLASSW,
SW_SHOWDEFAULT,
CS_HREDRAW,
CS_VREDRAW,
MB_OK,
IDC_ARROW,
IDI_APPLICATION
},
}
};

use std::ptr::{ null, null_mut };
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use std::iter::once;

#[cfg(windows)]
fn win32_string( value : &str ) -> Vec<u16> {
OsStr::new( value ).encode_wide().chain( once( 0 ) ).collect()
}

unsafe fn handle_message( handle: HWND, message: &mut MSG ) -> bool {
if GetMessageW(message, handle, 0, 0) > 0 {
TranslateMessage(message);
DispatchMessageW(message);
true
} else {
false
}
}

fn main() {
unsafe{
let mut hWnd: HWND;
let mut Message: MSG = std::mem::zeroed();
let mut hInstance = GetModuleHandleW( std::ptr::null_mut() );
let lpszClass = win32_string("First Window");
let mut g_hInst = hInstance;

let WndClass = WNDCLASSW {
style: CS_HREDRAW | CS_VREDRAW,
lpfnWndProc: Some( DefWindowProcW ),
cbClsExtra: 0,
cbWndExtra: 0,
hInstance,
hIcon: LoadIconW( null_mut(), IDC_ARROW ),
hCursor: LoadCursorW( null_mut() , IDI_APPLICATION ),
hbrBackground: GetStockObject(WHITE_BRUSH as i32) as HBRUSH,
lpszMenuName: null_mut(),
lpszClassName:lpszClass.as_ptr(),
};

RegisterClassW( &WndClass );

hWnd = CreateWindowExW(
0,
lpszClass.as_ptr(),
lpszClass.as_ptr(),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
null_mut(),
null_mut(),
hInstance,
null_mut()
);

if hWnd.is_null() {
let title = win32_string("Error!");
let text = win32_string("Creating window is faield");

let ret = MessageBoxW(0 as HWND, text.as_ptr(), title.as_ptr(), MB_OK);
} else {
loop {
if !handle_message(0 as HWND, &mut Message) {
break;
}
}
}
}
}

#[cfg(windows)]
unsafe extern "system" fn WndProc(hWnd: HWND, iMessage: UINT, wParam: WPARAM, lParam: LPARAM) -> LRESULT {
match iMessage {
WM_DESTROY => {
PostQuitMessage(0);
0
},
_ => DefWindowProcW(hWnd, iMessage, wParam, lParam)
}
}

最佳答案

如果使用类似if的条件,则不会引用此win32常量WM_DESTROY:

if iMessage == WM_DESTROY {
PostQuitMessage(0);
}
然后,您将得到编译错误:
error[E0425]: cannot find value `WM_DESTROY` in this scope
只需添加 WM_DESTROY:
use self::winapi::{
shared::{
windef::{HWND, HBRUSH},
minwindef::{LPARAM, WPARAM, UINT, LRESULT,ATOM},
},
um::{
errhandlingapi::GetLastError,
wingdi::{GetStockObject, WHITE_BRUSH},
libloaderapi::GetModuleHandleW,
winuser::{
RegisterClassW,
...,
IDI_APPLICATION,
WM_DESTROY
},
}
};
另外,创建窗口后,需要显示带有 ShowWindow的窗口:
...
lpfnWndProc: Some( WndProc ),
...
if hWnd.is_null() {
let title = win32_string("Error!");
let text = win32_string("Creating window is faield");

let ret = MessageBoxW(0 as HWND, text.as_ptr(), title.as_ptr(), MB_OK);
} else {
println!("successful");
ShowWindow(hWnd, SW_SHOWDEFAULT);
loop {
if !handle_message(0 as HWND, &mut Message) {
break;
}
}
}
然后它对我有用。

关于winapi - 如果我将wndproc函数分配给wndclass,则会发生错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64623705/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com