如何在我的组件中添加对操作的支持 [英] How do I add support for actions in my component

查看:121
本文介绍了如何在我的组件中添加对操作的支持的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要做些什么来为我的组件添加操作支持。它是一个按钮组件,但我猜这是任何组件类型是相同的。任何信息或如何帮助。

解决方案

这取决于您如何定义动作支持。有两种:




  • 您可以自定义Action组件的Action属性,由Action组件分配

  • Action组件本身。



动作属性



每个TControl后代都有一个Action属性,默认情况下执行链接到鼠标左键。此链接由ActionLink管理。默认的ActionLink类型为TControlActionLink,它处理Action和控件的标题,提示,已启用状态等的同步。如果这个基础功能是所有你想要的,那么只需在组件类型声明中发布Action属性,Delphi框架就会像 Serg LU RD 已经回答。



如果你想要自己的要链接到某些其他条件或事件(即Click以外)的Action属性,或者如果要为组件的特定子元素(不是TControl后代)实施Action属性,则可以实现自己的通过定义和实现自定义的ActionLink类,定制Action属性。



假设您的组件是某种具有列的网格,并且您希望每个列都有一个action属性当用户点击ti时调用它一列。由于这些列可能是一个TCollectionItem类型,默认情况下,列类型不具有操作属性。所以你必须自己实现一个。考虑下一个将操作标题链接到列的标题的示例,将操作的已启用状态与列的只读属性相反链接,等等...:

单位Unit1; 

接口

使用
类,ActnList,SysUtils;

type
TColumn = class;

TColumnActionLink = class(TActionLink)
protected
FClient:TColumn;
procedure AssignClient(AClient:TObject);覆盖
函数IsCaptionLinked:Boolean;覆盖
函数IsEnabledLinked:Boolean;覆盖
函数IsOnExecuteLinked:Boolean;覆盖
函数IsVisibleLinked:Boolean;覆盖
procedure SetCaption(const Value:String);覆盖
procedure SetEnabled(Value:Boolean);覆盖
procedure SetOnExecute(Value:TNotifyEvent);覆盖
procedure SetVisible(Value:Boolean);覆盖
结束

TColumnActionLinkClass = TColumnActionLink类;

TColumn = class(TCollectionItem)
private
FActionLink:TColumnActionLink;
FGrid:TComponent;
FOnTitleClick:TNotifyEvent;
FReadOnly:Boolean;
FTitle:String;
FVisible:Boolean;
function DefaultTitleCaption:String;
procedure DoActionChange(Sender:TObject);
函数GetAction:TBasicAction;
函数IsOnTitleClickStored:Boolean;
函数IsReadOnlyStored:Boolean;
函数IsVisibleStored:Boolean;
程序SetAction(Value:TBasicAction);
protected
procedure ActionChanged(Sender:TObject; CheckDefaults:Boolean);动态;
程序DoTitleClick;虚拟;
函数GetActionLinkClass:TColumnActionLinkClass;虚拟;
属性ActionLink:TColumnActionLink读取FActionLink写入FActionLink;
public
析构函数Destroy;覆盖
procedure InitiateAction;虚拟;
发布
属性Action:TBasicAction读取GetAction写入SetAction;
属性OnTitleClick:TNotifyEvent读取FOnTitleClick写入FOnTitleClick
存储IsOnTitleClickStored;
属性ReadOnly:Boolean读FReadOnly写FReadOnly
存储IsReadOnlyStored;
属性标题:字符串读取FTitle写入FTitle;
属性Visible:Boolean读取可读写FVisible
存储IsVisibleStored;
结束

实现

{TColumnActionLink}

程序TColumnActionLink.AssignClient(AClient:TObject);
begin
FClient:= TColumn(AClient);
结束

函数TColumnActionLink.IsCaptionLinked:Boolean;
begin
结果:=继承的IsCaptionLinked和(Action是TCustomAction)和
(FClient.Title = TCustomAction(Action).Caption);
结束

