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

发布于 2024-09-02 22:52:11 字数 1850 浏览 9 评论 0原文

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

必要的步骤如下:

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

就是这样。正确的?

如何在 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.

I want to minimize a Delphi application to the systray instead of the task bar.

The necessary steps seem to be the following:

  1. Create icon which should then be displayed in the systray.
  2. When the user clicks the [-] to minimize the application, do the following:
    1. Hide the form.
    2. Add the icon (step #1) to the systray.
    3. Hide/delete the application's entry in the task bar.
  3. When the user double-clicks the application's icon in the systray, do the following:
    1. Show the form.
    2. Un-minimize the application again and bring it to the front.
    3. If "WindowState" is "WS_Minimized" set to "WS_Normal".
    4. Hide/delete the application's icon in the systray.
  4. When the user terminates the application, do the following:
    1. Hide/delete the application's icon in the systray.

That's it. Right?

How could one implement this in Delphi?

I've found the following code but I don't know why it works. It doesn't follow my steps described above ...

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

极致的悲 2024-09-09 22:52:11

如果它仍然有效,那么使用 JVCLTJvTrayIcon 自动处理它。

If it still works, it's probably easiest to use JVCL's TJvTrayIcon to handle it automatically.

宫墨修音 2024-09-09 22:52:11

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

http://subsimple.com/delphi.asp

I would recommend using CoolTrayIcon. The author has already worked out all the issues involved with tray icons. Its free with source and examples and very debugged.

http://subsimple.com/delphi.asp

知足的幸福 2024-09-09 22:52:11

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

Instead of Application.BringToFront; use SetforegroundWindow(Application.Handle);

我爱人 2024-09-09 22:52:11

在下面的文本中,我将引用问题中提到的步骤号:

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

步骤#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

In the following text I'll be referring to the step numbers mentioned in the question:

The following solution is without any additional components. It's very easy to implement.

Step #1:

Just use the application's main icon (see following code).

Step #2:

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

Step #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;

Step #4:

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

Necessary code in interface part:

uses
  [...], ShellApi;

const
  WM_ICONTRAY = WM_USER + 1;

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

The only problem: The application can be minimized to the systray only once. The next time you want to minimize it, nothing will happen. Why?

Source: delphi.about.com

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文