Make the program DPI aware

- Set dpi-awareness to true in the manifest (i.e., "system-dpi aware")
- Check system dpi and scale and/or position widgets and windows
  that depend on the system dpi (only components within the status
  window are affected).

Note: Declaring dpi awareness eliminates automatic rescaling of
windows that causes blurred text on high dpi monitors.
Windows 8.1 and later allow per monitor dpi setting which is
not handled here.
pull/99/head
Selva Nair 2016-11-19 16:15:10 -05:00
parent 23771164a2
commit 5fe0d5225e
5 changed files with 66 additions and 11 deletions

42
main.c
View File

@ -302,6 +302,47 @@ ResumeConnections()
}
}
/*
* Set scale factor of windows in pixels. Scale = 100% for dpi = 96
*/
static void
dpi_setscale(UINT dpix)
{
/* scale factor in percentage compared to the reference dpi of 96 */
if (dpix != 0)
o.dpi_scale = MulDiv(dpix, 100, 96);
else
o.dpi_scale = 100;
PrintDebug(L"DPI scale set to %u", o.dpi_scale);
}
/*
* Get dpi of the system and set the scale factor.
* The system dpi may be different from the per monitor dpi on
* Win 8.1 later. We set dpi awareness to system-dpi level in the
* manifest, and let Windows automatically re-scale windows
* if/when dpi changes dynamically.
*/
static void
dpi_initialize(void)
{
UINT dpix = 0;
HDC hdc = GetDC(NULL);
if (hdc)
{
dpix = GetDeviceCaps(hdc, LOGPIXELSX);
ReleaseDC(NULL, hdc);
PrintDebug(L"System DPI: dpix = %u", dpix);
}
else
{
PrintDebug(L"GetDC failed, using default dpi = 96 (error = %lu)", GetLastError());
dpix = 96;
}
dpi_setscale(dpix);
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
@ -313,6 +354,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
/* Save Window Handle */
o.hWnd = hwnd;
dpi_initialize();
s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));

2
main.h
View File

@ -114,4 +114,6 @@ void PrintDebugMsg(TCHAR *msg);
DWORD GetDllVersion(LPCTSTR lpszDllName);
#define DPI_SCALE(x) MulDiv(x, o.dpi_scale, 100)
#endif

View File

@ -821,6 +821,19 @@ Cleanup (connection_t *c)
CloseHandle (c->exit_event);
c->exit_event = NULL;
}
/*
* Helper to position and scale widgets in status window using current dpi
* Takes status window width and height in screen pixels as input
*/
void
RenderStatusWindow(HWND hwndDlg, UINT w, UINT h)
{
MoveWindow(GetDlgItem(hwndDlg, ID_EDT_LOG), DPI_SCALE(20), DPI_SCALE(25), w - DPI_SCALE(40), h - DPI_SCALE(70), TRUE);
MoveWindow(GetDlgItem(hwndDlg, ID_TXT_STATUS), DPI_SCALE(20), DPI_SCALE(5), w - DPI_SCALE(25), DPI_SCALE(15), TRUE);
MoveWindow(GetDlgItem(hwndDlg, ID_DISCONNECT), DPI_SCALE(20), h - DPI_SCALE(30), DPI_SCALE(110), DPI_SCALE(23), TRUE);
MoveWindow(GetDlgItem(hwndDlg, ID_RESTART), DPI_SCALE(145), h - DPI_SCALE(30), DPI_SCALE(110), DPI_SCALE(23), TRUE);
MoveWindow(GetDlgItem(hwndDlg, ID_HIDE), w - DPI_SCALE(130), h - DPI_SCALE(30), DPI_SCALE(110), DPI_SCALE(23), TRUE);
}
/*
* DialogProc for OpenVPN status dialog windows
@ -871,22 +884,13 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
/* Set size and position of controls */
RECT rect;
GetClientRect(hwndDlg, &rect);
MoveWindow(hLogWnd, 20, 25, rect.right - 40, rect.bottom - 70, TRUE);
MoveWindow(GetDlgItem(hwndDlg, ID_TXT_STATUS), 20, 5, rect.right - 25, 15, TRUE);
MoveWindow(GetDlgItem(hwndDlg, ID_DISCONNECT), 20, rect.bottom - 30, 110, 23, TRUE);
MoveWindow(GetDlgItem(hwndDlg, ID_RESTART), 145, rect.bottom - 30, 110, 23, TRUE);
MoveWindow(GetDlgItem(hwndDlg, ID_HIDE), rect.right - 130, rect.bottom - 30, 110, 23, TRUE);
RenderStatusWindow(hwndDlg, rect.right, rect.bottom);
/* Set focus on the LogWindow so it scrolls automatically */
SetFocus(hLogWnd);
return FALSE;
case WM_SIZE:
MoveWindow(GetDlgItem(hwndDlg, ID_EDT_LOG), 20, 25, LOWORD(lParam) - 40, HIWORD(lParam) - 70, TRUE);
MoveWindow(GetDlgItem(hwndDlg, ID_DISCONNECT), 20, HIWORD(lParam) - 30, 110, 23, TRUE);
MoveWindow(GetDlgItem(hwndDlg, ID_RESTART), 145, HIWORD(lParam) - 30, 110, 23, TRUE);
MoveWindow(GetDlgItem(hwndDlg, ID_HIDE), LOWORD(lParam) - 130, HIWORD(lParam) - 30, 110, 23, TRUE);
MoveWindow(GetDlgItem(hwndDlg, ID_TXT_STATUS), 20, 5, LOWORD(lParam) - 25, 15, TRUE);
RenderStatusWindow(hwndDlg, LOWORD(lParam), HIWORD(lParam));
InvalidateRect(hwndDlg, NULL, TRUE);
return TRUE;

View File

@ -173,6 +173,7 @@ typedef struct {
HANDLE netcmd_semaphore;
version_t version;
char ovpn_version[16]; /* OpenVPN version string: 2.3.12, 2.4_alpha2 etc.. */
unsigned int dpi_scale;
} options_t;
void InitOptions(options_t *);

View File

@ -26,4 +26,10 @@
</requestedPrivileges>
</security>
</trustInfo>
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:windowsSettings
xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>