函数TColumnActionLink.IsEnabledLinked:Boolean;
begin
结果:=继承的IsEnabledLinked和(Action是TCustomAction)和
(FClient.ReadOnly> TCustomAction(Action).Enabled);
结束

函数TColumnActionLink.IsOnExecuteLinked:Boolean;
begin
结果:=继承的IsOnExecuteLinked和
(@ FClient.OnTitleClick = @ Action.OnExecute);
结束

函数TColumnActionLink.IsVisibleLinked:Boolean;
begin
结果:=继承的IsVisibleLinked和(Action是TCustomAction)和
(FClient.Visible = TCustomAction(Action).Visible);
结束

程序TColumnActionLink.SetCaption(const value:string);
begin
如果IsCaptionLinked然后
FClient.Title:= Value;
结束

程序TColumnActionLink.SetEnabled(Value:Boolean);
begin
如果IsEnabledLinked然后
FClient.ReadOnly:= not Value;
结束

程序TColumnActionLink.SetOnExecute(Value:TNotifyEvent);
begin
如果IsOnExecuteLinked然后
FClient.OnTitleClick:= Value;
结束

程序TColumnActionLink.SetVisible(Value:Boolean);
begin
if IsVisibleLinked then
FClient.Visible:= Value;
结束

{TColumn}

程序TColumn.ActionChanged(发件人:TObject; CheckDefaults:Boolean);
begin
如果发件人是TCustomAction,然后
与TCustomAction(发件人)做
开始
如果不是CheckDefaults或(Caption = DefaultTitleCaption)然后
FTitle:=标题;
如果不是CheckDefaults或(不是ReadOnly)然后
ReadOnly:= not Enabled;
如果不是CheckDefaults或未分配(FOnTitleClick)然后
FOnTitleClick:= OnExecute;
如果不是CheckDefaults或(Self.Visible = True)then
Self.Visible:= Visible;
更改(False);
结束
结束

函数TColumn.DefaultTitleCaption:String;
begin
结果:='Column'+ IntToStr(Index);
结束

析构函数TColumn.Destroy;
begin
FreeAndNil(FActionLink);
继承了Destroy;
结束

程序TColumn.DoActionChange(发件人:TObject);
begin
如果Sender = Action然后
ActionChanged(Sender,False);
结束

程序TColumn.DoTitleClick;
begin
如果分配(FOnTitleClick)然后
if(Action<> nil)和(@FOnTitleClick<> @ Action.OnExecute)然后
FOnTitleClick(Self)
else if FActionLink = nil then
FOnTitleClick(Self)
else if FActionLink<然后
if(FGrid<> nil)而不是(csDesigning in FGrid.ComponentState)然后
begin
如果不是FActionLink.Execute(FGrid)然后
FOnTitleClick(Self );
end
else
如果不是FActionLink.Execute(nil)then
FOnTitleClick(Self);
结束

函数TColumn.GetAction:TBasicAction;
begin
如果FActionLink<> nil then
结果:= FActionLink.Action
else
结果:= nil;
结束

函数TColumn.GetActionLinkClass:TColumnActionLinkClass;
begin
结果:= TColumnActionLink;
结束

程序TColumn.InitiateAction;
begin
如果FActionLink<> nil then
FActionLink.Update;
结束

函数TColumn.IsOnTitleClickStored:Boolean;
begin
结果:=(FActionLink = nil)或者ActionLink.IsOnExecuteLinked;
结束

函数TColumn.IsReadOnlyStored:Boolean;
begin
结果:=(FActionLink = nil)或不FAULTLink.IsEnabledLinked;
如果结果然后
结果:= FReadOnly;
结束

函数TColumn.IsVisibleStored:Boolean;
begin
结果:=(FActionLink = nil)或不是FActionLink.IsVisibleLinked;
如果结果然后
结果:=不可见;
结束

