Ver Mensaje Individual
  #1  
Antiguo 23-11-2009
Avatar de aeff
aeff aeff is offline
Miembro
 
Registrado: oct 2006
Ubicación: Cuba, Guantánamo
Posts: 348
Reputación: 18
aeff Va camino a la fama
Creación de un Menú Desplegable personal y el manejo de teclas

Saludos colegas.
Bien, hace unos días publique una duda con respecto a la creación de un menú, esto es más bien una duda más que me he econtrado en el desarrollo de la solución del
mismo problema, por esto pido disculpas a las molestias causadas al haber iniciado un nuevo hilo.
El problema consiste en crear un "componente para un menú desplegable" el cual pueda adoptar estilos predefinidos, con esto me refiero a skins. Ya había intentado hacer
un objeto descendente del "TPopupMenú" pero se me hacía imposible dibujar todos los detalles con relación al skin. Entonces, en el foro me recomendaron implementar un
objeto descendente del "TCustomControl" modificando algunas peculiaridades.
La implementación de lo que hasta el momento he realizado es la siguiente (DE PRUEBA):
Código Delphi [-]
  TAEFFCustomPopupMenuForm = class (TCustomControl)
  private
    FItems: TStringList;
    FItemHeight,
    FSelIndex: Integer;
    FBitmap: TBitmap;
    procedure WMMouseActivate(var Message: TMessage); message WM_MOUSEACTIVATE;
    procedure WMMouseMove(var Message: TWMMouseMove); message WM_MOUSEMOVE;
  protected
    procedure CreateParams(var Params: TCreateParams); override;
    procedure DrawBitmapItems();
    procedure Paint; override;
  public
    constructor Create(AOwner: TComponent); override;
  end; 
...
implementation
...
  constructor TAEFFCustomPopupMenuForm.Create(AOwner: TComponent);
  begin
    // Constructor
    inherited;
    FItemHeight := 20;
    FItems := TStringList.Create;
    FItems.Add('Nuevo');
    FItems.Add('Abrir');
    FItems.Add('Guardar');
    FItems.Add('Guardar como');
    Height := FItems.Count * FItemHeight;
    Width  := 100;
    FBitmap := TBitmap.Create;
    FBitmap.Height := Height;
    FBitmap.Width := Width;
    FSelIndex := 3;
    DrawBitmapItems();
  end;
  procedure TAEFFCustomPopupMenuForm.CreateParams(var Params: TCreateParams);
  begin
    // CreateParams
    inherited;
    with Params do
    begin
      Style := WS_POPUP or WS_BORDER;
      ExStyle := WS_EX_TOPMOST;
      WindowClass.Style := CS_SAVEBITS;
    end;
  end;
  procedure TAEFFCustomPopupMenuForm.WMMouseActivate(var Message: TMessage);
  begin
    // Mouse Activate
    Message.Result := MA_NOACTIVATE;
  end;
  procedure TAEFFCustomPopupMenuForm.WMMouseMove(var Message: TWMMouseMove);
  var
    vNewSelIndex: Integer;
  begin
    inherited;
    vNewSelIndex  := (Message.YPos div FItemHeight);
    if vNewSelIndex <> FSelIndex then
      begin
        FSelIndex := vNewSelIndex;
        DrawBitmapItems();
        Invalidate;
      end;
  end;
  procedure TAEFFCustomPopupMenuForm.DrawBitmapItems();
  var
    vIndexItm: Integer;
    vRectSel: TRect;
  begin
    vIndexItm := 0;
    FBitmap.Canvas.Brush.Color := clWhite;
    FBitmap.Canvas.FillRect(FBitmap.Canvas.ClipRect);
    while vIndexItm < FItems.Count do
      begin
        if FSelIndex = vIndexItm then
          begin
            vRectSel.Left   := 0;
            vRectSel.Top    := vIndexItm * FItemHeight;
            vRectSel.Right  := Width;
            vRectSel.Bottom := vIndexItm * FItemHeight + FItemHeight;
            FBitmap.Canvas.Brush.Color := clNavy;            
            FBitmap.Canvas.FillRect(vRectSel);
            FBitmap.Canvas.Font.Color := clWhite;
            FBitmap.Canvas.TextOut(5, (vIndexItm * FItemHeight), FItems.Strings[vIndexItm]);
            FBitmap.Canvas.Font.Color := clBlack;
            FBitmap.Canvas.Brush.Color := clWhite;
          end
        else
          FBitmap.Canvas.TextOut(5, (vIndexItm * FItemHeight), FItems.Strings[vIndexItm]);
        Inc(vIndexItm);
      end;
  end;
  procedure TAEFFCustomPopupMenuForm.Paint;
  begin
    Canvas.Draw(0,0, FBitmap);
  end;
Para crear este objeto:
Código Delphi [-]
...
var
  x: TAEFFCustomPopupMenuForm;
begin
  x := TAEFFCustomPopupMenuForm.Create(self);
  x.Parent := self;
  x.top := 10;
  x.left := 10;
...

*** La nueva problemática consiste en cómo lograr que:
1. Al presionar las teclas [UP] y [DOWN] pueda modificar el elemento selecionado.
2. Capturar las teclas [left] y [right].
3. Capturar la tecla [ESC] para "cerrar el menú".
4. Detectar cuando se ha dado click fuera del objeto para "cerrar el menú", y
5. Asignar un ShortCut a los elementos.
Bueno colegas, la parte de los detalles del skin no preocupa en estos momentos puesto que ya tengo la idea.
Espero que me puedan ayudar, MIL GRACIAS de ANTEMANO, Sinceramente no doy ni alante ni atrás con esto.
Saludos,
AEFF!!!
Responder Con Cita