VC++界面编程之--动态安装字体(CFont)
2013-08-27 21:08
197 查看
1. 起因:
在界面编程时,我们经常需要用到自定义字体,来使自己的界面更美观。可要是别人电脑上没有你预定义的字体就麻烦了,你的界面字体会被Windows默认字体所取代,然后控件变形、错位等等问题会接踵而至。
2. 解决办法:
遇到这种情况,我们可以把字体放在Visual Studio的自定义资源中,和exe一起打包。还有一种办法是将字体打包在dll中或者放在一个文件夹中,这样可以减少exe的体积。这里为了方便讲解,我将字体放入至自定义资源中,用一个ID值来索引它即可。
首先,将字体加入至resource文件中,因为我的字体文件是ttf格式的,所以给他取名为TTF,如下图:
我这里使用了2个字体,一个是中文篆体,一个是英文android字体。
接下来,我们需要用到Windows的两个API函数,来让Windows安装字体,或者是卸载字体。当你的程序完全退出时,可以将字体卸载。这两个函数分别是:AddFontMemResourceEx和RemoveFontMemResourceEx,他们是为GDI设计的,而GDI+可以直接使用PrivateFontCollection下的AddMemoryFont函数来进行字体的加载即可。
我这里设计了个类,它可以用在GDI和GDI+上面,可能有的看官会觉得多此一举,直接GDI+不就好了么?为什么还要照顾GDI呢?那是因为,我们的控件的设置字体SetFont还是基于GDI的,GDI+中的字体没办法直接用在上面。
GDI+中的字体要想转换为GDI的HFONT,就得用CreateFontIndirect来转换。转换得到的字体,在不用时,需要用DeleteObject删除之。以下是这个类的完整代码:
class CFontHelper { // Constructor, destructor and operator. public: CFontHelper() : m_Font(NULL), m_hFontRes(NULL), m_pData(NULL), m_nSize(0) { } ~CFontHelper() { DeleteOldFont(); } // Data members. public: Font* m_Font; private: PrivateFontCollection m_FontCollection; FontFamily m_FontFamily; HANDLE m_hFontRes; void* m_pData; int m_nSize; // Operations. public: void DeleteOldFont() { if (m_Font != NULL) { delete m_Font; m_Font = NULL; } if (m_hFontRes != NULL) { RemoveFontMemResourceEx(m_hFontRes); m_hFontRes = NULL; } } // Load font from resource manager. BOOL LoadFont(ATL::_U_STRINGorID resource, ATL::_U_STRINGorID type = _T("ttf")) { CResource res; if( !res.Load(type, resource) ) { ATLASSERT(FALSE); return FALSE; } m_nSize = (int)res.GetSize(); m_pData = res.Lock(); Gdiplus::Status nResults = m_FontCollection.AddMemoryFont(m_pData, m_nSize); if( nResults != Gdiplus::Ok ) { ATLASSERT(FALSE); return FALSE; } DWORD dwNum = 1; SetFontStyle(); return TRUE; } // Modify font style. BOOL SetFontStyle(Gdiplus::FontStyle fontstyle = FontStyleRegular, REAL nFontSize = 14.0F) { int nNumFound = 0; m_FontCollection.GetFamilies(1, &m_FontFamily, &nNumFound); DWORD dwFound = (DWORD)nNumFound; if (nNumFound <= 0) { // You need load font first. ATLASSERT(FALSE); return FALSE; } // Delete old font. DeleteOldFont(); m_Font = new Font(&m_FontFamily, nFontSize, fontstyle, UnitPixel); m_hFontRes = AddFontMemResourceEx(m_pData, (DWORD)m_nSize, NULL, &dwFound); if (m_Font != NULL) { return TRUE; } ATLASSERT(FALSE); return FALSE; } // Turn GDI+ Font to HFONT (ANSI). HFONT FontToHFONT_A(HWND m_hWnd) { if (m_Font == NULL || m_hWnd == NULL) { ATLASSERT(FALSE); return NULL; } Graphics g(m_hWnd); LOGFONTA logFont; m_Font->GetLogFontA(&g, &logFont); logFont.lfQuality = CLEARTYPE_QUALITY; logFont.lfOutPrecision = OUT_TT_ONLY_PRECIS; logFont.lfClipPrecision = CLIP_CHARACTER_PRECIS; logFont.lfCharSet = DEFAULT_CHARSET; logFont.lfPitchAndFamily = DEFAULT_PITCH; return ::CreateFontIndirectA(&logFont); } // Turn GDI+ Font to HFONT (UNICODE). HFONT FontToHFONT_W(HWND m_hWnd) { if (m_Font == NULL || m_hWnd == NULL) { ATLASSERT(FALSE); return NULL; } Graphics g(m_hWnd); LOGFONTW logFont; m_Font->GetLogFontW(&g, &logFont); logFont.lfQuality = CLEARTYPE_QUALITY; logFont.lfOutPrecision = OUT_TT_ONLY_PRECIS; logFont.lfClipPrecision = CLIP_CHARACTER_PRECIS; logFont.lfCharSet = DEFAULT_CHARSET; logFont.lfPitchAndFamily = DEFAULT_PITCH; return ::CreateFontIndirectW(&logFont); } };
好了,让我们新建个窗口,并创建两个CEdit控件,并用SetFont来设置他们的字体,看看是不是很简单?说真的,我们老祖宗创建的篆体是不是很好看呢?看来编程之余还得多多学习国学方面的知识啊,编程之美,国学之美,嘿嘿
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/smile.gif)
。
本文代码工程免费下载链接:http://download.csdn.net/detail/renstarone/6022471
相关文章推荐
- vc 界面编程常用方法 listctrl toolbar
- VC++动态链接库(DLL)编程深入浅出(三) - MFC动态库问题
- Windows下Openssl安装以及编程(VC.net环境)
- 为对话框程序添加工具条和状态栏-界面类编程-VC
- 使用VC 编程改变字体 注意点--需要设置GB2312—CHARSET
- VC中动态改变控件和对话框字体(大小)
- VC++界面编程之--使用STL auto_ptr管理GDI+对象
- 如何编程动态改变IE的代理服务器设置, 并且使之马上生效! - VC
- VC++界面编程总结
- vc中动态设置属性页字体
- VC++ GDI+编程的字体和文本绘制
- Windows下Openssl安装以及编程(VC.net环境)
- VC++界面编程之--托盘图标无缘无故被隐藏的原因
- Java Swing界面编程(4)---获取本地字体
- vc 界面编程常用方法(http://blog.emuch.net/244485/spacelist-blog-itemtypeid-2708.html)
- 通过修改注册表 改变VC6界面字体
- 修改命令行字体颜色以及在rhel 6.3中安装图形界面
- VC++界面编程总结
- 如何动态更改VC控件字体颜色
- 【VC编程技巧】窗体☞3.1利用字体对话框和颜色对话框改变静态标签中字体颜色背景.