在运行时更改对话框字体



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

所讨论的对话框都基于ATL/WTL,它们的声明与以下示例非常相似:

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

我的问题是如何改变整个CDialogImpl派生类的字体。据我所知,更改DLGTEMPLATE是可行的方法。但我不知道如何做到这一点!?我在哪里可以访问DLGTEMPLATE ?是CDialogImpl正确的类来解决我的问题?

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

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

方法如下:

  1. 从CDialogImpl中派生一个类

  2. 覆盖DoModal

  3. 加载DLGTEMPLATE模板到内存和

  4. 接受CDialogTemplate的实例来改变模板的字体

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

    模板<类T,类TBase>类ATL_NO_VTABLE CDialogImplEx:公共CDialogImplEx <T,>{公众:

    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);if (bRet == FALSE){:: SetLastError (ERROR_OUTOFMEMORY);返回1;}#endif//(_ATL_VER>= 0x0800)

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

    # ifdef _DEBUGm_bModal = true;#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);
    }
    

    };

希望对别人也有帮助。最好的祝福,

最新更新