procedure TColumn.SetAction(Value:TBasicAction);
begin
如果Value = nil then
FreeAndNil(FActionLink)
else
begin
如果FActionLink = nil then
FActionLink:= GetActionLinkClass。创建(自);
FActionLink.Action:= Value;
FActionLink.OnChange:= DoActionChange;
ActionChanged(Value,csLoading in Value.ComponentState);
如果FGrid<> nil then
Value.FreeNotification(FGrid);
结束
更改(False);
结束

结束。

请注意,此代码仅被剥离到适用的操作部分。


资料来源: www.nldelphi.com a>。



一个动作组件



一个动作组件可以分配给一个任意组件。但是,由于解释了编写这样一个动作组件所涉及到的全部内容,它是非常全面的,我将使自己能够轻松提供下面的例子。



假设你想一个提供缩放功能的控件,并且还需要可以分配给工具栏按钮的相应ZoomIn和ZoomOut操作。

 单位动物; 

接口

使用
类,控件,ActnList,窗体,菜单,Windows;

type
TZoomer = class;

TZoomAction = class(TCustomAction)
private
FZoomer:TZoomer;
程序SetZoomer(Value:TZoomer);
protected
function GetZoomer(Target:TObject):TZoomer;
程序通知(ACComponent:TComponent;操作:TOperation);
覆盖;
public
析构函数Destroy;覆盖
function HandlesTarget(Target:TObject):Boolean;覆盖
procedure UpdateTarget(Target:TObject);覆盖
发布
属性Caption;
属性启用;
属性HelpContext;
属性HelpKeyword;
属性HelpType;
属性提示;
属性ImageIndex;
属性ShortCut;
属性SecondaryShortCuts;
属性可见;
属性OnExecute; {此属性可以省略。但是如果你想要
可以覆盖这个动作
的默认行为(放大一个TZoomer组件),那么你需要
分配这个事件。从事件处理程序
中可以手动调用默认行为。 }
属性OnHint;
属性OnUpdate;
属性Zoomer:TZoomer读取FZoomer写SetZoomer;
结束

TZoomInAction = class(TZoomAction)
public
构造函数创建(AOwner:TComponent);覆盖
procedure ExecuteTarget(Target:TObject);覆盖
结束

TZoomer = class(TCustomControl)
public
procedure ZoomIn;
结束

程序注册;

执行

程序注册;
begin
RegisterComponents('RoyMKlever',[TZoomer]);
RegisterActions('Zoomer',[TZoomInAction],nil);
结束

{TZoomAction}

析构函数TZoomAction.Destroy;
begin
如果FZoomer<> nil then
FZoomer.RemoveFreeNotification(Self);
继承了Destroy;
结束

函数TZoomAction.GetZoomer(Target:TObject):TZoomer;
begin
如果FZoomer<>否则
结果:= FZoomer
else if(目标是TZoomer)和TZoomer(Target).Focused then
结果:= TZoomer(Target)
如果Screen.ActiveControl为TZoomer然后
结果:= TZoomer(Screen.ActiveControl)
else
{这不应该发生! HandlesTarget在ExecuteTarget之前调用,
或操作被禁用}
结果:= nil;
结束

函数TZoomAction.HandlesTarget(Target:TObject):Boolean;
begin
结果:=((FZoomer<> nil)和FZoomer.Enabled)或
((FZoomer = nil)和(Target为TZoomer)和TZoomer(Target) )或
((Screen.ActiveControl是TZoomer)和Screen.ActiveControl.Enabled);
结束

程序TZoomAction.Notification(AComponent:TComponent;
操作:TOperation);
begin
继承的通知(AComponent,Operation);
if(Operation = opRemove)和(AComponent = FZoomer)then
FZoomer:= nil;
结束

procedure TZoomAction.SetZoomer(Value:TZoomer);
begin
如果FZoomer<>价值然后
begin
如果FZoomer<> nil then
FZoomer.RemoveFreeNotification(Self);
FZoomer:= Value;
如果FZoomer<> nil then
FZoomer.FreeNotification(Self);
结束
结束

