尝试使用 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.
我看到两个问题:
你不应该获取本地过程的地址。使您的 EnumFontFamExProc
成为正常(非本地)程序。
转换 TStringList(Data)
不正确。 Data
不是 TStringList
实例。它是 TListBoxStrings
是 TStrings
,ListBox1.Items
属性 的类型。
尝试在 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.
我看到两个问题:
你不应该获取本地过程的地址。使您的
EnumFontFamExProc
成为正常(非本地)程序。转换
TStringList(Data)
不正确。Data
不是TStringList
实例。它是TListBoxStrings
是TStrings
,ListBox1.Items
属性 的类型。