我正在尝试显示一个TPANEL数组,供用户用作菜单系统。这一切似乎都很好,但这就是问题所在。
如果我总是点击第一项(即TPanel),那么我也可以点击其他项目。但是,如果我从点击最后一项开始,它会在显示项目后显示错误“访问冲突”。
奇怪的是,尽管有错误,但系统不会崩溃。所以我启用了调试器(DBG)。现在它崩溃了,错误如下:
一旦程序停止,我在调试器的历史窗口中看到以下内容。
请注意,我现在并不热衷于修复此错误,因为我认为这是微不足道的。但我希望能够在错误发生时捕获错误并执行某些操作(现在我想忽略它)。
我正在使用Ubuntu 12.04和Lazarus 1.0.10。 我使用的方法必须适用于WINDOWS和LINUX。
提前感谢您的帮助!
答案 0 :(得分:4)
通常,为了捕获异常,有try..except
块。确保您的目标不是捕获异常并忽略它,而是在代码中找到它并修复问题的根源。当然,可能存在异常风险高或预期的情况,因此在那里需要使用try..except
块。我们用这种方式包含的那些代码块:
procedure TForm1.Button1Click(Sender: TObject);
var
NotExistingPanel: TPanel;
begin
try
NotExistingPanel.Caption := ''; // <- this will raise an access violation
except
on E: Exception do
ShowMessage('An exception was raised: ' + E.Message);
end;
end;
您的问题将出现在某些控件的OnMouseUp
事件处理程序中,并且是由访问内存造成的,CPU无法实际寻址。这可能发生在例如当您访问尚未创建或已经发布的对象时,但是还有许多不同的方法可以导致访问冲突。
答案 1 :(得分:2)
首先,非常感谢 TLama 所有的解释和指示。我必须接受他的答案,因为我已经建立了我的答案。我只是将这个作为一个答案发布,以便另一个拉扎鲁斯初学者可能会觉得这很有用。我不是在暗示这是最好的事情,但这就是我现在想做的事情。也就是说,当某个异常发生时,我想陷阱并处理它。
鉴于此,
我们假设有10个这样的“按钮”(实际上是TPanels)。
问题: 当我第一次点击第一个按钮时,我可以点击另一个按钮(例如:第5个)。但是,如果我首先单击第5个或除第一个之外的任何其他内容,程序将抛出“访问冲突”错误。但请注意,尽管有关于数据损坏和内容的丑陋警告,程序仍然不崩溃。因此用户只需单击“确定”即可继续。奇怪的是,随后的点击,这个问题减少!我知道这很有趣。
现在,正如TLama所解释的,单击按钮后释放鼠标时会发生错误。
但这是我的问题......我没有鼠标事件。这是Pascal的一部分。
所以现在,我想忽略mouseup事件(至少目前为止)。必须有一个更好的方法。
但还有另一个问题。我不能忽视我没有的东西!而且我没有鼠标事件。所以我最终决定在应用程序级别捕获此错误,如下所示:
在主表单上,我输入了以下代码:
procedure TfrmMainForm.CatchErr(Sender: TObject; e:exception);
begin
if e.Message <> 'Access violation' then ShowMessage('MOL: ' + e.Message);
end;
然后在表单创建上,我把它放在:
Application.OnException:=@CatchErr;
而且(现在)我可以绕过这个问题。
正如TLama所指出的那样,这不是一个好建议。尽管如此,这正是我想要做的。
更令人困难的是,鼠标中出现错误,这是在control.inc中。这不是我的档案。相反,它是拉撒路的一部分。我认为如果我们有办法告诉Lazarus在代码中删除TPanels的事件会更好。我认为它涉及为它重写一个派生类,我不知道这对我现在有什么好处:)
再次感谢TLama!