Сообщений 1    Оценка 13        Оценить  
Система Orphus

Как добавить иконку в заголовок диалогового окна?

Автор: Игорь Вартанов

Версия текста: 1.0

Чтобы добавить иконку, нужно каким-либо образом дать знать окну диалога об этом.

Способ 1

Наиболее простым способом будет посылка сообщения WM_SETICON. Предварительно необходимо загрузить иконку из ресурса в память.

// hInstance - каким-либо образом полученный HINSTANCE модуля (.exe или .dll) с иконкой
//     Примеры получения hInstance:
//     а) static HINSTANCE hInstance = GetModuleHandle(NULL);
//     б) static HINSTANCE hInstance = GetWindowInstance(hDlg);
//        Внимание! GetWindowInstance - это макрос из windowsx.h
// pszIconResource - указатель LPCSTR ресурса иконки
//     Примеры получения pszIconResource:
//     а) для случая идентификации ресурса по имени
//        pszIconResource = "DialogIcon";
//     б) для случая идентификации ресурса по ординалу
//        pszIconResource = MAKEINTRESOURCE(IDI_DIALOGICON);

static HICON hIcon = NULL;

case WM_INITDIALOG:
    . . .
    hIcon = LoadIcon(hInstance, pszIconResource);
    SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
    //SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall);
    . . .
    break;
case WM_COMMAND:
    . . .
    case IDCANCEL:
        DestroyIcon(hIcon); // Не забываем освободить ресурс!
        EndDialog(hDlg, 0);     
        break; 
    . . .
    break;
Следует иметь ввиду некоторые нюансы работы с WM_SETICON. Если ресурс иконки содержит двойное изображение (большое 32x32 и малое 16x16), то при установке иконки с wParam = ICON_BIG в заголовке диалога будет отрисована малая иконка, а в диалоге переключения по ALT+TAB отрисуется большая. Если ресурс иконки содержит только большое изображение, то в заголовке диалога будет отрисована отмасштабированная большая иконка (в диалоге переключения появится она же в полный размер). При попытке использовать различные иконки для большого и малого изображений нужно всегда иметь ввиду, что даже в том случае, когда ресурс иконки содержит и малое, и большое изображения, при добавлении ее с wParam = ICON_SMALL в качестве малого изображения будет отрисовано отмасштабированное большое изображение (а не малое, как это можно было бы предположить). Хотя такое поведение никак не оговорено в MSDN, тем не менее оно наблюдается на всех Win32-платформах.

В MFC аналогичную операцию выполняет функция CWnd::SetIcon. В качестве первого параметра она получает дескриптор предварительно загруженной иконки, а второй параметр может принимать значение TRUE или FALSE, в зависимости от того, большую или маленькую иконку мы хотим задать для дмалога. Обычно функцию SetIcon вызывают из обработчика WM_INITDIALOG, например:

BOOL CMFCTipsDlg::OnInitDialog()
{
...
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

    SetIcon(m_hIcon, TRUE);         // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon
...
}

Способ 2 (Win32 API)

Более радикальным способом (с далеко идущими последствиями, о которых - позже) будет изменение свойств класса окна диалога, а именно, иконки, ассоциированной с данным классом окон. Имея загруженный ресурс иконки, выполним код:

case WM_INITDIALOG:
    . . .
    SetClassLong(hDlg, GCL_HICON, (LONG) hIcon);
    . . . 
    break;

Теперь о последствиях - все диалоги приложения после выполнения этого кода будут загружать эту иконку в свой заголовок, в том числе и MessageBox'ы. Иногда это бывает полезно... Кроме того, замечу, что установка иконки по варианту Версия 1 имеет высший приоритет и позволяет перекрыть иконку класса окон.


Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.
    Сообщений 1    Оценка 13        Оценить