IFontDisp和CFontHolder的使用问题

问题

最近处理一个控件Bug,发现COM组件字体读取有趣问题。
Bug描述:
      简体中文下的应用编写:
         ocx.Font.Name = "宋体"       '对控件的字体初始化
         text1.text = ocx.CellFont(1,1, KDS_FontProp_Name)   '读取单元格1,1的字体
     控件说明:当相应单元格未设置字体时,将使用控件的字体设置。
     问题:
        在繁体中文下运行,text1得到字体名为乱码。

分析:
先简化问题:
尝试:在简体操作系统下
       ocx.Font.Name = “abcd”
       Msgbox KDS12.CellFont(1,1, KDS_FontProp_Name)
       得到输出:abcd。
       呵呵,这显然不对。
       MsgBox KDS12.Font.Name
       输出:Arial  
       嗯,这才是对的,哪有什么abcd字体啊。
       好了,问题找到了,"宋体"两个字到繁体中文下,当然会变成乱码啦。
 
因此,初步确定是CellFont接口的问题。

查看代码:
      取字体的方法如下:
      CFontHolder &rFontHolder = pControl->InternalGetFont();
      HFONT hFont = rFontHolder.GetFontHandle();
      LOGFONT lf;
      CFont *pFont = CFont::FromHandle(hFont);
      pFont->GetLogFont(&lf);
      OK,明白了,是通过LOGFONT取字体信息。
      再试一下,不管你输入什么字体名,它取出来就是啥。嘿。

尝试换种方式取字体信息:
     (代码不完全,未处理出错情况,只是举例)
     IFont * pIFont = NULL;
     rFontHolder.GetFontDispatch()->QueryInterface(&pIFont)))
     然后,用IFont的接口取信息,如:get_Name(&bstrTemp)
     试试,这下取出是正确应用的字体,当设置错误时,会取出默认值。
     错误排除。

似乎的结论:
     采用 IFontDisp接口方式设置的字体信息,
     当采用pControl->InternalGetFont()取回CFontHolder后,如果通过GetFontHandle 取出Windows句柄,然后获取字体信息,并不一定是真实的应用值(即例子中,一旦出错,并不取出系统默认值,而是错误的设置值,其中保存的似乎是一个临时值,而非实际的最终应用值)
     如果采用GetFontDispatch 取出IFontDisp,然后再取出IFont来取值,才是正确地。
     Why? 天晓得。

时间: 2022-12-19

IFontDisp和CFontHolder的使用问题的相关文章

如何在ActiveX控件中使用字体

字体的使用是ActiveX控件制作过程中不可缺少的部分.本文将深入浅出地介绍在ActiveX控件中制作过程中如何使用字体.本文所提及的ActiveX控件制作是指利用VC++6.0的MFC ActiveX ControlWizard 工具,用其它方法制作 ActiveX 控件本文不作讨论. 本文专门设置了一些例程,以便您能够更好地掌握这些内容.这些例程都是完整的ActiveX控件制作源代码.为了突出重点,本文仅对字体使用相关部分的源代码作较详细的介绍,其余部分的代码本文不作过多讨论.字体作为一种属

如何将CB创建的Activex设定为脚本安全

深入解析ATL上就有,可惜我来晚了,昨天刚解决这个问题. 写在这个里面的public,就可以了 class ATL_NO_VTABLE TSignActiveFormXImpl: VCLCONTROL_IMPL(TSignActiveFormXImpl, SignActiveFormX, TSignActiveFormX, ISignActiveFormX, DIID_ISignActiveFormXEvents) { void __fastcall ActivateEvent(TObject

三维-关于Arcengine for .net 的一些问题

问题描述 关于Arcengine for .net 的一些问题 一.在图层上加点时,不能修改其样式esriSimpleMarkerStyle.esriSMSSquare,运行时看到点的样式都是esriSMSCircle.代码如下: IMarkerElement pMarkerElement; IMarkerSymbol pMarkerSymbol; ISimpleMarkerSymbol pSimpleMarkerSymbol = new SimpleMarkerSymbolClass(); p