我正在使用Delphi XE8编写可以访问多个数据库的客户端/服务器应用程序。
作为设置表单的一部分,TComboBoxEx用于显示和选择记录信息的动态数组,每个数据库和两个按钮用于添加或删除数组中的记录。
数组被保存并加载到单个格式化字符串中,每个记录的名称属性用作每个组合框项目的标题。
在表单显示上,在添加或删除数据库按钮时,将调用更新过程,首先清除并重新加载数组,然后重新填充组合框。
procedure TSettingsForm.UpdateDatabaseCombo;
var
i: integer;
begin
LoadDatabaseList; // Clears and reloads databaselist dynamic array.
with dbCombo.Items do
begin
BeginUpdate;
if Length(DatabaseList) <> 0 then
begin
Clear; // This section works fine.
for i := 0 to High(DatabaseList) do
begin
Add(DatabaseList[i].dbName);
dbCombo.ItemsEx[i].ImageIndex := 17;
end;
end;
if (Length(DatabaseList) < 1) and (Count <> 0) then
begin
Clear; // Access violation on this line.
end;
EndUpdate;
end;
end;
该过程适用于在启动时初始加载数组,即使没有保存记录,也没有添加新记录。 但是在删除记录期间会出现问题,或者我说在删除记录后更新组合框(从数据库列表中删除记录没有问题)。
如果阵列中存储的记录多于记录,则一切正常,组合框将被清除并重新填充。但是,如果删除的记录是最后一次存储的,即索引0,如前所述,记录将按预期从数组中删除,但组合框更新过程在调用clear方法时抛出错误Access violation at address 0040B2D2 in module ***** Read of address FFFFFFE7
。之后组合框项目列表清晰,但最后一个选定项目的文本仍然存在。
我尝试了很多不同的方法来解决这个问题,成功的关键是使用删除项方法,
Delete(dbCombo.ItemIndex);
这会再次从组合框中清除最终项目,没有例外,但文本仍然存在。
请任何人都可以帮助解决这个问题,并指出我遗漏的简单小事。
Addition........
根据要求,这是UpdateDatabaseCombo
例程的更新代码,
procedure TSettingsForm.UpdateDatabaseCombo;
var
i: integer;
begin
LoadDatabaseList; // Clears and reloads databaselist dynamic array.
if dbCombo.Items.Count <> 0 then
dbCombo.Items.Clear;
with dbCombo.Items do
begin
BeginUpdate;
if Length(DatabaseList) <> 0 then
begin
for i := 0 to High(DatabaseList) do
begin
Add(DatabaseList[i].dbName);
dbCombo.ItemsEx[i].ImageIndex := 17;
end;
end;
EndUpdate;
end;
end;
我已经注意到,如果调用items.clear
而没有检查items.count
值是否大于0,并且每次调用例程时都会引发异常,并且计数检查到位只有在删除组合框中的最后一项时才会引发异常。
我还添加了从数组中删除记录的例程,
procedure TSettingsForm.DBRemoveButtonClick(Sender: TObject);
var
ALength: Cardinal;
i: Cardinal;
begin
ALength := Length(DatabaseList);
Assert(ALength > 0);
Assert(dbCombo.ItemIndex < ALength);
for i := dbCombo.ItemIndex + 1 to ALength - 1 do
DatabaseList[i - 1] := DatabaseList[i];
SetLength(DatabaseList, ALength - 1);
SaveDatabaseList;
UpdateDatabaseCombo;
if dbCombo.Items.Count <> 0 then
dbCombo.ItemIndex := 0;
end;
如果在组合框为空时调用clear
,程序中的任何地方都会发生异常。
答案 0 :(得分:2)
非常感谢大家的帮助。我终于找到了问题,
'God I feel so silly'
。
罪魁祸首在OnChange
事件处理程序中,我在其中放置了一条指令,用于从数据库记录密码属性中填充编辑框,当从组合框中选择数据库时,该属性会自动更改。
问题是我没有添加条件语句来检查数据库列表中是否有任何项目要加载,因此没有引发异常。
在一个简单的if
声明中浪费了两天时间。我几年没有做过任何真正的编程,我真的很想念那些把你的头发拉出来的时刻。
再次,非常感谢。