Echo Writes Code

application.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use crate::application::{ ApplicationDelegate };
use crate::win32::window::{ win32_message_handler };

use windows::core::{ PCWSTR, w };
use windows::Win32::Foundation::{ HINSTANCE };
use windows::Win32::Graphics::Gdi::{ HBRUSH };
use windows::Win32::System::SystemServices::{ IMAGE_DOS_HEADER };

use windows::Win32::UI::WindowsAndMessaging::{
  CS_HREDRAW,
  CS_VREDRAW,
  HCURSOR,
  HICON,
  WNDCLASSEXW,
  RegisterClassExW,
};

use std::mem::{ self };
use std::ptr::{ self };
use std::sync::{ LazyLock };

static APPLICATION: LazyLock<Win32Application> = LazyLock::new(|| Win32Application::new());
const WINDOW_CLASS_NAME: PCWSTR = w!("Crucible Window");

struct Win32Application {
  window_class_atom: u16,
}

impl Win32Application {
  fn new() -> Win32Application {
    let window_class = WNDCLASSEXW {
      cbSize: mem::size_of::<WNDCLASSEXW>() as u32,
      style: CS_HREDRAW | CS_VREDRAW,
      lpfnWndProc: Some(win32_message_handler),
      cbClsExtra: 0,
      cbWndExtra: 0,
      hInstance: get_link_unit_hinstance(),
      hIcon: HICON(ptr::null_mut()),
      hCursor: HCURSOR(ptr::null_mut()),
      hbrBackground: HBRUSH(ptr::null_mut()),
      lpszMenuName: PCWSTR(ptr::null()),
      lpszClassName: WINDOW_CLASS_NAME,
      hIconSm: HICON(ptr::null_mut()),
    };

    let window_class_atom = unsafe {
      RegisterClassExW(&window_class)
    };

    Win32Application {
      window_class_atom,
    }
  }

  fn run(&self) {

  }

  fn terminate(&self) {

  }
}

pub fn run_win32_application<D: ApplicationDelegate + 'static>(_delegate: D) {
  APPLICATION.run();
}

pub fn terminate_win32_application() {
  APPLICATION.terminate();
}

// This is a bit better than GetModuleHandle(NULL) because it will still work if we're in a DLL.
// See: https://devblogs.microsoft.com/oldnewthing/20041025-00/?p=37483
fn get_link_unit_hinstance() -> HINSTANCE {
  unsafe extern "C" {
    static mut __ImageBase: IMAGE_DOS_HEADER;
  }

  HINSTANCE(&raw mut __ImageBase as *mut _)
}