我有一些代碼使用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:你的回調是垃圾回憶。看到我的答案。 –