Lazarus(FreePascal):如何捕获系统错误并抛出异常?

时间:2013-08-09 12:06:13

标签: exception-handling lazarus

我正在尝试显示一个TPANEL数组,供用户用作菜单系统。这一切似乎都很好,但这就是问题所在。

如果我总是点击第一项(即TPanel),那么我也可以点击其他项目。但是,如果我从点击最后一项开始,它会在显示项目后显示错误“访问冲突”。

奇怪的是,尽管有错误,但系统不会崩溃。所以我启用了调试器(DBG)。现在它崩溃了,错误如下: enter image description here

一旦程序停止,我在调试器的历史窗口中看到以下内容。 enter image description here

请注意,我现在并不热衷于修复此错误,因为我认为这是微不足道的。但我希望能够在错误发生时捕获错误并执行某些操作(现在我想忽略它)。

我正在使用Ubuntu 12.04和Lazarus 1.0.10。 我使用的方法必须适用于WINDOWS和LINUX。

提前感谢您的帮助!

2 个答案:

答案 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 所有的解释和指示。我必须接受他的答案,因为我已经建立了我的答案。我只是将这个作为一个答案发布,以便另一个拉扎鲁斯初学者可能会觉得这很有用。我不是在暗示这是最好的事情,但这就是我现在想做的事情。也就是说,当某个异常发生时,我想陷阱并处理它。

鉴于此,

  1. 我正在动态创建一组TPanel,看起来像按钮
  2. 每个TPanel都为其分配了一个鼠标点击事件
  3. 我们假设有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!