delphi TPopupMenu怎么指定系统托盘为所有者

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了delphi TPopupMenu怎么指定系统托盘为所有者相关的知识,希望对你有一定的参考价值。

我在主程序后台的情况下弹出菜单
TPopupMenu.Create(self) 菜单失去焦点时候无法自动关闭 ,有什么办法解决呢? 谢谢老师。

分数不足无法给分,抱歉。

参考技术A TTrayIcon 的主要属性:
TrayIcon.Icon
指定托盘图标, 有几种用法:
1、设计时选择; 2、把一个 TIcon 对象给它;
3、使用当前程序图标: TrayIcon1.Icon := Application.Icon;
4、TrayIcon1.SetDefaultIcon; 这也是使用当前程序图标.
TrayIcon.Icons 与 TrayIcon1.IconIndex
TrayIcon.Icons 对应一个 TImageList, 用 TrayIcon.IconIndex 来指定使用 TImageList 中的第一个图标.
这结合 TrayIcon 的其他功能做出图标动画都没有问题.
TrayIcon.PopupMenu
TrayIcon.PopupMenu 对应一个 TPopupMenu, 托盘图标一般少不了右键菜单.
TrayIcon.Visible
隐藏或显示系统托盘的图标; 虽简单、但关键, 因默认是 False.
TrayIcon.Hint
随鼠标指针的提示文本, 这是老式的, 下面有新型的.

TrayIcon.BalloonHint、BalloonTitle、BalloonFlags、BalloonTimeout
这都是新型的 Hint 相关的.
TrayIcon.BalloonHint: Hint 文本
TrayIcon.BalloonTitle: Hint 标题
TrayIcon.BalloonFlags: Hint 图标样式
TrayIcon.BalloonTimeout: Hint 停留时间
需要用 TrayIcon 的 ShowBalloonHint 方法启动显示
TrayIcon.Animate 与 TrayIcon1.AnimateInterval
TrayIcon 的新 Hint(BalloonHint)可设定动画.
TrayIcon.Animate: 这决定是否启用动画
TrayIcon1.AnimateInterval: 动画间隔时间

TTrayIcon 的主要事件:
OnAnimate: 写动画代码的事件
OnBalloonClick: 点击 BalloonHint 时...
OnClick: 单击图标时...
OnDblClick
OnMouseDown
OnMouseMove
OnMouseUp

TTrayIcon 还有两个方法, 前面都已提到了:
TTrayIcon.SetDefaultIcon;
TTrayIcon.ShowBalloonHint;

1 . TTrayIcon 。该控件是用于在托盘中显示自己软件的图标。使用 TTrayIcon 控件可以很容易的实现“动态图标”及“气泡提示”功能。如下图所示:
托盘显示
( 1 )“气泡提示”的制作
第一步:在窗体中放置 TrayIcon 控件( Additional 面板中可以找到)。
第二步:设置 TrayIcon 的 Icon 图标,载入一个 ICO 文件。
第三步:设置 TrayIcon 的 BalloonHint 为“ Delphi 2006 高级控件应用”,设置 BalloonTitle 为“电脑报 2005 年合订本”。设置 Visible 为 True 。
第四步:双击窗体,在 OnCreate 事件中写入下面代码: TrayIcon1.ShowBalloonHint;
好了, F9 运行程序,一个“气泡提示”就会出现在图标上。属性中的 BalloonTimeout 是设置“气泡提示”多少秒后消失,默认是 3 秒。
( 2 )动态图标
我们大家都知道,当有 QQ 消息时,托盘中会有一个闪烁图标,使用 TrayIcon 控件可以非常容易地实现这个功能。
使图标动起来,其实就是使用多个图标进行切换。QQ 的闪烁图标,其实就是使用的两个图标来进行切换的,一个是头像图标,一个是空的图标。
下面我们就来模拟 QQ 头像闪烁功能:
第一步:在窗体上放置 ImageList 控件(在 Win32 面板中可以找到)。
第二步:设置 ImageList 控件的 Width 和 Height 属性为 32 ,然后双击 ImageList ,点击“ Add ”按钮添加图标文件。第一个添加的是要显示的图标,第二个添加一个空的图标(可以使用 Image Editor 新建一个 ICO 文件,然后直接保存即可得到一个空的图标。)。
第三步:设置 TrayIcon 的 Icons 属性为 ImageList1 (可以直接在列表中选择)。
第四步:在 Form1 的 OnFormShow 事件中加入下面的代码:
TrayIcon1.Animate := True;
TrayIcon1.AnimateInterval := 450;
当 Animate 为 True 时,将自动按 ImageList 控件中图标的顺序进行依次显示,形成动态效果。 AnimateInterval 为每隔多少时间显示下一个图标。如果要停止闪烁,将 Animate 设置为 False 即可。

