Skip to content

Instantly share code, notes, and snippets.

@rossy
Created June 30, 2021 14:09
Show Gist options
  • Save rossy/3dfee6331c97b5ac4b974ecff5b98d4f to your computer and use it in GitHub Desktop.
Save rossy/3dfee6331c97b5ac4b974ecff5b98d4f to your computer and use it in GitHub Desktop.
Windows 11 rounded windows
#include <stdbool.h>
#include <windows.h>
#include <dwmapi.h>
extern IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
#define DWMWA_WINDOW_CORNER_PREFERENCE (33)
typedef enum {
DWMWCP_DEFAULT = 0,
DWMWCP_DONOTROUND = 1,
DWMWCP_ROUND = 2,
DWMWCP_ROUNDSMALL = 3,
} DWM_WINDOW_CORNER_PREFERENCE;
struct window {
HWND window;
bool destroyed;
DWM_WINDOW_CORNER_PREFERENCE roundness;
};
static void handle_nccreate(HWND window, CREATESTRUCTW *cs)
{
struct window *data = cs->lpCreateParams;
SetWindowLongPtrW(window, GWLP_USERDATA, (LONG_PTR)data);
DwmSetWindowAttribute(window, DWMWA_WINDOW_CORNER_PREFERENCE,
&(DWM_WINDOW_CORNER_PREFERENCE) { data->roundness },
sizeof(DWM_WINDOW_CORNER_PREFERENCE));
}
static LRESULT CALLBACK window_proc(HWND window, UINT msg, WPARAM wparam,
LPARAM lparam)
{
struct window *data = (void *)GetWindowLongPtrW(window, GWLP_USERDATA);
if (!data) {
if (msg == WM_NCCREATE)
handle_nccreate(window, (CREATESTRUCTW *)lparam);
return DefWindowProcW(window, msg, wparam, lparam);
}
switch (msg) {
case WM_CLOSE:
DestroyWindow(window);
data->destroyed = true;
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProcW(window, msg, wparam, lparam);
}
static ATOM get_class(void)
{
static ATOM cls = 0;
if (cls)
return cls;
cls = RegisterClassExW(&(WNDCLASSEXW) {
.cbSize = sizeof(WNDCLASSEXW),
.lpfnWndProc = window_proc,
.hInstance = HINST_THISCOMPONENT,
.hCursor = LoadCursor(NULL, IDC_ARROW),
.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1),
.lpszClassName = L"dark-mode-test",
});
return cls;
}
struct window *window_create(wchar_t *title, DWM_WINDOW_CORNER_PREFERENCE roundness)
{
struct window *data = calloc(1, sizeof(struct window));
data->roundness = roundness;
data->window = CreateWindowExW(WS_EX_APPWINDOW,
(LPWSTR)MAKEINTATOM(get_class()), title,
WS_OVERLAPPEDWINDOW | WS_SIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT,
350, 150, NULL, NULL, HINST_THISCOMPONENT, data);
ShowWindow(data->window, SW_SHOWDEFAULT);
UpdateWindow(data->window);
return data;
}
void window_destroy(struct window *window)
{
if (!window)
return;
if (!window->destroyed) {
DestroyWindow(window->window);
window->destroyed = true;
}
free(window);
}
int main()
{
struct window *unround_wnd = window_create(L"DWMWCP_DONOTROUND", DWMWCP_DONOTROUND);
struct window *round_wnd = window_create(L"DWMWCP_ROUND", DWMWCP_ROUND);
struct window *roundsmall_wnd = window_create(L"DWMWCP_ROUNDSMALL", DWMWCP_ROUNDSMALL);
MSG message;
while (GetMessageW(&message, NULL, 0, 0)) {
TranslateMessage(&message);
DispatchMessageW(&message);
}
window_destroy(unround_wnd);
window_destroy(round_wnd);
window_destroy(roundsmall_wnd);
UnregisterClassW((LPWSTR)MAKEINTATOM(get_class()), HINST_THISCOMPONENT);
return message.wParam;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment