Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6182279
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T01:10:21+00:00 2026-05-24T01:10:21+00:00

What do I need to do for adding actions support to my component. It

  • 0

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.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T01:10:22+00:00Added an answer on May 24, 2026 at 1:10 am

    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: http://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:

    • Writing action components,
    • How actions find their targets,
    • Registering actions,
    • What happens when an action fires,
    • Updating actions,
    • Setting up action lists.

    Source: http://www.nldelphi.com.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a problem with a form. I need it to perform two actions
Sorry the question may sound stupid, but I do need one. Right now I'm
I have authlogic working fine but now have the need to let administrator users
I need to create module in Magento which will have few database tables. One
I have a Scouts model that requires two actions in addition to the standard
It's easy to set up an Alt hotkey for a Windows Forms button by
I need to draw a lot of (about 500000) little lines in some area
I need a couple of computed columns that contain count totals (indexed columns). Do
I need to add an ado appender to an existing log4net config. I need
I need to create a Junction point (directory symbolic link) from C:\x to C:\xxx\yyy\zzz\aaa\bbb

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.