Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Llamada WM_MOUSELEAVE en un TrayIcon (https://www.clubdelphi.com/foros/showthread.php?t=61521)

byfali 11-11-2008 12:19:19

Llamada WM_MOUSELEAVE en un TrayIcon
 
Hola amigos del foro.
Tengo una duda que no logro solucionar. Tengo una aplicacion que se minimiza y coloca un TrayIcon en la bandeja y usa los mensajes WM_LBUTTONDOWN o WM_RBUTTONDOWN sin problema.
Pero lo que no logro es que al cituar el puntero del raton sobre el icono muestre cualquier mensaje.
He probado usando WM_MOUSELEAVE y WM_MOUSEHOVER pero no pasa nada.
Espero me podais ayudar, gracias.

roman 11-11-2008 18:40:47

¿Has probado con WM_MOUSEMOVE?

// Saludos

byfali 11-11-2008 18:54:10

Gracias, roman efectivamente con WM_MOUSEMOVE funciona pero yo quiero que cuando el raton este cituado en el icono muestre un Form y cuando el cursor se retire del icono el form desapasca por eso WM_MOUSELEAVE y WM_MOUSEHOVER.

cHackAll 11-11-2008 20:11:19

Cita:

Empezado por http://msdn.microsoft.com/en-us/library/ms645615(VS.85).aspx
...The application must call TrackMouseEvent when the mouse reenters its window if it requires further tracking of mouse hover behavior...

Saludos

dec 11-11-2008 20:11:22

Hola,

Aprovechando el mensaje "WM_MOUSEMOVE" quizás podrías encontrar las coordenadas en que se encuentra el ratón, así como también si estas están "dentro" del "TrayIcon". De este modo podrías acaso implementar lo que necesitas. Muy probablemente me equivoco, pero, me suena que "WM_MOUSELEAVE" y "WM_MOUSEHOVER" son mensajes "nuevos" que no todos los controles soportan. Esto último es igual una tontería, algo que "me suena", pero, sin pies ni cabeza. Lo primero, sin embargo, creo que tiene su lógica. ;)

roman 11-11-2008 20:19:19

Lo de WM_MOUSELEAVE y WM_MOUSEHOVER se uan con la función TrackMouseEvent, pero eso sirve para monitorear el ratón sobre una determinada ventana. En este caso, el icono no está en una de nuestras ventanas sino en la de la bandeja del sistema.

Yo creo que la idea de dec funcionaría si tomamos las coordenadas del ratón en el primer WM_MOUSEMOVE y con un Timer monitorear qué tan alejado está el ratón de esa posición inicial para "saber" si ya salimos del icono.

// Saludos

Lepe 11-11-2008 20:27:25

¿qué componente estás usando para el TrayIcon?

Lo digo porque cada uno implementa o no una función. Usando estrictamente la API de windows, se puede conseguir lo que quieres, de hecho proporciona un campo donde incluir el texto a mostrar a modo de Hint.

Si el componente que usas lo permite (la licencia, tienes el código, etc) puedes hacerlo tú mismo. En caso contrario, usar uno de los muchos que sí lo tienen implementados (JVCL, LMDTOOLS,etc)

Código Delphi [-]
unit Main;

interface

uses
  Classes, Controls, Dialogs, Forms, Graphics, Messages, SysUtils, Windows,
  Buttons, ComCtrls, Menus, ShellApi, StdCtrls;

type
  TwndIconic = class (TForm)
    PopupMenu1: TPopupMenu;
    miClose: TMenuItem;
    N1: TMenuItem;
    miProperties: TMenuItem;
    HotKey1: THotKey;
    HotKey2: THotKey;
    HotKey3: THotKey;
    HotKey4: THotKey;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    BitBtn1: TBitBtn;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure miCloseClick(Sender: TObject);
    procedure miPropertiesClick(Sender: TObject);
  private
    FTrayMessage: Cardinal;
    procedure RButtonUp;
    procedure LButtonDblClk;
  protected
    procedure WndProc(var Msg: TMessage); override;
  public
    procedure NotifyTray(Command: Word; const Hint: String);
  end;

var
  wndIconic: TwndIconic;

implementation

uses About;

{$R *.DFM}

resourcestring
  STrayMessage = 'Mad.Dog.Marteens';

