加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – WinAPI:GetFontUnicodeRanges – 我不明白结果

发布时间:2020-12-15 09:25:59 所属栏目:大数据 来源:网络整理
导读:我想获得Unicode字体字形范围(Delphi 6): var GS:PGlyphSet; GSSize:LongWord; rng:TWCRange;begin GSSize := GetFontUnicodeRanges(Canvas.Handle,nil); GetMem(Pointer(GS),GSSize); try GS.cbThis:=GSSize; GS.flAccel:=0; GS.cGlyphsSupported:=0; GS.c
我想获得Unicode字体字形范围(Delphi 6):

var GS:PGlyphSet;
    GSSize:LongWord;
    rng:TWCRange;
begin
  GSSize := GetFontUnicodeRanges(Canvas.Handle,nil);
  GetMem(Pointer(GS),GSSize);
  try
    GS.cbThis:=GSSize;
    GS.flAccel:=0;
    GS.cGlyphsSupported:=0;
    GS.cRanges:=0;
    if GetFontUnicodeRanges(Canvas.Handle,GS)<>0 then begin
      for i:=0 to GS.cRanges-1 do begin
        rng := GS.ranges[i];

奇怪的是,Length(GS.ranges)是1,但GS.cRanges是309,当我尝试访问第二个范围GS.ranges [1]时,我得到了一个范围检查错误.在我开启范围检查之前,它已经以某种神奇的方式运作.

供参考的类型(来自Windows模块):

PWCRange = ^TWCRange;
{$EXTERNALSYM tagWCRANGE}
tagWCRANGE = packed record
  wcLow: WCHAR;
  cGlyphs: SHORT;
end;
TWCRange = tagWCRANGE;

PGlyphSet = ^TGlyphSet;
{$EXTERNALSYM tagGLYPHSET}
tagGLYPHSET = packed record
  cbThis: DWORD;
  flAccel: DWORD;
  cGlyphsSupported: DWORD;
  cRanges: DWORD;
  ranges: array[0..0] of TWCRange;
end;
TGlyphSet = tagGLYPHSET;

解决方法

这个结构使用了所谓的struct hack:

> http://c-faq.com/struct/structhack.html
> http://tonywearme.wordpress.com/2011/07/26/c-struct-hack/

范围成员是可变长度数组,内嵌在结构中.但是你无法在静态C类型中实际编码.这就是为什么你调用函数来找出要分配多少内存,然后堆分配结构.如果您在堆栈上分配它,或使用SizeOf(…),那么结构将太小.

最简单的方法是禁用访问范围的代码的范围检查.虽然类型声明说只有0是范围的有效索引,但事实上0..cRanges-1是有效的.

如果您不想禁用相关代码的范围检查,则将指针指向元素0,然后在循环中使用指针算法.

var
  rng: PWCRange; 
....
rng := @GS.ranges[0];
for i:=0 to GS.cRanges-1 do begin
  // use rng^
  inc(rng);
end;

在我看来,这是编写顺序访问代码的最简洁方法.对于随机访问,并且有效范围检查,您将被迫声明一些额外的类型以阻止范围检查:

type 
  TWCRangeArray = array [0..(MaxInt div SizeOf(TWCRange))-1] of TWCRange; 
  PWCRangeArray = ^TWCRangeArray;

然后使用类型转换来访问各个元素:

rng := PWCRangeArray(@GS.ranges)[i];

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读