【问题标题】:What is the best way to autostart an action after OnShow event?在 OnShow 事件之后自动启动操作的最佳方式是什么?
【发布时间】:2013-01-14 12:54:11
【问题描述】:

我有一个小型应用程序,大部分时间在开始按钮后面都有一个动作,应该从命令行参数 /AUTORUN 触发。 如果缺少该参数,用户也可以手动按下它。

我的问题是我应该在哪里对命令行进行此检查,以便在给出时 GUI 仍会更新。当前的解决方案是这样,但直到操作完成后,GUI 才会更新。

procedure TfrmMainForm.FormShow(Sender: TObject);
begin
  if FindCmdLineSwitch('AUTORUN') then
    btnStart.Click;
end;

【问题讨论】:

标签: delphi delphi-2007


【解决方案1】:

从您的OnShow 事件处理程序向您自己发布一条消息。一旦您的应用程序开始为其消息队列提供服务,这将被处理。这只发生在应用程序准备好接收输入时。这符合我对您要求的理解。

const
  WM_STARTUP = WM_USER;
....
procedure TfrmMainForm.FormShow(Sender: TObject);
begin
  PostMessage(Handle, WM_STARTUP, 0, 0);
  OnShow := nil;//only ever post the message once
end;

添加消息处理程序来处理消息:

procedure WMStartup(var Msg: TMessage); message WM_STARTUP;

你可以这样实现:

procedure TfrmMainForm.WMStartup(var Msg: TMessage);
begin
  inherited;
  if FindCmdLineSwitch('AUTORUN') then
    btnStart.Click;
end;

【讨论】:

  • 此消息处理程序中的inherited; 有什么作用?
  • 它执行任何默认消息处理,或在父类中实现的任何内容。在这种情况下,可能没什么意义,因为它是用户定义的消息。但是,我通常将此作为消息处理程序的良好做法。
  • 根据我对TCustomForm.ShowModal: Integer; 的理解,它在进入阻塞循环之前已经发送了一条消息CM_ACTIVATE。他不能用那个吗?
  • 那么,在 OnShow 或 OnCreate 中将该消息发送给我自己哪个更好? (如此处所示stackoverflow.com/questions/11679235/…)。到目前为止,我一直在使用 OnCreate,但我倾向于更改代码并选择 OnShow,因为它比较晚。
【解决方案2】:

在 FormShow 中给自己留言。在消息处理程序中运行您的 btnStart。

TfrmMainForm = class(TForm)
// snip
private
  procedure AutoStart(var Message: TMessage); message wm_user;
// snip
end

procedure TfrmMainForm.FormShow(Sender: TObject);
begin
  if FindCmdLineSwitch('AUTORUN') then
    PostMessage(Handle, wm_user, 0, 0);
end;

procedure TfrmMainForm.AutoStart(var Message: TMessage);
begin
  btnStart.Click;
end;

【讨论】:

    【解决方案3】:

    一个简单的方法是一个计时器,像这样的事件:

    begin
      Timer1.Enabled := False;
      if FindCmdLineSwitch('AUTORUN') then
        btnStart.Click;
    end;
    

    还有几千毫秒的间隔。

    【讨论】:

    • 不要为此使用计时器。而是将消息发布到导致 btnStart 运行的表单。
    • 不要这样做。现在你失去了对事物运行时间的控制。
    • @mj2008 它允许用户在此操作运行之前调用操作。
    • @David 如果用户能够在几百毫秒内进入,那么他们做得很好。如果您认为它很重要,请将时间值设置为 1,或者在此代码运行之前禁用接口。但是这种事情的通常用途是自动执行标准操作,而不是用户按下按钮。虽然它可能并不完美,但它适用于大多数情况并且易于实施。
    • @mj2008 根据启动所需的时间,用户可能有几秒钟的时间。定时器消息是低优先级的,只有在消息队列为空时才会被合成。计时器在这里完全不合适。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-04
    • 1970-01-01
    • 2012-12-22
    • 1970-01-01
    • 1970-01-01
    • 2015-03-29
    • 1970-01-01
    相关资源
    最近更新 更多