Delphi:最小化应用程序到系统托盘

时间:2010-05-22 18:37:41

标签: windows delphi taskbar systray

我想将Delphi应用程序最小化到系统托盘而不是任务栏。

必要的步骤似乎如下:

  1. 创建应在系统托盘中显示的图标。
  2. 当用户单击[ - ]以最小化应用程序时,请执行以下操作:
    1. 隐藏表单。
    2. 将图标(步骤#1)添加到系统托盘。
    3. 隐藏/删除任务栏中的应用程序条目。
  3. 当用户双击系统托盘中的应用程序图标时,请执行以下操作:
    1. 显示表单。
    2. 再次取消应用程序的最小化并将其置于最前面。
    3. 如果“WindowState”是“WS_Minimized”设置为“WS_Normal”。
    4. 隐藏/删除系统托盘中的应用程序图标。
  4. 当用户终止应用程序时,请执行以下操作:
    1. 隐藏/删除系统托盘中的应用程序图标。
  5. 就是这样。正确?

    如何在Delphi中实现这一点?

    我发现了以下代码,但我不知道为什么会这样。它不遵循我上面描述的步骤......

    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.
    

4 个答案:

答案 0 :(得分:5)

如果它仍然有效,那么使用JVCLTJvTrayIcon自动处理它可能最简单。

答案 1 :(得分:4)

我建议使用CoolTrayIcon。作者已经解决了托盘图标所涉及的所有问题。它免费提供源代码和示例,并且已经过调试。

http://subsimple.com/delphi.asp

答案 2 :(得分:1)

使用Application.BringToFront;代替SetforegroundWindow(Application.Handle);

答案 3 :(得分:-1)

在下文中,我将提到问题中提到的步骤编号:

以下解决方案没有任何其他组件。它很容易实现。

第1步:

只需使用应用程序的主图标(参见下面的代码)。

第2步:

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

第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;

第4步:

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

界面部分中的必要代码:

uses
  [...], ShellApi;

const
  WM_ICONTRAY = WM_USER + 1;

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

唯一的问题:应用程序只能最小化到系统托盘一次。下次你想要最小化它,什么都不会发生。为什么?

来源:delphi.about.com