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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122 | #include <windows.h>
#include <commctrl.h>
#include <shellscalingapi.h>
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
HINSTANCE instance;
HMODULE shcore;
typedef HRESULT (*GetDpiForMonitorType)(HMONITOR hmonitor, MONITOR_DPI_TYPE dpiType, UINT *dpiX, UINT *dpiY);
typedef BOOL (*SetProcessDpiAwarenessContextType)(DPI_AWARENESS_CONTEXT value);
HFONT GetFont(HWND window) {
return (HFONT) GetWindowLongPtr(GetAncestor(window, GA_ROOT), 0);
}
int GetDPIScale(HWND window) {
return (int) GetWindowLongPtr(GetAncestor(window, GA_ROOT), sizeof(LONG_PTR));
}
bool CALLBACK SetFont(HWND child, LPARAM font) {
SendMessage(child, WM_SETFONT, font, true);
return true;
}
void RecreateFont(HWND window) {
if (shcore) {
HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY);
UINT x, y;
GetDpiForMonitorType getDpiForMonitor = (GetDpiForMonitorType) GetProcAddress(shcore, "GetDpiForMonitor");
getDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &x, &y);
SetWindowLongPtr(window, sizeof(LONG_PTR), y);
} else {
HDC screen = GetDC(NULL);
SetWindowLongPtr(window, sizeof(LONG_PTR), GetDeviceCaps(screen, LOGPIXELSY));
ReleaseDC(NULL, screen);
}
NONCLIENTMETRICSW metrics = {};
metrics.cbSize = sizeof(NONCLIENTMETRICSW);
SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(metrics), &metrics, 0);
metrics.lfMessageFont.lfHeight = -((9 * GetWindowLongPtr(window, sizeof(LONG_PTR))) / 72);
if (GetWindowLongPtr(window, 0)) DeleteObject((HFONT) GetWindowLongPtr(window, 0));
SetWindowLongPtr(window, 0, (LONG_PTR) CreateFontIndirectW(&metrics.lfMessageFont));
EnumChildWindows(window, (WNDENUMPROC) SetFont, (LPARAM) GetWindowLongPtr(window, 0));
}
LRESULT CALLBACK WindowProcedure(HWND window, UINT message, WPARAM wParam, LPARAM lParam) {
if (message == WM_DESTROY) {
PostQuitMessage(0);
} else if (message == WM_DPICHANGED) {
if (shcore) {
RECT *newBounds = (RECT *) lParam;
RecreateFont(window);
MoveWindow(window, newBounds->left, newBounds->top, newBounds->right - newBounds->left, newBounds->bottom - newBounds->top, TRUE);
}
} else if (message == WM_SIZE) {
int width = LOWORD(lParam), height = HIWORD(lParam);
// TODO Layout child windows.
} else if (message == WM_PAINT) {
PAINTSTRUCT paint;
HDC hdc = BeginPaint(window, &paint);
SelectObject(hdc, GetFont(window));
TextOut(hdc, 0, 0, "Hello, world!", 13);
// TODO Paint window contents.
EndPaint(window, &paint);
} else {
return DefWindowProc(window, message, wParam, lParam);
}
return 0;
}
int __stdcall WinMain(HINSTANCE _instance, HINSTANCE previousInstance, char *commandLine, int commandShow) {
instance = (HINSTANCE) _instance;
OSVERSIONINFOEXW version = { sizeof(version) };
((LONG (*)(PRTL_OSVERSIONINFOEXW)) GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlGetVersion"))(&version);
if (version.dwMajorVersion >= 10) {
shcore = LoadLibrary("shcore.dll");
SetProcessDpiAwarenessContextType setProcessDpiAwarenessContext = (SetProcessDpiAwarenessContextType) GetProcAddress(LoadLibrary("user32.dll"), "SetProcessDpiAwarenessContext");
setProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
} else {
SetProcessDPIAware();
}
CoInitialize(NULL);
INITCOMMONCONTROLSEX icc = {};
icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
icc.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&icc);
WNDCLASSEX windowClass = {};
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.cbWndExtra = sizeof(LONG_PTR) * 2 /* font, dpiScale */;
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = WindowProcedure;
windowClass.hInstance = instance;
windowClass.lpszClassName = "MyWindowClass";
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = (HBRUSH) COLOR_WINDOW;
RegisterClassEx(&windowClass);
HWND root = CreateWindowEx(0, "MyWindowClass", "My Window" /* TODO Window title. */,
WS_CLIPSIBLINGS | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, instance, NULL);
RecreateFont(root);
ShowWindow(root, commandShow);
MSG message;
while (GetMessage(&message, NULL, 0, 0) > 0) {
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam;
}
|