目前共有9篇帖子。 内容转换:不转换▼
 
点击 回复
567 8
【原创程序】C++编写的Win32 托盘图标及气球显示程序
一派护法 十九级
1楼 发表于:2015-12-24 13:11

【简介】

1.程序启动后不显示主窗口,在托盘建立一个文件夹图标(图标来自shell32.dll),双击该图标即可打开主窗口,主窗口最小化时自动隐藏。

一派护法 十九级
2楼 发表于:2015-12-24 13:13
2.托盘右键菜单:(点击空白处可自动关闭菜单)

一派护法 十九级
3楼 发表于:2015-12-24 13:13
3.显示鼠标位置的菜单命令:

一派护法 十九级
4楼 发表于:2015-12-24 13:14
4.显示气球:

一派护法 十九级
5楼 发表于:2015-12-24 13:16
5.自定义气球内容:
一派护法 十九级
6楼 发表于:2015-12-24 13:17
可选择的图标列表:

其中User Defined是调用shell32.dll中的文本文件的图标:


一派护法 十九级
7楼 发表于:2015-12-24 13:17
6.退出程序时自动删除托盘图标。
一派护法 十九级
8楼 发表于:2015-12-24 13:18
【主程序文件代码】
// NotifyIcon.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "NotifyIcon.h"
#include <CommCtrl.h>
#include <shellapi.h>
#include <windowsx.h>
// 启用XP风格控件
#pragma comment(lib, "Comctl32.lib")
#pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#define MAX_LOADSTRING 100
#define MAX_STRLEN 255
// Global Variables:
HINSTANCE hInst;        // current instance
TCHAR szTitle[MAX_LOADSTRING];     // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];   // the main window class name
NOTIFYICONDATA nid; // 系统托盘图标信息
LPWSTR list[] = {L"None", L"Information", L"Warning", L"Error", L"User Defined", NULL};
DWORD iconflags[] = {NIIF_NONE, NIIF_INFO, NIIF_WARNING, NIIF_ERROR, NIIF_USER};
// Forward declarations of functions included in this code module:
ATOM    MyRegisterClass(HINSTANCE hInstance);
BOOL    InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPTSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
 UNREFERENCED_PARAMETER(hPrevInstance);
 UNREFERENCED_PARAMETER(lpCmdLine);
  // TODO: Place code here.
 MSG msg;
 HACCEL hAccelTable;
 // Initialize global strings
 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
 LoadString(hInstance, IDC_NOTIFYICON, szWindowClass, MAX_LOADSTRING);
 MyRegisterClass(hInstance);
 // Perform application initialization:
 if (!InitInstance (hInstance, nCmdShow))
 {
  return FALSE;
 }
 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_NOTIFYICON));
 // Main message loop:
 while (GetMessage(&msg, NULL, 0, 0))
 {
  if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  {
   TranslateMessage(&msg);
   DispatchMessage(&msg);
  }
 }
 return (int) msg.wParam;
}


