我没有几个BS_OWNERDRAWN按钮,并且使用Direct2D和Direct2D来绘制它们。
我还需要在按钮矩形内绘制按钮文本,为此我使用IDWriteTextFormat,它需要在DIPs (设备独立像素)中指定“字体大小”。
我希望这些按钮中的字体大小与其他非所有者绘制的公共控件大小相同,或者与窗口标题栏中显示的系统字体相同。
下面的代码是“切分”版本,用于介绍我的工作方法,当然不会给出预期的结果,因为我在标题栏中获得了字体的LOGFONT结构,该结构给出了字体的宽度(单个字符),而不是IDWriteTextFormat希望在DIP中指定字体大小的字体大小。
class CustomControl
{
protected:
/** Caption text format used to draw text */
CComPtr<IDWriteTextFormat> mpTextFormat;
/** Caption font size (button text size) */
float mFontSize;
};
// Calculate caption bar (default) font size of a top level window
void CustomControl::CalculateFontSize()
{
NONCLIENTMETRICSW metrics;
metrics.cbSize = sizeof(NONCLIENTMETRICSW);
SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0);
LOGFONTW font = metrics.lfCaptionFont;
mFontSize = static_cast<float>(font.lfHeight);
}
// Create text format that is of same font size as default system font
HRESULT CustomControl::CreateTextFormat()
{
HRESULT hr = S_OK;
if (!mpTextFormat)
{
CalculateFontSize();
hr = mpWriteFactory->CreateTextFormat(
L"Arial",
NULL,
DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
mFontSize, // <-- Specifies font size in DIP's..
L"en-us",
&mpTextFormat);
}
return hr;
}下面是测试程序,它显示了窗口标题中的默认系统字体和下面的自定义按钮文本之间的字体大小的差异。

我需要帮助解决如何正确计算IDWriteTextFormat参数的字体大小,使其与其他非BS_OWNERDRAW控件中的文本大小相同,或者在本例中是窗口标题中的默认字体。
编辑:
我在我的CalculateFontSize()中发现了问题,我写了mFontSize = static_cast<float>(font.lfHeight);,但这是负数,所以在-符号后面加上预期的结果:
mFontSize = static_cast<float>(-font.lfHeight);
为什么是阴性?我还不确定,但这个答案很有帮助:
现在,我的问题仍然是,我应该如何更新CalculateFontSize(),以便它获得不是BS_OWNERDRAW而不是窗口标题条字体大小的普通控件的字体大小?
发布于 2021-08-12 12:32:04
我计算出用于IDWriteTextFormat的其他常用控件的字体大小,公式很简单:
float CustomControl::CalculateFontSize()
{
const long units = GetDialogBaseUnits();
const DWORD height = HIWORD(units);
return static_cast<float>(height);
}唯一的问题是,如果您使用通用控件的自定义字体,或者您的对话框使用不同的字体,那么您需要更新您的CalculateFontSize()以考虑这些更改。
但是,要使TextFormat与本机通用控件真正一致,还需要应用字体权重(大胆),例如在创建TextLayout之后(通过使用TextFormat):
std::size_t caption_len = 0;
StringCchLengthW(mCaption, STRSAFE_MAX_CCH, &caption_len);
DWRITE_TEXT_RANGE range = { 0u, caption_len };
mpTextLayout->SetFontSize(mFontSize, range);
mpTextLayout->SetFontWeight(DWRITE_FONT_WEIGHT::DWRITE_FONT_WEIGHT_BOLD, range);https://stackoverflow.com/questions/68756225
复制相似问题