Skip to content

Instantly share code, notes, and snippets.

@dcb9
Created January 1, 2024 07:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dcb9/fbd972e26da0ec703d95df6c83acf304 to your computer and use it in GitHub Desktop.
Save dcb9/fbd972e26da0ec703d95df6c83acf304 to your computer and use it in GitHub Desktop.
[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",
]
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