procedure TZoomAction.UpdateTarget(Target:TObject);
begin
启用:= HandlesTarget(Target);
结束

{TZoomInAction}

构造函数TZoomInAction.Create(AOwner:TComponent);
begin
继承Create(AOwner);
标题:='放大';
提示:='放大|放大所选的动物摄影控件';
ShortCut:= Menus.ShortCut(VK_ADD,[ssCtrl]);
结束

procedure TZoomInAction.ExecuteTarget(Target:TObject);
begin
GetZoomer(Target).ZoomIn;
{为了安全起见,您将检查GetZoomer<>零。在GetZoomer看到评论。 }
end;

{TZoomer}

程序TZoomer.ZoomIn;
begin
{执行放大}
end;

结束。

激活此操作(点击工具栏按钮或选择菜单项)以下优先级的ZoomIn例程:


  1. 手动设置在操作的相关属性中的Zoomer控件,如果已经这样做,以及如果启用该操作,否则:

  2. 由请求的应用程序目标,但只有当该目标是焦点齐聚的Zoomer控件或其他方式:

  3. 整个应用程序中的活动控件,但只有当启用了Zoomer控件时。

,只需添加ZoomOut操作:

 键入
TZoomOutAction = class(TZoomAction)
public
构造函数Create(AOwner:TComponent);覆盖
procedure ExecuteTarget(Target:TObject);覆盖
结束

{TZoomOutAction}

构造函数TZoomOutAction.Create(AOwner:TComponent);
begin
继承Create(AOwner);
标题:='缩小;
提示:='缩小|缩小所选的动物摄影控件';
ShortCut:= Menus.ShortCut(VK_SUBTRACT,[ssCtrl]);
结束

procedure TZoomOutAction.ExecuteTarget(Target:TObject);
begin
GetZoomer(Target).ZoomOut;
结束

请注意,操作组件需要在IDE中注册才能使用他们的设计时间。 >

适用于Delphi帮助中阅读的食物:





资料来源: www.nldelphi.com


What do I need to do for adding actions support to my component. It is a button component but I guess it is the same for whatever component type it is. Any information or how to will help.

解决方案

That depends on how you define action support. There is two kinds:

  • A possibly customized Action property of your component, which is assignable by an Action component
  • The Action component itself.

An action property

Every TControl descendant has an Action property which execution is by default linked to a left mouse button click. This link is managed by an ActionLink. The default ActionLink is of the type TControlActionLink which takes care of the synchronization of the caption, the hint, the enabled state, etc... of both the Action and that of the Control. If this basis functionality is all that you want, then simply publish the Action property in your component type declaration and the Delphi framework takes care of all, like Serg and LU RD already answered.

If you want your own Action property to be linked to some other condition or event (i.e. other than Click), or if you want to implement an Action property for a specific sub element of your component (that is not a TControl descendant), then you can implement your own custom Action property by defining and implementing a custom ActionLink class.

Suppose your component is some kind of grid which has columns and you want every column to have an action property that should be invoked when the user clicks the title of a column. Since such columns are likely to be of a TCollectionItem type, the column type does not have an action property by default. So you have to implement one yourself. Consider the next example which links the action's caption to the column's title, links the action's enabled state inversely to the column's readonly property and so on...:

unit Unit1;

interface

uses
  Classes, ActnList, SysUtils;

