如何在DirectWrite中使用默认UI字体绘制文本? [英] How to draw text with the default UI font in DirectWrite?

查看:411
本文介绍了如何在DirectWrite中使用默认UI字体绘制文本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

CreateTextFormat 方法需要一个fontFamilyName参数。如何创建使用默认UI字体的IDWriteTextFormat?解决方案请注意,这里的所有代码都没有任何检查(太多的方法在这里返回HRESULT,会吹这个例子!)。

为获取系统宽字体,你应该使用这个:

(这是从另一个stackoverflow问题!)

  NONCLIENTMETRICS ncm; 
ncm.cbSize = sizeof(ncm);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS,ncm.cbSize,& ncm,0);
HFONT hFont = CreateFontIndirect(&(ncm.lfMessageFont)); //

现在使用这个:

  HDC hdc = BeginPaint(...); //创建一个设备上下文
SelectObject(hdc,hFont);
//你的字体现在被设置为当前的设备上下文
//做某事

DeleteObject(hFont); //不要忘记最后这样做!

问题!



这个解决方案真的很原始,在我看来丑陋。



另一种解决方案是获得IDWriteFont(看起来很丑但很好):
$ b $

//除了hfont之外,与上面相同,而是使用
NONCLIENTMETRICS ncm;

ncm.cbSize = sizeof(ncm);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS,ncm.cbSize,& ncm,0);

IDWriteFactory * dwriteFactory_;
DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast< IUnknown **>(&dwriteFactory_)
);

IDWriteGdiInterop * gdiInterop = NULL;
dwriteFactory _-> GetGdiInterop(& gdiInterop);

IDWriteFont * sys_font = nullptr;
gdiInterop-> CreateFontFromLOGFONT(& ncm.lfMessageFont,& sys_font); //现在我们拥有了!

//文本格式现在可以像这样获得
//我们需要字体的字体系列
IDWriteFontFamily * family = nullptr;
sys_font-> GetFontFamily(& family);

//现在我们得到我们家族的本地化名字
IDWriteLocalizedStrings * font_family_name = nullptr;
family-> GetFamilyNames(& font_family_name);
UINT32 index = 0;
UINT32长度= 0;
BOOL exists = false;
font_family_name-> FindLocaleName(Len-us,& index,& exists);
font_family_name-> GetStringLength(index,& length);
wchar_t * name = new wchar_t [length + 1];
font_family_name-> GetString(index,name,length + 1);
wprintf(L%s \\\
,name);

//一些用户定义的东西
DWRITE_FONT_WEIGHT font_weight = DWRITE_FONT_WEIGHT_BLACK;
DWRITE_FONT_STYLE font_style = DWRITE_FONT_STYLE_ITALIC;
DWRITE_FONT_STRETCH font_stretch = DWRITE_FONT_STRETCH_EXPANDED;

IDWriteTextFormat * text_format = nullptr;
dwriteFactory _-> CreateTextFormat(name,nullptr,font_weight,font_style,font_stretch,10.0,Len-us,& text_format);

即使没有检查,代码在我的电脑上运行也没有任何问题,并给出了与第一个相同的结果解决方案(Windows 10,字体家族名称是Segoe UI)。



来源:
一般Microsoft DirectWrite API文档



CreateIndirectFont文档



如何枚举字体族,Microsoft文档


The CreateTextFormat method expects a fontFamilyName parameter. How do I create an IDWriteTextFormat that uses the default UI font?

解决方案

Please note, that all code here is done without any checks (too many methods here return HRESULT, would blow this example up!).

For acquiring the system wide font you should use this:

(This is from another stackoverflow question!)

NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(ncm);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
HFONT hFont = CreateFontIndirect(&(ncm.lfMessageFont)); //

for paint now use this:

HDC hdc = BeginPaint(...); //Creates a device context
SelectObject(hdc, hFont);
//Your font is now set for the current device context
//do something

DeleteObject(hFont); //Don't forget to do this at the end!

A bit changed from this question!

This solution is really raw and in my opinion ugly.

Alternative solution do get the IDWriteFont (looks ugly but is fine):

//just the same as above except the hfont, instead use
NONCLIENTMETRICS ncm;

ncm.cbSize = sizeof(ncm);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);

IDWriteFactory *dwriteFactory_;
DWriteCreateFactory(
    DWRITE_FACTORY_TYPE_SHARED,
    __uuidof(IDWriteFactory),
    reinterpret_cast<IUnknown**>(&dwriteFactory_)
);

IDWriteGdiInterop* gdiInterop = NULL;
dwriteFactory_->GetGdiInterop(&gdiInterop);

IDWriteFont* sys_font = nullptr;
gdiInterop->CreateFontFromLOGFONT(&ncm.lfMessageFont, &sys_font); //Now we have it!

//The text format can now be aquired like this
//We need the font family of our font
IDWriteFontFamily* family = nullptr;
sys_font->GetFontFamily(&family);

//Now we have to get the "localized" name of our family
IDWriteLocalizedStrings* font_family_name = nullptr;
family->GetFamilyNames(&font_family_name);
UINT32 index = 0;
UINT32 length = 0;
BOOL exists = false;
font_family_name->FindLocaleName(L"en-us", &index, &exists);
font_family_name->GetStringLength(index, &length);
wchar_t* name = new wchar_t[length + 1];
font_family_name->GetString(index, name, length + 1);
wprintf(L"%s\n", name);

//Some user defined stuff
DWRITE_FONT_WEIGHT font_weight = DWRITE_FONT_WEIGHT_BLACK;
DWRITE_FONT_STYLE font_style = DWRITE_FONT_STYLE_ITALIC;
DWRITE_FONT_STRETCH font_stretch = DWRITE_FONT_STRETCH_EXPANDED;

IDWriteTextFormat* text_format = nullptr;
dwriteFactory_->CreateTextFormat(name, nullptr, font_weight, font_style, font_stretch, 10.0, L"en-us", &text_format);

Even without checks, code runs on my computer without any problems and gives me the same result as the first solution (Windows 10, Font family name is Segoe UI).

Sources: General Microsoft DirectWrite API documentation

CreateIndirectFont Documentation

How to enumerate font families, Microsoft documentation

这篇关于如何在DirectWrite中使用默认UI字体绘制文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