我对 Delphi 还很陌生,我正在尝试使用不同的单位来存储 TLists 和 TObjects,以及基于以前的组合框选择生成其他组合框选项。我在运行后立即收到以下错误消息:
项目 Project1.exe 引发异常类 $C0000005,并带有消息“0x004087d7 处的访问冲突:读取地址 0x00000000”
模块“Project1.exe”中地址 00408813 处的访问冲突。读取地址 00000000。
我已经跟踪了调试工具中的步骤,但我不明白为什么它不起作用。我用谷歌搜索了这个问题并找到了一些解决方案,但似乎没有任何适用于我当前的问题。
unit MainForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TfMain = class(TForm)
lCPU: TLabel;
cbCPU: TComboBox;
lGPU: TLabel;
cbGPU: TComboBox;
lMotherboard: TLabel;
cbMotherboard: TComboBox;
lRAM: TLabel;
cbRAM: TComboBox;
eCompatible: TEdit;
lCompatible: TLabel;
eCost: TEdit;
lCost: TLabel;
Label11: TLabel;
lbCPU: TListBox;
lbMotherboard: TListBox;
lbGPU: TListBox;
lbRAM: TListBox;
procedure FormShow(Sender: TObject);
procedure cbCPUChange(Sender: TObject);
private
{ Private declarations }
public
// procedure cbCPUpopulate();
end;
type TGPU = class(TObject)
public
name : string;
vram : integer;
clock : integer;
price : string;
end;
type TCPU = class(TObject)
public
name : string;
cores : integer;
clock : real;
intel : boolean;
amd : boolean;
price : string;
end;
type TMobo = class(TObject)
public
name : string;
intel : boolean;
amd : boolean;
price : string;
end;
type TRAM = class(TObject)
public
name : string;
memory : integer;
clock : integer;
price : string;
end;
var
fMain: TfMain;
implementation
{$R *.dfm}
uses CPUs, GPUs, Motherboards;
procedure TfMain.cbCPUChange(Sender: TObject);
var
i : integer;
mobo : TMobo;
begin
if TCPU(fMain.cbCPU.ItemIndex).intel = true then begin
for i := 0 to Motherboards.MoboPartsList.Count-1 do begin
mobo := TMobo(Motherboards.MoboPartsList.Items[i]);
if mobo.intel = true then begin
fMain.cbMotherboard.Items.AddObject(mobo.name, mobo);
end;
end;
end;
end;
procedure cbCPUpopulate();
var
i : integer;
CPU : TCPU;
begin
for i := 0 to CPUs.CPUPartsList.Count-1 do begin
CPU := TCPU(CPUs.CPUPartsList.Items[i]);
fMain.cbCPU.Items.AddObject(CPU.name, CPU);
end;
end;
procedure TfMain.FormShow(Sender: TObject);
begin
Motherboards.MakeMoboList;
CPUs.MakeCPUList();
GPUs.popgpulist();
cbCPUpopulate;
end;
end.
Run Code Online (Sandbox Code Playgroud)
在 中cbCPUChange(),您TCPU错误地访问了对象。
该表达式TCPU(fMain.cbCPU.ItemIndex)将列表索引类型转换为对象指针。您需要改为使用ItemIndex来访问 ComboBox 的Objects[]属性,该属性TCPU由填充了对象cbCPUpopulate()。
此外,不需要fMain从TfMain类的方法内部使用全局变量。改用方法的隐式Self指针。
尝试更像这样的事情:
procedure TfMain.cbCPUChange(Sender: TObject);
var
i : integer;
mobo : TMobo;
begin
cbMotherboard.Items.BeginUpdate;
try
cbMotherboard.Items.Clear;
i := cbCPU.ItemIndex;
if i < 0 then Exit;
if TCPU(cbCPU.Items.Objects[i]).intel then begin
for i := 0 to Motherboards.MoboPartsList.Count-1 do begin
mobo := TMobo(Motherboards.MoboPartsList.Items[i]);
if mobo.intel then begin
cbMotherboard.Items.AddObject(mobo.name, mobo);
end;
end;
end;
finally
cbMotherboard.Items.EndUpdate;
end;
end;
Run Code Online (Sandbox Code Playgroud)
附带说明一下TCPU,TMobo、 和TRAM类型的声明不属于该MainForm单元。它们应该在实际创建这些类型的对象列表的其他单元中声明,例如:TCPU在CPUs单元中,TMobo在Motherboards单元中等:
unit MainForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TfMain = class(TForm)
lCPU: TLabel;
cbCPU: TComboBox;
lGPU: TLabel;
cbGPU: TComboBox;
lMotherboard: TLabel;
cbMotherboard: TComboBox;
lRAM: TLabel;
cbRAM: TComboBox;
eCompatible: TEdit;
lCompatible: TLabel;
eCost: TEdit;
lCost: TLabel;
Label11: TLabel;
lbCPU: TListBox;
lbMotherboard: TListBox;
lbGPU: TListBox;
lbRAM: TListBox;
procedure FormShow(Sender: TObject);
procedure cbCPUChange(Sender: TObject);
private
{ Private declarations }
procedure cbCPUpopulate;
public
end;
var
fMain: TfMain;
implementation
{$R *.dfm}
uses
CPUs, GPUs, Motherboards;
procedure TfMain.cbCPUChange(Sender: TObject);
var
i : integer;
mobo : Motherboards.TMobo;
begin
cbMotherboard.Items.BeginUpdate;
try
cbMotherboard.Items.Clear;
i := cbCPU.ItemIndex;
if i < 0 then Exit;
if CPUs.TCPU(cbCPU.Items.Objects[i]).intel then begin
for i := 0 to Motherboards.MoboPartsList.Count-1 do begin
mobo := Motherboards.TMobo(Motherboards.MoboPartsList.Items[i]);
if mobo.intel then begin
cbMotherboard.Items.AddObject(mobo.name, mobo);
end;
end;
end;
finally
cbMotherboard.Items.EndUpdate;
end;
end;
procedure TfMain.cbCPUpopulate;
var
i : integer;
CPU : CPUs.TCPU;
begin
for i := 0 to CPUs.CPUPartsList.Count-1 do begin
CPU := CPUs.TCPU(CPUs.CPUPartsList.Items[i]);
cbCPU.Items.AddObject(CPU.name, CPU);
end;
end;
procedure TfMain.FormShow(Sender: TObject);
begin
Motherboards.MakeMoboList;
CPUs.MakeCPUList;
GPUs.popgpulist;
cbCPUpopulate;
end;
end.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
205 次 |
| 最近记录: |