首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何知道TButton单击是否执行了TAction?

如何知道TButton单击是否执行了TAction?
EN

Stack Overflow用户
提问于 2020-09-01 20:27:53
回答 1查看 92关注 0票数 1

我在VCL应用程序中使用TActions和TButtons。将TButtons操作字段设置为现有操作集中代码。

动作执行方法如下所示:

代码语言:javascript
复制
void __fastcall MyFrame::MyActionExecute(TObject *Sender)
{
//Some action code
}

将MyAction分配给名为MyBtn的TButton并查看操作ActionComponent

代码语言:javascript
复制
void __fastcall MyFrame::MyActionExecute(TObject *Sender)
{

  if(MyAction->ActionComponent == MyBtn)
  {
   //.. action code when the MyBtn was clicked..
  }
}

好像挺管用的。

但是,通过编程调用MyAction的Execute方法,如下所示:

代码语言:javascript
复制
MyActionExcecute(NULL);

似乎没有将ActionComponent设置为NULL,但是“仍然”使用MyBtn作为ActionCompoent。因此,即使没有单击按钮,上面的if语句也可以计算为true。

问题是,处理按钮单击和手动调用操作执行方法的正确方法是什么?

我知道我可以检查Sender参数是否为NULL,如果是,我可以假设它不是按钮。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-01 23:59:54

该操作的ActionComponent属性仅在UI控件触发该操作时通过该控件为自己在内部创建的内部TBasicActionLink对象设置。链接的Execute()方法有一个AComponent参数,控件将其Self/this指针传递给该参数,以在调用操作的Execute()方法之前设置操作的ActionComponent

例如,VCL内部就是这样做的:

代码语言:javascript
复制
procedure TControl.SetAction(Value: TBasicAction);
begin
  if Value = nil then
  begin
    ActionLink.Free;
    ActionLink := nil;
    ...
  end
  else
  begin
    ...
    if ActionLink = nil then
      ActionLink := GetActionLinkClass.Create(Self);
    ActionLink.Action := Value;
    ...
  end;
end;
代码语言:javascript
复制
procedure TControl.Click;
begin
  { Call OnClick if assigned and not equal to associated action's OnExecute.
    If associated action's OnExecute assigned then call it, otherwise, call
    OnClick. }
  if Assigned(FOnClick) and (Action <> nil) and not DelegatesEqual(@FOnClick, @Action.OnExecute) then
    FOnClick(Self)
  else if not (csDesigning in ComponentState) and (ActionLink <> nil) then
    ActionLink.Execute(Self) // <-- HERE
  else if Assigned(FOnClick) then
    FOnClick(Self);
end;
代码语言:javascript
复制
function TBasicActionLink.Execute(AComponent: TComponent): Boolean;
begin
  FAction.ActionComponent := AComponent; // <-- HERE
  Result := FAction.Execute;
end;

因此,不要直接调用OnExecute事件处理程序。这根本不会更新操作。调用操作的Execute()方法。您只需事先将操作的ActionComponent设置为空,例如:

代码语言:javascript
复制
MyAction->ActionComponent = NULL;
MyAction->Execute();

文档声称:

当用户单击客户端控件时,该客户端在调用操作的ActionComponent方法之前设置Execute。操作执行后,动作将ActionComponent 重置为0 (Delphi)或NULL (C++)。

但是,只有当下一次UI控件决定为自己执行操作时,ActionComponent才不会自动重置。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63695008

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档