尝试使用 EnumFontFamiliesEx 在 Windows 64 位平台上枚举字体时收到访问冲突

Receive Access violation when trying enumerate Fonts on Windows 64-bit Platform with EnumFontFamiliesEx

尝试在 Windows 64 位平台上使用 EnumFontFamiliesEx 枚举字体时收到访问冲突。

尝试了很多方法来解决我的问题,但非常重视您的帮助!!!

First chance exception at &0000000000713034. Exception class $C0000005 with message 'c0000005 ACCESS_VIOLATION'. Process Progect1.exe

这是我的程序:

{ On Windows 64-bit Platform "EnumFontFamiliesEx" shows Error     }
{ On Windows 32-bit Platform "EnumFontFamiliesEx" works perfectly }
{ On Form TListBox "ListBox1" and TButton "Button1"               }

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TFontTypeObject = class (TObject)
    FtoFontType: Integer;
    FtoFlags: Cardinal;
  end;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

  function EnumFontFamExProc(var LogFont: TEnumLogFontEx; var TextMetric: TNewTextMetric; FontType: Integer; Data: Pointer): Integer; stdcall;
  var
    Strings: TStringList;
    TempFaceName: String;
    FontTypeObject: TFontTypeObject;
  begin
    Strings:= TStringList(Data);
    TempFaceName:= LogFont.elfLogFont.lfFaceName;

    if (Strings.IndexOf(TempFaceName) = -1) then      // ERROR HERE

    // First chance exception at &0000000000713034. Exception class $C0000005 with message 'c0000005 ACCESS_VIOLATION'. Process Progect1.exe

      begin
        FontTypeObject:= TFontTypeObject.Create;
        FontTypeObject.FtoFontType:= FontType;
        FontTypeObject.FtoFlags:= TextMetric.ntmFlags;
        Strings.AddObject(TempFaceName, TFontTypeObject(FontTypeObject));
       end;
     Result:= 1;
  end;

var
  DC: HDC;
  LogFont: TLogFont;
begin
  DC:= GetDC(0);
  try
    FillChar(LogFont, SizeOf(LogFont), 0);
    LogFont.lfCharSet:= DEFAULT_CHARSET;
    LogFont.lfFaceName:= '';
    LogFont.lfPitchAndFamily:= 0;
    EnumFontFamiliesEx(DC, LogFont, @EnumFontFamExProc, LPARAM(ListBox1.Items), 0);
    ListBox1.Sorted:= TRUE;
  finally
    ReleaseDC(0, DC);
  end;
end;

end.

我看到两个问题:

  1. 你不应该获取本地过程的地址。使您的 EnumFontFamExProc 成为正常(非本地)程序。

  2. 转换 TStringList(Data) 不正确。 Data 不是 TStringList 实例。它是 TListBoxStringsTStringsListBox1.Items 属性 的类型。