用我自己的TCustomEdit上下文菜单替换

Sal*_*dor 11 windows delphi

我想使用我自己的弹出菜单(它有很多动作)替换TCustomEdit组件中的delphi显示的所有弹出菜单,如TEdit或TMemo.到目前为止,我用我自己的TPopUpMenu手动替换每个组件的PopUpMenu属性.但是我想知道如果我不能手动为我的所有表单中的每个组件修改此属性,我是否可以这样做.

我想要一个钩子来截取对这个系统菜单的调用并替换我自己的菜单.这可能吗?

在此输入图像描述

kob*_*bik 6

例如,如果你的表格来自一个共同的祖先(而不是默认的TForm)TMyBaseForm,这意味着TForm1 = class(TMyBaseForm)这可以很容易地完成.在TMyBaseForm.OnShow事件中,你可以通过它的控制循环,如果你发现一个TEdit或者TMemo你设置的PopupMenu动态属性.

另一种方法是使用Screen.OnActiveFormChange(在你的主窗体事件处理程序中Screen.OnActiveControlChange右键单击活动控件 - 编辑:这只有D5时才会触发,以捕获活动表单并迭代Screen.ActiveForm控件并设置TEditTMemo属性PopupMenu为你的定制MyPopupMenu:

procedure TForm1.FormCreate(Sender: TObject);
begin
  Screen.OnActiveFormChange := ActiveFormChange;
end;    

procedure TForm1.ActiveFormChange(Sender: TObject);
begin
  CustomEditControlsNormalize(Screen.ActiveForm);
end;

type
  TCustomEditAccess = class(TCustomEdit);

procedure TForm1.CustomEditControlsNormalize(F: TForm);
var
  I: Integer;
begin
  if not Assigned(F) then Exit;
  for I := 0 to F.ComponentCount - 1 do
    if F.Components[I] is TCustomEdit then
      TCustomEditAccess(F.Components[I]).Popupmenu := MyPopupMenu;
end;    
Run Code Online (Sandbox Code Playgroud)

要确定哪个TCustomEdit控件导致Popupmenu弹出,请参考MyPopupMenu.PopupComponent(在MyPopupMenu.OnPopup事件中):

procedure TForm1.MyPopupMenuPopup(Sender: TObject);
begin
  if MyPopupMenu.PopupComponent is TCustomEdit then
  begin
    FEditPopupControl := TCustomEdit(MyPopupMenu.PopupComponent);
    Caption := FEditPopupControl.Name; // debug :-P
  end;
end;
Run Code Online (Sandbox Code Playgroud)

编辑: Screen.OnActiveControlChange是我最初的想法.我在D5测试了它.如果Edit1聚焦并且我右键单击Edit2,它将首先弹出默认菜单,然后它才成为活动控件.我终于用D7和D2009进行了测试.两者都很好.这只是一个D5问题,所以Justmade的答案肯定是比使用更好的解决方案Screen.OnActiveFormChange.


Rem*_*eau 5

您可以OnContextPopup为所有编辑控件分配单个事件处理程序,让它调用Popup()方法TPopupMenu,并将事件的Handled参数设置为True.但这与直接分配TPopupMenu给所有编辑控件没什么不同.

为了更进一步,您可以OnContextPopup为父级TForm而不是单独的编辑控件分配单个事件处理程序.该事件告诉您鼠标调用菜单时的鼠标坐标.您可以在这些坐标下找到子控件,如果它是您的编辑控件之一,则调用Popup()并设置Handled为True.用户可以通过键盘调用菜单,在这种情况下鼠标坐标将是{-1, -1},因此使用该TScreen.ActiveControl属性来知道正在调用哪个控件.


Jus*_*ade 5

在主窗体中,添加以下代码.它应该适用于您的所有表单的自定义控件.

TForm2 = class(TForm)
  procedure FormCreate(Sender: TObject);
private
  procedure ActiveControlChanged(Sender: TObject);
end;

implementation

type
  TCustomEditAccess = class(TCustomEdit);
  TCustomGridAccess = class(TCustomGrid);

procedure TForm2.ActiveControlChanged(Sender: TObject);
begin
  if (Screen.ActiveControl is TCustomEdit) and not Assigned(TCustomEditAccess(Screen.ActiveControl).PopupMenu) then
    TCustomEditAccess(Screen.ActiveControl).PopupMenu := MyPopupMenu
  else if (Screen.ActiveControl is TCustomGrid) then
  begin
    TCustomGridAccess(Screen.ActiveControl).ShowEditor;
    if Assigned(TCustomGridAccess(Screen.ActiveControl).InplaceEditor) then
      TCustomEditAccess(TCustomGridAccess(Screen.ActiveControl).InplaceEditor).PopupMenu := MyPopupMenu;
  end;
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  Screen.OnActiveControlChange := ActiveControlChanged;
end;
Run Code Online (Sandbox Code Playgroud)

它只是kobik答案的简化版本(在编码方面),并且还将解决由代码或其他不使用Form作为所有者的复杂控件创建的任何TCustomEdit.

他关于如何确定应用哪个CustomEdit弹出窗口的说明.

编辑:添加Grid InplaceEditor支持