//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
 WNDCLASSEX wcex;
 wcex.cbSize = sizeof(WNDCLASSEX);
 wcex.style   = CS_HREDRAW | CS_VREDRAW;
 wcex.lpfnWndProc = WndProc;
 wcex.cbClsExtra  = 0;
 wcex.cbWndExtra  = 0;
 wcex.hInstance  = hInstance;
 wcex.hIcon   = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_NOTIFYICON));
 wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);
 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
 wcex.lpszMenuName = MAKEINTRESOURCE(IDC_NOTIFYICON);
 wcex.lpszClassName = szWindowClass;
 wcex.hIconSm  = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
 return RegisterClassEx(&wcex);
}
//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;
   hInst = hInstance; // Store instance handle in our global variable
   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
   if (!hWnd)
   {
      return FALSE;
   }
   addTrayIcon(hWnd); // 添加系统托盘图标
   nCmdShow = SW_HIDE; // 无论nCmdShow的值是什么,启动程序时一律不显示窗口
   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);
   return TRUE;
}
//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND - process the application menu
//  WM_PAINT - Paint the main window
//  WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 int wmId, wmEvent;
 PAINTSTRUCT ps;
 HDC hdc;
 switch (message)
 {
 case WM_COMMAND:
  wmId    = LOWORD(wParam);
  wmEvent = HIWORD(wParam);
  // Parse the menu selections:
  switch (wmId)
  {
  case ID_1_SHOW: // 当点击托盘菜单的Open命令时显示窗口
   ShowWindow(hWnd, SW_SHOW);
   break;
  case ID_1_SHOWMOUSEPOSITION: // 当点击托盘菜单的显示鼠标位置的命令时
   showCursorPosition(hWnd);
   break;
  case IDM_ABOUT:
   DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
   break;
  case ID_1_EXIT: // 当点击托盘菜单的Exit命令时退出程序
  case IDM_EXIT:
   DestroyWindow(hWnd);
   break;
  case ID_1_SHOWBALLOON:
  case ID_NOTIFYICON_SHOWBALLOON:
   showBalloon();
   break;
  case ID_1_SHOWCUSTOMBALLOON:
  case ID_NOTIFYICON_SHOWCUSTOMBALLOON:
   showDlg1(hWnd);
   break;
  default:
   return DefWindowProc(hWnd, message, wParam, lParam);
  }
  break;
 case WM_SYSCOMMAND:
  wmId = LOWORD(wParam);
  switch (wmId)
  {
  case SC_MINIMIZE:
   // 最小化时隐藏窗口
   ShowWindow(hWnd, SW_HIDE);
   break;
  default:
   return DefWindowProc(hWnd, message, wParam, lParam);
  }
 case WM_PAINT:
  hdc = BeginPaint(hWnd, &ps);
  // TODO: Add any drawing code here...
  EndPaint(hWnd, &ps);
  break;
 case WM_DESTROY:
  deleteTrayIcon(); // 当主窗口关闭时删除托盘图标
  PostQuitMessage(0);
  break;
 case WM_SHOWTASK:
  wmEvent = LOWORD(lParam);
  wmId = HIWORD(lParam);
  switch (wmEvent)
  {
  case WM_LBUTTONDBLCLK:
   // 双击托盘图标时显示窗口
   ShowWindow(hWnd, SW_SHOW);
   break;
  case WM_RBUTTONDOWN:
   // 右键点击托盘图标时显示菜单
   showTrayMenu(hWnd);
   break;
  }
  break;
 default:
  return DefWindowProc(hWnd, message, wParam, lParam);
 }
 return 0;
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
 UNREFERENCED_PARAMETER(lParam);
 switch (message)
 {
 case WM_INITDIALOG:
  return (INT_PTR)TRUE;
 case WM_COMMAND:
  if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
  {
   EndDialog(hDlg, LOWORD(wParam));
   return (INT_PTR)TRUE;
  }
  break;
 }
 return (INT_PTR)FALSE;
}
void addTrayIcon(HWND hWnd)
{
 HINSTANCE hShellInst = GetModuleHandle(L"shell32.dll");
 nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA);
 nid.hWnd = hWnd;
 nid.uID = IDR_MAINFRAME;
 nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO;
 nid.uCallbackMessage = WM_SHOWTASK;
 LoadIconMetric(hShellInst, MAKEINTRESOURCE(4), LIM_SMALL, &nid.hIcon); // 加载shell32.dll中的文件夹图标,尺寸为16x16
 wcscpy_s(nid.szTip, L"My Icon");
 Shell_NotifyIcon(NIM_ADD, &nid);
}
void showBalloon()
{
 wcscpy_s(nid.szInfo, L"This is my balloon.");
 wcscpy_s(nid.szInfoTitle, L"Balloon Title");
 nid.dwInfoFlags = NIIF_INFO; // 气球上的图标
 Shell_NotifyIcon(NIM_MODIFY, &nid);
}
void showCursorPosition(HWND hWnd)
{
 POINT point;
 WCHAR str[50];
 GetCursorPos(&point);
 wsprintf(str, L"Your cursor position was (%d, %d).", point.x, point.y);
 MessageBox(hWnd, str, L"Cursor Position", MB_ICONINFORMATION);
}
void showDlg1(HWND hWnd)
{
 DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, Dialog1);
}
void showTrayMenu(HWND hWnd)
{
 POINT point;
 HMENU hMenuRoot = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1));
 HMENU hMenu = GetSubMenu(hMenuRoot, 0);
 GetCursorPos(&point);
 SetMenuDefaultItem(hMenu, 0, TRUE); // 设置加粗的菜单项
 SetForegroundWindow(hWnd); // 鼠标点击菜单以外的区域时,自动关闭菜单
 TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, point.x, point.y, NULL, hWnd, NULL);
 DestroyMenu(hMenuRoot);
 DestroyMenu(hMenu);
}
void deleteTrayIcon()
{
 Shell_NotifyIcon(NIM_DELETE, &nid);
}

