[英]How can I change the default CDialog font for a non-modal dialog?
對於所有對話框控件,必須關閉默認字體的“ClearType”屬性。 通過設置可以對一個控件執行此操作
logfont.lfQuality = ANTIALIASED_QUALITY
有很多建議如何對模態對話框做同樣的事情( http://neelaakash.wordpress.com/2007/12/31/change-default-dialog-font-of-cdialog/等),但那應該是可以用於非模態對話框(使用new和Create(...)方法實例化)。 我試過自己這樣做:
覆蓋“創建”方法,並修改對話框模板:
BOOL CActivationChildDialogLicenseInfo::Create(UINT nIDTemplate,
CWnd* pParentWnd)
{
CDialogTemplate dlt;
int nResult;
// load dialog template
if (!dlt.Load(MAKEINTRESOURCE(nIDTemplate))) return -1;
// set your own font, for example “Arial”, 10 pts.
dlt.SetFont(L"Arial", 12);
// get pointer to the modified dialog template
LPSTR pdata = (LPSTR)GlobalLock(dlt.m_hTemplate);
// let MFC know that you are using your own template
m_lpszTemplateName = NULL;
InitModalIndirect(pdata);
// display dialog box
nResult = CActivationChildDialog::Create(nIDTemplate, pParentWnd);
// unlock memory object
GlobalUnlock(dlt.m_hTemplate);
return nResult ;
}
似乎這個方法什么都不做(它被稱為,我已經檢查了內部的斷點)。 我試着打電話
nResult = CActivationChildDialog::Create(NULL, pParentWnd);
......但是得到了很多ASSERT。
我也嘗試覆蓋'OnSetFont'方法:
void CActivationChildDialogLicenseInfo::OnSetFont(CFont *pFont)
{
CActivationChildDialog::OnSetFont(pFont);
LOGFONT logfont;
pFont->GetLogFont(&logfont);
LOGFONT logfont2=logfont;
pFont->DeleteObject();
logfont2.lfItalic = true;
logfont2.lfQuality = ANTIALIASED_QUALITY;
pFont->CreateFontIndirect(&logfont2);
}
這會在運行時導致ASSERT並導致使用非常大的字體(丟失默認字體設置,不接受新的指定設置)...我不知道為什么。
請指教,如何更改所有對話框控件將“繼承”的默認對話框字體?
非常感謝你。
首先:簡單,可靠的方法是創建對話框,然后將WM_SETFONT
(或調用SetFont()
)發送到對話框及其中的每個控件。 我將在下面告訴你如何做到這一點,但首先,這就是為什么你已經嘗試過的兩種策略沒有(也做不到)的原因:
首先,如果您希望使用已加載的對話框模板,則應調用CDialog::CreateIndirect()
。
但是不要打擾。 該對話框的模板包含只有面部名稱和大小-它不允許你指定其他LOGFONT值,如lfQuality
。 如果是這樣 ,您可以在資源定義中指定它,並避免編寫任何運行時代碼!
WM_SETFONT
從理論上講,你可以做到這一點。 但這不切實際。 您的代碼有幾個問題:首先,您必須為每個子控件攔截此消息,以便它執行任何有用的操作:對話框本身可能不會呈現任何文本。 但更糟糕的是,您將原始字體傳遞給基類(將其傳遞給默認窗口過程,該過程在內部存儲以供以后使用)然后立即銷毀它 - 這意味着對話框(以及使用該字體的所有其他內容,包括所有子控件)將嘗試使用偽造字體繪制文本,並因此恢復為默認字體。 最后,您正在創建一個附加到由MFC創建和銷毀的臨時對象( pFont
)的新字體 - 在內部,您正在使用的CFont對象將從字體句柄中分離並銷毀,泄漏字體對象的句柄什么都沒用。
HFONT是Windows用於表示字體對象的句柄類型。 像大多數GDI一樣,有用於創建字體的特定函數,以及用於銷毀它們的通用DeleteObject()
函數。
CFont是HFONTs的輕量級包裝機。 CFont實例可以與現有的HFONT連接或分離,或用於創建新的實例。 如果CFont實例在解析器執行時仍然附加到HFONT,它將調用DeleteObject()
來銷毀底層對象。 在內部,MFC利用在調用各種消息處理程序(例如OnSetFont)時附加和分離HFONT的臨時CFont實例。 值得記住的是,在內部,Windows對CFont一無所知,並且在任何給定的時間點,單個HFONT可能屬於0個或更多CFont實例。
當您創建一個新字體 - 無論它是否包含在CFont對象中 - 您是該字體的所有者,並且您有責任在完成使用后銷毀它。 將它傳遞給WM_SETFONT
( CWnd::SetFont()
)不會改變所有權! 這實際上非常有用,因為它允許你將相同的字體傳遞給多個窗口,而不用擔心哪一個會破壞它 - 你仍然是所有者,所以你可以(並且必須)自己銷毀它(一旦沒有窗戶仍在使用它)。
所以你現在應該有足夠的背景來理解必要的步驟:
// define this as a class member - class destructor then handles step four!
CFont m_nonCleartypeFont;
BOOL CActivationChildDialogLicenseInfo::Create(UINT nIDTemplate,
CWnd* pParentWnd)
{
// step one: create dialog normally
BOOL nResult = CActivationChildDialog::Create(nIDTemplate, pParentWnd);
// step two: create custom font
// relying on destructor to destroy font once we're done with it
// so be careful to only create it once!
if ( NULL == m_nonCleartypeFont.m_hObject )
{
CFont* pOriginalFont = GetFont(); // use template font as... template!
// pull information from original font
LOGFONT logfont;
pOriginalFont->GetLogFont(&logfont);
// make font adjustments:
// specify italics
logfont.lfItalic = true;
// and non-cleartype antialiasing
logfont.lfQuality = ANTIALIASED_QUALITY;
// create our font based on adjusted information
m_nonCleartypeFont.CreateFontIndirect(&logfont);
}
// step three: set our custom font on the dialog and all children
SetFont(&m_nonCleartypeFont, FALSE);
// Send message to quickly set this font for all children.
// See documentation for SendMessageToDescendants()
// - this is actually the example given!
SendMessageToDescendants(WM_SETFONT,
(WPARAM)m_nonCleartypeFont.m_hObject,
MAKELONG(FALSE, 0),
FALSE);
return nResult;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.