質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

1240閲覧

(WINAPI)タスク常駐アプリのアイコン-visual studioでデバッグ中は表示されるが、exeファイルでは非表示

mercurian-teto

総合スコア75

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2018/04/22 14:15

編集2018/04/28 08:15

windowsAPIでタスク常駐するアプリを作成したのですが、
visual studioでデバッグして実行しているときには
常駐アプリが表示されるタスクトレイにアイコンが表示されていました。
しかし、

エクスプローラーでビルドして出来上がったexeファイルのものを実行すると
タスクバーにアイコンが表示されませんでした。

メッセージボックスのアイコンは両方正常に表示されます。

なぜこのような現象が起こるのかわからないのですが、
出来上がった実行ファイルでも同様にタスクトレイにアイコンが表示されるようにするにはどうすればいいですか。

下のコードが実際に実行したコードです。
###試したこと
このサイトにある通りコードを追加したりしました。
##実行環境
windows 10 pro
visual studio 2017

###コード

#include <Windows.h> #include <tchar.h> #include "resource.h" #include <stdarg.h> #include <stdbool.h> #include <Shlwapi.h> #include <locale.h> #define WM_TASKTRAY (WM_USER+1) #define ID_TASKTRAY 0 #define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array[0])) void SetShutdownPriority(); HWND g_hWnd; LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { static UINT s_uTaskbarRestart; SetShutdownPriority(); switch (msg) { /*case WM_CREATE: { s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); return 0; }break;*/ case WM_TASKTRAY: if (wParam == ID_TASKTRAY) { switch (lParam) { break; case WM_LBUTTONUP: int iRetYesNo; iRetYesNo = MessageBox(NULL, _T("RAguardを終了しますか"), _T("RAguard"), MB_YESNO | MB_ICONQUESTION); if (iRetYesNo == IDYES) { setlocale(LC_ALL, "Japanese"); //メモ帳のウィンドウを探す HWND hWnd = FindWindow (_T("WindowsForms10.Window.8.app.0.141b42a_r6_ad1"), _T("パソコンねむねむPro")); if (hWnd != NULL) { MessageBox(NULL, _T("ぱそこんねむねむが起動中です"), _T("RAguard"), MB_OK | MB_ICONWARNING); } else { MessageBox(NULL, _T("処理が完了しました"), _T("RAguard"), MB_OK); ::PostQuitMessage(0); //!< WM_QUITを送る return ::DefWindowProc(hWnd, msg, wParam, lParam); } } if (iRetYesNo == IDNO) { return -2; } } } break; case WM_QUERYENDSESSION: ShutdownBlockReasonCreate(hWnd, L"パソコンねむねむを終了させるか、RAGuardを終了してください"); // Prevent shutdown. Return FALSE as a return value for WM_QUERYENDSESSION. // If your window is not a dialog, you can simply use `return FALSE`. // シャットダウンを抑制するために FALSE を返します。 // 通常のウィンドウなら `return FALSE` で構いません。 return FALSE; case WM_ENDSESSION: // Do nothing. break; case WM_DESTROY: //!< ウインドウを閉じる ::PostQuitMessage(0); //!< WM_QUITを送る return ::DefWindowProc(hWnd, msg, wParam, lParam); default: /*if (msg == s_uTaskbarRestart) { s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); return 0; }*/ return ::DefWindowProc(hWnd, msg, wParam, lParam); } return ::DefWindowProc(hWnd, msg, wParam, lParam); } BOOL Init(HINSTANCE hInstance) { /*HANDLE hMSP; hMSP = CreateMutex(NULL, TRUE, _T("MultiplexStartingPreventionTest")); すでに起動しているか判定 if (GetLastError() == ERROR_ALREADY_EXISTS) { ReleaseMutex(hMSP); CloseHandle(hMSP); return FALSE; }*/ // ウインドウ生成 WNDCLASS wc; //!< ウインドウクラス // ウインドウクラスの登録 wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = static_cast<WNDPROC>(WndProc); //!< メッセージを受け取るウインドウ関数 wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); //!< アイコン登録 wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); //!< カーソル登録 wc.hbrBackground = static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH)); wc.lpszMenuName = NULL; //!< メニューの登録 wc.lpszClassName = L"パソコンねむねむPro"; // ウインドウクラスの登録 if (!::RegisterClass(&wc)) return EXIT_FAILURE; // ウインドウを作成 g_hWnd = ::CreateWindow(L"パソコンねむねむPro", //!< クラス名 L"パソコンねむねむPro", //!< タイトル名 WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, //!< スタイル 0, //!< X座標 0, //!< Y座標 100, //!< 横幅 100, //!< 高さ NULL, //!< 親ウインドウのハンドル NULL, //!< メニューハンドル hInstance, //!< インスタンスハンドル NULL); //!< lParam // ウインドウの作成 if (!g_hWnd) return EXIT_FAILURE; // ウインドウの表示状態の設定 ::ShowWindow(g_hWnd, SW_HIDE); // ウインドウの更新 ::UpdateWindow(g_hWnd); NOTIFYICONDATA nif; // タスクトレイに登録 nif.cbSize = sizeof(NOTIFYICONDATA); /*nif.hIcon = LoadIcon(NULL, IDI_APPLICATION);*/ nif.hIcon = (HICON)LoadImage(0, TEXT("shutdown.ico"), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); nif.hWnd = g_hWnd; nif.uCallbackMessage = WM_TASKTRAY; nif.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; nif.uID = ID_TASKTRAY; ::wcscpy_s(nif.szTip, 128, L"RAguard"); Shell_NotifyIcon(NIM_ADD, &nif); return EXIT_SUCCESS; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; if (Init(hInstance) == EXIT_FAILURE) return EXIT_FAILURE; while (::GetMessage(&msg, NULL, 0, 0)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } return EXIT_SUCCESS; } void SetShutdownPriority() { int i; EXECUTION_STATE state; DWORD priorityLevels[5] = { 0x4FF, 0x4F0, 0x3FF, 0x3F0, 0x300 }; for (i = 0; i < 5; i++) if (SetProcessShutdownParameters(priorityLevels[i], 0)) break; // ついでにプロセスをスタンバイや画面オフから守る state = ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED; SetThreadExecutionState(state); }

