У меня есть код, который использует EnumFontFamiliesEX для определения того, установлен ли конкретный шрифт (с использованием его «имя-имя»). Код работал отлично в 32-битном режиме. Когда я компилирую и запускаю его как 64-битный, он все время бросает исключение в процедуру обратного вызова.Возврат результата из обратного вызова Windows в 64-разрядном XE6
Теперь я получил его для работы как у , но только если вместо передачи функции FindFontbyFaceName в качестве 4-го параметра в 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 имеют разные размеры в Win32 и Win64. Самый простой способ - сделать MyResult: LPARAM, а затем дать результат: = (MyResult = -1). – FredS
@FredS Спасибо. Однако ключевой вопрос заключается в том, зачем мне нужна эта локальная/глобальная переменная? Почему я не могу просто использовать результат напрямую? – TomB
@TomB: ваш обратный вызов является ошибкой памяти. См. Мой ответ. –