如何在 Delphi Form Designer 中为自定义组件添加上下文菜单操作?

Posted

技术标签:

【中文标题】如何在 Delphi Form Designer 中为自定义组件添加上下文菜单操作?【英文标题】:How to add context-menu actions in Delphi Form Designer for a custom component? 【发布时间】:2014-01-14 04:34:08 【问题描述】:

我正在做一个自定义组件,它是 Delphi XE2 中 TComponent 的后代,我想右键单击它并有 2 个选项:下一个和上一个(例如)

如何做到这一点?请提供代码 sn-p 或示例。

该选项应该在设计时出现,右键单击放置在表单上的组件,现在是 TComponent 的后代。但如果有更好的选择来拥有该功能,则不需要这样做。

下一个和上一个将用于根据集合中的主题切换组件的颜色(通过所有者组件列表)。

【问题讨论】:

在设计时,你的意思是? @Andreas, direct TComponent 后代在运行时是不可见的(为什么要实现它们的可见性机制)。所以是的,应该是在设计时。 @eelias:谢谢你的澄清。我现在已经删除了我的反对票。但我仍然怀疑互联网已经多次回答了这个问题。甚至可能在官方文档中,甚至可能在 SO。 你需要一个组件编辑器。在询问 codez 之前,请阅读精美的 Component Writer's Guide docwiki.embarcadero.com/RADStudio/XE2/en/… 和 sourceforge.net/p/radstudiodemos/code/HEAD/tree/trunk/Delphi/… 【参考方案1】:

你需要为你的组件注册一个自定义的组件编辑器,并重写三个方法:

function GetVerbCount: Integer;
function GetVerb(Index: Integer): string; 
procedure ExecuteVerb(Index: Integer);

这是一个(极少的)示例,在 Delphi 2007 中快速组合在一起:

MyTestComponentPackage.dpk - 一个新的 VCL 包(文件->新建->包)

package MyTestComponentPackage;

$R *.res
$ALIGN 8
$ASSERTIONS ON
$BOOLEVAL OFF
$DEBUGINFO ON
$EXTENDEDSYNTAX ON
$IMPORTEDDATA ON
$IOCHECKS ON
$LOCALSYMBOLS ON
$LONGSTRINGS ON
$OPENSTRINGS ON
$OPTIMIZATION ON
$OVERFLOWCHECKS OFF
$RANGECHECKS OFF
$REFERENCEINFO ON
$SAFEDIVIDE OFF
$STACKFRAMES OFF
$TYPEDADDRESS OFF
$VARSTRINGCHECKS ON
$WRITEABLECONST OFF
$MINENUMSIZE 1
$IMAGEBASE $400000
$IMPLICITBUILD ON

requires
  rtl,
  DesignIDE;

contains
  MyComponentUnit in 'MyComponentUnit.pas',
  MyCompRegUnit in 'MyCompRegUnit.pas';
end.

MyComponentUnit.pas - 用于组件代码本身的新 Delphi 单元(文件->新建->单元)。 Unit 为后退/前进功能声明了一个自定义类型。该组件除了声明我们可以在设计时通过弹出菜单设置的那种类型的属性之外什么都不做。

unit MyComponentUnit;

interface

uses
  Classes;

type
  TMyComponentDirection = (cdBack, cdForward);

type
  TMyComponent=class(TComponent)
  private
    FDirection: TMyComponentDirection;
  published
    property Direction: TMyComponentDirection read FDirection write FDirection;
  end;


implementation

end.

MyCompRegUnit.pas,实现自定义组件编辑器,同时注册组件及其编辑器:

unit MyCompRegUnit;

interface

uses
  DesignIntf, DesignEditors, Classes;

type
  TMyComponentEditor=class(TComponentEditor)
    function GetVerbCount: Integer; override;
    function GetVerb(Index: Integer): string; override;
    procedure ExecuteVerb(Index: Integer); override;
  end;

  procedure Register;

implementation

 TMyComponentEditor 

uses
  MyComponentUnit;

// Called when component of this type is right-clicked. It's where
// you actually perform the action. The component editor is passed a reference
// to the component as "Component", which you need to cast to your specific
// component type
procedure TMyComponentEditor.ExecuteVerb(Index: Integer);
begin
  inherited;
  case Index of
    0: (Component as TMyComponent).Direction := cdBack;
    1: (Component as TMyComponent).Direction := cdForward;
  end;
end;

// Called the number of times you've stated you need in GetVerbCount.
// This is where you add your pop-up menu items
function TMyComponentEditor.GetVerb(Index: Integer): string;
begin
  case Index of
    0: Result := '&Back';
    1: Result := '&Forward';
  end;
end;

// Called when the IDE needs to populate the menu. Return the number
// of items you intend to add to the menu.
function TMyComponentEditor.GetVerbCount: Integer;
begin
  Result := 2;
end;

procedure Register;
begin
  RegisterComponents('TestStuff', [TMyComponent]);
  RegisterComponentEditor(TMyComponent, TMyComponentEditor);
end;

end.

您需要保存并构建包,然后在项目管理器中右键单击它并选择“安装”。它将在TestStuff 组件面板页面上注册组件。

全部保存,然后启动一个新的 VCL 表单应用程序。在 Component Palette 中,键入 TMy 以找到新组件,然后双击它以将其添加到新表单中。在表单上右键单击它:

【讨论】:

组件编辑器 (TComponentEditor) 不应与属性编辑器 (TPropertyEditor) 混淆。 请查看您写的描述。 啊,明白了(第一句中的措辞缺失)。将编辑更正。谢谢! 在“MyCompRegUnit.pas,它也实现了...”。 是的。通读一遍,又抓到了几个。再次感谢。 :-)

以上是关于如何在 Delphi Form Designer 中为自定义组件添加上下文菜单操作?的主要内容,如果未能解决你的问题,请参考以下文章

delphi 如何将form2的值传递form1

delphi 如何改变主窗体

如何更换DevExpress控件皮肤

Delphi:如何在公共函数中使用 ComponentCount?

DELPHI中如何调用FROM

Delphi如何在Form的标题栏绘制自定义文字