#include <windows.h>
#define IDR_PAUSE 12
#define IDR_START 13
LPCTSTR szAppClassName = TEXT("服务程序")
LPCTSTR szAppWindowName = TEXT("服务程序")
HMENU hmenu//菜单句柄
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
NOTIFYICONDATA nid
UINT WM_TASKBARCREATED
POINT pt//用于接收鼠标坐标
int xx//用于接收菜单选项返回值
// 不要修改TaskbarCreated,这是系统任务栏自定义的消息
WM_TASKBARCREATED = RegisterWindowMessage(TEXT("TaskbarCreated"))
switch (message)
{
case WM_CREATE://窗口创建时候的消息.
nid.cbSize = sizeof(nid)
nid.hWnd = hwnd
nid.uID = 0
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP
nid.uCallbackMessage = WM_USER
nid.hIcon = LoadIcon(NULL, IDI_APPLICATION)
lstrcpy(nid.szTip, szAppClassName)
Shell_NotifyIcon(NIM_ADD, &nid)
hmenu=CreatePopupMenu()//生成菜单
AppendMenu(hmenu,MF_STRING,IDR_PAUSE,L"暂停服务")//为菜单添加两个选项
AppendMenu(hmenu,MF_STRING,IDR_START,L"关于")
break
case WM_USER://连续使用该程序时候的消息.
if (lParam == WM_LBUTTONDOWN)
MessageBox(hwnd, TEXT("Win32 API 实现系统托盘程序,双击托盘可以退出!"), szAppClassName, MB_OK)
if (lParam == WM_LBUTTONDBLCLK)//双击托盘的消息,退出.
SendMessage(hwnd, WM_CLOSE, wParam, lParam)
if (lParam == WM_RBUTTONDOWN)
{
GetCursorPos(&pt)//取鼠标坐标
::SetForegroundWindow(hwnd)//解决在菜单外单击左键菜单不消失的问题
EnableMenuItem(hmenu,IDR_PAUSE,MF_GRAYED)//让菜单中的某一项变灰
xx=TrackPopupMenu(hmenu,TPM_RETURNCMD,pt.x,pt.y,NULL,hwnd,NULL)//显示菜单并获取选项ID
if(xx==IDR_PAUSE) MessageBox(hwnd, TEXT("111"), szAppClassName, MB_OK)
if(xx==IDR_START) MessageBox(hwnd, TEXT("222"), szAppClassName, MB_OK)
if(xx==0) PostMessage(hwnd,WM_LBUTTONDOWN,NULL,NULL)
//MessageBox(hwnd, TEXT("右键"), szAppName, MB_OK)
}
break
case WM_DESTROY://窗口销毁时候的消息.
Shell_NotifyIcon(NIM_DELETE, &nid)
PostQuitMessage(0)
break
default:
/*
* 防止当Explorer.exe 崩溃以后,程序在系统系统托盘中的图标就消失
*
* 原理:Explorer.exe 重新载入后会重建系统任务栏。当系统任务栏建立的时候会向系统内所有
* 注册接收TaskbarCreated 消息的顶级窗口发送一条消息,我们只需要捕捉这个消息,并重建系
* 统托盘的图标即可。
*/
if (message == WM_TASKBARCREATED)
SendMessage(hwnd, WM_CREATE, wParam, lParam)
break
}
return DefWindowProc(hwnd, message, wParam, lParam)
}
int main()
{
HWND hwnd
MSG msg
WNDCLASS wndclass
HWND handle = FindWindow(NULL, szAppWindowName)
if (handle != NULL)
{
MessageBox(NULL, TEXT("Application is already running"), szAppClassName, MB_ICONERROR)
return 0
}
wndclass.style = CS_HREDRAW | CS_VREDRAW
wndclass.lpfnWndProc = WndProc
wndclass.cbClsExtra = 0
wndclass.cbWndExtra = 0
wndclass.hInstance = NULL
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION)
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW)
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH)
wndclass.lpszMenuName = NULL
wndclass.lpszClassName = szAppClassName
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppClassName, MB_ICONERROR)
return 0
}
// 此处使用WS_EX_TOOLWINDOW 属性来隐藏显示在任务栏上的窗口程序按钮
hwnd = CreateWindowEx(WS_EX_TOOLWINDOW,
szAppClassName, szAppWindowName,
WS_POPUP,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL, NULL, NULL, NULL)
ShowWindow(hwnd, 0)
UpdateWindow(hwnd)
//消息循环
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg)
DispatchMessage(&msg)
}
return 0
}
用的控件是:TrayIcon具体用法如下:
在
Borland
C++
Builder
5.0
中编写Tray程序是件很简单的事。在安装
Borland
C++
Builder
5.0
时选择Full(完全)安装,安装完成后,在Samples组件页中有一个TrayIcon组件,它封装编写Tary所需的Window
API函数,使用该组件编写Tary程序不用加一句程序代码,真是易如反掌。
首先,我们先看一下TrayIcon组件常用的属性:
属性说明
Animate设为true时,顺序更改Icons属性设置的图标
AnimateInterva设置更改图标的时间(单位:毫秒)
Hide设为true时,最小化时隐藏在任务栏上的标题栏
Hint设置鼠标移动到Tary图标上出现的提示信息
IconIndex设置图标索引值
Icons设置图标源(通常设置一个ImageList组件)
PopupMenu设置要d出的菜单(通常设置一个PopupMenu组件)
PopupMenuOn设置触发d出菜单的鼠标 *** 作
RestoreOn设置恢复最小化到正常状态的鼠标 *** 作
Visible设为true时,在任务栏最右边显示图标
鼠标 *** 作说明:
值说明
imClick鼠标单击
imDoubleClick鼠标双击
imLeftClickUp单击鼠标左键,放开
imLeftDoubleClick双击鼠标左键
imMouseDown按下鼠标键
imMouseUp按下鼠标键,放开
imNone不设置鼠标 *** 作
imRightClickUp单击鼠标右键,放开
imRightDoubleClick双击鼠标右键
下面让我们来编一个简单的Tary程序:
1、新建工程,添加一个TrayIcon组件、一个PopupMenu组件和一个ImageList组件。它们的Name属性
都用默认的名字:TrayIcon1、PopupMenu1、ImageList1。
2、设置TrayIcon1的属性,如下:
属性值
linux
Animate
true
AnimateInterva
1000
Hide
true
Hint
Tary演示程序
IconIndex
0
Icons
ImageList1
Name
TrayIcon1
PopupMenu
PopupMenu1
PopupMenuOn
imRightClickUp
RestoreOn
imDoubleClick
Visible
true
3、双击PopupMenu1,d出菜单设计器,随意地加入几个菜单项。
4、双击ImageList1,加入支持的图片(*.ico、*.bmp)。
到此,不用编写一句程序代码,一个简单的Tary程序就做好了。按F9编译运行,将鼠标移动到Tary上面就会出现“Tary演示程序”的提示信息;在Tary上单击鼠标右键d出菜单Popmenu1;按下程序窗口的最小化按钮,程序最小化后隐藏任务栏上的标题栏;双击Tary将会恢复程序最小化;而且,Tary图标以1000毫秒(1秒)的速度变换。够简单了吧?!
TaryIcon组件的演示源程序在
Borland
C++
Builder
5.0
安装目录下的\CBuilder5\Examples\Apps\TrayIcon。若你不想使用TaryIcon组件编写Tary,只想使用API函数,可以参考安装目录\CBuilder5\Examples\Controls\Traydemo下的源程序
注意以下几点:
1、这个控件的托盘图标要使用到TimageList控件,请设置其Icons属性和对应的TimageList关联就可以
了,如果图标要变化,TimageList中要有多个图标,用TrayIcon控件的IconIndex的值的改变来改变托
盘图标。
2、最小化和隐窗体应该用:
TrayIconMe->Minimize()来实现
还原窗体用:TrayIconMe->Restore()。
3、至于菜单的d出就在窗体上加一个PopupMenu控件就可以了,PopupMenu的设定和一般的设定没有什
么不同。然后把TrayIcon控件的PopupMenu属性和PopupMenu控件关联起来就可以了。当然,别忘了
设定一个PopupMenuOn属性,决定这个菜单的鼠标触发方式。
4、当鼠标指向托盘时,显出的字是TrayIcon的Hint属性来设定的
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)