Windows: implement window close method
This commit is contained in:
parent
45ea5387b4
commit
8c2c743da4
|
@ -5,20 +5,20 @@ use std::ptr::null_mut;
|
||||||
|
|
||||||
use self::winapi::shared::guiddef::GUID;
|
use self::winapi::shared::guiddef::GUID;
|
||||||
use self::winapi::shared::minwindef::{LPARAM, LRESULT, UINT, WPARAM};
|
use self::winapi::shared::minwindef::{LPARAM, LRESULT, UINT, WPARAM};
|
||||||
use self::winapi::shared::windef::{HGLRC, HWND};
|
use self::winapi::shared::windef::{HDC, HGLRC, HWND};
|
||||||
use self::winapi::um::combaseapi::CoCreateGuid;
|
use self::winapi::um::combaseapi::CoCreateGuid;
|
||||||
use self::winapi::um::libloaderapi::{GetProcAddress, LoadLibraryA};
|
use self::winapi::um::libloaderapi::{GetProcAddress, LoadLibraryA};
|
||||||
use self::winapi::um::wingdi::{
|
use self::winapi::um::wingdi::{
|
||||||
wglCreateContext, wglMakeCurrent, ChoosePixelFormat, SetPixelFormat, SwapBuffers,
|
wglCreateContext, wglDeleteContext, wglMakeCurrent, ChoosePixelFormat, SetPixelFormat,
|
||||||
PFD_DOUBLEBUFFER, PFD_DRAW_TO_WINDOW, PFD_MAIN_PLANE, PFD_SUPPORT_OPENGL, PFD_TYPE_RGBA,
|
SwapBuffers, PFD_DOUBLEBUFFER, PFD_DRAW_TO_WINDOW, PFD_MAIN_PLANE, PFD_SUPPORT_OPENGL,
|
||||||
PIXELFORMATDESCRIPTOR,
|
PFD_TYPE_RGBA, PIXELFORMATDESCRIPTOR,
|
||||||
};
|
};
|
||||||
use self::winapi::um::winuser::{
|
use self::winapi::um::winuser::{
|
||||||
CreateWindowExA, DefWindowProcA, DispatchMessageA, GetDC, MessageBoxA, PeekMessageA,
|
CreateWindowExA, DefWindowProcA, DestroyWindow, DispatchMessageA, GetDC, MessageBoxA,
|
||||||
PostQuitMessage, RegisterClassA, TranslateMessage, CS_HREDRAW, CS_OWNDC, CS_VREDRAW,
|
PeekMessageA, PostQuitMessage, RegisterClassA, ReleaseDC, TranslateMessage, UnregisterClassA,
|
||||||
CW_USEDEFAULT, MB_ICONERROR, MB_OK, MB_TOPMOST, MSG, PM_REMOVE, WM_DESTROY, WM_QUIT, WNDCLASSA,
|
CS_HREDRAW, CS_OWNDC, CS_VREDRAW, MB_ICONERROR, MB_OK, MB_TOPMOST, MSG, PM_REMOVE, WM_CLOSE,
|
||||||
WS_CAPTION, WS_CHILD, WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, WS_MINIMIZEBOX, WS_POPUPWINDOW,
|
WM_QUIT, WNDCLASSA, WS_CAPTION, WS_CHILD, WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, WS_MINIMIZEBOX,
|
||||||
WS_SIZEBOX, WS_VISIBLE,
|
WS_POPUPWINDOW, WS_SIZEBOX, WS_VISIBLE,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::Parent::WithParent;
|
use crate::Parent::WithParent;
|
||||||
|
@ -49,21 +49,35 @@ unsafe fn generate_guid() -> String {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Window;
|
pub struct Window {
|
||||||
|
hwnd: HWND,
|
||||||
|
hdc: HDC,
|
||||||
|
gl_context: HGLRC,
|
||||||
|
class_name: *const i8,
|
||||||
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
// todo: we should decide this interface
|
// todo: we should decide this interface
|
||||||
pub fn open(options: WindowOpenOptions) -> Self {
|
pub fn open(options: WindowOpenOptions) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let mut hwnd = null_mut();
|
||||||
|
let mut hdc = null_mut();
|
||||||
|
let mut gl_context = null_mut();
|
||||||
// We generate a unique name for the new window class to prevent name collisions
|
// We generate a unique name for the new window class to prevent name collisions
|
||||||
let class_name = format!("Baseview-{}", generate_guid());
|
let class_name = format!("Baseview-{}", generate_guid()).as_ptr() as *const i8;
|
||||||
|
|
||||||
|
let window = Window {
|
||||||
|
hwnd,
|
||||||
|
hdc,
|
||||||
|
gl_context,
|
||||||
|
class_name,
|
||||||
|
};
|
||||||
|
|
||||||
let wnd_class = WNDCLASSA {
|
let wnd_class = WNDCLASSA {
|
||||||
// todo: for OpenGL, will use it later
|
|
||||||
style: CS_OWNDC | CS_HREDRAW | CS_VREDRAW,
|
style: CS_OWNDC | CS_HREDRAW | CS_VREDRAW,
|
||||||
lpfnWndProc: Some(wnd_proc),
|
lpfnWndProc: Some(wnd_proc),
|
||||||
hInstance: null_mut(),
|
hInstance: null_mut(),
|
||||||
lpszClassName: class_name.as_ptr() as *const i8,
|
lpszClassName: class_name,
|
||||||
cbClsExtra: 0,
|
cbClsExtra: 0,
|
||||||
cbWndExtra: 0,
|
cbWndExtra: 0,
|
||||||
hIcon: null_mut(),
|
hIcon: null_mut(),
|
||||||
|
@ -71,6 +85,7 @@ impl Window {
|
||||||
hbrBackground: null_mut(),
|
hbrBackground: null_mut(),
|
||||||
lpszMenuName: std::ptr::null::<i8>(),
|
lpszMenuName: std::ptr::null::<i8>(),
|
||||||
};
|
};
|
||||||
|
|
||||||
RegisterClassA(&wnd_class);
|
RegisterClassA(&wnd_class);
|
||||||
|
|
||||||
let mut flags = WS_POPUPWINDOW
|
let mut flags = WS_POPUPWINDOW
|
||||||
|
@ -87,14 +102,13 @@ impl Window {
|
||||||
flags = WS_CHILD | WS_VISIBLE;
|
flags = WS_CHILD | WS_VISIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
let hwnd = CreateWindowExA(
|
hwnd = CreateWindowExA(
|
||||||
0,
|
0,
|
||||||
class_name.as_ptr() as *const i8,
|
class_name,
|
||||||
(options.title.to_owned() + "\0").as_ptr() as *const i8,
|
(options.title.to_owned() + "\0").as_ptr() as *const i8,
|
||||||
// todo: fine for now, will have to change with a parent
|
|
||||||
flags,
|
flags,
|
||||||
CW_USEDEFAULT,
|
0,
|
||||||
CW_USEDEFAULT,
|
0,
|
||||||
// todo: check if usize fits into i32
|
// todo: check if usize fits into i32
|
||||||
options.width as i32,
|
options.width as i32,
|
||||||
options.height as i32,
|
options.height as i32,
|
||||||
|
@ -104,7 +118,7 @@ impl Window {
|
||||||
null_mut(),
|
null_mut(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let hdc = GetDC(hwnd);
|
hdc = GetDC(hwnd);
|
||||||
|
|
||||||
let mut pfd: PIXELFORMATDESCRIPTOR = std::mem::zeroed();
|
let mut pfd: PIXELFORMATDESCRIPTOR = std::mem::zeroed();
|
||||||
pfd.nSize = std::mem::size_of::<PIXELFORMATDESCRIPTOR>() as u16;
|
pfd.nSize = std::mem::size_of::<PIXELFORMATDESCRIPTOR>() as u16;
|
||||||
|
@ -119,20 +133,28 @@ impl Window {
|
||||||
|
|
||||||
let pf_id: i32 = ChoosePixelFormat(hdc, &pfd);
|
let pf_id: i32 = ChoosePixelFormat(hdc, &pfd);
|
||||||
if pf_id == 0 {
|
if pf_id == 0 {
|
||||||
return Window;
|
// todo: use a more useful return like an Option
|
||||||
|
// todo: also launch error message boxes
|
||||||
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
if SetPixelFormat(hdc, pf_id, &pfd) == 0 {
|
if SetPixelFormat(hdc, pf_id, &pfd) == 0 {
|
||||||
return Window;
|
// todo: use a more useful return like an Option
|
||||||
|
// todo: also launch error message boxes
|
||||||
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
let gl_context: HGLRC = wglCreateContext(hdc);
|
gl_context = wglCreateContext(hdc);
|
||||||
if gl_context == 0 as HGLRC {
|
if gl_context == 0 as HGLRC {
|
||||||
return Window;
|
// todo: use a more useful return like an Option
|
||||||
|
// todo: also launch error message boxes
|
||||||
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
if wglMakeCurrent(hdc, gl_context) == 0 {
|
if wglMakeCurrent(hdc, gl_context) == 0 {
|
||||||
return Window;
|
// todo: use a more useful return like an Option
|
||||||
|
// todo: also launch error message boxes
|
||||||
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
let h = LoadLibraryA("opengl32.dll\0".as_ptr() as *const i8);
|
let h = LoadLibraryA("opengl32.dll\0".as_ptr() as *const i8);
|
||||||
|
@ -155,9 +177,20 @@ impl Window {
|
||||||
SwapBuffers(hdc);
|
SwapBuffers(hdc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Window
|
pub fn close(&self) {
|
||||||
|
// todo: see https://github.com/wrl/rutabaga/blob/f30ff67e157375cafdbafe5fb549f1790443a3a8/src/platform/win/window.c#L402
|
||||||
|
unsafe {
|
||||||
|
wglMakeCurrent(null_mut(), null_mut());
|
||||||
|
wglDeleteContext(self.gl_context);
|
||||||
|
ReleaseDC(self.hwnd, self.hdc);
|
||||||
|
DestroyWindow(self.hwnd);
|
||||||
|
UnregisterClassA(self.class_name, null_mut());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,12 +217,10 @@ unsafe extern "system" fn wnd_proc(
|
||||||
l_param: LPARAM,
|
l_param: LPARAM,
|
||||||
) -> LRESULT {
|
) -> LRESULT {
|
||||||
match msg {
|
match msg {
|
||||||
WM_DESTROY => {
|
WM_CLOSE => {
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => return DefWindowProcA(hwnd, msg, w_param, l_param),
|
||||||
return DefWindowProcA(hwnd, msg, w_param, l_param);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue