Чтобы добавить иконку, нужно каким-либо образом дать знать окну диалога об этом.
Наиболее простым способом будет посылка сообщения 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 ... } |
Более радикальным способом (с далеко идущими последствиями, о которых - позже) будет изменение свойств класса окна диалога, а именно, иконки, ассоциированной с данным классом окон. Имея загруженный ресурс иконки, выполним код:
case WM_INITDIALOG: . . . SetClassLong(hDlg, GCL_HICON, (LONG) hIcon); . . . break; |
Теперь о последствиях - все диалоги приложения после выполнения этого кода будут загружать эту иконку в свой заголовок, в том числе и MessageBox'ы. Иногда это бывает полезно... Кроме того, замечу, что установка иконки по варианту Версия 1 имеет высший приоритет и позволяет перекрыть иконку класса окон.