procedure TwndIconic.NotifyTray(Command: Word; const Hint: String);
var
  Data: TNotifyIconData;
begin
  Data.cbSize := SizeOf(Data);
  Data.uID    := 0;
  Data.uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
  Data.Wnd    := Self.Handle;
  Data.uCallbackMessage := FTrayMessage;
  Data.hIcon  := Application.Icon.Handle;
  StrLCopy(Data.szTip, PChar(Hint), SizeOf(Data.szTip)); //<<<<<<<<<<< HINT
  Shell_NotifyIcon(Command, @Data);
end;

procedure TwndIconic.WndProc(var Msg: TMessage);
begin
  if Msg.Msg = FTrayMessage then
    case Msg.LParam of
      WM_RBUTTONUP: RButtonUp;
      WM_LBUTTONDBLCLK: LButtonDblClk;
    end
  else
    inherited WndProc(Msg);
end;

procedure TwndIconic.LButtonDblClk;
begin

  wndiconic.Create(self);
  wndiconic.show;

end;

procedure TwndIconic.RButtonUp;
var
  Pt: TPoint;
begin
  GetCursorPos(Pt);
  SetForegroundWindow(Application.Handle);
  Application.ProcessMessages;
  PopupMenu1.Popup(Pt.X, Pt.Y);
end;

procedure TwndIconic.FormCreate(Sender: TObject);
begin
  Application.ShowMainForm := False;
  ShowWindow(Application.Handle, SW_HIDE);
  FTrayMessage := RegisterWindowMessage(PChar(STrayMessage));
  NotifyTray(NIM_ADD, Application.Title);
end;

procedure TwndIconic.FormDestroy(Sender: TObject);
begin
  NotifyTray(NIM_DELETE, '');
end;

procedure TwndIconic.miCloseClick(Sender: TObject);
begin
  Close;
end;

procedure TwndIconic.miPropertiesClick(Sender: TObject);
begin
  wndiconic.Show;
end;

end.

Saludos

roman 11-11-2008 20:38:48

Cita:

Empezado por Lepe (Mensaje 325354)
Lo digo porque cada uno implementa o no una función. Usando estrictamente la API de windows, se puede conseguir lo que quieres, de hecho proporciona un campo donde incluir el texto a mostrar a modo de Hint.

Bueno. Yo he presupuesto en todo este hilo, que se quiere usar directamente la API, y no veo de qué forma se puede implementar lo que quiere como no sea con un truco como los que se han esbozado. Lo que él quiere es detectar en qué momento entra el puntero al icono (esto sí puede hacerse detectando el primer mensaje WM_MOUSEMOVE) y en qué momento sale (esto no veo cómo puede hacerlo directamente).

// Saludos

byfali 12-11-2008 10:08:43

Gracias a todos, lo intentare capturando las coordenadas del raton.
Ya os cuento.

Lepe 12-11-2008 14:17:29

Como siempre tienes razón roman, por eso no he añadido nada.

¿hay posibilidad de cambiar el diseño?

Para mí, el hecho de pasar el ratón por ese área accidentalmente y que se muestre y oculte la ventana puede llegar a incomodarme mucho (por supuesto es mi opinión, tan válida como otra cualquiera).

Creo que lo más rápido de implementar y más cómodo, sería que al hacer clic con el botón izquierdo, se muestre el Form, con un timer se oculta pasados ¿5 segundos? y si el usuario hace clic encima del form pues que se oculte... o en fin, tú podrás hacer otra cosa.

También ten en cuenta que ese área está "sobre usada", todos los programas sacan mensajitos en ese área, quizás te interese buscar otra alternativa diferente.

Saludos

roman 12-11-2008 17:46:32

Cita:

Empezado por Lepe (Mensaje 325496)
Para mí, el hecho de pasar el ratón por ese área accidentalmente y que se muestre y oculte la ventana puede llegar a incomodarme mucho (por supuesto es mi opinión, tan válida como otra cualquiera).

Totalmente de acuerdo con esto. A veces las cosas que nos parecen "cool", resultan incómodas para el usuario. Aunque a veces es el usuario quien pide estas cosas.

// Saludos


La franja horaria es GMT +2. Ahora son las 02:11:05.

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