Delphi 7下最小化到系统托盘(主要是WM_TRAYMSG和WM_SYSCOMMAND消息)

 在Delphi 7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本。定义如下:

1
2
3
4
5
6
7
8
9
  _NOTIFYICONDATAA = record 
  cbSize: DWORD; 
  Wnd: HWND; 
  uID: UINT; 
  uFlags: UINT; 
  uCallbackMessage: UINT; 
  hIcon: HICON; 
  szTip: array [0..63] of AnsiChar; 
end; 

下面开始实现下最小化到系统托盘功能:
1.新建应用程序,然后在“菜单栏”→“Project”→“Options”→”Application“为程序设定下标题和图标,一定得设置图标,不让显示系统托盘的时候就会空白;
2.在窗体上放置一个右键菜单,添加两个菜单项,如下图所示:

技术分享

3.窗体单元文件代码如下:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
  unit Unit1; 
 
interface 
 
uses 
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, ShellAPI, Menus; 
 
const 
  WM_TRAYMSG = WM_USER + 101;                   //自定义托盘消息 
type 
  TForm1 = class(TForm) 
    pm1: TPopupMenu; 
    mniN1: TMenuItem; 
    mniwo1: TMenuItem; 
    procedure FormCreate(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    procedure mniN1Click(Sender: TObject); 
  private 
    procedure WMTrayMsg(var Msg: TMessage);message WM_TRAYMSG;    //声明托盘消息 
    procedure WMSysCommand(var Msg: TMessage);message WM_SYSCOMMAND; 
  public 
    { Public declarations } 
  end; 
 
var 
  Form1: TForm1; 
  NotifyIcon: TNotifyIconData;                    //定义托盘图标结构体 
implementation 
 
{$R *.dfm} 
{------------------------------------------------------------------------------- 
 Description: 窗体创建时,即创建托盘 
-------------------------------------------------------------------------------} 
procedure TForm1.FormCreate(Sender: TObject); 
begin 
  with NotifyIcon do 
  begin 
    cbSize := SizeOf(TNotifyIconData); 
    Wnd := Self.Handle; 
    uID := 1; 
    uFlags := NIF_ICON + NIF_MESSAGE + NIF_TIP;   //图标、消息、提示信息 
    uCallbackMessage := WM_TRAYMSG; 
    hIcon := Application.Icon.Handle; 
    szTip := ‘托盘测试‘; 
  end; 
  Shell_NotifyIcon(NIM_ADD,@NotifyIcon); 
end; 
{------------------------------------------------------------------------------- 
 Description: 窗体销毁时,卸载托盘 
-------------------------------------------------------------------------------} 
procedure TForm1.FormDestroy(Sender: TObject); 
begin 
  Shell_NotifyIcon(NIM_DELETE,@NotifyIcon); 
end; 
{------------------------------------------------------------------------------- 
 Description: 截获窗体最小化消息,最小化到托盘 
-------------------------------------------------------------------------------} 
procedure TForm1.WMSysCommand(var Msg: TMessage); 
begin 
  if Msg.WParam = SC_ICON then 
    Self.Visible := False 
  else 
    DefWindowProc(Self.Handle,Msg.Msg,Msg.WParam,Msg.LParam); 
end; 
{------------------------------------------------------------------------------- 
 Description: 自定义的托盘消息 
-------------------------------------------------------------------------------} 
procedure TForm1.WMTrayMsg(var Msg: TMessage); 
var 
  p: TPoint; 
begin 
  case Msg.LParam of 
    WM_LBUTTONDOWN: Self.Visible := True;   //显示窗体 
    WM_RBUTTONDOWN: 
      begin 
        SetForegroundWindow(Self.Handle);   //把窗口提前 
        GetCursorPos(p); 
        pm1.Popup(p.X,p.Y); 
      end; 
  end;     
end; 
{------------------------------------------------------------------------------- 
 Description: 测试菜单项 
-------------------------------------------------------------------------------} 
procedure TForm1.mniN1Click(Sender: TObject); 
begin 
  ShowMessage(‘One‘); 
end; 
 
end. 

4.运行结果如下:

技术分享

参考MSDN(http://msdn.microsoft.com/en-us/library/bb773352(VS.85).aspx)对NOTIFYICONDATA结构体的介绍却是:

typedef struct _NOTIFYICONDATA {    
    DWORD cbSize;        //结构体的大小,以字节为单位    
    HWND hWnd;           //窗口的句柄    
    UINT uID;            //应用程序定义的任务栏图标的标识符    
    UINT uFlags;         //此成员表明具体哪些其他成员为合法数据    
    UINT uCallbackMessage;   //应用程序定义的消息标示    
    HICON hIcon;         //增加、修改或删除的图标的句柄    
    TCHAR szTip[64];     //指向一个以/0结束的字符串的指针    
    DWORD dwState;       //Version 5.0,图标的状态    
    DWORD dwStateMask;   //Version 5.0. 指明dwState成员的那些位可以被设置或者访问    
    TCHAR szInfo[256];   //指向一个以/0结束的字符串的指针,字符串的内容为气球提示内容    
    union {    
        UINT uTimeout;   //表示气球提示超时的时间,单位为毫秒,此时间后气球提示将消失    
        UINT uVersion;   //用来设置使用Windows 95 还是 Windows 2000风格的图标消息接口    
    };    
    TCHAR szInfoTitle[64];   //指向一个以/0结束的字符串的指针。字符串的内容为气球提示的标题    
    DWORD dwInfoFlags;   //设置此成员用来给气球提示框增加一个图标,增加的图标出现在气球提示标题的左侧    
    GUID guidItem;       //保留    
    HICON hBalloonIcon;  //用于Windows Vista或更高版本的自定义气球图标    
} NOTIFYICONDATA, *PNOTIFYICONDATA;   

那么为了在Windows XP下也有气泡提示,那么我们手动添加几个类型,大概代码如下:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
  unit Unit1; 
 
interface 
 
uses 
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, ShellAPI, Menus; 
//---------------------开始:Delphi 7下添加此声明------------------------------- 
const 
  NIF_INFO        = $00000010;          //气泡显示标志 
  NIIF_NONE       = $00000000;          //无图标 
  NIIF_INFO       = $00000001;          //信息图标 
  NIIF_WARNING    = $00000002;          //警告图标 
  NIIF_ERROR      = $00000003;          //错误图标 
  NIIF_USER       = $00000004;          //XP使用hIcon图标 
type 
  TNotifyIconDataEx = record 
    cbSize: DWORD; 
    Wnd: HWND; 
    uID: UINT; 
    uFlags: UINT; 
    uCallbackMessage: UINT; 
    hIcon: HICON; 
    szTip: array [0..127] of AnsiChar; 
    dwState: DWORD; 
    dwStateMask: DWORD; 
    szInfo: array [0..255] of AnsiChar; 
    case Integer of 
      0: ( 
        uTimeout: UINT); 
      1: (uVersion: UINT; 
        szInfoTitle: array [0..63] of AnsiChar; 
        dwInfoFlags: DWORD);  
  end; 
//---------------------开始:Delphi 7下添加此声明------------------------------- 
const 
  WM_TRAYMSG = WM_USER + 101;                   //自定义托盘消息 
type 
  TForm1 = class(TForm) 
    pm1: TPopupMenu; 
    mniN1: TMenuItem; 
    mniwo1: TMenuItem; 
    procedure FormCreate(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    procedure mniN1Click(Sender: TObject); 
  private 
    procedure WMTrayMsg(var Msg: TMessage);message WM_TRAYMSG;    //声明托盘消息 
    procedure WMSysCommand(var Msg: TMessage);message WM_SYSCOMMAND; 
  public 
    { Public declarations } 
  end; 
 
var 
  Form1: TForm1; 
  NotifyIcon: TNotifyIconDataEx;                    //定义托盘图标结构体 
implementation 
 
{$R *.dfm} 
{------------------------------------------------------------------------------- 
 Description: 窗体创建时,即创建托盘 
-------------------------------------------------------------------------------} 
procedure TForm1.FormCreate(Sender: TObject); 
begin 
  with NotifyIcon do 
  begin 
    cbSize := SizeOf(TNotifyIconDataEx); 
    Wnd := Self.Handle; 
    uID := 1; 
    uFlags := NIF_ICON + NIF_MESSAGE + NIF_TIP + NIF_INFO;   //图标、消息、提示信息 
    uCallbackMessage := WM_TRAYMSG; 
    hIcon := Application.Icon.Handle; 
    szTip := ‘托盘测试‘; 
    szInfo := ‘提示内容‘; 
    szInfoTitle := ‘气泡标题‘; 
    dwInfoFlags := NIIF_USER; 
  end; 
  Shell_NotifyIcon(NIM_ADD,@NotifyIcon); 
end; 
{------------------------------------------------------------------------------- 
 ……以下代码与上面例子一样 
-------------------------------------------------------------------------------} 

运行结果如下:

技术分享 技术分享

 

 

http://blog.csdn.net/zisongjia/article/details/68067370

以上是关于delphi TPopupMenu怎么指定系统托盘为所有者的主要内容,如果未能解决你的问题,请参考以下文章

delphi怎么写“最小化到系统托盘”(有控件最好)

如何将delphi程序图标放入系统托盘中?

delphi托盘弹出信息

delphi 如何在delphi中实现托盘图标

Delphi托盘问题

delphi2010自带 TTrayIcon 托盘图标控件使用方法