我有一些代码使用EnumFontFamiliesEX来确定是否安装了特定的字体(使用它的“facename”)。该代码在32位工作正常。当我编译并运行它为64位时,它在回调例程中不断抛出异常。在64位XE6中返回Windows回调的结果
现在我已经得到了它在这两个工作,但只有当强似功能FindFontbyFaceName的结果作为第四个参数来EnumFontFamiliesEX,我通过本地(或全局)变量 - 在这种情况下MYresult。(然后从中设置结果)。我不明白发生了什么事?任何人都可以解释或指出我更好的方式。 (我对这些字体的机制并没有太多兴趣,因为它是基本的回调机制)。
// single font find callback
function FindFontFace( {$IFDEF CPUX86} lpelf: PLogFont; {$ENDIF}
{$IFDEF CPUX64} lpelf: PEnumLogFontEx; {$ENDIF}
lpntm: PNewTextMetricEx;
AFontType: DWORD; var Aresult: lparam): integer ; stdcall;
begin
result := 0; // 1 shot only please - not interested in any variations in style etc
if (lpelf <> nil) then
Aresult := -1 // TRUE
else
Aresult := 0;
end;
function FindFontbyFaceName(ACanvas: TCanvas; const AFacename: string): boolean;
var
lf: TLogFont;
Myresult: boolean;
begin
MYresult := false;
FillChar(lf, SizeOf(lf), 0);
StrLCopy(lf.lfFaceName, PChar(AFacename), 32);
lf.lfCharSet := DEFAULT_CHARSET;
// this works in both 32 and 64 bit
EnumFontFamiliesEX(ACanvas.Handle, lf, @FindFontFace, lparam(@MYresult), 0);
result := MYresult;
// this works in 32 bit but throws exception in callback in 64 bit
// EnumFontFamiliesEX(ACanvas.Handle, lf, @FindFontFace, lparam(@result), 0);
end;
function FindFont(const AFacename: string): boolean;
var
AImage: TImage;
begin
AImage := Timage.Create(nil);
try
result := FindFontbyFaceName(AImage.Canvas, Afacename);
finally
Aimage.Free;
end;
end;
LPARAMs有不同的大小和Win64平台。最简单的就是制作MyResult:LPARAM,然后让Result:=(MyResult = -1)。 – FredS
@FredS谢谢。关键问题在于为什么我需要这个本地/全局变量呢?为什么我不能直接使用结果? – TomB
@TomB:你的回调是垃圾回忆。看到我的答案。 –