delphicontextmenudelphi-10.4-sydneytmemo

How to execute my custom action when right-clicking on a TMemo control?


In a Delphi 10.4.2 32-bit VCL Application, I need to do different actions when the user (left- or right-)clicks on a TMemo control (which is in ReadOnly mode):

procedure TForm1.Memo1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbLeft then
    DoAction1
  else if Button = mbRight then
    DoAction2;
end;

DoAction2 consists of invoking a specific dialog.

However, when I right-click on the Memo control, the native context menu of the TMemo control shows up, and DoAction2 is not executed:

enter image description here

I have tried to deactivate the right-click context menu of the Memo control with this code:

Memo1.OnContextPopup := nil;

But it does not work: The context menu still shows up when right-clicking the Memo control.

So how can I deactivate the native context menu and execute my action when right-clicking on the Memo control?


Solution

  • This is easy.

    Your code Memo1.OnContextPopup := nil; has no effect because the Memo1.OnContextPopup property already is nil, as you can see in the Object Inspector; that is, by default you have no custom handler.

    What you need to do is to add such a custom handler and set the Handled var property to True. At design time, use the Object Inspector to create an OnContextPopup handler for your memo, with the following code:

    procedure TForm1.Memo1ContextPopup(Sender: TObject; MousePos: TPoint;
      var Handled: Boolean);
    begin
      Handled := True;
    end;
    

    Now the default context menu is suppressed and you can try, for example,

    procedure TForm1.Memo1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      if Button = mbLeft then
        Winapi.Windows.Beep(300, 250)
      else if Button = mbRight then
        Winapi.Windows.Beep(300, 1000);
    end;