タスクバー常駐アプリを作成しました。
タスクバーに表示されるtaskbar常駐アプリを左クリックするとコンテキストメニューが表示され、メッセージボックスが起動されるような仕様です。
ソフトウェア自体の多重起動は防ぐことはできるのですが、
(下のコードに実装しています。)
タスクバーのコンテキストメニューでのメニュー選択によって表示される
messageboxの多重起動は防ぐことができません。
普段使用するようなタスクバー常駐のソフトウェアは多重起動できずにブロックするような仕組みがあると思うのですが、どう実装するのかがわかりません。回答お願いします。
winapi
1#include <Windows.h> 2#include <tchar.h> 3#include "resource.h" 4#include <Shlwapi.h> 5#include <locale.h> 6 7#define WM_TASKTRAY (WM_USER+1) 8#define ID_TASKTRAY 0 9#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array[0])) 10 11 12HWND g_hWnd; 13BOOL MultiplexStartingPrevention(VOID); 14 15 16LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 17{ 18 HANDLE hMSP; 19 hMSP = CreateMutex(NULL, TRUE, _T("MultiplexStartingPreventionTest")); 20 POINT po; 21 static HMENU tmp, hmenuR, hmenuL; 22 static UINT s_uTaskbarRestart; 23 24 25 switch (msg) 26 { 27 case WM_CREATE: 28 tmp = LoadMenu(((LPCREATESTRUCT)(lParam))->hInstance, TEXT("IDR_MENU1")); 29 hmenuR = GetSubMenu(tmp, 0); 30 /*hmenuL = GetSubMenu(tmp, 1);*/ 31 break; 32 33 34 case WM_TASKTRAY: 35 if (wParam == ID_TASKTRAY) 36 { 37 switch (lParam) { 38 39 case WM_RBUTTONUP: 40 41 GetCursorPos(&po); 42 ClientToScreen(hWnd, &po); 43 44 TrackPopupMenu(hmenuR, TPM_LEFTALIGN | TPM_BOTTOMALIGN, 45 po.x, po.y, 0, hWnd, NULL 46 ); 47 break; 48 49 } 50 51 } 52 break; 53 case WM_COMMAND: 54 switch (LOWORD(wParam)) 55 { 56 case ID_a: 57 //バージョン(A) 58 MessageBox(hWnd, _T("aaaaaaaaaaaaaaaaaaaa"), _T("id_a"), MB_OK); 59 60 break; 61 case ID_b: 62 MessageBox(hWnd, _T("bbbbbbbbbbbbbbbbbbbb"), _T("id_b"), MB_OK); 63 64 break; 65 } 66 break; 67 68 69 case WM_ENDSESSION: 70 71 72 // Do nothing. 73 break; 74 75 case WM_DESTROY: //!< ウインドウを閉じる 76 ::PostQuitMessage(0); //!< WM_QUITを送る 77 return ::DefWindowProc(hWnd, msg, wParam, lParam); 78 default: 79 80 return ::DefWindowProc(hWnd, msg, wParam, lParam); 81 } 82 return ::DefWindowProc(hWnd, msg, wParam, lParam); 83} 84 85BOOL Init(HINSTANCE hInstance) 86{ 87 /*HANDLE hMSP; 88 hMSP = CreateMutex(NULL, TRUE, _T("MultiplexStartingPreventionTest")); 89 90 if (GetLastError() == ERROR_ALREADY_EXISTS) { 91 92 93 ReleaseMutex(hMSP); 94 CloseHandle(hMSP); 95 return FALSE; 96 }*/ 97 if (MultiplexStartingPrevention() == EXIT_FAILURE)return EXIT_FAILURE; 98 99 100 // ウインドウ生成 101 WNDCLASS wc; //!< ウインドウクラス 102 // ウインドウクラスの登録 103 wc.style = CS_HREDRAW | CS_VREDRAW; 104 wc.lpfnWndProc = static_cast<WNDPROC>(WndProc); //!< メッセージを受け取るウインドウ関数 105 wc.cbClsExtra = 0; 106 wc.cbWndExtra = 0; 107 wc.hInstance = hInstance; 108 wc.hIcon = NULL; //!< アイコン登録 109 wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); 110 wc.hbrBackground = static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH)); 111 wc.lpszMenuName = NULL; //!< メニューの登録 112 wc.lpszClassName = _T("taskbarapp"); 113 114 115 // ウインドウクラスの登録 116 if (!::RegisterClass(&wc)) 117 { 118 MessageBox(NULL, _T("windowsクラスの登録に失敗"), _T("バージョン情報"), MB_OK); 119 return EXIT_FAILURE; 120 121 } 122 // ウインドウを作成 123 g_hWnd = ::CreateWindow(_T("taskbarapp"), //!< クラス名 124 _T("gregrergere"), //!< タイトル名 125 WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, //!< スタイル 126 0, //!< X座標 127 0, //!< Y座標 128 100, //!< 横幅 129 100, //!< 高さ 130 NULL, //!< 親ウインドウのハンドル 131 NULL, //!< メニューハンドル 132 hInstance, //!< インスタンスハンドル 133 NULL); //!< lParam 134 135 // ウインドウの作成 136 if (!g_hWnd) 137 { 138 MessageBox(NULL, _T("window作成に失敗"), _T("バージョン情報"), MB_OK); 139 return EXIT_FAILURE; 140 } 141 // ウインドウの表示状態の設定 142 ::ShowWindow(g_hWnd, SW_SHOW); 143 // ウインドウの更新 144 ::UpdateWindow(g_hWnd); 145 146 147 NOTIFYICONDATA nif; 148 // タスクトレイに登録 149 nif.cbSize = sizeof(NOTIFYICONDATA); 150 nif.hIcon = NULL; 151 nif.hWnd = g_hWnd; 152 nif.uCallbackMessage = WM_TASKTRAY; 153 nif.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; 154 nif.uID = ID_TASKTRAY; 155 ::wcscpy_s(nif.szTip, 128, _T("takbarapp")); 156 157 Shell_NotifyIcon(NIM_ADD, &nif); 158 159 return EXIT_SUCCESS; 160} 161 162int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 163{ 164 MSG msg; 165 166 167 168 if (Init(hInstance) == EXIT_FAILURE) 169 { 170 MessageBox(NULL, _T("failure"), _T("failure"), MB_OK); 171 return EXIT_FAILURE; /*return EXIT_FAILURE*/ 172 } 173 174 while (::GetMessage(&msg, NULL, 0, 0)) 175 { 176 ::TranslateMessage(&msg); 177 ::DispatchMessage(&msg); 178 } 179 return EXIT_SUCCESS; 180} 181 182 183 184 185int MultiplexStartingPrevention() 186{ 187 HANDLE hMSP; /* 多重起動防止用Mutex Handle */ 188 hMSP = CreateMutex(NULL, TRUE, _T("MultiplexStartingPreventionTest")); 189 /* すでに起動しているか判定 */ 190 if (GetLastError() == ERROR_ALREADY_EXISTS) { 191 /* すでに起動している。*/ 192 /*MessageBox(NULL, _T("すでに起動しております。"), _T("Multiplex starting prevention Test C"), MB_OK);*/ 193 ReleaseMutex(hMSP); 194 CloseHandle(hMSP); 195 return EXIT_FAILURE; 196 } 197 return EXIT_SUCCESS; 198 199} 200
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/02/25 07:29