Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   PopupMenu con SpeedButton (https://www.clubdelphi.com/foros/showthread.php?t=8354)

roman 18-03-2004 16:59:38

PopupMenu con SpeedButton
 
Este es un viejo problema que nunca he podido resolver.

Tengo un SpeedButton y quiero desplegar un PopupMenu al oprimirlo. Con exactitud lo que deseo es lo siguiente:

1. Al oprimir el botón éste debe aparecer sumido y el menú desplegado
2. Al cancelar el menú o seleccionar una opción el botón debe volver a su posicion normal
3. Si el menú está desplegado y se hace click sobre el botón entonces el menú debe cerrarse y el botón regresar a su posición normal.

Los resultados que obtengo son:

1. Si uso el evento OnClick del botón para desplegar el menú, el botón se sume pero recupera inmediatamente su posición normal mientras el menú está desplegado.

2. Si uso el evento OnMouseDown el botón no se sume y cuando cierro el menú el botón se queda sumido.

3. Si uso el evento OnMouseUp el botón se sume mienras se despliega el menú y recupera su posición al cerrarse el menú pero si el menú está desplegado y hago click en el botón entonces el menú se cierra pero se abre inmediatamente de nuevo.

En otras palabras, quiero que el comportamiento sea como el de un ToolButton en una ToolBar pero no me apetece usar una ToolBar.

// Gracias

__cadetill 18-03-2004 18:47:23

Cita:

Empezado por roman
En otras palabras, quiero que el comportamiento sea como el de un ToolButton en una ToolBar pero no me apetece usar una ToolBar.

Pero mira que haces cosas raritas, eh!!! :D

A ver, lo máximo que he conseguido es esto, a lo mejor te ayuda

Código:

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  if SpeedButton1.GroupIndex = 0 then
    SpeedButton1.GroupIndex := 1
  else
  begin
    PopupMenu1.Popup(Self.Left + SpeedButton1.Left,
                  Self.Top + SpeedButton1.Top + (SpeedButton1.Height*2));
    SpeedButton1.GroupIndex := 0;
  end;
end;

Problema: que si haces los clics rápidos, no funciona, han de ser a camara lenta :p

roman 18-03-2004 19:02:41

Cita:

Empezado por cadetill
Pero mira que haces cosas raritas, eh!!! :D

¿Por qué raritas? ¡Sólo quiero que un speedbutton se comporte como cualquier botón decente que despliega un menú!

Cita:

Empezado por cadetill
A ver, lo máximo que he conseguido es esto, a lo mejor te ayuda

Gracias, pero el comportamiento resulta errático: lo hace a veces y a veces no, o mejor dicho, lo hace una vez y depués no.

Bueno, seguiré intentando.

Te mando un saludo

Amilius 18-03-2004 20:50:37

Cita:

Empezado por roman
En otras palabras, quiero que el comportamiento sea como el de un ToolButton en una ToolBar pero no me apetece usar una ToolBar.

Que tal si usas on mouse up, controlas el estado en "tag" que tienen todos los componentes, el problema es que tendrías que colocar el tag en estado normal al cerrar el menú, el tag del menu sería una referencia al botón y controlar si no es nil y es un referencia a un objeto de la clase boton. :(

roman 18-03-2004 20:57:38

Gracias Amilius

Verás, intenté algo similar usado una variable booleana:

Código:

if not MenuAbierto then
begin
  MenuAbierto := true;
  PopupMenu.Popup(...);
  MenuAbierto := false;
end;

pero el problema es que para cuando vuelvo a hacer click en el botón, el Popup ya terminó y por tanto MenuAbierto vuelve a false.

// Saludos

Ohcan 13-12-2005 17:33:59

Ya sé que es un hilo un poco antiguo, pero me he topado con él buscando sobre algo parecido a lo que plantea Roman... y yo lo tengo resuelto (creo).

Si tenemos un formulario (wPrincipal), un SpeedButton (btPruebas) y un PopupMenu (pmPruebas) al que le he añadido un par de Items..
Código Delphi [-]
//OnClick del botón
procedure TwPrincipal.btPruebaClick(Sender: TObject); 
var
  Punto:TPoint;
begin
  if btPrueba.Down then
    begin
      GetCursorPos(Punto);
      pmPrueba.Popup(Punto.X,Punto.Y);
      btPrueba.Down := False;
    end;
end;

//Se lo asigno al OnClick de ambos Items:
procedure TwPrincipal.ItemA1Click(Sender: TObject); 
begin
  //Sólo para que hagan algo
  ShowMessage('Item: ' + TComponent(Sender).Name);
  //Aquí puede ponerse btPrueba.Down := False; para que no se levante ...
end;

Creo que esto es lo que se busca...

Yo, partiendo de aquí, tengo otro problemilla... pero primero intentaré buscar (¡lo que se aprende buscando!) y si no consigo nada ya postearé un hilo para buscar ayuda ;)

Ohcan 13-12-2005 18:21:23

Bueno, pues ya está :D:
Código Delphi [-]
//OnClick del botón
procedure TwPrincipal.btPruebaClick(Sender: TObject); 
var
  Punto:TPoint;
begin
  if btPrueba.Down then
    begin
      GetCursorPos(Punto);
      pmPrueba.Popup(Punto.X,Punto.Y);
      Application.ProcessMessages; //Esto me faltaba
      btPrueba.Down := False; //Por si no selecciono nada del menu
    end;
end;

//Se lo asigno al OnClick de ambos Items:
procedure TwPrincipal.ItemA1Click(Sender: TObject); 
begin
  //Sólo para que hagan algo
  ShowMessage('Item: ' + TComponent(Sender).Name);
  //Aquí puede ponerse btPrueba.Down := False; 
  //para que no se levante ... o no hacerlo y así quedrá pulsado
  //mientras vemos el mensaje y se levantará al aceptarlo
end;
¿Porqué todo esto?
Tenía, como Román, un SpeedButton que me despliega un Popup y lo que quería: si no se seleccionaba nada en el menú, levantar el botón. Y si se seleccionaba algo que saliera un formulario pero que se viera que el botón seguía abajo...
Al principio, sin el ProcessMessages, puse un btPrueba.Down := False antes del ShowMessage del click del menu, pero eso causaba que se viera al botón levantarse y volverse a presionar... y no me gustaba.

Pues esa es la historia... espero que no haya aburrido a nadie :o;)

Saludos,


La franja horaria es GMT +2. Ahora son las 21:07:02.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi