スポンサーリンク

win32api タスクトレイアイコンをクリックしたときにメニューを表示

なんでもタスクトレイという言い方は正しくなく、通知領域、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);

}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: