2010-05-22 4 views
2

Je souhaite réduire une application Delphi au systray au lieu de la barre des tâches.Delphi: Réduire l'application à systray

Les étapes nécessaires semblent être les suivants:

  1. Créer icône qui devrait alors être affiché dans le systray.
  2. Lorsque l'utilisateur clique sur le [-] pour réduire l'application, procédez comme suit:
    1. Masquer la forme.
    2. Ajoutez l'icône (étape 1) à la barre d'état système.
    3. Masquer/supprimer l'entrée de l'application dans la barre des tâches.
  3. Lorsque le utilisateur double-clique sur l'icône de l'application dans le systray, procédez comme suit:
    1. Afficher le formulaire.
    2. Désactivez de nouveau l'application et ramenez-la vers l'avant.
    3. Si "WindowState" est "WS_Minimized" défini sur "WS_Normal".
    4. Masquer/supprimer l'icône de l'application dans la barre des tâches.
  4. Lorsque l'utilisateur met fin à l'application, procédez comme suit:
    1. Cacher/supprimer l'icône de l'application dans le systray.

Voilà. Droite?

Comment pourrait-on implémenter cela dans Delphi?

J'ai trouvé le code suivant mais je ne sais pas pourquoi cela fonctionne. Il ne suit pas mes étapes décrites ci-dessus ...

unit uMinimizeToTray; 

interface 

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

const WM_NOTIFYICON = WM_USER+333; 

type 
    TMinimizeToTray = class(TForm) 
    procedure FormCreate(Sender: TObject); 
    procedure FormClose(Sender: TObject; var Action: TCloseAction); 
    procedure CMClickIcon(var msg: TMessage); message WM_NOTIFYICON; 
    private 
    { Private-Deklarationen } 
    public 
    { Public-Deklarationen } 
    end; 

var 
    MinimizeToTray: TMinimizeToTray; 

implementation 

{$R *.dfm} 

procedure TMinimizeToTray.CMClickIcon(var msg: TMessage); 
begin 
    if msg.lparam = WM_LBUTTONDBLCLK then Show; 
end; 

procedure TMinimizeToTray.FormCreate(Sender: TObject); 
VAR tnid: TNotifyIconData; 
    HMainIcon: HICON; 
begin 
    HMainIcon := LoadIcon(MainInstance, 'MAINICON'); 
    Shell_NotifyIcon(NIM_DELETE, @tnid); 
    tnid.cbSize := sizeof(TNotifyIconData); 
    tnid.Wnd := handle; 
    tnid.uID := 123; 
    tnid.uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP; 
    tnid.uCallbackMessage := WM_NOTIFYICON; 
    tnid.hIcon := HMainIcon; 
    tnid.szTip := 'Tooltip'; 
    Shell_NotifyIcon(NIM_ADD, @tnid); 
end; 

procedure TMinimizeToTray.FormClose(Sender: TObject; var Action: TCloseAction); 
begin 
    Action := caNone; 
    Hide; 
end; 

end. 
+0

Il fut un temps que le TApplication est celui qui a créé l'entrée de la barre des tâches, et les TForms étaient libres d'agir de façon indépendante. Cela a-t-il changé dernièrement? –

+2

Quelle version de Delphi utilisez-vous? Dans les versions plus récentes, il y a un TTrayIcon dans la VCL, que vous pouvez utiliser pour créer l'icône de la barre, au moins. –

+1

Le code est différent avec vos étapes dans cela; - l'icône systray est toujours visible, - elle n'interfère pas avec 'minimiser' (il n'y a pas d'étape 2), quand on clique deux fois sur l'icône, elle montre le formulaire caché en cliquant sur la case de fermeture [X], - ne prend pas fin en compte (il n'y a pas d'étape 4). –

Répondre

3

Je recommanderais d'utiliser CoolTrayIcon. L'auteur a déjà résolu tous les problèmes liés aux icônes de plateau. C'est gratuit avec source et exemples et très débogué.

http://subsimple.com/delphi.asp

+0

Ce composant fonctionne correctement. Il fait tout ce que l'on veut pour un TrayIcon. Je vous remercie! – caw

4

Si cela fonctionne encore, il est probablement plus facile à utiliser de TJvTrayIconJVCL pour gérer automatiquement.

+0

Probablement, je suis juste stupide, mais je n'ai pas trouvé de lien de téléchargement pour cela. Merci quand même! ;) Si vous regardez les votes +3, votre réponse semble être bonne ... – caw

+0

C'est le lien "Téléchargements" sur la gauche au premier lien. –

-1

Dans le texte suivant, je vais faire référence aux numéros des étapes mentionnées dans la question:

La solution suivante est sans composants supplémentaires. C'est très facile à mettre en œuvre.

Étape # 1:

Il suffit d'utiliser l'icône principale de l'application (voir code suivant).

Étape # 2:

procedure TForm1.ApplicationEvents1Minimize(Sender: TObject); 
begin 
    Shell_NotifyIcon(NIM_ADD, @TrayIconData); 
    Form1.Hide; 
end; 

Étape # 3:

procedure TForm1.TrayMessage(var Msg: TMessage); 
begin 
    if Msg.lParam = WM_LBUTTONDOWN then begin 
    Form1.Show; 
    Form1.WindowState := wsNormal; 
    Application.BringToFront; 
    Shell_NotifyIcon(NIM_DELETE, @TrayIconData); 
    end; 
end; 

Étape # 4:

procedure TForm1.FormDestroy(Sender: TObject); 
begin 
    Shell_NotifyIcon(NIM_DELETE, @TrayIconData); 
end; 

code nécessaire dans la partie interface:

uses 
    [...], ShellApi; 

const 
    WM_ICONTRAY = WM_USER + 1; 

type 
    TForm1 = class(TForm) 
    [...] 
    procedure TrayMessage(var Msg: TMessage); message WM_ICONTRAY; 
    end; 

Le seul problème: L'application peut être réduite au minimum à la systray une seule fois. La prochaine fois que vous voulez le minimiser, rien ne se passera. Pourquoi?

Source: delphi.about.com

Questions connexes