Created
April 4, 2023 16:31
-
-
Save Kreijstal/ed20c7740ffc7e9be1ae7afad7456db5 to your computer and use it in GitHub Desktop.
Difference between rust winapi and windows-rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::ptr::null_mut; | |
use winapi::shared::{ | |
minwindef::{HIWORD, LOWORD, LPARAM, LRESULT, UINT, WPARAM}, | |
windef::{HWND, POINT, RECT}, | |
}; | |
use std::ffi::CString; | |
use winapi::shared::basetsd::LONG_PTR; | |
use winapi::um::wingdi::GetStockObject; | |
use winapi::um::wingdi::SYSTEM_FONT; | |
use winapi::um::winuser::{GetSysColor,COLOR_WINDOWTEXT,GetDlgItem,GetSysColorBrush,SendMessageA,SetClassLongPtrA,COLOR_WINDOW,GCLP_HBRBACKGROUND,WM_SETFONT, | |
CreateWindowExA, DefWindowProcA, DispatchMessageA, GetMessageA, PostQuitMessage, | |
RegisterClassA, ShowWindow, TranslateMessage, BS_DEFPUSHBUTTON, BS_PUSHBUTTON, CW_USEDEFAULT, | |
ES_AUTOHSCROLL, IDCANCEL, IDOK, MSG, SW_SHOW, WM_COMMAND, WM_DESTROY, WNDCLASSA, WS_CHILD, | |
WS_OVERLAPPEDWINDOW, WS_SYSMENU, WS_VISIBLE, | |
}; | |
extern "system" fn window_proc(hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM) -> LRESULT { | |
match msg { | |
WM_COMMAND => { | |
let id = LOWORD(wparam as u32) as usize; | |
let code = HIWORD(wparam as u32); | |
let control_hwnd = lparam as HWND; | |
if code == 0 && id == IDOK as usize && control_hwnd == unsafe { GetDlgItem(hwnd, IDOK) } | |
{ | |
println!("Ok clicked!"); | |
} else if code == 0 | |
&& id == IDCANCEL as usize | |
&& control_hwnd == unsafe { GetDlgItem(hwnd, IDCANCEL) } | |
{ | |
println!("Cancel Clicked"); | |
} | |
0 | |
} | |
WM_DESTROY => { | |
unsafe { PostQuitMessage(0) }; | |
0 | |
} | |
_ => unsafe { DefWindowProcA(hwnd, msg, wparam, lparam) }, | |
} | |
} | |
fn main() { | |
unsafe { | |
let class_name = "MyWindowClass\0".as_ptr() as *const i8; | |
//let class_name = CString::new("MyWindowClass").unwrap(); | |
// Register a window class | |
let wnd_class = WNDCLASSA { | |
style: 0, | |
lpfnWndProc: Some(window_proc), //Some(DefWindowProcA), | |
hInstance: null_mut(), | |
lpszClassName: class_name, | |
cbClsExtra: 0, | |
cbWndExtra: 0, | |
hIcon: null_mut(), | |
hCursor: null_mut(), | |
hbrBackground: null_mut(), | |
lpszMenuName: null_mut(), | |
}; | |
RegisterClassA(&wnd_class); | |
// Create the main window | |
let hwnd_main = CreateWindowExA( | |
0, | |
class_name, | |
"Hello World\0".as_ptr() as *const i8, | |
WS_OVERLAPPEDWINDOW | WS_SYSMENU, | |
CW_USEDEFAULT, | |
CW_USEDEFAULT, | |
640, | |
480, | |
null_mut(), | |
null_mut(), | |
null_mut(), | |
null_mut(), | |
); | |
// Create the text box | |
let hwnd_text = CreateWindowExA( | |
0, | |
"EDIT\0".as_ptr() as *const i8, | |
null_mut(), | |
WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL, | |
10, | |
10, | |
300, | |
20, | |
hwnd_main, | |
null_mut(), | |
null_mut(), | |
null_mut(), | |
); | |
// Create the OK button | |
let hwnd_ok = CreateWindowExA( | |
0, | |
"BUTTON\0".as_ptr() as *const i8, | |
"OK\0".as_ptr() as *const i8, | |
WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, | |
320, | |
10, | |
80, | |
20, | |
hwnd_main, | |
IDOK as isize as *mut _, | |
null_mut(), | |
null_mut(), | |
); | |
// Create the Cancel button | |
let hwnd_cancel = CreateWindowExA( | |
0, | |
"BUTTON\0".as_ptr() as *const i8, | |
"Cancel\0".as_ptr() as *const i8, | |
WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, | |
410, | |
10, | |
80, | |
20, | |
hwnd_main, | |
IDCANCEL as isize as *mut _, | |
null_mut(), | |
null_mut(), | |
); | |
// Show the main window | |
ShowWindow(hwnd_main, SW_SHOW); | |
// Run the message loop | |
let mut msg = MSG { | |
hwnd: null_mut(), | |
message: 0, | |
wParam: 0, | |
lParam: 0, | |
time: 0, | |
pt: POINT { x: 0, y: 0 }, | |
}; | |
loop { | |
let result = GetMessageA(&mut msg, null_mut(), 0, 0); | |
if result == 0 { | |
break; | |
} else if result == -1 { | |
//handle error | |
} else { | |
TranslateMessage(&msg); | |
DispatchMessageA(&msg); | |
} | |
} | |
// Clean up | |
PostQuitMessage(0); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use windows::{ | |
core::*, | |
w, | |
Win32::{ | |
Foundation::*, | |
Graphics::Gdi::*, | |
System::LibraryLoader::*, | |
UI::{Controls::RichEdit::*, WindowsAndMessaging::*}, | |
}, | |
}; | |
pub fn LOWORD(l: usize) -> usize { | |
l & 0xffff | |
} | |
pub fn HIWORD(l: usize) -> usize { | |
(l >> 16) & 0xffff | |
} | |
unsafe extern "system" fn window_proc( | |
hwnd: HWND, | |
msg: u32, | |
wparam: WPARAM, | |
lparam: LPARAM, | |
) -> LRESULT { | |
match msg { | |
WM_COMMAND => { | |
let control_id = LOWORD(wparam.0); | |
let notification_code = HIWORD(wparam.0); | |
let control_handle = lparam; | |
if control_id == IDOK.0 as usize && notification_code == 0 && control_handle.0 == GetDlgItem(hwnd, IDOK.0).0 { | |
println!("OK button clicked!"); | |
} else if control_id == IDCANCEL.0 as usize && notification_code == 0 && control_handle.0 == GetDlgItem(hwnd, IDCANCEL.0).0 { | |
println!("Cancel button clicked!"); | |
} | |
} | |
WM_DESTROY => { | |
PostQuitMessage(0); | |
} | |
_ => { | |
return DefWindowProcW(hwnd, msg, wparam, lparam); | |
} | |
} | |
return LRESULT(0); | |
} | |
fn main() { | |
// Get the HINSTANCE for the current process | |
let h_instance = unsafe { GetModuleHandleW(None).unwrap() }; | |
// Load the default application icon | |
let h_icon = unsafe { LoadIconW(None, IDI_APPLICATION).unwrap() }; | |
// Load the default arrow cursor | |
let h_cursor = unsafe { LoadCursorW(None, IDC_ARROW).unwrap() }; | |
// Register a window class | |
//let class_name = "MyWindowClass\0".encode_utf16().collect::<Vec<u16>>(); | |
let class_name = w!("MyWindowClass"); | |
let wnd_class = WNDCLASSW { | |
style: WNDCLASS_STYLES(0), | |
lpfnWndProc: Some(window_proc), | |
hInstance: h_instance, | |
lpszClassName: windows::core::PCWSTR(class_name.as_ptr()), | |
cbClsExtra: 0, | |
cbWndExtra: 0, | |
hIcon: h_icon, | |
hCursor: h_cursor, | |
hbrBackground: unsafe { GetSysColorBrush(COLOR_WINDOW) }, | |
lpszMenuName: PCWSTR::null(), | |
}; | |
unsafe { | |
RegisterClassW(&wnd_class); | |
// Create the main window | |
let hwnd_main = CreateWindowExW( | |
WINDOW_EX_STYLE(0), | |
class_name, | |
w!("Only 1 letter in title"), | |
WS_OVERLAPPEDWINDOW | WS_SYSMENU, | |
CW_USEDEFAULT, | |
CW_USEDEFAULT, | |
640, | |
480, | |
HWND(0), | |
HMENU(0), | |
h_instance, | |
None, | |
); | |
// Create the text box | |
let hwnd_text = CreateWindowExW( | |
WINDOW_EX_STYLE(0), | |
w!("EDIT"), | |
w!(""), | |
WS_CHILD | WS_VISIBLE | WINDOW_STYLE(ES_LEFT as u32) | WINDOW_STYLE(ES_AUTOHSCROLL as u32), | |
10, | |
10, | |
300, | |
20, | |
hwnd_main, | |
HMENU(0), | |
h_instance, | |
None, | |
); | |
// Create the OK button | |
let hwnd_ok = CreateWindowExW( | |
WINDOW_EX_STYLE(0), | |
w!("BUTTON"), | |
w!("Ok"), | |
WS_VISIBLE | WS_CHILD | WINDOW_STYLE(BS_DEFPUSHBUTTON as u32), | |
320, | |
10, | |
80, | |
20, | |
hwnd_main, | |
HMENU(IDOK.0 as isize), | |
h_instance, | |
None, | |
); | |
// Create the Cancel button | |
let hwnd_cancel = CreateWindowExW( | |
WINDOW_EX_STYLE(0), | |
w!("BUTTON"), | |
w!("Cancel"), | |
WS_VISIBLE | WS_CHILD | WINDOW_STYLE(BS_DEFPUSHBUTTON as u32), | |
410, | |
10, | |
80, | |
20, | |
hwnd_main, | |
HMENU(IDCANCEL.0 as isize), | |
h_instance, | |
None, | |
); | |
// Show the main window | |
ShowWindow(hwnd_main, SW_SHOW); | |
// Run the message loop | |
let mut msg = MSG::default(); | |
loop { | |
let result = GetMessageW(&mut msg, HWND(0), 0, 0); | |
if result == BOOL(0) { | |
break; | |
} else if result == BOOL(-1) { | |
//handle error | |
} else { | |
TranslateMessage(&msg); | |
DispatchMessageW(&msg); | |
} | |
} | |
// Clean up | |
PostQuitMessage(0); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment