我正在尝试使用标准 Windows API 窗口和子窗口作为控件(最具体的是静态文本、文本框和按钮)创建一个窗口窗体。
我正在使用 Windows 板条箱,代码编译时没有任何错误并运行,但我只能看到空白窗口,而看不到里面的控件。
我做错了什么?
提前致谢!
#![allow(non_snake_case)]
use windows::{
core::*,
Win32::Foundation::*,
Win32::Graphics::Gdi::*,
Win32::System::LibraryLoader::GetModuleHandleA,
Win32::UI::WindowsAndMessaging::*,
};
fn main() -> Result<()> {
unsafe {
let instance = GetModuleHandleA(None)?;
let window_class = s!("window");
let wc = WNDCLASSA {
hCursor: LoadCursorW(None, IDC_ARROW)?,
hInstance: instance.into(),
lpszClassName: window_class,
style: CS_HREDRAW | CS_VREDRAW,
lpfnWndProc: Some(wndproc),
..Default::default()
};
let atom = RegisterClassA(&wc);
debug_assert!(atom != 0);
let _hwnd = CreateWindowExA(
WINDOW_EX_STYLE::default(),
window_class,
s!("A simple Form"),
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
None,
None,
instance,
None,
)?;
let _hndLabel = CreateWindowExA(
WINDOW_EX_STYLE::default(),
s!("static"),
s!("What's your name? "),
WINDOW_STYLE::default(),
50, 100, 200, 30, _hwnd, None, instance, None)?;
let _hndCaixa = CreateWindowExA(
WINDOW_EX_STYLE::default(),
s!("edit"),
s!("Type Here!"),
WINDOW_STYLE::default(),
200, 100, 200, 30, _hwnd, None, instance, None)?;
let _hndButton = CreateWindowExA(
WINDOW_EX_STYLE::default(),
s!("Button"),
s!(" OK "),
WINDOW_STYLE::default(),
400, 100, 200, 30, _hwnd, None, instance, None)?;
let _ = ShowWindow(_hwnd, SW_SHOW);
let _ = UpdateWindow(_hwnd);
let mut message = MSG::default();
while GetMessageA(&mut message, None, 0, 0).into() {
DispatchMessageA(&message);
}
Ok(())
}
}
extern "system" fn wndproc(window: HWND, message: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT {
unsafe {
match message {
WM_PAINT => {
println!("WM_PAINT");
_ = ValidateRect(window, None);
LRESULT(0)
}
WM_DESTROY => {
println!("WM_DESTROY");
PostQuitMessage(0);
LRESULT(0)
}
_ => DefWindowProcA(window, message, wparam, lparam),
}
}
}
由于您没有提供合理的窗口样式,因此创建窗口的方式存在多个问题。
首先,主窗口获得
WS_OVERLAPPEDWINDOW | WS_VISIBLE
。您不想WS_VISIBLE
在创建子窗口之前将其传递给主窗口,因为这样,如果您创建了足够多的子窗口,您就会看到它们闪烁出现。您应该首先将主窗口创建为不可见,然后创建其所有子窗口,最后使用ShowWindow
以使主窗口可见。(即使窗口已经可见,您也要执行最后一部分。)其次,由于您没有传递
WS_CHILD
样式,所以您的所有子窗口实际上都不是子窗口。这意味着它们只是拥有的顶层窗口。WS_VISIBLE
第三,由于您既没有传递样式也没有调用子窗口,所以子窗口不可见ShowWindow
。您需要传递样式,因为如果主窗口不可见,那么让子窗口“可见”只是意味着它在最终显示时与主窗口一起出现。