内容概述
win10部分字体不能安装(Win10无法安装字体)#程序员##IT教育##软件开发##软件工程师##cpp#锐英源精品原创,禁止全文或局部转载,禁止任何形式的非法使用,侵权必究。点名“简易百科”和闲暇巴盗用锐英源原创内容。背景显示文本是软
win10部分字体不能安装
(Win10无法安装字体)
#程序员##IT教育##软件开发##软件工程师##cpp#
锐英源精品原创, 禁止 全文或局部转载, 禁止 任何形式的非法使用,侵权必究。点名“简易百科”和闲暇巴盗用锐英源原创 内容 。
背景 显示 文本是软件常用 功能 ,而 显示 文本依赖字体,字体的安装卸载有时候很麻烦,内嵌字体资源比较保险。翻译本文,供大家参考学习。
介绍 每隔一段时间,我们开发的应用程序就需要 用户 系统中可能存在也可能不存在的字体。 一个 常见的 解决方 案是将字体 文件 与应用程序设置的其余部分捆绑在一起,并将它们与其他所有 内容 一起安装。诸如 MSI、NSIS 或 Inno 之类的软件包使这很容易。 一个 缺点是您的字体在系统范围内永久可见,例如, 用户 可以随时 删除 /卸载您的应用程序所依赖的字体。为了防止这种情况,您可以实现 代码 ,在每次运行应用程序时检查字体的状态,如果需要,继续自行终止、警告 用户 或即时安装字体。
当然,如果您正在动态安装字体,您可以更进一步,将字体的生命周期限制为应用程序的执行。该 方法 将具有额外的优势,即在一定程度上保护字体的“隐私”,因为它仅在您的应用程序启动时可见。本文介绍了 一个 简单的类,它封装了这样的 功能 ,即允许应用程序从编译的资源中动态安装/卸载字体,只需几行 代码 。
使用 代码 代码 的直接使用将遵循以下步骤:
在项目中包含AP_FontInstaller.h和AP_FontInstaller.cpp。将相关字体 文件 作为资源 添加 到项目中。将CAP_FontInstaller类 标题 插入到主对话框的 标题 中:#include " AP_FontInstaller.h"创建类的对象CAP_FontInstaller:CAP_FontInstaller m_capFontInstaller;在 中OnInitDialog(),将字体资源 添加 到安装程序并安装字体:m_capFontInstaller .AddFont( _T("Camelot MF"),IDR_FONT_CAMELOT,_T("FONTS") ) .AddFont( _T("Cigno MF"),IDR_FONT_CIGNO,_T("FONTS") ); m_capFontInstaller.InstallAllFonts(); 确保 在应用程序终止之前卸载字体,例如,在OnClose() 方法 中:m_capFontInstaller.UninstallAllFonts();只有系统中不存在的字体才会被CAP_FontInstaller类安装和卸载。因此,如果您忘记卸载字体,下次运行应用程序时,它会将这些字体 标记 为已存在,您将无法卸载它们。当然,您也可以 修改 代码 的行为以适应其他用途,这可能不是问题。
兴趣点 该类的 代码 CAP_FontInstaller旨在实现 一个 相当简单的公式,即保留 一个 可以安装和卸载的字体列表。要尊重的规则是,如果系统中已经存在任何这些字体,它们将不会被干预。
因此,首要任务是找出已经安装了哪些字体。这是通过 调用 API 来完成的,而 APIEnumFontFamiliesEx又依赖于回调 函数 的实现。 代码 如下所示:
BOOL CAP_FontInstaller::IsFontAlreadyInSy stem ( const CString& csFontName ){ HDC hDC = GetDC( NULL ); LOGFONT lf = { 0,ANSI_CHARSET,NULL }; FONT_DETAILS fdFont; fdFont.m_csFontName = csFontName; fdFont.m_bInstalled = FALSE; EnumFontFamiliesEx( hDC,&lf,(FONTENUMPROC)_EnumFontFamExProc,(LP ara M)(LPVOID)&fdFont,0 ); return fdFont.m_bInstalled;}int CALLBACK CAP_FontInstaller::_EnumFontFamExProc( ENUMLOGFONTEX * lpelfe,NEWTEXTMETRICEX * /*lpntme*/,int /*nFontType*/,LP ara M lP ara m ){ PFONT_DETAILS pfd = (PFONT_DETAILS)lP ara m; if( pfd->m_csFontName == lpelfe->elfLogFont.lfFaceName ) { pfd->m_bInstalled = TRUE; return FALSE; // Finished } else return TRUE; // Continue}
回调 函数 _EnumFontFamExProc由系统 调用 ,一次只针对一种字体。请注意,face-name 不必(而且通常不是)与字体 文件 名相同。如有疑问,请使用字体查看器。
注:这个不相同,意义很大。
如前所述,安装程序会保留要安装/卸载的字体列表。此列表是 一个 结构数组,其声明如下所示:
typedef struct{ CString m_csFontName; CString m_csInstalledFontFullPath; UINT m_uResID; CString m_csResType; BOOL m_bInstalled; BOOL m_bAlreadyInTheSy stem ;} FONT_DETAILS,*PFONT_DETAILS;
对于传递给公共 方法 的每种字体,都会填充 一个 结构并将其 添加 到数组中AddFont。
安装涉及从应用程序的编译资源中 提取 字体并在相应的系统 文件 夹中创建字体 文件 (视操作系统版本而异)。 代码 如下所示:
BOOL CAP_FontInstaller::WriteFontFile( const CString& csInstalledFontFullPath,UINT uResID,const CString& csResType ){ BOOL bSuccess = FALSE; HINSTANCE hInst = AfxGetResourceHandle(); HRSRC hResource = FindResource( hInst,MAKEINTRESOURCE( uResID ),csResType ); if( hResource ) { HGLOBAL hGlobal = LoadResource( hInst,hResource ); if( hGlobal ) { TCHAR* szTemp = (TCHAR*)LockResource( hGlobal ); UINT uSize = (UINT)SizeofResource( hInst,hResource ); DeleteObject( (HG dio BJ)hGlobal ); CFile cf; if( cf.Open( csInstalledFontFullPath,CFile::modeWrite | CFile::modeCreate ) ) { cf.Write( szTemp,uSize ); cf.Close(); bSuccess = TRUE; } } } return bSuccess;}BOOL CAP_FontInstaller::InstallFont( const CString& csFontName ){ BOOL bSuccess = FALSE; PFONT_DETAILS pfd = NULL; if( FindFontDescription( csFontName,pfd ) && pfd->m_bInstalled == FALSE && pfd->m_bAlreadyInTheSy stem == FALSE && WriteFontFile( pfd->m_csInstalledFontFullPath,pfd->m_uResID,pfd->m_csResType ) ) { bSuccess = ( AddFontResource( pfd->m_csInstalledFontFullPath ) != 0 ); pfd->m_bInstalled = bSuccess; } return bSuccess;}
如您所见, 提取 资源和编写字体 文件 很简单。如果成功,安装字体需要 调用 API AddFontResource。
卸载更简单:首先 调用 API RemoveFontResource,然后 删除 字体 文件 本身。
BOOL CAP_FontInstaller::UninstallFont( const CString& csFontName ){ BOOL bSuccess = FALSE; PFONT_DETAILS pfd = NULL; if( FindFontDescription( csFontName,pfd ) && pfd->m_bInstalled == TRUE && pfd->m_bAlreadyInTheSy stem == FALSE && RemoveFontResource( pfd->m_csInstalledFontFullPath ) ) { _unlink( pfd->m_csInstalledFontFullPath ); pfd->m_bInstalled = FALSE; bSuccess = TRUE; } return bSuccess;}
请记住,如果字体 文件 被系统锁定, 调用 _unlink将失败。
笔记 Windows 在 修改 字体方面特别挑剔。因此,让我提醒您, 代码 按“原样”提供,没有任何明示或暗示的保证。继续需要您自担风险。
用于演示项目的字体(Camelot MF 和 Cigno MF)是 Rick W. Mueller 的财产。
演示应用程序/项目不是很复杂。如果任一字体已安装在您的系统中,则演示将无法安装/卸载字体,因此将无法正常工作。
路由
总结
以上是 为你收集整理的 win10部分字体不能安装-(Win10无法安装字体) 全部内容。
如果觉得 网站内容还不错,欢迎将 网站 推荐给好友。
Win10系统搜不到airpods怎么办?Win10配对不了airpods的解决方法
Airpods是苹果品牌的蓝牙无线耳机,有些用户想将airpods连接电脑,但是遇到Win10系统搜不到airpods的情况,导致没办法配对,这是怎么回事呢?可能是电脑蓝牙没有打开被可发现的设置,本篇整理了详细的解决方法,接下来和小编一起看下去吧。
win10提示任务管理器被管理员停用怎么解决?
任务管理器能够实时的反馈软件的状态已经CPU的使用情况,最近有部分使用win10系统的小伙伴反映说打开被提示任务管理器被管理员停用,面对这个情况不知道要如何解决,那么本期的win10教程就来为大伙进行解答,有需要的用户欢迎来下载使用。
win10系统wifi不能输入怎么办?win10无法输入wifi密码解决方法
现在很多台式和笔记本电脑都是使用了win10系统,也安装了无线网卡,可以通过wifi连接进行使用,但是有些小伙伴发现无法输入密码,导致连接失败,面对这个问题,大伙都不知道怎么解决,那么本期就为大伙带来三种解决方法,一起来了解看看吧。
Win10电脑任务栏图标重叠怎么分开?Win10任务栏图标重叠的解决方法
有些用户在使用电脑的时候,会一次性打开多个窗口进行操作,发现此时的任务栏图标会重叠,导致看不清楚,很影响操作,那么应该怎么设置不重叠呢?其实将窗口设置为平铺显示即可,就此,本篇整理了详细的教程,分享给大家,一起看看吧。
Win10应用商店打不开提示无法加载页面请重试怎么办?
电脑中的应用商店可以帮助用户下载应用程序,非常的方便实用,遇到应用商店打不开的情况是怎么回事呢?最近就有Win10系统的用户反映这个问题,其实造成这个问题的原因有多种,本篇带来了三种不同的解决方法,分享给大家,感兴趣的一起看下去吧。
Win10不能连续输入字符怎么办?Win10不能连续输入字符的解决方法
Win10系统是现在的主流系统,在使用的过程中难免会遇到各种故障问题,最近就有一些用户向小编询问,使用电脑打字的时候发现没办法按同一个键进行连续输入,遇到这种情况怎么处理呢?就此,本篇带来了详细的教程,分享给大家,一起看看吧。
Win10怎么退出已有的管理员账号?Win10退出本地管理员账户方法
最近有用户向小编询问关于如何退出账户的问题,在使用Win10系统的时候,想要登陆一个新的账号,就想把之前的管理员账号退出,会不会很麻烦呢?其实不会,操作简单易上手,就此,本篇整理了详细的教程,分享给大家,感兴趣的一起看看吧。
Win10系统如何禁用Chrome清理功能?
现在大部分用户的电脑都在使用Win10系统,在使用谷歌浏览器浏览的时候,想要禁止使用谷歌浏览器的清理功能,但是不知道具体怎么设置操作,其实方法很简单,针对这一问题,本篇整理了详细的教程,操作简单易上手,分享给大家,一起来看看吧。
查看更多关于win10部分字体不能安装-(Win10无法安装字体)的详细内容...