使用 Duilib 设置高 DPI 显示适应性

在开发 Windows 桌面应用程序时,有效处理高 DPI 设置对于确保应用界面在现代显示器上看起来清晰且功能正常非常关键。本文将引导您使用 Duilib 配置应用程序以处理高 DPI 设置。

准备工作

  • Visual Studio(推荐使用 2015 或更高版本)
  • Duilib(确保已克隆或下载最新版本)

1.配置高 DPI 设置

为确保您的应用程序具有 DPI-aware:

  1. 修改应用程序清单

    • Visual Studio 提供了通过应用程序清单轻松设置高 DPI 的方法。可以通过打开项目属性,导航到 Manifest Tool 设置,将 DPI Awareness 设置为 Per Monitor High DPI Aware。这告诉 Windows 您的应用程序打算自己处理高 DPI 显示器的缩放。

  2. 代码
    1. 监听 DPI 变化

         在 Windows 应用程序中,系统会通过发送 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 设置,确保界面元素在所有设备上都能正确显示。

  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
duilib是一个基于C++的开源UI库,用于快速开发Windows桌面应用程序。它提供了丰富的UI控件和功能,其中包括设置定时器的功能。 在duilib中,可以通过CControlUI类的SetTimer方法来设置定时器。该方法的原型如下: ```cpp void SetTimer(UINT nTimerID, UINT uElapse); ``` 其中,nTimerID是定时器的ID,uElapse是定时器的间隔时间(以毫秒为单位)。 下面是一个使用duilib设置定时器的示例代码: ```cpp class CMyWindow : public CWindowWnd, public INotifyUI { public: CMyWindow() { // 创建一个定时器,ID为1,间隔时间为1000毫秒(1秒) SetTimer(1, 1000); } void OnTimer(UINT nTimerID) { if (nTimerID == 1) { // 定时器触发后执行的操作 // ... } } void Notify(TNotifyUI& msg) { if (msg.sType == _T("timer")) { // 定时器消息处理 OnTimer(msg.wParam); } } }; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow) { // 初始化duilib CPaintManagerUI::SetInstance(hInstance); CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath()); // 创建窗口 CMyWindow wnd; if (!wnd.Create(NULL, _T("duilib定时器示例"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE)) { return 0; } // 显示窗口 wnd.CenterWindow(); wnd.ShowWindow(); // 消息循环 CPaintManagerUI::MessageLoop(); return 0; } ``` 在上述示例代码中,我们创建了一个CMyWindow类,该类继承自CWindowWnd和INotifyUI接口。在构造函数中,我们调用SetTimer方法设置了一个定时器,ID为1,间隔时间为1000毫秒(1秒)。然后,在OnTimer方法中处理定时器触发后的操作。最后,在Notify方法中处理定时器消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值