在运行时更改对话框字体
Change dialog font at runtime
我想更改一些对话框的字体。这些对话框的字体不能使用资源编辑器更改,它们将在运行时更改。
有问题的对话框都是基于 ATL/WTL 并且它们的声明与以下示例非常相似:
class CDiscardErrorDlg :
public CDialogImpl<CDiscardErrorDlg>,
public CDialogResize<CDiscardErrorDlg>
{
}
我的问题是如何更改派生的整个 CDialogImpl 的字体 class。
据我所知,更改 DLGTEMPLATE 是可行的方法。
但我不知道如何实现这一目标!?!
我在哪里可以访问 DLGTEMPLATE?
CDialogImpl 是解决我的问题的正确 class 吗?
你有什么想法或网络参考可以帮助我解决这个问题吗?
只是想让你知道我已经找到了解决问题的方法:
这是要做的事情:
从 CDialogImpl
派生一个 class
覆盖 DoModal
在内存中加载 DLGTEMPLATE 模板并
获取 CDialogTemplate 实例来更改模板的字体
将修改后的模板传递给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);
}
};
希望它也能对某人有所帮助。
最好的问候,
我想更改一些对话框的字体。这些对话框的字体不能使用资源编辑器更改,它们将在运行时更改。
有问题的对话框都是基于 ATL/WTL 并且它们的声明与以下示例非常相似:
class CDiscardErrorDlg :
public CDialogImpl<CDiscardErrorDlg>,
public CDialogResize<CDiscardErrorDlg>
{
}
我的问题是如何更改派生的整个 CDialogImpl 的字体 class。 据我所知,更改 DLGTEMPLATE 是可行的方法。 但我不知道如何实现这一目标!?! 我在哪里可以访问 DLGTEMPLATE? CDialogImpl 是解决我的问题的正确 class 吗?
你有什么想法或网络参考可以帮助我解决这个问题吗?
只是想让你知道我已经找到了解决问题的方法:
这是要做的事情:
从 CDialogImpl
派生一个 class覆盖 DoModal
在内存中加载 DLGTEMPLATE 模板并
获取 CDialogTemplate 实例来更改模板的字体
将修改后的模板传递给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); }
};
希望它也能对某人有所帮助。 最好的问候,