PDA

Ver la Versión Completa : TrayIcon y su Popup


gluglu
26-09-2007, 18:46:03
Hola !

Cualquiera de los programas que tenemos abajo a la derecha en el SysTary al lado del reloj, cuando hacemos Click con el ratón sobre ellos, aparece un Menu Popup.

Hasta ahí llego.

Pero cuando hacemos Click en cualquier otro programa diferente (sin siquiera haber elegido una opción del Menu Popup), o en cualquier otra parte del escritorio, ese Menu Popup desaparece automáticamente, evidentemente sin tener que estar esa aplicación activa.

Ahi NO llego ! :o

Como puedo hacer desaparecer el Popupmenu dichoso al hacer click en cualquier otra parte.

He probado con Application.OnDeactivate pero al parecer no entra ahí ya que la ventana principal de la aplicación esta oculta (Visible := False).

Gracias por vuestra ayuda. ;)

Edito y añado : Lo que quiero decir es cuando pulso el botón izquierdo del ratón. Con el derecho y mediante la activación del PopupMenu de manera automática, si funciona.

Pero por ejemplo el messenger, si se pulsa el botón izquierdo sale tam´bién el Popupmenu, y si pulso en otro lado, desaparece.

jhonny
26-09-2007, 18:57:15
:eek: Se supone que eso funciona solito, sin necesidad de hacerle nada.

Acabo de probarlo con el TTrayIcon de D2007 y funciono sin problema, recuerdo haberlo hecho alguna vez con el de las RxTray y eso tambien funcionaba sin problema.

seoane
26-09-2007, 18:58:31
Hola glugu, el tema de los popup y el systray es sencillo. Antes de mostrar el popup se debe de usar la funcion SetForegroundWindow con la ventana a la que pertenece ese menu. No importa si la ventana esta oculta.

eduarcol
26-09-2007, 19:00:10
y ese no es el comportamiento normal del popup?? al tener el foco otra aplicacion este va a desaparecer acabo de probarlo en delphi 7 funciona asi sin cambiar ninguna propiedad ni evento

jhonny
26-09-2007, 19:01:57
Hola glugu, el tema de los popup y el systray es sencillo. Antes de mostrar el popup se debe de usar la funcion SetForegroundWindow con la ventana a la que pertenece ese menu. No importa si la ventana esta oculta.

¿Pero el TTrayIcon no hace ya esa llamada a dicha función?

eduarcol
26-09-2007, 19:02:04
pero bueno hoy el club esta movido aqui tambien se me han adelantado

seoane
26-09-2007, 19:04:51
¿Pero el TTrayIcon no hace ya esa llamada a dicha función?
gluglu no ha mencionado el TTrayicon :confused: Puede que este usando, por ejemplo, el delphi 7 que no trae ese componente y le toque crear el icono "a mano"

jhonny
26-09-2007, 19:05:45
pero bueno hoy el club esta movido aqui tambien se me han adelantado

Bueno, pero el movido sos vos, te me haz adelantado :D

jhonny
26-09-2007, 19:07:30
gluglu no ha mencionado el TTrayicon :confused: Puede que este usando, por ejemplo, el delphi 7 que no trae ese componente y le toque crear el icono "a mano"

:D, cierto, cierto, tienes razón... no habia caido en ese detalle, aunque seguramnete mi subconciente si, ya que mencione el TRxTray :p.

gluglu
26-09-2007, 19:31:42
Perdón, me perdí por ahí 20 minutos y menuda se ha armado también aquí.

Utilizo Delphi 2006 y sí, si utilizo el TTrayIcon.

Insisto, el problema es con el botón izquierdo ...

En el evento OnClick del TrayIcon tengo

procedure TWakeUp.TrayIcon1Click(Sender: TObject);
begin
PopupMenu1.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y);
end;

y de hecho, cuando pulso en otra parte del escritorio o en otra aplicación, ese menú popup NO desaparece automáticamente.

No lo he probado, pero podría tener algo que ver que la Ventana principal de la aplicación correspondiente a ese TrayIcon tengo FormStyle := fsStayOnTop ?, ya que cuando se active, quiere que esté siempre por delante de las demás.

dec
26-09-2007, 19:37:23
Hola,

Una posible solución pasa por lo que ha comentado Domingo:


SetForegroundWindow(self.Handle);
PopupMenu1.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y);
PostMessage(self.Handle, WM_NULL, 0, 0);


Echa un vistazo a la ayuda de la función "TrackPopupMenu" (del API de Windows) para más información.

seoane
26-09-2007, 19:38:06
Pero no entiendo por que no usas la propiedad PopupMenu del TTrayicon, asi el ya se encarga de mostraralo correctamente.

De todas formas si quieres mostraralo "a mano":

procedure TWakeUp.TrayIcon1Click(Sender: TObject);
begin
SetForegroundWindow(PopupMenu1.WindowHandle);
PopupMenu1.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y);
end;

gluglu
26-09-2007, 19:39:56
Efectivamente, gracias Domingo.

Seoane tiene razón. Con este código en el OnClick del TrayIcon funciona correctamente :

procedure TWakeUp.TrayIcon1Click(Sender: TObject);
begin
SetForegroundWindow(Handle);
PopupMenu1.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y);
end;

