#include "stdafx.h"
#include "StudyDuilib.h"
#include <shellapi.h>
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, APP_NAME);
Shell_NotifyIcon(NIM_ADD, &nid);
hMenu = CreatePopupMenu();//生成菜单
//为托盘菜单添加两个选项
AppendMenu(hMenu, MF_STRING, ID_SHOW, TEXT("策略更新"));
AppendMenu(hMenu, MF_STRING, ID_RECORD, TEXT("管控记录"));
AppendMenu(hMenu, MF_STRING, ID_ABOUT, TEXT("关于"));
Shell_NotifyIcon(NIM_ADD, &nid);
break;
case WM_USER://连续使用该程序时候的消息.
if (lParam == WM_LBUTTONDOWN)
MessageBox(hwnd, TEXT("Win32 API 实现系统托盘程序,双击托盘可以退出!"), APP_NAME, MB_OK);
if (lParam == WM_LBUTTONDBLCLK)//双击托盘的消息,退出.
SendMessage(hwnd, WM_CLOSE, wParam, lParam);
if (lParam == WM_RBUTTONDOWN)
{
GetCursorPos(&pt);//取鼠标坐标
::SetForegroundWindow(hwnd);//解决在菜单外单击左键菜单不消失的问题
//EnableMenuItem(hMenu, ID_SHOW, MF_GRAYED);//让菜单中的某一项变灰
xx = TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, NULL, hwnd, NULL);//显示菜单并获取选项ID
if (xx == ID_SHOW) MessageBox(hwnd, TEXT("策略更新"), APP_NAME, MB_OK);
if (xx == ID_RECORD) MessageBox(hwnd, TEXT("管控记录"), APP_NAME, MB_OK);
if (xx == ID_ABOUT) MessageBox(hwnd, TEXT("关于"), APP_NAME, MB_OK);
if (xx == 0) PostMessage(hwnd, WM_LBUTTONDOWN, NULL, NULL);
}
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 APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
HWND handle = FindWindow(NULL, APP_NAME);
if (handle != NULL)
{
MessageBox(NULL, TEXT("Application is already running"), APP_NAME, 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 = APP_NAME;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"), APP_NAME, MB_ICONERROR);
return 0;
}
// 此处使用WS_EX_TOOLWINDOW 属性来隐藏显示在任务栏上的窗口程序按钮
hwnd = CreateWindowEx(WS_EX_TOOLWINDOW,
APP_NAME, APP_NAME,
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;
}