LoginSignup
1
1

More than 1 year has passed since last update.

日記 Visual Studio 2019 C++ タスクトレイのアイコンに右クリックメニューを追加する方法

Last updated at Posted at 2021-08-02

完成イメージ

7.png

手順

前提

次の記事の内容が適用されている事
日記 Visual Studio 2019 C++でタスクトレイに常駐するアプリケーションを作成

リソースにメニューを追加する

1.png
2.png
3.png
4.png
各メニューのプロパティ設定、どのメニューが選択されたか判別するIDをわかりやすい名前にする
5.png

プログラム

デスクトップアプリケーションのテンプレートに★マークで囲まれた範囲を追加
※ 一部次の記事の内容も混ざっている
 日記 Visual Studio 2019 C++でタスクトレイに常駐するアプリケーションを作成

定数、グローバル変数定義、初期処理

Sample.cpp
// Sample.cpp : アプリケーションのエントリ ポイントを定義します。
//

#include "framework.h"
#include "Sample.h"
// ★★★★★★★★★★★★★★★★★★★★
#include "shellapi.h"
// ★★★★★★★★★★★★★★★★★★★★

#define MAX_LOADSTRING 100

// ★★★★★★★★★★★★★★★★★★★★
#define WM_TASKTRAY (WM_APP + 1)                // タスクトレイのマウス・メッセージ定数
// ★★★★★★★★★★★★★★★★★★★★

// グローバル変数:
HINSTANCE hInst;                                // 現在のインターフェイス
WCHAR szTitle[MAX_LOADSTRING];                  // タイトル バーのテキスト
WCHAR szWindowClass[MAX_LOADSTRING];            // メイン ウィンドウ クラス名

// ★★★★★★★★★★★★★★★★★★★★
// アイコン
HICON hIcon;
// メニューに追加したIDR_MENU1のハンドルを設定するためのグローバル変数
HMENU hTaskTrayMenu;
// ★★★★★★★★★★★★★★★★★★★★

// このコード モジュールに含まれる関数の宣言を転送します:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

// ★★★★★★★★★★★★★★★★★★★★
// タスクトレ イアイコン追加、削除
VOID AddSystemTrayIcon(HWND hWnd);
VOID DellSystemTrayIcon(HWND hWnd);
// ★★★★★★★★★★★★★★★★★★★★

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: ここにコードを挿入してください。

    // ★★★★★★★★★★★★★★★★★★★★
    // アイコン AddSystemTrayIcon()で使用するため
    hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SAMPLE));

    // 作成したメニューを読み込む
    hTaskTrayMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1));
    // ★★★★★★★★★★★★★★★★★★★★

    // グローバル文字列を初期化する
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);

メッセージ処理に処理を追加

  • タスクトレイのアイコンの右クリック時のメニューポップアップ処理
  • 各メニューを選択した時の処理の記述(コメント)
Sample.cpp
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        // ★★★★★★★★★★★★★★★★★★★★
        // タスクトレイのアイコンに対する処理
        case WM_TASKTRAY:
        {
            switch (lParam)
            {
                // 右クリック
                case WM_RBUTTONDOWN:
                {
                    // hTaskTrayMenuは初期処理でセットしている
                    if (hTaskTrayMenu)
                    {
                        // GetSubMenuは0でメニューの一番左のドロップダウンリストを取得する
                        HMENU hTrayIconSubMenu = GetSubMenu(hTaskTrayMenu, 0);
                        if (hTrayIconSubMenu)
                        {
                            // タスクトレイのアイコンを右クリックした時の座標を取得
                            POINT po;
                            GetCursorPos(&po);

                            // ウィンドウをフォアグラウンドに持ってくる
                            SetForegroundWindow(hWnd);

                            // これをしないと、メニュー外をクリックした時に、ポップアップメニューが消えない
                            SetFocus(hWnd);

                            // メニューの表示
                            TrackPopupMenu(hTrayIconSubMenu, TPM_LEFTALIGN | TPM_BOTTOMALIGN,
                                po.x, po.y, 0, hWnd, NULL
                            );
                        }
                    }
                }
                break;
            }
        }
        break;
        // ★★★★★★★★★★★★★★★★★★★★
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 選択されたメニューの解析:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;

            // ★★★★★★★★★★★★★★★★★★★★
            // タスクトレイの右クリックメニューで選択されたメニューに応じた処理を追加する
            // case IDM_HOGE1:
                // break;
            // case IDM_HOGE2:
                // break;
            // ★★★★★★★★★★★★★★★★★★★★

            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1