Vamos a rizar el rizo. Resulta que (vuelvo a poner como ejemplo el messenger), si pulso el botón izquierdo del ratón, abre el correspondiente Popupmenu del messenger. Si ahora pulso dobre cualquier aplicación que se encuentra en la barra de tareas, se cierra el popupmenu y se da 'foco' directamente a la aplicación seleccionada de la barra de tareas.

A mi no me funciona así. :( Al pulsar sobre una aplicación de la barra de tareas desaparece correctamente el popupmenu de mi TrayIcon pero la aplicación seleccionada en la barra de tareas se pone intermitente y no se le dá foco automáticamente.

:o

Casimiro Notevi
26-09-2007, 19:43:37
Te veo cambiando al componente de las RX ;)

gluglu
26-09-2007, 19:46:27
Creo que las RX no están disponibles para VCL.Net :o .... o me equivoco ?

Caral
26-09-2007, 19:54:02
Hola
Perdon que me meta pero yo trate con el componente TrayIncon y la verdad no me funciono bien, me genero varios problemas.
Aqui tienes un ejemplo, sin ese componente, tal vez te sirva.
No pude subir el zip, estoy teniendo problemas con esto.
Colocas un popupmenu y le pones abrir en su primer item.

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, ShellApi,
Forms, Dialogs, Menus;

type
TForm1 = class(TForm)
PopupMenu1: TPopupMenu;
Abrir1: TMenuItem;
procedure Abrir1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
IconData : TNotifyIconData;
procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
procedure Espabila(var Msg : TMessage); message WM_USER+1;

public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.WMSysCommand(var Msg: TWMSysCommand);
begin
if (Msg.CmdType = SC_MINIMIZE) then begin
with IconData do
begin
cbSize := sizeof(IconData);
Wnd := Handle;
uID := 100;
uFlags := NIF_MESSAGE + NIF_ICON + NIF_TIP;
uCallbackMessage := WM_USER + 1;
{Usamos de icono el mismo de la aplicacion}
{We use the same icon as the application}
hIcon := Application.Icon.Handle;
{Como Hint del icono, el nombre de la aplicacion}
{The name of te app for the hint of the icon}
StrPCopy(szTip, Application.Title);
end;
{Ponemos el icono al lado del reloj}
{Place the icon next to the clock}
Shell_NotifyIcon(NIM_ADD, @IconData);
{Ocultamos la Form...}
{Hide the form...}
Hide;
end else DefaultHandler(Msg);
end;

procedure TForm1.Espabila(var Msg : TMessage);
{Aqui se recibe la pulsacion sobre el icono}
{Here we recieve the click on the icon}
var
p : TPoint;
begin
if Msg.lParam = WM_RBUTTONDOWN then begin
SetForegroundWindow(Handle);
GetCursorPos(p);
PopupMenu1.Popup(p.x, p.y);
PostMessage(Handle, WM_NULL, 0, 0);
end;
end;


procedure TForm1.Abrir1Click(Sender: TObject);
begin
{Mostramos de nuevo la form}
{We show the form again}
Form1.Show;
ShowWindow(Application.Handle, SW_HIDE);
{Y nos cargamos el icono de la system tray}
{Destroy the systray icon}
Shell_NotifyIcon(NIM_DELETE, @IconData);
IconData.Wnd:=0;

end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
{Quitamos el icono (en el caso de haberlo puesto antes...)}
{Take off the icon (in case of had placed it before.....)}
if IconData.Wnd <> 0 then Shell_NotifyIcon(NIM_DELETE, @IconData);

end;

end.
Saludos

gluglu
27-09-2007, 19:21:40
Caral, gracias por tu aporte también.

Lo he probado tal y como lo expones y denoto que tengo los mismos problemas. Cuando pulso sobre cualquier otra aplicación de la barra de tareas, esta se queda intermitente (algunas veces, otras no) y no trae al frente dicha aplicación seleccionada.

No sé si será un problema en general de Windows XP, de los iconos de Delphi en el SysTray, o de la instalación particular de mi ordenador.

Seguiré intentando de ambas formas y si encuentro una solución definitiva y satisfactoria, volveré a comentarla aquí.

Saludos, ;)

Arsenio
01-11-2011, 21:36:37
Yo estoy usando el TTrayIcon en Delphi XE, y funciona todo correcto... salvo que al recuperar la ventana y querer otra vez minimizarla no ejecuta el evento, si cambio de ventana y vuelvo a la de mi proyecto vuelve a funcionar.

Lo que si hice distinto (y acá puede estar el tema) es que para capturar el evento que minimiza utilicé el de la aplicación:

//Asigno evento a la aplicación
Application.OnMinimize := MinimizarAplicacion;

El evento es de los "comunes":
procedure TFormCustom.MinimizarAplicacion(Sender: TObject);
begin
TrayIcon1.Visible := True;
Hide();
end;

Para restaurar la ventana hice un método que es llamado tanto en el doble click del TaryIcon como en un item del popUpMenu:


procedure TFormCustom.Restaurar1Click(Sender: TObject);
begin
RestaurarVentana;
end;

procedure TFormCustom.TrayIcon1DblClick(Sender: TObject);
begin
RestaurarVentana;
end;

procedure TFormCustom.RestaurarVentana;
begin
//Lo siguiente es para darle prioridad a la ventana
SetForegroundWindow(Self.Handle);
TrayIcon1.Visible := False;
Show();
WindowState := wsNormal;
end;

Si a alguno se le ocurre que puede estar fallando se agradece.