INT_PTR CALLBACK Dialog1(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
 int wmId;
 UNREFERENCED_PARAMETER(lParam);
 switch (message)
 {
 case WM_INITDIALOG:
  Dlg1_Init(hDlg);
  return (INT_PTR)TRUE;
 case WM_COMMAND:
  wmId = LOWORD(wParam);
  switch (wmId)
  {
  case IDOK:
   showCustomTrayMenu(hDlg);
   break;
  case IDCANCEL:
   EndDialog(hDlg, LOWORD(wParam));
   return (INT_PTR)TRUE;
  }
  break;
 }
 return (INT_PTR)FALSE;
}
void Dlg1_Init(HWND hDlg)
{
 LPWSTR *pList = list;
 HWND combo = GetDlgItem(hDlg, IDC_COMBO1);
 while (*pList != NULL)
 {
  ComboBox_AddString(combo, *pList);
  pList++;
 }
 ComboBox_SetCurSel(combo, 0);
}
int Dlg1_GetIconFlagId(HWND combo)
{
 int selection = ComboBox_GetCurSel(combo);
 WCHAR selectionStr[MAX_LOADSTRING];
 int i;
 ComboBox_GetLBText(combo, selection, selectionStr);
 for (i = 0; list[i] != NULL; i++)
 {
  if (wcscmp(list[i], selectionStr) == 0)
   return i;
 }
 return -1;
}
void showCustomTrayMenu(HWND hDlg)
{
 HINSTANCE hShellInst;
 HWND edit1 = GetDlgItem(hDlg, IDC_EDIT1);
 HWND edit2 = GetDlgItem(hDlg, IDC_EDIT2);
 HWND combo = GetDlgItem(hDlg, IDC_COMBO1);
 int id = Dlg1_GetIconFlagId(combo);
 GetWindowText(edit1, nid.szInfoTitle, MAX_STRLEN);
 GetWindowText(edit2, nid.szInfo, MAX_STRLEN);
 if (wcslen(nid.szInfo) == 0) {
  MessageBox(hDlg, L"The content is empty so the balloon cannot open.", L"Error", MB_ICONERROR);
  SetFocus(edit2);
  return;
 }
 nid.dwInfoFlags = iconflags[id];
 if (nid.dwInfoFlags == NIIF_USER) {
  hShellInst = GetModuleHandle(L"shell32.dll");
  LoadIconMetric(hShellInst, MAKEINTRESOURCE(152), LIM_SMALL, &nid.hBalloonIcon);
 }
 Shell_NotifyIcon(NIM_MODIFY, &nid);
}
一派护法 十九级
9楼 发表于:2015-12-24 13:23

回复帖子

内容:
用户名: 您目前是匿名发表
验证码:
(快捷键:Ctrl+Enter)
 

本帖信息

点击数:567 回复数:8
评论数: ?
作者:巨大八爪鱼
最后回复:巨大八爪鱼
最后回复时间:2015-12-24 13:23
 
©2010-2024 Arslanbar Ver2.0
除非另有声明,本站采用知识共享署名-相同方式共享 3.0 Unported许可协议进行许可。