Created
July 30, 2023 13:25
-
-
Save poppyfanboy/30221b602f688faf3ff6903ce89ba878 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
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