###編集したところ

wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = static_cast<WNDPROC>(WndProc); //!< メッセージを受け取るウインドウ関数 wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, iconid);; //!< アイコン登録 wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); //!< カーソル登録 wc.hbrBackground = static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH)); wc.lpszMenuName = NULL; //!< メニューの登録 wc.lpszClassName = L"パソコンねむねむPro";
NOTIFYICONDATA nif; // タスクトレイに登録 nif.cbSize = sizeof(NOTIFYICONDATA); nif.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SMALL)); nif.hWnd = g_hWnd; nif.uCallbackMessage = WM_TASKTRAY; nif.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; nif.uID = ID_TASKTRAY; ::wcscpy_s(nif.szTip, 128, L"RAguard"); Shell_NotifyIcon(NIM_ADD, &nif); return EXIT_SUCCESS; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

nif.hIcon = (HICON)LoadImage(0, TEXT("shutdown.ico"), IMAGE_ICON, 0, 0, LR_LOADFROMFILE);

これちゃんと取得できてますか?
具体的には、NULLが返ってきてないか調べてみてはいかがでしょうか。

なんとなく予想としてはカレントディレクトリからshutdown.icoを探そうとして失敗している予感がします。
実行ファイルの場合カレントディレクトリは想定外の場所になることもあるので
(ショートカットファイルを作成したり、D&Dとか)
必要ならばGetModuleFileName+PathRemoveFileSpec<filesystem>等を使って実行ファイルのあるディレクトリを取得してカレントディレクトリにする
などの措置が必要になります。

投稿2018/04/22 15:31

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mercurian-teto

2018/04/28 08:28

パスでの設定方法も試してみます。ありがとうございました。
guest

0

ベストアンサー

asmさんの回答の通り、エクスプローラーから起動したことでカレントディレクトリーが変わり、アイコンファイル(shutdown.ico)のロードに失敗していることが原因でしょう。

アイコンファイルはソースファイルと同じ場所(プロジェクトを作ったフォルダー)に置かれていると思いますが、Visual Studioから起動すればそこがカレントフォルダーになるので正しくロードできます。一方、エクスプローラーから起動すると、EXEファイルの場所がカレントフォルダーになります。そこにアイコンファイルがなければ当然ロードに失敗します。ロードに失敗すればアイコンは表示されません。

パス操作でアイコンファイルを正しくロードできるようにするのも良いですが、よりスマートな解決策としては、アイコンイメージをリソースにしてEXEファイルに埋め込むことです。そうすればパスを気にする必要はありませんし、配布の際もEXEファイル1個で済みます。
Windowsアプリでは、アイコンイメージを(アイコンに限らずGUI関連のビットマップイメージ等も)リソースで持つことはごく一般的に行われています。

投稿2018/04/22 16:22

catsforepaw

総合スコア5938

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

0

リソースをexeファイルに埋め込む方針にしました。

とりあえず、

visual studio 新規作成→プロジェクト→windowsデスクトップウィザード

windowsデスクトップ プロジェクトでは

プリコンパイル済みヘッダー(P)
セキュリティ関連ライフサイクル(SDL)チェック(C)
にチェックを入れました。

エクスプローラーに移動して
デフォルトで作成されてある

プログラム名.ico
small.ico


設定したいアイコン画像で上書きして、

アイコンのロード先を変更するように追記した通りにコードを修正したら、

タスクバーに表示されるアイコンや実行ファイルのアイコンが正常に表示されるようになりました。

投稿2018/04/28 08:27

mercurian-teto

総合スコア75

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問