type
  TColumn = class;

  TColumnActionLink = class(TActionLink)
  protected
    FClient: TColumn;
    procedure AssignClient(AClient: TObject); override;
    function IsCaptionLinked: Boolean; override;
    function IsEnabledLinked: Boolean; override;
    function IsOnExecuteLinked: Boolean; override;
    function IsVisibleLinked: Boolean; override;
    procedure SetCaption(const Value: String); override;
    procedure SetEnabled(Value: Boolean); override;
    procedure SetOnExecute(Value: TNotifyEvent); override;
    procedure SetVisible(Value: Boolean); override;
  end;

  TColumnActionLinkClass = class of TColumnActionLink;

  TColumn = class(TCollectionItem)
  private
    FActionLink: TColumnActionLink;
    FGrid: TComponent;
    FOnTitleClick: TNotifyEvent;
    FReadOnly: Boolean;
    FTitle: String;
    FVisible: Boolean;
    function DefaultTitleCaption: String;
    procedure DoActionChange(Sender: TObject);
    function GetAction: TBasicAction;
    function IsOnTitleClickStored: Boolean;
    function IsReadOnlyStored: Boolean;
    function IsVisibleStored: Boolean;
    procedure SetAction(Value: TBasicAction);
  protected
    procedure ActionChanged(Sender: TObject; CheckDefaults: Boolean); dynamic;
    procedure DoTitleClick; virtual;
    function GetActionLinkClass: TColumnActionLinkClass; virtual;
    property ActionLink: TColumnActionLink read FActionLink write FActionLink;
  public
    destructor Destroy; override;
    procedure InitiateAction; virtual;
  published
    property Action: TBasicAction read GetAction write SetAction;
    property OnTitleClick: TNotifyEvent read FOnTitleClick write FOnTitleClick
      stored IsOnTitleClickStored;
    property ReadOnly: Boolean read FReadOnly write FReadOnly
      stored IsReadOnlyStored;
    property Title: String read FTitle write FTitle;
    property Visible: Boolean read FVisible write FVisible
      stored IsVisibleStored;
  end;

implementation

{ TColumnActionLink }

procedure TColumnActionLink.AssignClient(AClient: TObject);
begin
  FClient := TColumn(AClient);
end;

function TColumnActionLink.IsCaptionLinked: Boolean;
begin
  Result := inherited IsCaptionLinked and (Action is TCustomAction) and
    (FClient.Title = TCustomAction(Action).Caption);
end;

function TColumnActionLink.IsEnabledLinked: Boolean;
begin
  Result := inherited IsEnabledLinked and (Action is TCustomAction) and
    (FClient.ReadOnly <> TCustomAction(Action).Enabled);
end;

function TColumnActionLink.IsOnExecuteLinked: Boolean;
begin
  Result := inherited IsOnExecuteLinked and
    (@FClient.OnTitleClick = @Action.OnExecute);
end;

function TColumnActionLink.IsVisibleLinked: Boolean;
begin
  Result := inherited IsVisibleLinked and (Action is TCustomAction) and
    (FClient.Visible = TCustomAction(Action).Visible);
end;

procedure TColumnActionLink.SetCaption(const Value: string);
begin
  if IsCaptionLinked then
    FClient.Title := Value;
end;

procedure TColumnActionLink.SetEnabled(Value: Boolean);
begin
  if IsEnabledLinked then
    FClient.ReadOnly := not Value;
end;

procedure TColumnActionLink.SetOnExecute(Value: TNotifyEvent);
begin
  if IsOnExecuteLinked then
    FClient.OnTitleClick := Value;
end;

procedure TColumnActionLink.SetVisible(Value: Boolean);
begin
  if IsVisibleLinked then
    FClient.Visible := Value;
end;

{ TColumn }

procedure TColumn.ActionChanged(Sender: TObject; CheckDefaults: Boolean);
begin
  if Sender is TCustomAction then
    with TCustomAction(Sender) do
    begin
      if not CheckDefaults or (Caption = DefaultTitleCaption) then
        FTitle := Caption;
      if not CheckDefaults or (not ReadOnly) then
        ReadOnly := not Enabled;
      if not CheckDefaults or not Assigned(FOnTitleClick) then
        FOnTitleClick := OnExecute;
      if not CheckDefaults or (Self.Visible = True) then
        Self.Visible := Visible;
      Changed(False);
    end;
