I've been trying to design a small interface with winapi (no MFC) for some weeks and there is a problem I've not been able to solve. The creation of my window is specified in pixels, but the size of my controls is in logical units.
I thought the solution would be to use the MulDiv
function when I create the font for my window:
#include <windows.h>
LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch(msg) {
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
const char * g_szClassName = "SampleWindow";
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
//Let's register our window class
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = wndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = CreateSolidBrush(RGB(240,240,240));
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = NULL;
if(!RegisterClassEx(&wc)) {
return 0;
}
DWORD dwStyle=( (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)&~WS_MAXIMIZEBOX);
RECT rect;
rect.left = rect.top = 0;
rect.right = 300;
rect.bottom = 100;
::AdjustWindowRect(&rect, dwStyle, false);
HWND mWindow = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"Sample Window",
dwStyle,
CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top,// (x,y,width,height)
NULL, NULL, hInstance, NULL);
if(mWindow == NULL) {
return 0;
}
HDC hdc = GetDC(mWindow);
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(NONCLIENTMETRICS);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0);
ncm.lfMessageFont.lfWidth = 0;
ncm.lfMessageFont.lfHeight = -MulDiv(16, GetDeviceCaps(hdc, LOGPIXELSY), 72);
HFONT normalFont = CreateFontIndirect(&ncm.lfMessageFont);
HWND someText = CreateWindow( "Static", "This text will scale badly",
WS_VISIBLE | WS_CHILD | SS_LEFT, // Styles
10, 10, 500, 30, // (x, y, width, height)
mWindow, (HMENU) NULL, hInstance, NULL);
SendMessage(someText, WM_SETFONT, (WPARAM) normalFont, MAKELPARAM(TRUE, 0));
ShowWindow(mWindow, SW_SHOW);
UpdateWindow(mWindow);
//Run the window
MSG Msg;
while(GetMessage(&Msg, NULL, 0, 0) > 0) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
DeleteObject(normalFont);
ReleaseDC(hdc);
}
Normally I compile the code with MSVC2010, but this minimal example was compiled with gcc 7.2.0 (MinGW 64 bit). This works in my computer, also playing with the scaling settings of windows 10. However, I've noticed in some computers the text looks bigger. I just can't get a window with a control to preserve the ratio between the window and the elements across all test machines. My application is not DPI aware, so every element should be scaled the same way, but it is every Edit and Static control which just seems to disobey the 16pt Font I'm asking for.
What is the correct way to get a ratio-preserving window with winapi?
Here is an example of what happens. The correct picture is as it looks in my machine (changing the scaling does scale the whole window, and it preserves the ratio between the font and the window) and the right is a Dell computer running the same program (Changing the scaling parameters modifies nothing, the whole window gets scaled but the text still looks bad).
Thank you.