Mam trochę kodu, który używa EnumFontFamiliesEX, aby ustalić, czy konkretna czcionka (używając jej "nazwy użytkownika") jest zainstalowana. Kod działał poprawnie w wersji 32-bitowej. Kiedy skompilowałem i uruchomiłem go jako 64-bitowy, wciąż zgłaszano wyjątek w procedurze wywołania zwrotnego.Powracający wynik z wywołania zwrotnego Windows w 64-bitowym XE6
Mam teraz to działa zarówno pod , ale tylko wtedy, gdy zamiast podania wyniku FindFontbyFaceName jako czwartego parametru do EnumFontFamiliesEX, przekazuję lokalną (lub globalną) zmienną - MYresult w tym przypadku. (A następnie ustaw wynik z tego). Nie rozumiem, co się dzieje? Czy ktoś może mi wytłumaczyć lub wskazać lepszy sposób? (Nie jestem tak bardzo zainteresowany mechaniką czcionek, jak podstawową mechaniką zwrotną).
// 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 są w różnych rozmiarach i Win32 Win64. Najprościej byłoby zrobić MyResult: LPARAM, a następnie pozwolić Wynik: = (MyResult = -1). – FredS
@FredS Dzięki. Kluczową kwestią jest jednak, dlaczego w ogóle potrzebuję tej zmiennej lokalnej/globalnej? Dlaczego nie mogę po prostu użyć wyniku bezpośrednio? – TomB
@TomB: Twoje oddzwanianie niszczy pamięć. Zobacz moją odpowiedź. –