- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我用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/
是否绝对有必要始终为您的应用程序构建和注册一个新的 WNDCLASS(EX)?然后将 lpszClassName 用于主窗口? 难道没有一些我们可以用于主窗口的预建类名,比如按钮和文本框等有“Butt
好吧,严重的困境。我正在尝试包装 Windows API。我遇到的最大的设计问题(目前)是什么类适合包装什么?由于我之前已经创建了大约 3 次 Windows API 包装器,总是在中间遇到设计问题,
我正在阅读 Petzold 的书并坚持执行以下一段代码,我根本无法理解它的作用。 作者说: You can create the new brush and insert the handle in
我有一个问题,使用这段代码: BOOL RegisterApp(HINSTANCE hInst) { WNDCLASS wc; wc.style = CS_HREDRA
我在我的位图中填写了 WNDCLASS 和 hbrBackground 属性 wc.hbrBackground = CreatePatternBrush( LoadBitmap( hInstance,
考虑以下代码: #include LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI wWinMain(HINSTANC
我现在正在使用 playground SDK,需要获取游戏窗口的 WNDCLASS。我在 SDK 中没有找到任何东西,这就是为什么我试图用游戏窗口的 hWnd 来做到这一点。那么有没有办法从HWND获
在创建窗口时: 1)为什么要注册窗口类,CreateWindow是如何理解我们想要的类的? WNDCLASS wc; RegisterClass(&wc) 2) 我们为什么要使用这个循环: MSG m
我刚刚将游戏切换为使用 WNDCLASSEX,这样我就可以更改 hIconSm,但由于某种原因,标题栏中不再有图标。任务栏上的光标和图标以及 EXE 的图标都可以正常工作。下面是窗口创建代码的主要部分
我用 VS2010 为我用 DirectX 制作的游戏创建了一个自定义 .ico 当我将 .ico 文件设置为我的 wndClass 的 hIcon 成员时,它将显示在任务栏中,但不会显示在标题栏中。
我是一名优秀的程序员,十分优秀!