David Schwartz 426 Posted December 21, 2020 I've always used TRichView when I've needed RichEdit stuff, but where I'm at now doesn't have it, so I'm using TRzRichEdit, which is derived from the standard TRichEdit control. So I apologize in advance if this seems like a basic topic. I have some RichEdits and added a Popup to them. I multiplex the popup across the RichEdits and set a Tag to figure out which one is being used. I know both TMemos and TRichEdits have basic editing stuff wired-in -- cut, copy, paste, etc. I seem to recall that if you don't provide your own Popup, then you get a default with those menu items in it. Anyway, I did not define these common actions and only had my own menu items in the popup. As a result, you CAN use the hotkeys <ctrl-C>, <ctrl-X>, <ctrl-V> etc, but there are no corresponding menu items in the popup. I just added them to the popup explicitly, but now the hot-keys don't work. I defined the hot-keys in the popup menu items, but that doesn't seem to do anything (unless they're disabling the hot-keys instead). Isn't there some way to inherit all of this from the default popup menu? Or ... how do you get these default actions added to your own popup menu without redefining them? Share this post Link to post
Anders Melander 1782 Posted December 21, 2020 I don't have any knowledge about your exact problem but: You have the source so you should be able to see how and why assigning a popup menu to the control affects the standard menu. Use a TActionList instead of wiring the menu items directly. Share this post Link to post
Guest Posted December 22, 2020 4 hours ago, David Schwartz said: Isn't there some way to inherit all of this from the default popup menu? Or ... how do you get these default actions added to your own popup menu without redefining them? see my sample creating all by code and assinging PopupMenu to RichEdit component, or anyother! unit uFormMain; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.StdActns, System.Actions, Vcl.ActnList, Vcl.Menus, Vcl.ComCtrls; type TfrmFormMain = class(TForm) RichEdit1: TRichEdit; RichEdit2: TRichEdit; Edit1: TEdit; Edit2: TEdit; RichEdit3: TRichEdit; Button1: TButton; procedure RichEdit1Enter(Sender: TObject); procedure RichEdit1Exit(Sender: TObject); procedure RichEdit2Enter(Sender: TObject); procedure RichEdit2Exit(Sender: TObject); procedure FormCreate(Sender: TObject); private procedure prcCreatMyItemsAndActionsToMyPopupMenuOnRichEdit; procedure prcMyActionNonDefaultExecute(Sender: TObject); public { Public declarations } end; var frmFormMain: TfrmFormMain; implementation {$R *.dfm} { Here, my way to show as all can be defined. But, exist better way to quick create and definitions by using others functions in your IDE, ok? Ex.: to Menu, exist the "NewMenu/NewPopupMenu, etc..." procedure in "VCL.Menus.pas" - see in your Help or VCL sources! } var { for easy access in all form!!! } lMyActionList: TActionList; lMyPopupMenu : TPopupMenu; procedure TfrmFormMain.prcCreatMyItemsAndActionsToMyPopupMenuOnRichEdit; var lMyMenuItemCopy : TMenuItem; lMyMenuItemCut : TMenuItem; lMyMenuItemPaste : TMenuItem; lMyMenuItemToNonDefaultAction: TMenuItem; // // Category: Edit (my group for Edit actions) lMyActionToEditCopy : TEditCopy; lMyActionToEditCut : TEditCut; lMyActionToEditPaste: TEditPaste; // lMyActionNonDefault: TAction; begin // creating our Actions definitions: all in my "Edit" category! // lMyActionToEditCopy := TEditCopy.Create(lMyActionList); lMyActionToEditCopy.Name := 'myActionToEditCopy'; lMyActionToEditCopy.Category := 'ActionToEdit'; lMyActionToEditCopy.Caption := 'My&Copy'; lMyActionToEditCopy.ShortCut := TextToShortCut('Ctrl+C'); // 16451; // { uppercase or lowercase, does matter } // Hint, Image, etc... lMyActionToEditCut := TEditCut.Create(lMyActionList); lMyActionToEditCut.Name := 'myActionToEditCut'; lMyActionToEditCut.Category := 'ActionToEdit'; lMyActionToEditCut.Caption := 'MyC&ut'; lMyActionToEditCut.ShortCut := TextToShortCut('Ctrl+U'); // 16472; // lMyActionToEditPaste := TEditPaste.Create(lMyActionList); lMyActionToEditPaste.Name := 'myActionToEditPaste'; lMyActionToEditPaste.Category := 'ActionToEdit'; lMyActionToEditPaste.Caption := 'My&Paste'; lMyActionToEditPaste.ShortCut := TextToShortCut('Ctrl+P'); // 16470; // lMyActionNonDefault := TAction.Create(lMyActionList); lMyActionNonDefault.Name := 'myActionNonDefault'; lMyActionNonDefault.Category := 'ActionToNonDefaultAction'; lMyActionNonDefault.Caption := 'My&Non-Default Action'; lMyActionNonDefault.ShortCut := TextToShortCut('Ctrl+N'); lMyActionNonDefault.OnExecute := prcMyActionNonDefaultExecute; // // creating MenuItems to our PopupMenu // lMyMenuItemCopy := TMenuItem.Create(lMyPopupMenu); lMyMenuItemCopy.Name := 'myMenuItemCopy'; lMyMenuItemCopy.Action := lMyActionToEditCopy; // lMyMenuItemCut := TMenuItem.Create(lMyPopupMenu); lMyMenuItemCut.Name := 'myMenuItemCut'; lMyMenuItemCut.Action := lMyActionToEditCut; // lMyMenuItemPaste := TMenuItem.Create(lMyPopupMenu); lMyMenuItemPaste.Name := 'myMenuItemPaste'; lMyMenuItemPaste.Action := lMyActionToEditPaste; // lMyMenuItemToNonDefaultAction := TMenuItem.Create(lMyPopupMenu); lMyMenuItemToNonDefaultAction.Name := 'myMenuItemToNonDefaultAction'; lMyMenuItemToNonDefaultAction.Action := lMyActionNonDefault; // // Adding our MenuItems on our PopupMneu // lMyPopupMenu.Items.Add(lMyMenuItemCopy); lMyPopupMenu.Items.Add(lMyMenuItemCut); lMyPopupMenu.Items.Add(lMyMenuItemPaste); lMyPopupMenu.Items.Add(lMyMenuItemToNonDefaultAction); end; procedure TfrmFormMain.prcMyActionNonDefaultExecute(Sender: TObject); begin ShowMessage('Hello world, i''m ' + (Sender as TAction).Name); end; procedure TfrmFormMain.FormCreate(Sender: TObject); begin prcCreatMyItemsAndActionsToMyPopupMenuOnRichEdit; end; procedure TfrmFormMain.RichEdit1Enter(Sender: TObject); begin RichEdit1.PopupMenu := lMyPopupMenu; // Edit2.Text := 'RichEdit1.PopupMenu := ' + lMyPopupMenu.Name; end; procedure TfrmFormMain.RichEdit1Exit(Sender: TObject); begin RichEdit1.PopupMenu := nil; // Edit2.Text := 'RichEdit1.PopupMenu := nil'; end; procedure TfrmFormMain.RichEdit2Enter(Sender: TObject); begin RichEdit2.PopupMenu := lMyPopupMenu; // Edit2.Text := 'RichEdit2.PopupMenu := ' + lMyPopupMenu.Name; end; procedure TfrmFormMain.RichEdit2Exit(Sender: TObject); begin RichEdit2.PopupMenu := nil; // Edit2.Text := 'RichEdit2.PopupMenu := nil'; end; initialization ReportMemoryLeaksOnShutdown := true; // testing "memory leaks"... // lMyPopupMenu := TPopupMenu.Create(nil); lMyPopupMenu.Name := 'myPopupMenu'; // lMyActionList := TActionList.Create(nil); // or Self, etc... you choice how all end! lMyActionList.Name := 'myActionList'; // finalization lMyActionList.Free; lMyPopupMenu.Free; end. hug Share this post Link to post
David Schwartz 426 Posted December 23, 2020 Ok, assigning the popup menu in the Enter/Exit events made me go DUH! Yeah, it's a lot easier than what I did with tags. But all of the boilerplate code for the menu items and actions is already defined somewhere. I mean ... it's there by default if you don't override the PopupMenu. Isn't there some way to "inherit" it? Share this post Link to post
Guest Posted December 23, 2020 (edited) yeah, you need some like "MergeMenu" items used in TMainMenu! object myPopupMenu1: TPopupMenu Left = 584 Top = 176 object myPopupMenu1Item11: TMenuItem Caption = 'myPopupMenu1_Item1' end object myPopupMenu1Item21: TMenuItem Caption = 'myPopupMenu1_Item2' end object myPopupMenu1Item31: TMenuItem Caption = 'myPopupMenu1_Item3' end end object myPopupMenu2: TPopupMenu Left = 584 Top = 248 object myPopupMenu2Item11: TMenuItem Caption = 'myPopupMenu2_Item1' end object myPopupMenu2Item21: TMenuItem Caption = 'myPopupMenu2_Item2' end object myPopupMenu2Item31: TMenuItem Caption = 'myPopupMenu2_Item3' end end object myPopupMenu3: TPopupMenu Left = 584 Top = 320 end unit uFormSecond; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, Vcl.StdCtrls, Vcl.ComCtrls; type TfrmFormSecond = class(TForm) RichEdit1: TRichEdit; RichEdit2: TRichEdit; RichEdit3: TRichEdit; myPopupMenu1: TPopupMenu; myPopupMenu1Item11: TMenuItem; myPopupMenu1Item21: TMenuItem; myPopupMenu1Item31: TMenuItem; myPopupMenu2: TPopupMenu; myPopupMenu2Item11: TMenuItem; myPopupMenu2Item21: TMenuItem; myPopupMenu2Item31: TMenuItem; myPopupMenu3: TPopupMenu; Edit1: TEdit; procedure RichEdit1Enter(Sender: TObject); procedure RichEdit1Exit(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var frmFormSecond: TfrmFormSecond; implementation {$R *.dfm} procedure prcMergerPopupMenu(lPMtarget: TPopupMenu; const lPMSource: TPopupMenu); var lMenuItem: TMenuItem; lMItmp : TMenuItem; begin // if (lPMtarget = lPMSource) then exit; // // I dont worry about any "AV" here, ok! just for test... // for lMenuItem in lPMSource.Items do // this is not a recursive copy, but you can increment it if you want! begin lMItmp := TMenuItem.Create(lPMtarget); // // if (lPMtarget.FindComponent(lMenuItem.Name) = nil) then // if not used "(lPMtarget = lPMSource)" above begin lMItmp.Name := lMenuItem.Name; lMItmp.Caption := lMenuItem.Caption; lMItmp.ShortCut := lMenuItem.ShortCut; // lPMtarget.Items.Add(lMItmp); end; end; end; procedure TfrmFormSecond.FormCreate(Sender: TObject); begin Self.ActiveControl := Edit1; // just for tests... // RichEdit2.OnEnter := RichEdit1.OnEnter; RichEdit2.OnExit := RichEdit1.OnExit; end; procedure TfrmFormSecond.RichEdit1Enter(Sender: TObject); begin // cleaning old items on my "PopupMenu" with new options // else, "AV" can be raised if "items" already exist! myPopupMenu3.Items.Clear; // prcMergerPopupMenu(myPopupMenu3, myPopupMenu1); // PopupMenu1 have 3 menuitems in my test // prcMergerPopupMenu(myPopupMenu3, myPopupMenu2); // PopupMenu2 have 3 menuitems in my test // prcMergerPopupMenu(myPopupMenu3, myPopupMenu3); // same PopupMenu's // (Sender as TRichEdit).PopupMenu := myPopupMenu3; end; procedure TfrmFormSecond.RichEdit1Exit(Sender: TObject); begin (Sender as TRichEdit).PopupMenu := nil; end; initialization ReportMemoryLeaksOnShutdown := true; finalization end. hug Edited December 24, 2020 by Guest Share this post Link to post
Guest Posted December 24, 2020 all would be more ease if "ADD()" methods dont verify the "Parent" before add new items on PopupMenu! Share this post Link to post