以下代码演示了如何在系统托盘,即桌面的右下角添加图标
把鼠标放在图标上,会显示信息.单击它会显示消息框.右击它会有菜单出现
#define
WM_TRAYMESSAGE WM_USER + 1
#include < windows.h >
#include < shellapi.h >
#include " resource.h "
// 过程函数的返回值都是LRESULT,类型都是CALLBACK
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpszCmdLine, int nCmdShow)
{
HWND hwnd; // 主窗口句柄,在CreateWindow中赋值
MSG msg; // 消息变量,在GetMessage中使用
WNDCLASS wndclass; // 窗口类
TCHAR * szAppName = TEXT( " Tray " ); // 类名和窗口名
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 窗口背景
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); // 鼠标
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); // 图标
wndclass.lpszClassName = szAppName; // 类名
wndclass.cbClsExtra = 0 ; // 类的额外参数
wndclass.cbWndExtra = 0 ; // 窗口的额外参数.用于基于同一窗口类的窗口各自区分.
// 在自定义对话框类时必须指定为DLGWINDOWEXTRA的大小
wndclass.lpszMenuName = NULL; // 菜单名.可以用作子窗口的id
wndclass.style = CS_HREDRAW | CS_VREDRAW; // 窗口风格
wndclass.lpfnWndProc = WndProc; // 窗口过程
wndclass.hInstance = hInstance; // 包含窗口过程的实例句柄
if ( ! RegisterClass( & wndclass) ) // 注册窗口类
return 0 ;
hwnd = CreateWindow( // 创建窗口
szAppName, // 窗口类名
szAppName, // 窗口标题
WS_OVERLAPPEDWINDOW | WS_VSCROLL, // 窗口风格
CW_USEDEFAULT, // 初始的x坐标
CW_USEDEFAULT, // 初始的y坐标
CW_USEDEFAULT, // 初始的宽度
CW_USEDEFAULT, // 初始的高度
NULL, // 父窗口
NULL, // 菜单
hInstance, // 和窗口相关的实例句柄
NULL // 额外参数
);
ShowWindow( hwnd,nCmdShow ); // 显示窗口
UpdateWindow( hwnd ); // 更新窗口
while ( GetMessage( & msg,NULL, 0 , 0 ) ) // 消息循环
{
TranslateMessage( & msg); // 将WM_XXXKEYXXX消息翻译为WM_CHAR消息
DispatchMessage( & msg); // 传递消息到窗口过程
}
return msg.wParam; // 返回
}
LRESULT WINAPI WndProc( HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam )
{
static NOTIFYICONDATA nid;
static HMENU hMainMenu;
static HMENU hPopupMenu;
static HINSTANCE hInstance;
switch ( message )
{
case WM_CREATE:
{
hInstance = ((LPCREATESTRUCT)lParam) -> hInstance;
hMainMenu = (HMENU)LoadMenu(hInstance, TEXT( " TRAYMENU " ));
hPopupMenu = GetSubMenu(hMainMenu, 0 );
nid.cbSize = sizeof (nid);
nid.hIcon = (HICON)LoadIcon( hInstance, TEXT( " TRAYICON " ) );
nid.hWnd = hwnd;
nid.uCallbackMessage = WM_TRAYMESSAGE;
nid.uID = 1 ;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
lstrcpy( nid.szTip, TEXT( " This is a Tray Icon! " ));
Shell_NotifyIcon(NIM_ADD, & nid);
return 0 ;
}
case WM_DESTROY:
Shell_NotifyIcon(NIM_DELETE, & nid);
PostQuitMessage( 0 );
return 0 ;
case WM_TRAYMESSAGE:
{
switch ( lParam )
{
case WM_LBUTTONDOWN:
MessageBox(hwnd, TEXT( " LBUTTONDOWN in TrayIcon! " ),
TEXT( " TrayIcon " ), MB_OK);
return 0 ;
case WM_RBUTTONDOWN:
{
POINT point;
GetCursorPos( & point );
SetForegroundWindow(hwnd);
TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN,
point.x, point.y, 0 , hwnd, NULL);
return 0 ;
}
}
}
case WM_COMMAND:
switch ( LOWORD(wParam) )
{
case IDM_TRAY_MESSAGEBOX:
MessageBox(hwnd, TEXT( " Menu Selected in TrayIcon! " ),
TEXT( " TrayIcon " ), MB_OK);
return 0 ;
case IDM_TRAY_QUIT:
PostQuitMessage( 0 );
return 0 ;
}
}
return DefWindowProc( hwnd,message,wParam,lParam );
}
#include < windows.h >
#include < shellapi.h >
#include " resource.h "
// 过程函数的返回值都是LRESULT,类型都是CALLBACK
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpszCmdLine, int nCmdShow)
{
HWND hwnd; // 主窗口句柄,在CreateWindow中赋值
MSG msg; // 消息变量,在GetMessage中使用
WNDCLASS wndclass; // 窗口类
TCHAR * szAppName = TEXT( " Tray " ); // 类名和窗口名
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 窗口背景
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); // 鼠标
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); // 图标
wndclass.lpszClassName = szAppName; // 类名
wndclass.cbClsExtra = 0 ; // 类的额外参数
wndclass.cbWndExtra = 0 ; // 窗口的额外参数.用于基于同一窗口类的窗口各自区分.
// 在自定义对话框类时必须指定为DLGWINDOWEXTRA的大小
wndclass.lpszMenuName = NULL; // 菜单名.可以用作子窗口的id
wndclass.style = CS_HREDRAW | CS_VREDRAW; // 窗口风格
wndclass.lpfnWndProc = WndProc; // 窗口过程
wndclass.hInstance = hInstance; // 包含窗口过程的实例句柄
if ( ! RegisterClass( & wndclass) ) // 注册窗口类
return 0 ;
hwnd = CreateWindow( // 创建窗口
szAppName, // 窗口类名
szAppName, // 窗口标题
WS_OVERLAPPEDWINDOW | WS_VSCROLL, // 窗口风格
CW_USEDEFAULT, // 初始的x坐标
CW_USEDEFAULT, // 初始的y坐标
CW_USEDEFAULT, // 初始的宽度
CW_USEDEFAULT, // 初始的高度
NULL, // 父窗口
NULL, // 菜单
hInstance, // 和窗口相关的实例句柄
NULL // 额外参数
);
ShowWindow( hwnd,nCmdShow ); // 显示窗口
UpdateWindow( hwnd ); // 更新窗口
while ( GetMessage( & msg,NULL, 0 , 0 ) ) // 消息循环
{
TranslateMessage( & msg); // 将WM_XXXKEYXXX消息翻译为WM_CHAR消息
DispatchMessage( & msg); // 传递消息到窗口过程
}
return msg.wParam; // 返回
}
LRESULT WINAPI WndProc( HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam )
{
static NOTIFYICONDATA nid;
static HMENU hMainMenu;
static HMENU hPopupMenu;
static HINSTANCE hInstance;
switch ( message )
{
case WM_CREATE:
{
hInstance = ((LPCREATESTRUCT)lParam) -> hInstance;
hMainMenu = (HMENU)LoadMenu(hInstance, TEXT( " TRAYMENU " ));
hPopupMenu = GetSubMenu(hMainMenu, 0 );
nid.cbSize = sizeof (nid);
nid.hIcon = (HICON)LoadIcon( hInstance, TEXT( " TRAYICON " ) );
nid.hWnd = hwnd;
nid.uCallbackMessage = WM_TRAYMESSAGE;
nid.uID = 1 ;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
lstrcpy( nid.szTip, TEXT( " This is a Tray Icon! " ));
Shell_NotifyIcon(NIM_ADD, & nid);
return 0 ;
}
case WM_DESTROY:
Shell_NotifyIcon(NIM_DELETE, & nid);
PostQuitMessage( 0 );
return 0 ;
case WM_TRAYMESSAGE:
{
switch ( lParam )
{
case WM_LBUTTONDOWN:
MessageBox(hwnd, TEXT( " LBUTTONDOWN in TrayIcon! " ),
TEXT( " TrayIcon " ), MB_OK);
return 0 ;
case WM_RBUTTONDOWN:
{
POINT point;
GetCursorPos( & point );
SetForegroundWindow(hwnd);
TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN,
point.x, point.y, 0 , hwnd, NULL);
return 0 ;
}
}
}
case WM_COMMAND:
switch ( LOWORD(wParam) )
{
case IDM_TRAY_MESSAGEBOX:
MessageBox(hwnd, TEXT( " Menu Selected in TrayIcon! " ),
TEXT( " TrayIcon " ), MB_OK);
return 0 ;
case IDM_TRAY_QUIT:
PostQuitMessage( 0 );
return 0 ;
}
}
return DefWindowProc( hwnd,message,wParam,lParam );
}