なんでもタスクトレイという言い方は正しくなく、通知領域、Notification Areaが正しいらしい。知ったことではない。
タスクトレイにアイコンを表示する方法を以前調べた。
タスクトレイにアイコンを表示する
クリックしたときにメニューを表示する場合、GetCursorPosでマウスカーソルの位置を取得して、TrackPopupMenuでメニューを表示する。
#pragma warning(disable:4996) #include <windows.h> #include <shellapi.h> static const int TasktrayIconID = 100; static const int WM_MY_NOTIFYICON = WM_USER + TasktrayIconID; const int ID_MENU_MSG = 100; const int ID_MENU_EXIT = 101; HMENU myCreateMenu(); void intoTasktray(HWND hwnd, const int IconID); void fromTasktray(HWND hwnd, const int IconID); void menuPopup(HWND hwnd, HMENU menu); ///////////////////////////////// ///////////////////////////////// ///////////////////////////////// /////////////////////////////////
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { static HMENU hMenu = nullptr; switch (msg) { case WM_CREATE: hMenu = myCreateMenu();//メニュー作成 break; case WM_LBUTTONDOWN://ウィンドウをクリックしたらアイコン表示開始 { intoTasktray(hwnd, TasktrayIconID); break; } case WM_MY_NOTIFYICON: if (lp == WM_LBUTTONDOWN && wp == TasktrayIconID) { // アイコンを左クリックしたらウィンドウを表示 fromTasktray(hwnd, TasktrayIconID); } else if (lp == WM_RBUTTONUP) { // アイコンを右クリックしたらポップアップメニューを表示 menuPopup(hwnd, hMenu); } break; case WM_COMMAND: switch (wp) { case ID_MENU_MSG: // "Open"がクリックされた場合 MessageBoxA(hwnd, "MessageBox", "Info", MB_OK); break; case ID_MENU_EXIT: // "Exit"がクリックされた場合 DestroyWindow(hwnd); break; } break; case WM_DESTROY: DestroyWindow(hwnd); PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, msg, wp, lp); }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow) { HWND hwnd; MSG msg; WNDCLASS winc; winc.style = CS_HREDRAW | CS_VREDRAW; winc.lpfnWndProc = WndProc; winc.cbClsExtra = winc.cbWndExtra = 0; winc.hInstance = hInstance; winc.hIcon = LoadIcon(NULL, IDI_APPLICATION); winc.hCursor = LoadCursor(NULL, IDC_ARROW); winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); winc.lpszMenuName = NULL; winc.lpszClassName = TEXT("SZL-WINDOW"); if (!RegisterClass(&winc)) return -1; hwnd = CreateWindow( TEXT("SZL-WINDOW"), TEXT("test"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, NULL, NULL, hInstance, NULL ); if (hwnd == NULL) return -1; while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg); return msg.wParam; }
// メニューの作成 HMENU myCreateMenu() { HMENU menu = CreatePopupMenu(); AppendMenuA(menu, MF_STRING, ID_MENU_MSG, "Open"); AppendMenuA(menu, MF_STRING, ID_MENU_EXIT, "Exit"); return menu; }
// ウィンドウを消し、アイコンをタスクトレイへ格納 void intoTasktray(HWND hwnd, const int IconID) { NOTIFYICONDATA nid; nid.cbSize = sizeof(nid); nid.hWnd = hwnd; nid.uID = IconID;//複数のアイコンを表示したときの識別ID。なんでもいい。 nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; nid.uCallbackMessage = WM_MY_NOTIFYICON; //WM_USER以降の定数。 nid.hIcon = (HICON)LoadIcon(NULL, IDI_APPLICATION); wcscpy(nid.szTip, L"タスクトレイで表示する文字列"); int ret = (int)Shell_NotifyIcon(NIM_ADD, &nid); ShowWindow(hwnd, SW_HIDE); }
// タスクトレイからアイコンを削除し、ウィンドウを表示 void fromTasktray(HWND hwnd, const int IconID) { ShowWindow(hwnd, SW_SHOW); //タスクトレイアイコンを削除 NOTIFYICONDATA nid; nid.cbSize = sizeof(nid); nid.hWnd = hwnd; nid.uID = IconID; nid.uFlags = 0; Shell_NotifyIcon(NIM_DELETE, &nid); }
// ポップアップメニューを表示 void menuPopup(HWND hwnd, HMENU menu) { POINT pt; GetCursorPos(&pt); SetForegroundWindow(hwnd); TrackPopupMenu(menu, TPM_RIGHTALIGN, pt.x, pt.y, 0, hwnd, NULL); }