在开发 Windows 桌面应用程序时,有效处理高 DPI 设置对于确保应用界面在现代显示器上看起来清晰且功能正常非常关键。本文将引导您使用 Duilib 配置应用程序以处理高 DPI 设置。
准备工作
- Visual Studio(推荐使用 2015 或更高版本)
- Duilib(确保已克隆或下载最新版本)
1.配置高 DPI 设置
为确保您的应用程序具有 DPI-aware:
-
修改应用程序清单:
- Visual Studio 提供了通过应用程序清单轻松设置高 DPI 的方法。可以通过打开项目属性,导航到 Manifest Tool 设置,将 DPI Awareness 设置为
Per Monitor High DPI Aware
。这告诉 Windows 您的应用程序打算自己处理高 DPI 显示器的缩放。
- Visual Studio 提供了通过应用程序清单轻松设置高 DPI 的方法。可以通过打开项目属性,导航到 Manifest Tool 设置,将 DPI Awareness 设置为
-
代码:
在 Windows 应用程序中,系统会通过发送
1. 监听 DPI 变化WM_DPICHANGED
消息来通知应用程序 DPI 已经改变。因此,首先需要在应用程序的消息处理函数中监听这个消息:-
LRESULT CMainWnd::HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { LRESULT lRes = 0; switch (uMsg) { case WM_TIMER: lRes = OnTimer(uMsg, wParam, lParam, bHandled); break; case WM_DPICHANGED: lRes = OnDPIChanged(uMsg, wParam, lParam, bHandled); break; default: break; } return lRes; }
-
2. 响应 DPI 变化
一旦接收到 WM_DPICHANGED
消息,应用程序需要对此作出响应。这包括调整窗口大小和更新界面元素:
LRESULT CMainWnd::OnDPIChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
int newDPI = LOWORD(wParam);
setDPI(newDPI);
RECT* const prcNewWindow = (RECT*)lParam;
SetWindowPos(m_hWnd,
NULL,
prcNewWindow->left,
prcNewWindow->top,
prcNewWindow->right - prcNewWindow->left,
prcNewWindow->bottom - prcNewWindow->top,
SWP_NOZORDER | SWP_NOACTIVATE);
if (m_pm.GetRoot() != NULL) m_pm.GetRoot()->NeedUpdate();
bHandled = false;
return 0;
}
3. 更新 DPI 设置
在 setDPI
方法中,DPI 值被更新,并触发界面元素的重绘,以确保所有元素都根据新的 DPI 设置进行缩放和显示:
void CMainWnd::setDPI(int DPI)
{
if (m_currentDPI != DPI) {
m_pm.SetDPI(DPI);
m_currentDPI = DPI;
if (m_pm.GetRoot() != NULL) {
m_pm.GetRoot()->NeedUpdate();
}
}
}
综合设置
在 WinMain
函数中,初始化窗口和设置资源路径,同时在创建窗口后即刻检测并应用当前监视器的 DPI:
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
::CoInitialize(NULL);
CPaintManagerUI::SetInstance(hInstance);
CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath() + _T("skin\\HiDPITest"));
CFrameWnd *pFrame = new CFrameWnd(_T("Main_dlg.xml"));
pFrame->Create(NULL, _T("HiDPI Demo Window1"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);
pFrame->ShowWindow();
int currentDPI = CDPI::GetMainMonitorDPI();
pFrame->setDPI(currentDPI);
pFrame->CenterWindow();
CPaintManagerUI::MessageLoop();
delete pFrame;
::CoUninitialize();
return 0;
}
正确处理高 DPI 设置对于提升用户体验至关重要,特别是在高分辨率显示设备越来越普及的今天。通过上述步骤,您的 Duilib 应用程序将能够优雅地适应不同的 DPI 设置,确保界面元素在所有设备上都能正确显示。