[英]How to explicitly set taskbar icon?
在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,那么您將獲得某種操作系統默認值。 你必須創建自己的窗口並給它一個圖標,然后Windows將使用它。
這看起來就像示例代碼。 如果真實代碼是非控制台Windows應用程序,則可以執行以下操作:
通過調用SetIcon()為應用程序的主窗口提供任務欄圖標。 然后,當您調用MessageBox()時,將第一個參數設置為應用程序主窗口的HWND。
對於這種特殊情況( WinMain
函數中的一個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");
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.