Cómo agregar elementos dinámicamente a un menú de TPopUp en Delphi

Cuando se trabaja con menús o menús PopUp en aplicaciones Delphi, en la mayoría de los escenarios, se crean los elementos de menú en tiempo de diseño. Cada elemento del menú está representado por una clase TMenuItem Delphi. Cuando un usuario selecciona (hace clic) en un elemento, el evento OnClick se dispara para que usted (como desarrollador) tome el evento y responda a él.

Puede haber situaciones en las que los elementos del menú no se conozcan en tiempo de diseño, pero necesiten ser añadidos en tiempo de ejecución (instanciados dinámicamente).

Agregar TMenuItem en tiempo de ejecución

Supongamos que hay un componente de TPopupMenu llamado "PopupMenu1" en un formulario Delphi, para agregar un elemento al menú emergente se puede escribir un fragmento de código como:

 var

   menuItem : TMenuItem;

begin

  menuItem := TMenuItem.Create(PopupMenu1) ;

  menuItem.Caption := 'Item added at ' + TimeToStr(now) ;

  menuItem.OnClick := PopupItemClick;

  //assign it a custom integer value..

  menuItem.Tag := GetTickCount;

  PopupMenu1.Items.Add(menuItem) ;

end;

Notas:

  • En el código anterior, se añade un elemento al componente PopupMenu1. Tenga en cuenta que asignamos un valor entero a la propiedad Tag. La propiedad Tag (cada componente de Delphi la tiene) está diseñada para permitir a un desarrollador asignar un valor entero arbitrario almacenado como parte del componente.
  • La función de la API GetTickCount recupera el número de milisegundos que han transcurrido desde que se inició Windows.
  • Para el manejador de eventos OnClick, asignamos "PopupItemClick" - el nombre de la función con la firma *correcta*.

Importante: al hacer clic en el elemento añadido dinámicamente, se ejecutará el "PopupItemClick". Para diferenciar entre uno o más elementos añadidos en tiempo de ejecución (todos ejecutando el código en PopupItemClick) podemos utilizar el parámetro Sender:

 procedure TMenuTestForm.PopupItemClick(Sender: TObject) ;

var

   menuItem : TMenuItem;

begin

   if NOT (Sender is TMenuItem) then

   begin

     ShowMessage('Hm, if this was not called by Menu Click, who called this?!') ;

     ShowMessage(Sender.ClassName) ;

     exit;

   end;

   menuItem := TMenuItem(sender) ;

   ShowMessage(Format('Clicked on "%s", TAG value: %d',[menuItem.Name, menuItem.Tag])) ;

end;

El método "PopupItemClick" comprueba primero si el remitente es realmente un objeto TMenuItem. Si el método se ejecuta como resultado de un elemento de menú, el manejador de eventos OnClick simplemente muestra un mensaje de diálogo con el valor Tag que se asignó cuando el elemento de menú se añadió al menú.

¿Cadena personalizada en (creada en tiempo de ejecución) TMenuItem?

En aplicaciones del mundo real, usted podría necesitar más flexibilidad. Supongamos que cada elemento "representará" una página web - un valor de cadena sería necesario para mantener la URL de la página web. Cuando el usuario selecciona este elemento, puede abrir el navegador web predeterminado y navegar hasta la URL asignada con el elemento de menú.

Aquí hay una clase TMenuItemExtended personalizada equipada con una propiedad "Value" de cadena personalizada:

 type

  TMenuItemExtended = class(TMenuItem)

  private

    fValue: string;

  published

    property Value : string read fValue write fValue;

  end;

A continuación, se explica cómo añadir este elemento de menú "extendido" a un PoupMenu1:

 var

   menuItemEx : TMenuItemExtended;

begin

   menuItemEx := TMenuItemExtended.Create(PopupMenu1) ;

   menuItemEx.Caption := 'Extended added at ' + TimeToStr(now) ;

   menuItemEx.OnClick := PopupItemClick;

   //assign it a custom integer value..

   menuItemEx.Tag := GetTickCount;

   //this one can even hold a string value

   menuItemEx.Value := 'http://delphi.about.com';

   PopupMenu1.Items.Add(menuItemEx) ;

end;

Ahora, el "PopupItemClick" debe ser modificado para procesar correctamente este elemento de menú:

 procedure TMenuTestForm.PopupItemClick(Sender: TObject) ;

var

   menuItem : TMenuItem;

begin

   //...same as above

   if sender is TMenuItemExtended then

   begin

     ShowMessage(Format('Ohoho Extended item .. here''s the string value : %s',[TMenuItemExtended(Sender).Value])) ;

   end;

end;

Nota: para abrir el explorador web predeterminado, puede utilizar la propiedad Value como parámetro de una función de la API de ShellExecuteEx.

Eso es todo. Depende de usted extender el TMenuItemExtended según sus necesidades. La sección Crear componentes Delphi personalizados es donde buscar ayuda para crear sus propias clases/componentes.

(0 votes)