Skip to content

Instantly share code, notes, and snippets.

@poppyfanboy
Created July 30, 2023 13:25
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 poppyfanboy/30221b602f688faf3ff6903ce89ba878 to your computer and use it in GitHub Desktop.
Save poppyfanboy/30221b602f688faf3ff6903ce89ba878 to your computer and use it in GitHub Desktop.
use std::{iter, ptr};
unsafe extern "stdcall" fn window_procedure(
window_handle: win32::WindowHandle,
message: u32,
w_parameter: u64,
l_parameter: i64,
) -> i64 {
if message == win32::MessageType::Destroy.into() {
win32::PostQuitMessage(0);
return 0;
}
win32::DefWindowProcW(window_handle, message, w_parameter, l_parameter)
}
fn to_utf16(source: &str) -> Vec<u16> {
source
.encode_utf16()
.chain(iter::once(0))
.collect::<Vec<_>>()
}
fn main() {
let instance_handle = unsafe { win32::GetModuleHandleW(ptr::null()) };
let window_class_name = to_utf16("My window");
let window_title = to_utf16("Заголовок окна");
let window_class = win32::WindowClass {
window_procedure,
instance_handle,
class_name: window_class_name.as_ptr(),
..Default::default()
};
unsafe { win32::RegisterClassW(&window_class as *const _) };
let window_handle = unsafe {
win32::CreateWindowExW(
0,
window_class_name.as_ptr(),
window_title.as_ptr(),
win32::WindowStyle::OverlappedWindow.into(),
i32::MIN,
i32::MIN,
i32::MIN,
i32::MIN,
Default::default(),
ptr::null_mut(),
instance_handle,
ptr::null_mut(),
)
};
if window_handle.0.is_null() {
return;
}
unsafe { win32::ShowWindow(window_handle, win32::WindowShowOption::Normal.into()) };
let mut message = win32::Message::default();
while unsafe { win32::GetMessageW(&mut message as *mut _, Default::default(), 0, 0) } > 0 {
unsafe {
win32::TranslateMessage(&message as *const _);
win32::DispatchMessageW(&message as *const _);
}
}
}
pub mod win32 {
use std::{ffi::c_void, ptr};
pub type Handle = *mut c_void;
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct InstanceHandle(pub Handle);
impl Default for InstanceHandle {
fn default() -> Self {
Self(ptr::null_mut())
}
}
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct WindowHandle(pub Handle);
impl Default for WindowHandle {
fn default() -> Self {
Self(ptr::null_mut())
}
}
pub type WindowProcedure = unsafe extern "stdcall" fn(
window_handle: WindowHandle,
message: u32,
w_parameter: u64,
l_parameter: i64,
) -> i64;
pub type WideString = *const u16;
#[repr(C)]
pub struct WindowClass {
pub style: u32,
pub window_procedure: WindowProcedure,
pub cb_cls_extra: i32,
pub cb_wnd_extra: i32,
pub instance_handle: InstanceHandle,
pub icon_handle: Handle,
pub cursor_handle: Handle,
pub background_brush_handle: Handle,
pub menu_name: WideString,
pub class_name: WideString,
}
impl Default for WindowClass {
fn default() -> Self {
Self {
style: 0,
window_procedure: DefWindowProcW,
cb_cls_extra: 0,
cb_wnd_extra: 0,
instance_handle: Default::default(),
icon_handle: ptr::null_mut(),
cursor_handle: ptr::null_mut(),
background_brush_handle: ptr::null_mut(),
menu_name: ptr::null(),
class_name: ptr::null(),
}
}
}
#[repr(C)]
#[derive(Default)]
pub struct CursorPosition {
pub x: i32,
pub y: i32,
}
#[repr(C)]
#[derive(Default)]
pub struct Message {
pub window_handle: WindowHandle,
pub message: u32,
pub w_parameter: u64,
pub l_parameter: i64,
pub time: u32,
pub cursor_position: CursorPosition,
pub l_private: u32,
}
pub enum MessageType {
Destroy,
}
impl From<MessageType> for u32 {
fn from(message_type: MessageType) -> Self {
match message_type {
MessageType::Destroy => 0x0002,
}
}
}
pub enum WindowShowOption {
Normal,
}
impl From<WindowShowOption> for i32 {
fn from(window_show_option: WindowShowOption) -> Self {
match window_show_option {
WindowShowOption::Normal => 1,
}
}
}
pub enum WindowStyle {
Overlapped,
Caption,
SysMenu,
ThickFrame,
MinimizeBox,
MaximizeBox,
OverlappedWindow,
}
impl From<WindowStyle> for u32 {
fn from(window_style: WindowStyle) -> Self {
match window_style {
WindowStyle::Overlapped => 0x00000000,
WindowStyle::Caption => 0x00c00000,
WindowStyle::SysMenu => 0x00080000,
WindowStyle::ThickFrame => 0x00400000,
WindowStyle::MinimizeBox => 0x00020000,
WindowStyle::MaximizeBox => 0x00010000,
WindowStyle::OverlappedWindow => {
Into::<u32>::into(WindowStyle::Overlapped)
| Into::<u32>::into(WindowStyle::Caption)
| Into::<u32>::into(WindowStyle::SysMenu)
| Into::<u32>::into(WindowStyle::ThickFrame)
| Into::<u32>::into(WindowStyle::MinimizeBox)
| Into::<u32>::into(WindowStyle::MaximizeBox)
}
}
}
}
#[link(name = "Kernel32")]
extern "C" {
pub fn GetModuleHandleW(module_name: WideString) -> InstanceHandle;
}
#[link(name = "User32")]
extern "C" {
pub fn RegisterClassW(window_class: *const WindowClass) -> u16;
pub fn CreateWindowExW(
extended_style: u32,
class_name: WideString,
title: WideString,
style: u32,
x: i32,
y: i32,
width: i32,
height: i32,
parent_window_handle: WindowHandle,
menu_handle: Handle,
instance_handle: InstanceHandle,
l_parameter: *mut c_void,
) -> WindowHandle;
pub fn ShowWindow(window_handle: WindowHandle, n_cmd_show: i32) -> i32;
pub fn PostQuitMessage(exit_code: i32);
pub fn GetMessageW(
message: *mut Message,
window_handle: WindowHandle,
message_filter_min: u32,
message_filter_max: u32,
) -> i32;
pub fn TranslateMessage(message: *const Message) -> i32;
pub fn DispatchMessageW(message: *const Message) -> i64;
}
#[link(name = "User32")]
extern "stdcall" {
pub fn DefWindowProcW(
window_handle: WindowHandle,
message: u32,
w_parameter: u64,
l_parameter: i64,
) -> i64;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment