質問
Visual Studioでは、単純な古いWin32アプリケーションを生成し、すべてのリソースを削除してコードを生成したため、アプリケーションは次のようになります。
#include "stdafx.h"
#include "IcoTest.h"
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
::MessageBox( NULL, L"Testing", L"Test", MB_OK );
}
アプリケーションを実行すると、これが表示されます。
質問は、タスクバーのデフォルトのアプリケーションアイコンを変更できますか?その場合、それを行うにはどのコードを追加する必要がありますか?
編集:
これは私がやったことで、この種の作品ですが、理想的ではありません。新しいアイコンは申し分なく表示されますが、Vistaのタスクバープレビューウィンドウは機能せず、システムメニューも機能しないため、ここではそのままにします。
HWND CreateDummyWindow(HINSTANCE hInstance, int iconId, LPCTSTR taskbarTitle)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = DefWindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(iconId));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = 0;
wcex.lpszMenuName = 0;
wcex.lpszClassName = taskbarTitle,
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(iconId));
ATOM atom = RegisterClassEx(&wcex);
HWND wnd = ::CreateWindow(
wcex.lpszClassName, taskbarTitle, WS_ICONIC | WS_DISABLED,
-1000, -1000, 1, 1, NULL, NULL, hInstance, NULL);
return wnd;
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
HWND wnd = CreateDummyWindow(hInstance, IDI_ICON1, _T("Test") );
::MessageBox( wnd, _T("Testing"), _T("Test"), MB_OK );
::DestroyWindow( wnd );
}
解決
タスクバーに表示されるアイコンは、ウィンドウ自体から取得されます。唯一のウィンドウが標準のWindows MesssageBoxである場合、何らかのOSのデフォルトが表示されます。独自のウィンドウを作成してアイコンを付ける必要があります。その後、Windowsはそれを使用します。
他のヒント
これは単なるサンプルコードのように見えます。実際のコードがコンソール以外のWindowsアプリケーションである場合、これを行うことができます。
SetIcon()。次に、MessageBox()を呼び出すときに、最初のパラメーターをアプリケーションのメインウィンドウのHWNDに設定します。
この特定のケース( WinMain
関数での1つの MessageBox
呼び出し)の場合、メッセージボックスダイアログの作成をフックし、そこにアイコンを設定できます。このように:
HHOOK g_hMsgBoxHook;
HINSTANCE g_hInstance;
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode == HC_ACTION)
{
CWPSTRUCT* pcwp = (CWPSTRUCT*)lParam;
if(pcwp->message == WM_INITDIALOG)
{
HICON hIcon = NULL;
HICON hIconBig = NULL;
// Small icon.
hIcon = (HICON)LoadImage(g_hInstance,
MAKEINTRESOURCE(IDI_MYICON),
IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON),
0);
if(hIcon)
{
SendMessage(pcwp->hwnd, WM_SETICON,
ICON_SMALL, (LPARAM)hIcon);
}
// Big icon.
hIconBig = (HICON)LoadImage(g_hInstance,
MAKEINTRESOURCE(IDI_MYICON),
IMAGE_ICON,
GetSystemMetrics(SM_CXICON),
GetSystemMetrics(SM_CXICON),
0);
if(hIconBig)
{
SendMessage(pcwp->hwnd, WM_SETICON,
ICON_BIG, (LPARAM)hIconBig);
}
}
}
return CallNextHookEx(g_hMsgBoxHook, nCode, wParam, lParam);
}
int CALLBACK wWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nCmdShow
)
{
g_hInstance = hInstance;
g_hMsgBoxHook = SetWindowsHookEx(WH_CALLWNDPROC,
CallWndProc, NULL, GetCurrentThreadId());
MessageBoxW(NULL, L"Testing", L"Test", MB_OK);
// ...
UnhookWindowsHookEx(g_hMsgBoxHook);
}
IDI_MYICON
は、アイコンリソースのIDです。
WNDCLASSEX wndclass;
wndclass.cbSize = sizeof(wndclass);
// ..
wndclass.hIconSm = ExtractIconEx( ... );
RegisterClassEx(&wndclass);
HWDN wnd = CreateWindow(...)
アイコンリソースをEXEに追加するだけではどうですか? Windowsが「汎用」にフォールバックする前にそれを試すと確信しています。アイコン。
フォームを作成しますが、表示せずにアイコンを割り当て、メッセージボックスの親として使用します。
これによりアイコンが非表示になります:
using (var f = new Form())
{
MessageBox.Show(f,"my message");
}
これによりアイコンが作成されます:
using (var f = new Form())
{
f.Icon = Resources.IconUpload;
f.Location=new Point(-1000,-1000);
f.StartPosition = FormStartPosition.Manual;
f.Show();
MessageBox.Show(f,"my message");
}