Created
January 1, 2024 07:51
-
-
Save dcb9/fbd972e26da0ec703d95df6c83acf304 to your computer and use it in GitHub Desktop.
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
[package] | |
name = "counter" | |
version = "0.1.0" | |
edition = "2021" | |
[dependencies] | |
[dependencies.windows] | |
version = "0.52" | |
features = [ | |
"Win32_Foundation", | |
"Win32_Graphics_Gdi", | |
"Win32_System_LibraryLoader", | |
"Win32_UI_WindowsAndMessaging", | |
] |
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::ffi::c_void; | |
use windows::core::*; | |
use windows::Win32::{ | |
Foundation::*, | |
UI::WindowsAndMessaging::*, | |
Graphics::Gdi::UpdateWindow, | |
System::LibraryLoader::GetModuleHandleExW, | |
}; | |
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 { | |
hCursor: LoadCursorW(None, IDC_ARROW)?, | |
hInstance: instance.into(), | |
lpszClassName: w!("my_window"), | |
lpfnWndProc: Some(window_proc), | |
cbSize: std::mem::size_of::<WNDCLASSEXW>() as u32, | |
..Default::default() | |
}; | |
let atom = RegisterClassExW(&wnd_class); | |
debug_assert!(atom != 0); | |
let hwnd = CreateWindowExW( | |
Default::default(), | |
w!("my_window"), | |
w!("Hello, Windows!"), | |
WS_OVERLAPPEDWINDOW, | |
CW_USEDEFAULT, | |
CW_USEDEFAULT, | |
CW_USEDEFAULT, | |
CW_USEDEFAULT, | |
None, | |
None, | |
instance, | |
Some(lparam as *mut c_void), | |
); | |
ShowWindow(hwnd, SW_SHOW); | |
UpdateWindow(hwnd); | |
let mut msg = MSG::default(); | |
while GetMessageW(&mut msg, None, 0, 0).into() { | |
TranslateMessage(&msg); | |
DispatchMessageW(&msg); | |
} | |
Ok(()) | |
} | |
} | |
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 | |
CreateWindowExW( | |
WS_EX_LEFT, | |
w!("BUTTON"), | |
w!("CLICK"), | |
WS_VISIBLE | WS_CHILD, | |
0, | |
0, | |
200, 40, | |
hwnd, | |
None, | |
HINSTANCE(GetWindowLongPtrW(hwnd, GWLP_HINSTANCE)), | |
None, | |
); | |
// 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) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment