Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何使用onchange事件创建tstring?_Delphi_Delphi Xe7 - Fatal编程技术网

Delphi 如何使用onchange事件创建tstring?

Delphi 如何使用onchange事件创建tstring?,delphi,delphi-xe7,Delphi,Delphi Xe7,我知道如何制作Tstringlist onchange事件,但是Tstrings呢?我不想使用像tmemo之类的VCL。我可以这样做吗?是否可以在tstring上设置此事件,并在其更改时执行某些操作 我试着做类似的事情,但却被侵犯了访问权限 //on form show event stringlist:= TStringList.Create; stringlist.OnChange := HandleStringListChange; //implantation pro

我知道如何制作Tstringlist onchange事件,但是Tstrings呢?我不想使用像tmemo之类的VCL。我可以这样做吗?是否可以在tstring上设置此事件,并在其更改时执行某些操作

我试着做类似的事情,但却被侵犯了访问权限

//on form show event
   stringlist:= TStringList.Create;
  stringlist.OnChange := HandleStringListChange;
//implantation 
    procedure TChatFo.HandleStringListChange(Sender: tObject);
    begin
    if stringlist.Text <> '' then
    ProcessCommands(stringlist.Text);
    stringlist.Clear;
    end;
异常消息

Project 1.exe引发异常类$C0000005,并显示消息 '0x6d40c92c处的访问冲突:读取地址0x00000150'

Project Project1.exe引发了异常类EStringListError 消息“列表索引超出范围5”

Project Project1.exe引发了异常类EStringListError 消息“列表索引超出范围5”

这个tstringlist应该作为我用线程创建的命令标识符

举例来说

类型


如果使用Tmemo,则不会发生错误或异常

TStrings是一个抽象类,是TStringList的祖先。您可以创建TStringList的实例并将其用作tstring。

错误的可能原因是您正在修改其OnChange事件处理程序中的列表。这是绝对不允许的。OnChange处理程序不能改变对象的状态

现在发生的事情是,您有一些我们看不到的其他代码,它们修改了列表,可能是在一个循环中。当它修改列表时,您的事件处理程序将清除列表,然后调用代码将地毯从下面拉出来

当然,我不得不在这里猜测,因为您没有显示完整的代码。也许具体情况有所不同,但这似乎是您问题的根源

你需要找到另一种方法来解决你的问题。根据现有信息,我们无法建议如何做到这一点

查看更新的代码,根本不需要字符串列表。完全移除它。相反,您要做的是:

FLogResult.Add( strData );
这样做:

ProcessCommands( strData );

我们都是在黑暗中拍摄的,因为你没有提供所有相关的代码。也就是说,你提供的信息有很多问题,我可以提供建议帮助你解决

调试101 通过IDE运行代码。当您获得异常时,调试器将在导致异常的行停止。 这通常是找出问题所在的最重要的一步。您可以访问此信息。运行程序并仔细查看引发错误的行。您可能已经能够找出导致错误的原因。如果没有,可以应用其他基本技术来获取更多信息:

获取错误行和其他闭合行上的对象和变量值。您可以将鼠标光标悬停以获取工具提示,或按Ctrl+F7。 通过双击调用堆栈中的前一行,可以检查导致错误的行的调用堆栈。 在错误之前的行上放置断点,然后重新运行应用程序。调试器将在该行停止,并让您有机会按照前面的说明检查值,但在错误发生之前。 求助 当你向人们提供所有相关信息时,从他们那里获得帮助会更加有效。首先,发生访问冲突的代码行非常有用。。。。告诉我们

给我们真正的代码。 说我试过做这样的事情并不是特别有用。请复制并粘贴您尝试的内容。如果您的代码不同,您的错误可能不再存在

访问违规 在以下情况下,您会遇到访问冲突:

您忘记创建要使用的对象,或者没有将其分配给相应的变量。 您创建了该对象,但在再次尝试使用它之前已将其销毁或释放。 您更改了引用对象的变量。 您执行了从一种类型到不兼容类型的“硬转换”或未经检查的类型转换。 以上是基础。有一些变化,和一些特殊的边缘情况,但这些是绝大多数错误的原因。 因此,使用上述内容,这就是您需要检查的内容。如果您复制粘贴了更多代码,我们可能会看到您做错了什么

注意:有一种可能性是你在错误的地方销毁了你的字符串列表。也许备忘录之所以有效,是因为作为表单上的一个组件,您并没有试图破坏它

堆栈溢出 让我们检查一下当添加字符串时,OnChange事件中发生了什么:

事件触发。 文本不是空的。 所以你调用ProcessCommands 然后你叫清楚 清除、更改的结尾将再次调用。 再次触发您的事件。 这一次文本为空,因此您不会调用ProcessCommands 但您确实尝试再次清除字符串列表。。。 这可能永远持续下去;至少在调用堆栈耗尽空间并出现堆栈溢出错误之前。 被钟声拯救

没有得到堆栈溢出的唯一原因是清除 如果字符串列表为空,则不执行任何操作:

procedure TStringList.Clear;
begin
  if FCount <> 0 then //You're lucky these 2 lines stop your stack-overflow
  begin
    ...
    FCount := 0;      //You're lucky these 2 lines stop your stack-overflow
    SetCapacity(0);
    Changed;
  end;
end;
我建议您重新思考如何解决您的问题,因为导致无意递归的代码将使您的生活变得困难

使用线程 在尝试使用线程之前,您确实需要掌握编程的基本知识。多线程编程带来了巨大的复杂性

我已经看到了一个潜在错误的巨大可能性。尽管这取决于您在ProcessCommand中执行的操作

您可以在线程上下文中修改字符串列表。 这意味着您的OnChange事件处理程序也会在线程的上下文中激发。它在表单上实现的事实与此无关。 如果ProcessCommands方法执行任何要求它在主线程上操作的操作,那么您将遇到问题。
作为最后一点考虑,我注意到相当多的初学者程序员完全没有注意到启动线程的代码可以在线程完成之前完成这一点。例如,返回访问冲突主题:如果在创建线程后不久就要销毁字符串列表,那么当先前的对象突然消失时,线程可能会突然抛出访问冲突。

请显示mcve。这里的片段不足以识别您的错误。Dan mcve引发的异常是我们真正需要的。然而,我想我能猜出你的问题是什么。现在我要温和地责备你。您正在查看的代码不是我们可以看到的代码。这不是寻求帮助的最佳方式。请阅读关于如何提问的网站帮助部分。更多细节已经添加。我仍然认为我的答案是准确的。您不能在其OnChange事件处理程序中修改列表。此语句为true。但是它与被问到的问题没有任何关系,因为这个问题没有与字符串相关的代码。尽管如此,你还是投了一票。德尔菲标签有时似乎更关心的是不冒犯他人,而不是奖励好的答案。@DavidHeffernan:在问题被编辑成额外的解释之前,它是这样做的。另外,看看主题中的问题,它都与TStrings的使用有关。原始代码显示了TStringList.Create。你只是对另一个问题给出了一个简单的答案。
procedure TStringList.Clear;
begin
  if FCount <> 0 then //You're lucky these 2 lines stop your stack-overflow
  begin
    ...
    FCount := 0;      //You're lucky these 2 lines stop your stack-overflow
    SetCapacity(0);
    Changed;
  end;
end;