end;

function TColumn.DefaultTitleCaption: String;
begin
  Result := 'Column' + IntToStr(Index);
end;

destructor TColumn.Destroy;
begin
  FreeAndNil(FActionLink);
  inherited Destroy;
end;

procedure TColumn.DoActionChange(Sender: TObject);
begin
  if Sender = Action then
    ActionChanged(Sender, False);
end;

procedure TColumn.DoTitleClick;
begin
  if Assigned(FOnTitleClick) then
    if (Action <> nil) and (@FOnTitleClick <> @Action.OnExecute) then
      FOnTitleClick(Self)
    else if FActionLink = nil then
      FOnTitleClick(Self)
    else if FActionLink <> nil then
      if (FGrid <> nil) and not (csDesigning in FGrid.ComponentState) then
      begin
        if not FActionLink.Execute(FGrid) then
          FOnTitleClick(Self);
      end
      else
        if not FActionLink.Execute(nil) then
          FOnTitleClick(Self);
end;

function TColumn.GetAction: TBasicAction;
begin
  if FActionLink <> nil then
    Result := FActionLink.Action
  else
    Result := nil;
end;

function TColumn.GetActionLinkClass: TColumnActionLinkClass;
begin
  Result := TColumnActionLink;
end;

procedure TColumn.InitiateAction;
begin
  if FActionLink <> nil then
    FActionLink.Update;
end;

function TColumn.IsOnTitleClickStored: Boolean;
begin
  Result := (FActionLink = nil) or not ActionLink.IsOnExecuteLinked;
end;

function TColumn.IsReadOnlyStored: Boolean;
begin
  Result := (FActionLink = nil) or not FActionLink.IsEnabledLinked;
  if Result then
    Result := FReadOnly;
end;

function TColumn.IsVisibleStored: Boolean;
begin
  Result := (FActionLink = nil) or not FActionLink.IsVisibleLinked;
  if Result then
    Result := not Visible;
end;

procedure TColumn.SetAction(Value: TBasicAction);
begin
  if Value = nil then
    FreeAndNil(FActionLink)
  else
  begin
    if FActionLink = nil then
      FActionLink := GetActionLinkClass.Create(Self);
    FActionLink.Action := Value;
    FActionLink.OnChange := DoActionChange;
    ActionChanged(Value, csLoading in Value.ComponentState);
    if FGrid <> nil then
      Value.FreeNotification(FGrid);
  end;
  Changed(False);
end;

end.

Note that this code is stripped to only the applicable action parts.

Source: www.nldelphi.com.

An action component

An action component is assignable to the action property of an arbitrary component. But since explaining all that is involved with writing such an action component is pretty comprehensive, I will make it easy for myself in providing the example below.

Suppose you want to make a control that provides zoom capabilities and that you also want the corresponding ZoomIn and ZoomOut actions that can be assigned to toolbar buttons.

unit Zoomer;

interface

uses
  Classes, Controls, ActnList, Forms, Menus, Windows;

type
  TZoomer = class;

  TZoomAction = class(TCustomAction)
  private
    FZoomer: TZoomer;
    procedure SetZoomer(Value: TZoomer);
  protected
    function GetZoomer(Target: TObject): TZoomer;
    procedure Notification(AComponent: TComponent; Operation: TOperation);
      override;
  public
    destructor Destroy; override;
    function HandlesTarget(Target: TObject): Boolean; override;
    procedure UpdateTarget(Target: TObject); override;
  published
    property Caption;
    property Enabled;
    property HelpContext;
    property HelpKeyword;
    property HelpType;
    property Hint;
    property ImageIndex;
    property ShortCut;
    property SecondaryShortCuts;
    property Visible;
    property OnExecute; { This property could be omitted. But if you want to be
                          able to override the default behavior of this action
                          (zooming in on a TZoomer component), then you need to
                          assign this event. From within the event handler
                          you could invoke the default behavior manually. }
    property OnHint;
    property OnUpdate;
    property Zoomer: TZoomer read FZoomer write SetZoomer;
  end;

  TZoomInAction = class(TZoomAction)
  public
    constructor Create(AOwner: TComponent); override;
    procedure ExecuteTarget(Target: TObject); override;
  end;

  TZoomer = class(TCustomControl)
  public
    procedure ZoomIn;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('RoyMKlever', [TZoomer]);
  RegisterActions('Zoomer', [TZoomInAction], nil);
