silly-stuff/borderless-win32-odin/main.odin

168 lines
4.9 KiB
Odin
Raw Normal View History

package borderless_win
import "core:os"
import win32 "core:sys/windows"
// foreign import win32ex "system:User32.lib"
// @(default_calling_convention="stdcall")
// foreign win32ex {
// IsZoomed :: proc (hwnd: win32.HWND) -> win32.BOOL ---
// }
// IsMaximized :: IsZoomed
WM_NCUAHDRAWCAPTION :: (0x00AE)
WM_NCUAHDRAWFRAME :: (0x00AF)
UserData := struct {
dwm_enabled: win32.BOOL,
width: i32,
height: i32,
} {
dwm_enabled = false,
width = 0,
height = 0,
}
handle_nchittest :: proc "stdcall" (hwnd: win32.HWND, lparam: win32.LPARAM) -> win32.LRESULT {
// if IsMaximized(hwnd) do return win32.HTCLIENT
mouse := win32.POINT{win32.GET_X_LPARAM(lparam), win32.GET_Y_LPARAM(lparam)}
win32.ScreenToClient(hwnd, &mouse)
frame_size :=
win32.GetSystemMetrics(win32.SM_CXFRAME) + win32.GetSystemMetrics(win32.SM_CXPADDEDBORDER)
diagonal_width := frame_size * 2 + win32.GetSystemMetrics(win32.SM_CXBORDER)
if mouse.y < frame_size {
if mouse.x < diagonal_width do return win32.HTTOPLEFT
if mouse.x >= UserData.width - diagonal_width do return win32.HTTOPRIGHT
return win32.HTTOP
}
if mouse.y >= UserData.height - frame_size {
if mouse.x < diagonal_width do return win32.HTBOTTOMLEFT
if mouse.x >= UserData.width - diagonal_width do return win32.HTBOTTOMRIGHT
return win32.HTBOTTOM
}
if mouse.x < frame_size do return win32.HTLEFT
if mouse.x >= UserData.width - frame_size do return win32.HTRIGHT
return win32.HTCLIENT
}
handle_windowposchanged :: proc "stdcall" (
hwnd: win32.HWND,
pos: ^win32.WINDOWPOS,
) -> win32.LRESULT {
client: win32.RECT
win32.GetClientRect(hwnd, &client)
last_width, last_height := UserData.width, UserData.height
UserData.width, UserData.height = client.right, client.bottom
client_changed := UserData.width != last_width || UserData.height != last_height
if client_changed {
if UserData.width > last_width do win32.InvalidateRect(hwnd, &(win32.RECT){last_width - 1, 0, last_width, last_height}, true)
else do win32.InvalidateRect(hwnd,&(win32.RECT){UserData.width - 1, 0, UserData.width, UserData.height}, true)
if UserData.height > last_height do win32.InvalidateRect(hwnd, &(win32.RECT){0, last_height - 1, last_width, last_height}, true)
else do win32.InvalidateRect(hwnd, &(win32.RECT){0, UserData.height - 1, UserData.width, UserData.height}, true)
}
return 0
}
handle_dwmcompositionchanged :: proc "stdcall" (hwnd: win32.HWND) {
enabled: win32.BOOL = false
win32.DwmIsCompositionEnabled(&enabled)
UserData.dwm_enabled = enabled
if enabled {
win32.DwmSetWindowAttribute(
hwnd,
u32(win32.DWMWINDOWATTRIBUTE.DWMWA_NCRENDERING_POLICY),
rawptr(uintptr(win32.DWORD(win32.DWMNCRENDERINGPOLICY.DWMNCRP_ENABLED))),
size_of(win32.DWORD),
)
}
}
handle_win32_events :: proc "stdcall" (
hwnd: win32.HWND,
msg: win32.UINT,
wparam: win32.WPARAM,
lparam: win32.LPARAM,
) -> win32.LRESULT {
switch msg {
case win32.WM_CLOSE:
win32.DestroyWindow(hwnd)
return 0
case win32.WM_DESTROY:
win32.PostQuitMessage(0)
return 0
case win32.WM_PAINT:
ps: win32.PAINTSTRUCT
hdc := win32.BeginPaint(hwnd, &ps)
win32.FillRect(hdc, &ps.rcPaint, win32.HBRUSH(win32.COLOR_BACKGROUND + uintptr(1)))
win32.EndPaint(hwnd, &ps)
return 0
case win32.WM_NCACTIVATE:
return win32.DefWindowProcW(hwnd, msg, wparam, -1)
case win32.WM_NCHITTEST:
return handle_nchittest(hwnd, lparam)
case win32.WM_WINDOWPOSCHANGED:
return handle_windowposchanged(hwnd, transmute(^win32.WINDOWPOS)(lparam))
case win32.WM_NCCALCSIZE:
return 0
case win32.WM_NCPAINT:
if !UserData.dwm_enabled do return 0
case win32.WM_LBUTTONDOWN:
win32.ReleaseCapture()
win32.SendMessageW(hwnd, win32.WM_NCLBUTTONDOWN, win32.HTCAPTION, 0)
case win32.WM_DWMCOMPOSITIONCHANGED:
handle_dwmcompositionchanged(hwnd)
return 0
case WM_NCUAHDRAWCAPTION:
return 0
case WM_NCUAHDRAWFRAME:
return 0
}
return win32.DefWindowProcW(hwnd, msg, wparam, lparam)
}
main :: proc() {
hinstance := win32.HINSTANCE(win32.GetModuleHandleW(nil))
cid := win32.RegisterClassExW(
&(win32.WNDCLASSEXW) {
cbSize = size_of(win32.WNDCLASSEXW),
hInstance = hinstance,
hbrBackground = win32.HBRUSH(win32.COLOR_WINDOW + uintptr(1)),
lpszClassName = win32.utf8_to_wstring("OdinBorderlessWindow"),
hCursor = win32.LoadCursorA(nil, win32.IDC_ARROW),
lpfnWndProc = handle_win32_events,
},
)
hwnd := win32.CreateWindowExW(
0,
win32.LPCWSTR(uintptr(cid)),
win32.utf8_to_wstring("Borderless Window"),
win32.WS_OVERLAPPEDWINDOW | win32.WS_SIZEBOX,
win32.CW_USEDEFAULT,
win32.CW_USEDEFAULT,
win32.CW_USEDEFAULT,
win32.CW_USEDEFAULT,
nil,
nil,
hinstance,
nil,
)
handle_dwmcompositionchanged(hwnd)
win32.ShowWindow(hwnd, win32.SW_SHOWNORMAL)
win32.UpdateWindow(hwnd)
message: win32.MSG
for win32.GetMessageW(&message, nil, 0, 0) != 0 {
win32.TranslateMessage(&message)
win32.DispatchMessageW(&message)
}
win32.UnregisterClassW(win32.LPCWSTR(uintptr(cid)), hinstance)
os.exit(int(message.wParam))
}