es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo detectar el clic derecho en un TMenuItem con WM_MENURBUTTONUP?

En una aplicación VCL Delphi 11 de 32 bits en Windows 10, utilizo un componente TApplicationEvents para capturar mensajes de Windows. Desafortunadamente, TApplicationEvents parece que no reacciona al mensaje WM_MENURBUTTONUP cuando hago “clic-derecho” en un elemento de menú TPopupMenu:

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
begin
  case Msg.message of
      Winapi.Messages.WM_MENURBUTTONUP: CodeSite.Send('TForm1.ApplicationEvents1Message: WM_MENURBUTTONUP');
  end;
end;

La documentación de Microsoft (Microsoft documentation) dice:

Mensaje WM_MENURBUTTONUP
Se envía cuando el usuario suelta el botón derecho del mouse mientras el cursor está en un elemento de menú.

Como alternativa, se envía WM_COMMAND con ambos clics, izquierdo y derecho. Sin embargo, para un propósito específico, necesito reaccionar solo cuando hago “clic-derecho” en un elemento de menú.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Solución para que TApplicationEvents no responda al mensaje WM_MENURBUTTONUP al hacer clic derecho en un elemento de menú de TPopupMenu en una aplicación VCL de Delphi 11 en Windows 10

    El problema se puede resolver manejando el mensaje WM_CONTEXTMENU en el propio TForm en lugar de usar TApplicationEvents. El mensaje WM_CONTEXTMENU se envía cuando el usuario invoca el menú contextual (generalmente haciendo clic derecho) en una ventana que no tiene un controlador de mensajes WM_RBUTTONUP.

    Aquí hay un ejemplo de código para manejar el mensaje WM_CONTEXTMENU y verificar si se realizó el clic derecho en un elemento de menú de TPopupMenu:

    type
      TForm1 = class(TForm)
        // ...
      protected
        procedure WMContextMenu(var Message: TWMContextMenu); message WM_CONTEXTMENU;
        // ...
      end;
    
    implementation
    
    procedure TForm1.WMContextMenu(var Message: TWMContextMenu);
    var
      MenuItem: TMenuItem;
    begin
      // Verificar si se mostró el menú contextual al hacer clic derecho en un elemento de menú
      if (Message.Command = 0) and (Message.Pos.x > 0) and (Message.Pos.y > 0) then
      begin
        // Obtener el elemento de menú en el que se hizo clic derecho
        MenuItem := (FindVCLWindow(Message.Handle) as TMenuItem);
        if Assigned(MenuItem) and (MenuItem.Owner is TPopupMenu) then
        begin
          // Verificar si el elemento de menú pertenece a un TPopupMenu
          if Message.Pos.x >= MenuItem.Left then
          begin
            // Manejar el mensaje WM_MENURBUTTONUP para el clic derecho en el elemento de menú
            CodeSite.Send('TForm1.WMContextMenu: WM_MENURBUTTONUP');
          end;
        end;
      end;
    end;
    

    Nota: CodeSite es una biblioteca de registro para Delphi, utilizada aquí para registrar el mensaje WM_MENURBUTTONUP. Puede reemplazarlo por su propio mecanismo de registro o eliminarlo por completo.

Comments are closed.