我知道怎么做Tstringlist
onchange事件,但是Tstrings怎么样?我不想像tmemo或其他东西一样使用VCL。我能这样做吗?是否有可能在tstrings上发生这个事件并在改变时做一些事情?
我试图做类似这样的事情,但遭到访问违规
//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 Project1.exe引发了带有消息的异常类$ C0000005 &#39;访问违规行为0x6d40c92c:读取地址0x00000150&#39;。
Project Project1.exe引发了异常类EStringListError 消息&#39;列出索引越界(5)&#39;。
Project Project1.exe引发了异常类EStringListError 消息&#39;列出索引越界(5)&#39;。
这个tstringlist应该作为命令标识符使用我的线程
创建它例如
型
TReadingThread = class(TThread)
protected
FConnection : TIdTCPConnection;
FLogResult : TStrings;
procedure Execute; override;
public
constructor Create(AConn: TIdTCPConnection; ALogResult: TStrings); reintroduce;
end;
ListeningThread := TReadingThread.Create( TCPClient, stringlist);
constructor TReadingThread.Create(AConn: TIdTCPConnection; ALogResult: TStrings);
begin
FConnection := AConn;
FLogResult := ALogResult;
inherited Create(False);
end;
procedure TReadingThread.Execute;
Var
strData : String;
begin
while not Terminated do
begin
try
strData := FConnection.IOHandler.ReadLn;
if strData <> '' then
begin
FLogResult.Add( strData );
end;
except
on E: Exception do
begin
FConnection.Disconnect(False);
if FConnection.IOHandler <> nil
then FConnection.IOHandler.InputBuffer.Clear;
Break;
end;
end;
Sleep(10);
end; // While
end;
如果我使用Tmemo没有错误或发生异常。
答案 0 :(得分:2)
我们所有人都在黑暗中拍摄,因为您还没有提供所有相关代码。也就是说,您提供的信息存在很多问题,我可以提供建议来帮助您解决问题。
通过IDE运行代码。当您收到异常时,调试器将在导致异常的行停止 这通常是找出问题的最重要步骤。您可以访问此信息。运行程序并仔细查看引发错误的行。您可能已经能够确定导致错误的原因。如果没有,可以应用其他基本技术来获取更多信息:
当您向他们提供所有相关信息时,获得人们的帮助会更有效。首先,发生访问冲突的代码行非常有用....告诉我们!
给我们真实代码 说&#34;我试图做这样的事情&#34;不是特别有用。请复制并 粘贴 。如果您的代码不同,您的错误可能不再存在。
在以下情况下,您会收到访问冲突:
Destroy
ed或Free
d。因此,使用上述内容,您需要检查的内容。如果您复制了 粘贴 更多代码,我们可能会看到您做错了什么。
注意:一个黑暗中的可能性是你在错误的地方销毁你的字符串列表。也许备忘录有效,因为作为一个组件放在表单上,你不会试图破坏它。
让我们检查一下你的OnChange事件会发生什么变化,例如添加一个字符串:
Text
不为空。ProcessCommands
Clear
Clear
,Changed
的结尾。Text
为空,因此您无法致电ProcessCommands
Clear
字符串列表...... 通过铃声保存
您没有获得堆栈溢出的唯一原因是,如果字符串列表为空,Clear
不会执行任何操作:
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;
我建议你重新考虑如何解决你的问题,因为导致无意递归的代码会让你的生活变得困难。
在尝试使用线程之前,您确实需要掌握编程的基础知识。多线程编程会带来很大的复杂性。
我已经看到了一个潜在错误的巨大可能性。 (虽然这取决于你在ProcessCommands
内做了什么。)
OnChange
事件处理程序也会在线程的上下文中触发。 (它在表单上实现的事实无关紧要。)ProcessCommands
方法执行任何需要它在主线程上运行的方法,那么您将遇到问题。作为最后的考虑,我注意到很多初学程序员完全忽略了启动一个线程的代码可以在线程之前完成的点。例如。 (回到有关访问冲突的主题。):如果您在创建线程后立即销毁字符串列表,那么当前一个对象突然消失时,您的线程可能会突然抛出访问冲突。
答案 1 :(得分:1)
您错误的可能解释是您正在修改其OnChange
事件处理程序中的列表。这根本不允许。 OnChange
处理程序不得改变对象的状态。
发生的事情是你有一些其他代码,我们看不到,它修改了列表,也许是在一个循环中。当它修改列表时,你的事件处理程序会清除列表,然后调用代码就会从它下面拉出地毯。
当然,我不得不在这里猜测,因为你没有显示完整的代码。也许具体情况有所不同,但似乎这可能是你问题的根源。
您需要找到另一种方法来解决您的问题。有了这些信息,我们无法建议如何做到这一点。
查看更新的代码,根本不需要字符串列表。完全删除它。相反,你去的地方:
FLogResult.Add( strData );
这样做:
ProcessCommands( strData );
答案 2 :(得分:0)
TStrings
是一个抽象类,TStringList
的祖先。您可以创建TStringList
的实例,并将其用作TStrings
。