Pregunta

En Visual Studio, generé una aplicación Win32 antigua y simple y eliminé todos los recursos y el código generado para que mi aplicación consista en esto:

#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 );
}

Cuando ejecuto la aplicación, esto es lo que veo:

 captura de pantalla

Entonces, la pregunta es ¿puedo cambiar el icono de la aplicación predeterminada en la barra de tareas? Si es así, ¿qué código debe agregarse para hacerlo?

Editar:

Esto es lo que hice, y este tipo de trabajo funciona, pero no es lo ideal. El nuevo ícono se muestra bien, pero la ventana de vista previa de la barra de tareas en Vista no funciona y el menú del sistema no funciona, así que solo lo dejaré solo por ahora.

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 );
}
¿Fue útil?

Solución

El icono que se muestra en la barra de tareas se toma de la ventana misma. Si la única ventana es el Windows MesssageBox estándar, obtendrá algún tipo de sistema operativo predeterminado. Debe crear su propia ventana y darle un icono, luego Windows la usará.

Otros consejos

Esto parece solo un código de muestra. Si el código real es una aplicación de Windows que no es de consola, puede hacer esto:

Dele a la ventana principal de su aplicación un icono de barra de tareas llamando a SetIcon () . Luego, cuando llame a MessageBox (), configure el primer parámetro en el HWND de la ventana principal de su aplicación.

Para este caso en particular (una llamada MessageBox en la función WinMain ) puede enganchar la creación del cuadro de diálogo del cuadro de mensaje y establecer un icono allí. Así:

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);
}

Donde IDI_MYICON es la ID de su recurso de icono.

WNDCLASSEX wndclass;

wndclass.cbSize        = sizeof(wndclass);
// ..
wndclass.hIconSm       = ExtractIconEx( ... );
RegisterClassEx(&wndclass);

HWDN wnd = CreateWindow(...)

¿Por qué no solo agregar un recurso de icono al EXE? Estoy bastante seguro de que Windows lo intentará antes de recurrir al genérico iconos.

Cree un formulario pero nunca lo muestre, luego asígnele un icono y úselo como padre de su cuadro de mensaje.

Esto oculta el ícono:

using (var f = new Form())
{
    MessageBox.Show(f,"my message");
}

Esto creará un icono:

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");
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top