arrays - 清除组合框上的访问冲突

标签 arrays delphi combobox delphi-xe8

我正在使用 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,如前所述,记录将按预期从数组中删除,但组合框更新过程会抛出错误 模块 ***** 中地址 0040B2D2 处的访问冲突调用clear方法时读取地址FFFFFFE7。之后,组合框项目列表清晰,但最后选定项目的文本仍然保留。

我尝试了很多不同的方法来解决这个问题,最接近成功的是使用删除项目方法,

Delete(dbCombo.ItemIndex);

这再次从组合框中清除了最后一项,无一异常(exception),但文本仍然保留。

请有人帮忙解决这个问题,也许可以指出我缺少的简单的小东西。

<小时/>

添加......

根据要求,这里是 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,则程序中的任何位置也会发生异常。

最佳答案

非常感谢大家的帮助。终于找到问题所在了

“天哪,我感觉太傻了”

罪魁祸首是在 OnChange 事件处理程序中,我在其中放置了一条指令,用于从数据库记录密码属性填充编辑框,当从组合框中选择数据库时,该属性会自动更改。

问题是我没有添加条件语句来检查数据库列表中是否有任何项目可供加载,因此当没有异常时会引发异常。

在一个简单的 if 语句上浪费了两天时间。我已经好几年没有做过任何真正的编程了,我真的很怀念那些让人抓狂的时刻。

再次非常感谢。

关于arrays - 清除组合框上的访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33589560/

相关文章:

c++ - 在 C++ 中获取对象的数组索引

使用数组指针的 C++ 简单技巧可提高性能

ModalPopup 中的 ASP.Net Ajax 组合框

python - 关闭 PyQt 对话框而不关闭主程序

delphi - 通过指针修改字符串变量的内容安全吗?

mysql - 如何动态更改 sqlstatement 中用于使用组合框检索数据的列名称

C 凯撒密码函数调用未按预期运行

python - numpy 数组中的快速值交换

multithreading - Delphi 线程速度提升

.net - 在Delphi中销毁COM对象