在运行时更改对话框字体

Change dialog font at runtime

我想更改一些对话框的字体。这些对话框的字体不能使用资源编辑器更改,它们将在运行时更改。

有问题的对话框都是基于 ATL/WTL 并且它们的声明与以下示例非常相似:

class CDiscardErrorDlg :
public CDialogImpl<CDiscardErrorDlg>,
public CDialogResize<CDiscardErrorDlg>
{
}

我的问题是如何更改派生的整个 CDialogImpl 的字体 class。 据我所知,更改 DLGTEMPLATE 是可行的方法。 但我不知道如何实现这一目标!?! 我在哪里可以访问 DLGTEMPLATE? CDialogImpl 是解决我的问题的正确 class 吗?

你有什么想法或网络参考可以帮助我解决这个问题吗?

只是想让你知道我已经找到了解决问题的方法:

这是要做的事情:

  1. 从 CDialogImpl

    派生一个 class
  2. 覆盖 DoModal

  3. 在内存中加载 DLGTEMPLATE 模板并

  4. 获取 CDialogTemplate 实例来更改模板的字体

  5. 将修改后的模板传递给DialogBoxIndirectParam

    模板 class ATL_NO_VTABLE CDialogImplEx : public CDialogImpl { public:

     INT_PTR DoModal(
         _In_ HWND hWndParent = ::GetActiveWindow(),
         _In_ LPARAM dwInitParam = NULL)
     {
         T* pT = static_cast<T*>(this);
         ATLASSERT(pT->m_hWnd == NULL);
    
         LPDLGTEMPLATE pTemplate = nullptr;
    
         HINSTANCE hInstance = AfxGetResourceHandle();
         HRSRC hDlg = AtlFindResource(hInstance, MAKEINTRESOURCE(static_cast<T*>(this)->IDD), RT_DIALOG);
         if (hDlg != NULL)
         {
             HRSRC hDlgInit = AtlFindResource(hInstance, MAKEINTRESOURCE(static_cast<T*>(this)->IDD), _ATL_RT_DLGINIT);
             HGLOBAL hData = NULL;
             BYTE* pInitData = NULL;
    
             if (hDlgInit)
             {
                 hData = ::LoadResource(hInstance, hDlgInit);
                 ATLASSUME(hData != nullptr);
                 pInitData = (BYTE*) ::LockResource(hData);
             }
    
             DWORD dwLastError = 0;
             HGLOBAL hResource = LoadResource(hInstance, hDlg);
             if (hResource != nullptr)
             {
                 DLGTEMPLATE* pTempl = (DLGTEMPLATE*)LockResource(hResource);
                 CDialogTemplate DialogTempl(pTempl);
    
                 DialogTempl.SetFont(_T("Segoe UI"), 20); // Set a huge font
    
                 HGLOBAL hDialogTemplate = DialogTempl.Detach();
    
                 pTemplate = (DLGTEMPLATE*)::GlobalLock(hDialogTemplate);
    
                 ::FreeResource(hResource);
                 hResource = nullptr;
             }
             else
             {
                 dwLastError = ::GetLastError();
             }
         }
    

    #if (_ATL_VER >= 0x0800) // 在这里分配 thunk 结构,在这里我们可以优雅地失败。 BOOL bRet = m_thunk.Init(nullptr, nullptr); 如果(bRet == FALSE) { ::SetLastError(ERROR_OUTOFMEMORY); return-1; } #endif // (_ATL_VER >= 0x0800)

         _AtlWinModule.AddCreateWndData(&m_thunk.cd, (ATL::CDialogImplBaseT< TBase >*)pT);
    

    #ifdef _DEBUG m_bModal = 真; #endif // _DEBUG

         INT_PTR nRet = ::DialogBoxIndirectParam(hInstance, pTemplate, hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam);
    
         if (nRet == -1)
         {
             DWORD dwErr = ::GetLastError();
             dwErr = 0;
         }
    
         return nRet;
         //return CDialogImpl<T>::DoModal(hWndParent, dwInitParam);
     }
    

    };

希望它也能对某人有所帮助。 最好的问候,