做菜单的时候遇到的一个问题,为了匹配菜单风格,需要一些特殊字体,但是客户的系统里面不一定会有这些字体,而我也不希望我们软件的字体会出现在客户的字体菜单中。因此找了个让字体加载进资源文件,从资源文件读取字体的办法。
-
void NMenu::InstallFont()
-
{
-
m_resourceFont = NULL;
-
HINSTANCE hResInstance = GetModuleHandle(_T("MenuLibrary.dll"));//AfxGetResourceHandle( );
-
HRSRC res = FindResource(hResInstance,MAKEINTRESOURCE(IDR_FONT_MSYH),RT_FONT);//_T("Font"));
-
if(res)
-
{
-
HGLOBAL mem = LoadResource(hResInstance, res);
-
void *data = LockResource(mem);
-
DWORD len = SizeofResource(hResInstance, res);
-
DWORD nFonts = 0;
-
m_resourceFont = AddFontMemResourceEx(data,len,NULL,&nFonts);
-
if(!m_resourceFont)
-
AfxMessageBox(_T("字体加载失败!"));
-
}
-
else
-
{
-
AfxMessageBox(_T("字体加载失败!"));
-
}
-
}
需要注意的是
hResInstance是指向包含资源的模块句柄。一开始开发的时候,自绘菜单类、调用菜单的对话框类和资源类在同一个项目中,所以可以用
HINSTANCE hResInstance = AfxGetResourceHandle( );直接获取本程序的资源句柄,貌似用AfxGetApp()->m_hInstance也是一样的。
后来自绘菜单类封装成dll(MenuLibrary.dll)后,从另一个项目调用菜单dll,那么
hResInstance读到的就是对话框的句柄,因此需要指定自绘菜单类的dll的句柄
HINSTANCE hResInstance = GetModuleHandle(_T("MenuLibrary.dll"));。
当然为了防止以后自己一不小心手贱改了dll的名字,又找到了另一个方法。作为模块句柄,其实在dllMain函数的第一个参数就是模块句柄了,通过一个全局变量去获取,同样可以得到当前模块的句柄哦!
另外还需要注意
HRSRC res = FindResource(hResInstance,MAKEINTRESOURCE(IDR_FONT_MSYH),RT_FONT);这句话,这个跟加载字体资源有一点点关系。顺便记录下加载字体过程。
添加资源->自定义...->资源类型填写Font,资源类视图中出现Font。再次添加资源,此时资源类型里面并不会出现Font,直接选择导入,文件类型选“所有文件”,选择.ttf类型的字体文件。点击确定后,会弹框询问资源类型,再次填写Font,那么文字资源就会加到Font中了。程序中
IDR_FONT_MSYH就是字体的资源ID,而
RT_FONT是资源类型(有看到说字体资源是标准资源来着)。
当然,自定义的时候,你可能填写的不是
Font,而是TTF或者别的,也是可以的。那么再次添加资源的时候,资源类型就会出现新添加的“TTF”类型(“”是系统自己加上去的,应该是为了识别用户自定义吧),选择资源导入后,弹框询问资源类型时选择“TTF”,文字加载到“TTF”类型中。而此时
RT_FONT需要改为_T("TTF")。
关于自定义资源获取的具体知识,可以参照 http://www.cnblogs.com/gakusei/articles/1352922.html
感谢阅读
End
阅读(3633) | 评论(0) | 转发(0) |