end;

{ TZoomAction }

destructor TZoomAction.Destroy;
begin
  if FZoomer <> nil then
    FZoomer.RemoveFreeNotification(Self);
  inherited Destroy;
end;

function TZoomAction.GetZoomer(Target: TObject): TZoomer;
begin
  if FZoomer <> nil then
    Result := FZoomer
  else if (Target is TZoomer) and TZoomer(Target).Focused then
    Result := TZoomer(Target)
  else if Screen.ActiveControl is TZoomer then
    Result := TZoomer(Screen.ActiveControl)
  else
    { This should not happen! HandlesTarget is called before ExecuteTarget,
      or the action is disabled }
    Result := nil;
end;

function TZoomAction.HandlesTarget(Target: TObject): Boolean;
begin
  Result := ((FZoomer <> nil) and FZoomer.Enabled) or
    ((FZoomer = nil) and (Target is TZoomer) and TZoomer(Target).Focused) or
    ((Screen.ActiveControl is TZoomer) and Screen.ActiveControl.Enabled);
end;

procedure TZoomAction.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and (AComponent = FZoomer) then
    FZoomer := nil;
end;

procedure TZoomAction.SetZoomer(Value: TZoomer);
begin
  if FZoomer <> Value then
  begin
    if FZoomer <> nil then
      FZoomer.RemoveFreeNotification(Self);
    FZoomer := Value;
    if FZoomer <> nil then
      FZoomer.FreeNotification(Self);
  end;
end;

procedure TZoomAction.UpdateTarget(Target: TObject);
begin
  Enabled := HandlesTarget(Target);
end;

{ TZoomInAction }

constructor TZoomInAction.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Caption := 'Zoom in';
  Hint := 'Zoom in|Zooms in on the selected zoomer control';
  ShortCut := Menus.ShortCut(VK_ADD, [ssCtrl]);
end;

procedure TZoomInAction.ExecuteTarget(Target: TObject);
begin
  GetZoomer(Target).ZoomIn;
  { For safety, you cóuld check if GetZoomer <> nil. See remark in GetZoomer. }
end;

{ TZoomer }

procedure TZoomer.ZoomIn;
begin
  { implementation of zooming in }
end;

end.

Activating this action (with a click on a toolbar button, or choosing a menu item) calls in the following priority the ZoomIn routine of:

  1. the Zoomer control that you manually have set in the relating property of the action, if done so, and if the action is enabled, otherwise:
  2. the by the application requested Target, but only if that target is a focused Zoomer control, or otherwise:
  3. the active control in the entire application, but only if that is an enabled Zoomer control.

Subsequently, the ZoomOut action is simply added:

type
  TZoomOutAction = class(TZoomAction)
  public
    constructor Create(AOwner: TComponent); override;
    procedure ExecuteTarget(Target: TObject); override;
  end;

{ TZoomOutAction }

constructor TZoomOutAction.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Caption := 'Zoom out';
  Hint := 'Zoom out|Zooms out on the selected zoomer control';
  ShortCut := Menus.ShortCut(VK_SUBTRACT, [ssCtrl]);
end;

procedure TZoomOutAction.ExecuteTarget(Target: TObject);
begin
  GetZoomer(Target).ZoomOut;
end;

Note that action components require registration in the IDE for being able to use them design time.

Applicable read food in the Delphi help:

Source: www.nldelphi.com.

这篇关于如何在我的组件中添加对操作的支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