Search code examples
delphicomponentspopupmenu

delphi custom component with default popupmenu item


I use a custom listview component and I need it to have a popupmenu item "copy data to clipboard". If there is no assigned popup, I create one and add the menuitem, if there is already a menu assigned, add the item to the current popup. Tried to put the code in the constructor, but then I realized, that popupmenu is still not created or associated to my listview. So any idea when to create my default item?

constructor TMyListView.Create(AOwner: TComponent);
var
  FpopupMenu: TPopupMenu;
begin
  inherited;
  .....
  FPopUpMenuItem := TMenuItem.Create(self);
  FPopUpMenuItem.Caption := 'Copy data to clipboard';
  FPopUpMenuItem.OnClick := PopupMenuItemClick;
  if assigned(PopupMenu) then begin
    popupMenu.Items.Add(FPopUpMenuItem);
  end
  else begin
    FpopupMenu := TPopupMenu.Create(self);
    FpopupMenu.Items.Add(FPopUpMenuItem);
    PopupMenu := FpopupMenu;
  end;
...
end;

Solution

  • Override the virtual TControl.DoContextPopup() method, eg:

    type
      TMyListView = class(TListView)
      protected
        ...
        procedure DoContextPopup(MousePos: TPoint; var Handled: Boolean); override;
        ...
      end;
    
    procedure TMyListView.DoContextPopup(MousePos: TPoint; var Handled: Boolean);
    var
      LPopupMenu: TPopupMenu;
      LItem: TMenuItem;
    
      function IsSameEvent(const E1, E2: TNotifyEvent): Boolean;
      begin
        Result := (TMethod(E1).Code = TMethod(E2).Code) and
                  (TMethod(E1).Data = TMethod(E2).Data);
      end;
    
    begin
      inherited DoContextPopup(MousePos, Handled);
      if Handled then Exit;
    
      LPopupMenu := PopupMenu;
      if not Assigned(LPopupMenu) then
      begin
        LPopupMenu := TPopupMenu.Create(Self);
        PopupMenu := LPopupMenu;
      end;
    
      for I := 0 to LPopupMenu.Items.Count-1 do
      begin
        LItem := LPopupMenu.Items[I];
        if IsSameEvent(LItem.OnClick, PopupMenuItemClick) then
          Exit;
      end;
    
      LItem := TMenuItem.Create(Self);
      LItem.Caption := 'Copy data to clipboard';
      LItem.OnClick := PopupMenuItemClick;
      LPopupMenu.Items.Add(LItem);
    end;