分类: Windows平台
2014-02-26 15:38:57
如何做到当我们单击窗口的最小化按钮时,窗口先最小化到任务栏成为按钮,然后消失,图标显示到通知栏呢?大家熟悉的FoxMail能做到,我们也可以做到。 只要我们能截获最小化这个事件发送给窗口的消息,然后换成我们自定义的过程,问题就解决了。大家仔细想一想,当按下最小化按纽时会引发什么事件?最小化时窗口大小会发生变化会引发Form1.Resize事件,我们只要在Form1.Resize事件里用Form1.Visible = False使窗口消失,然后将窗口图标显示到通知栏即可达到我们想要的效果。 怎样判断发生Resize事件时窗口是最小化状态呢?VB里没有现成的做法,我们可以用非富的API函数。API函数库里有一个函数IsIconic(ByVal hwnd As Long),它就是专门判断窗口是否已最小化的。这样当Form产生Resize事件时,用IsIconic函数判断一下窗口是否为最小化状态,就可知道是否用户按了最小化按钮。 最关键的一步就是将图标显示在通知栏里,VB里没有现成的做法,我们还得用API函数。API函数库里有一个函数Shell_NotifyIcon(ByVal dwMessage As Long, lpData As NOTIFYICONDATA),是专门操作(包括添加、修改、删除)通知栏里图标的。 点一下通知栏图标,会出现一些诸如"退出"、"显示窗口"的弹出菜单,怎样实现弹出菜单呢?这个很容易实现,因为点击图标会触发图标所在窗口的MouseDown事件,我们把弹出菜单触发过程写入Form1_MouseDown事件即可。具体例程如下: 第一步、为了增强程序的可移植性,我们新建一个模块,取名为:NoticeIcon,在此模块中定义一些常量、自定义类型、所需的API函数说明及操作通知栏图标的三个自定义函数(添加、修改、删除),模块NoticeIcon具体代码如下所示:用VB实现窗口图标最小化到通系统托盘(二) 第二步:新建一窗口,取名为:Form1: 1、 设置属性如下: 1、 设置属性如下: .Name=Form1 .Caption="通知栏图标测试" .Icon=(Icon),选择一个漂亮的图标 其它默认即可 2、 设置窗口全局变量,并设置初始值点击(此处)折叠或打开
- Public Const DefaultIconIndex = 1 '图标缺省索引
- Public Const WM_LBUTTONDOWN = &H201 '按鼠标左键
- Public Const WM_RBUTTONDOWN = &H204 '按鼠标右键
- Public Const NIM_ADD = 0 '添加图标
- Public Const NIM_MODIFY = 1 '修改图标
- Public Const NIM_DELETE = 2 '删除图标
- Public Const NIF_MESSAGE = 1 'message 有效
- Public Const NIF_ICON = 2 '图标操作(添加、修改、删除)有效
- Public Const NIF_TIP = 4 'ToolTip(提示)有效
- 'API函数声明
- '图标操作
- Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long
- '判断窗口是否最小化
- Declare Function IsIconic Lib "user32" (ByVal hwnd As Long) As Long
- '
- '设置窗口位置和状态(position)的功能
- Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
- '定义类型
- '通知栏图标状态
- Public Type NOTIFYICONDATA
- cbSize As Long
- hwnd As Long
- uID As Long
- uFlags As Long
- uCallbackMessage As Long
- hIcon As Long
- szTip As String * 64
- End Type
- '函数定义
- '添加图标至通知栏
- Public Function Icon_Add(iHwnd As Long, sTips As String, hIcon As Long, IconID As Long) As Long
- '参数说明:iHwnd:窗口句柄,sTips:当鼠标移到通知栏图标上时显示的提示内容
- 'hIcon:图标句柄,IconID:图标Id号
- Dim IconVa As NOTIFYICONDATA
- With IconVa
- .hwnd = iHwnd
- .szTip = sTips + Chr$(0)
- .hIcon = hIcon
- .uID = IconID
- .uCallbackMessage = WM_LBUTTONDOWN
- .cbSize = Len(IconVa)
- .uFlags = NIF_MESSAGE Or NIF_ICON Or NIF_TIP
- Icon_Add = Shell_NotifyIcon(NIM_ADD, IconVa)
- End With
- End Function
- '删除通知栏图标(参数说明同Icon_Add)
- Function Icon_Del(iHwnd As Long, lIndex As Long) As Long
- Dim IconVa As NOTIFYICONDATA
- Dim L As Long
- With IconVa
- .hwnd = iHwnd
- .uID = lIndex
- .cbSize = Len(IconVa)
- End With
- Icon_Del = Shell_NotifyIcon(NIM_DELETE, IconVa)
- End Function
- '修改通知栏图标(参数说明同Icon_Add)
- Public Function Icon_Modify(iHwnd As Long, sTips As String, hIcon As Long, IconID As Long) As Long
- Dim IconVa As NOTIFYICONDATA
- With IconVa
- .hwnd = iHwnd
- .szTip = sTips + Chr$(0)
- .hIcon = hIcon
- .uID = IconID
- .uCallbackMessage = WM_LBUTTONDOWN
- .cbSize = Len(IconVa)
- .uFlags = NIF_MESSAGE Or NIF_ICON Or NIF_TIP
- Icon_Modify = Shell_NotifyIcon(NIM_MODIFY, IconVa)
- End With
- End Function
3、 窗口最小化时产生Resize事件,设置Form1.Resize事件,判断窗口是否最小化点击(此处)折叠或打开
- '用于标识窗口是否已经按过最小化按纽
- Dim MinFlag As Boolean
- Private Sub Form1_Load()
- MinFlag = False
- End Sub
4、如图所示用菜单设计器建一个弹出菜单,取名为main,main内有一个菜单数组: 菜单一:m_Menu(0) 标题:显示窗口 菜单二:m_Menu(1))标题:退出 菜单事件:点击(此处)折叠或打开
- Private Sub Form1_Resize()
- '判断窗口是否最小化状态,并且是按最小化按纽后第一次发生Resize事件
- If IsIconic(Me.hwnd) <> 0 And MinFlag = False Then
- MinFlag = True
- IcCardMain.Visible = False '隐藏窗口
- '将窗口图标加入通知栏
- Call Icon_Add(Me.hwnd, Me.Caption, IcCardMain.Icon, 0)
- End If
- End Sub
5、设置Form_MouseDown事件,用于单通知栏图标时调出弹出菜单点击(此处)折叠或打开
- Private Sub m_Menu_Click(Index As Integer)
- Select Case Index
- Case 0: '当单击"显示窗口"菜单时
- Call Icon_Del(Form1.hwnd, 0) '删除通知栏图标
- Form1.Show '调出窗口
- Case 1: '当单击"退出"菜单时
- Call Icon_Del(Form1.hwnd, 0) '删除通知栏图标
- End '退出程序
- End Select
- End Sub
程序编写完毕,设置工程的主程序为Form1,保存后运行。按下窗口最小化按纽,窗口消失,并在通知栏显示出窗口的图标;将鼠标移到图标上,有"通知栏图标测试"提示文本显示;用鼠标左键单击通知栏图标,图标变成另外的图案;单出鼠标右键,出现如上图所示的弹出菜单,接着单击弹出菜单"显示窗体",通知栏图标消失、窗口又恢复成原来的样子了,单击菜单"退出"则退出程序了。点击(此处)折叠或打开
- Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
- Dim L
- L = X \ 15
- '点击通知栏图标,用鼠标右键时调出弹出菜单
- IF L = WM_LBUTTONDOWN Then
- Me.PopupMenu m_Main
- '点击通知栏图标,用鼠标左键时,将通知栏图标改为另外的图标
- ElseIF L = WM_LBUTTONDOWN Then
- Call Icon_Modify(Form1.hwnd,Form1.Caption, LoadPicture("D:\Pic2.ico"), 0)
- End If
- End Sub