Программирование на Visual C++. Архив рассылки - Алекс Jenter
Шрифт:
Интервал:
Закладка:
Стиль кнопки, а также связанный с ней список изображений, задаются в конструкторе класса CBitmapButton, хотя можно установить/изменить их и позже, используя соответствующие методы. Для задания текста всплывающей подсказки также существуют соответствующий метод. Полный список методов класса CBitmapButton приведён в таблице 7.
Метод Описание CBitmapButtonImpl(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE, HIMAGELIST hImageList = NULL) Конструктор. Параметры – набор расширенных стилей и хэндл списка изображений, который следует связать с кнопкой. ~CBitmapButtonImpl() Деструктор. Напоминаю, что внутри деструктора будет разрушен список изображений, связанный с кнопкой в данный момент. Чтобы этого не произошло, следует назначить кнопке расширенный стиль BMPBTN_SHAREIMAGELISTS. BOOL SubclassWindow(HWND hWnd) Метод для подмены оконной процедуры (т.н. сабклассинга) существующего контрола. Используется макросом DDX_CONTROL, но вы можете вызывать этот метод и сами. DWORD GetBitmapButtonExtendedStyle() Возвращает набор расширенных стилей. DWORD SetBitmapButtonExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) Устанавливает набор расширенных стилей. HIMAGELIST GetImageList() Возвращает хэндл списка изображений. HIMAGELIST SetImageList(HIMAGELIST hImageList) Устанавливает список изображений. bool GetToolTipText(LPTSTR lpstrText, int nLength) Возвращает текст всплывающей подсказки. bool SetToolTipText(LPCTSTR lpstrText) Устанавливает текст всплывающей подсказки (память для него динамически распределяется внутри класса CBitmapButton). void SetImages(int nNormal, int nPushed = –1, int nFocusOrHover = –1, int nDisabled = –1) Устанавливает соответствие состояний кнопки и изображений в списке. Используйте –1, чтобы оставить соответствующее состояние без изменений. Вы должны задать, по меньшей мере, изображение для состояния nNormal (отпущена), иначе программа не будет работать корректно. Замечу, что вы можете назначить нескольким состояниям одно и то же изображение. BOOL SizeToImage() Принудительно масштабирует кнопку по размеру связанных с ней изображений. void DoPaint(CDCHandle dc) Эта функция рисует кнопку в одном из четырёх состояний. Вам вряд ли понадобится вызывать её напрямую; зато её можно переопределить в производном классе и придать кнопке нестандартный вид, сохранив при этом остальную функциональность, которую предоставляет класс CBitmapButton. Класс CCheckListViewCtrlИз названия может показаться, что этот класс реализует список с галочками (check boxes), но это не совсем так. Стандартный контрол ListView уже поддерживает галочки. Достаточно задать ему расширенный стиль LVS_EX_CHECKBOXES. Что касается класса CCheckListViewCtrl, то он позволяет манипулировать несколькими галочками одновременно. Для этого пользователь выделяет несколько элементов в списке (используя Shift и Ctrl, в списке можно довольно быстро пометить нужную группу элементов). После этого щелчок по галочке любого элемента (или нажатие на Space) будет приводить к изменению состояния галочек у всех выделенных элементов. При необходимости такое поведение контрола можно подавить, удерживая Ctrl (при этом список будет вести себя, как обычный ListView).
Реализация класса CCheckListViewCtrl достаточно очевидна. Метод SubclassWindow подменяет оконную процедуру списка и принудительно устанавливает ему стиль LVS_EX_CHECKBOXES. Всю остальную работу делают обработчики сообщений WM_LBUTTONDOWN, WM_LBUTTONDBLCLK и WM_KEYDOWN. Все они используют для переключения галочек вспомогательную функцию CheckSelectedItems. Вы можете вызывать эту функцию и сами, хотя такая необходимость возникает нечасто. Функция CheckSelectedItems получает единственный параметр – номер элемента (этот элемент должен быть выделен). Она считывает состояние его галочки, инвертирует это состояние и применяет ко всем выделенным элементам в списке.
Резюмируя сказанное выше, для применения класса CCheckListViewCtrl в большинстве случаев достаточно просто связать объект этого класса с контролом, используя макрос DDX_CONTROL.
Класс CHyperLinkКласс CHyperLink предназначен для создания гиперссылок. На самом деле, большую часть функциональности он наследует от базового класса CHyperLinkImpl. Гиперссылка создаётся на основе статического элемента управления.
Класс CHyperLink наглядно демонстрирует, что иногда для решения самых простых задач приходится написать множество строк кода. Если, конечно, учесть разные мелочи, о которых задумываются далеко не все. Вот список основных возможностей класса.
• Гиперссылка выглядит, как в IE. Интересно, что цвета для ссылки (обычной и посещённой) берутся из настроек IE, хранящихся в реестре. Если настройки обнаружить не удаётся, используются цвета по умолчанию (синий и фиолетовый).
• При наведении на ссылку курсор приобретает форму руки. Обратите внимание, что под Windows 2000 класс CHyperLink использует системный курсор, а в других версиях Windows создаёт его на лету, избавляя вас от необходимости включать его в ресурсы во всех случаях. Кроме того, следует отметить, что курсор должен располагаться именно на надписи, а не в любой точке статического контрола, даже если вы нарисовали его очень большим.
• Если задержать курсор над ссылкой, появляется всплывающая подсказка с адресом, по которому будет осуществляться переход.
• Класс CHyperLink поддерживает не только мышиный, но и клавиатурный интерфейс. Ссылка, на которую установлен фокус ввода, выделяется пунктирной рамкой. При этом можно перейти по ней, нажав Enter или Space.
ПРИМЕЧАНИЕ
В типичном модальном диалоге Enter не будет попадать в ссылку, так как диалог преобразует его в нажатие кнопки по умолчанию. При желании изменить это поведение можно, переопределив обработчик OnGetDlgCode класса CHyperLink.
Переход по ссылке реализован через функцию ShellExecute. Эта функция понимает как адреса сайтов (при этом открывается броузер), так и почтовые адреса (при этом запускается почтовый клиент).
Список методов класса CHyperLink приведён в таблице 8.
Метод Описание CHyperLinkImpl() Конструктор. Записывает в переменные объекта значения по умолчанию. ~CHyperLinkImpl() Деструктор. Освобождает ресурсы, распределённые в процессе инициализации. bool GetLabel(LPTSTR lpstrBuffer, int nLength) const Возвращает метку гиперссылки (то есть строку, которую пользователь видит на экране). bool SetLabel(LPCTSTR lpstrLabel) Устанавливает метку гиперссылки. Текст сохраняется внутри объекта класса. Память для него распределяется динамически. По умолчанию в качестве метки используется содержимое статического контрола, который связывается с объектом класса. Поэтому часто удаётся обойтись и без метода SetLabel. bool GetHyperLink(LPTSTR lpstrBuffer, int nLength) const Возвращает адрес гиперссылки, по которому осуществляется фактический переход. bool SetHyperLink(LPCTSTR lpstrLink) Устанавливает адрес гиперссылки. Адрес также сохраняется внутри объекта класса в динамически распределяемой памяти. Иногда адрес совпадает с меткой. В этом случае устанавливать его вызовом SetHyperLink необязательно, так как класс CHyperLink сделает это за вас. BOOL SubclassWindow(HWND hWnd) Подменяет оконную процедуру окна, подключая к нему объект класса. bool Navigate() Осуществляет переход по ссылке. void Init() Инициализирует объект класса: создаёт или загружает курсор в виде руки, создаёт подчёркнутый фонт и тултип для ссылки, загружает из реестра цвета, которые использует IE. void DoPaint(CDCHandle dc) Рисует ссылку. Вы можете переопределить этот метод в производном классе, чтобы изменить её внешний вид.ПРИМЕЧАНИЕ
Обратите внимание: если метка и адрес гиперссылки у вас отличаются, метод SetHyperLink следует вызывать до связывания объекта класса с контролом. Дело в том, что в момент связывания (в функции Init, которая вызывается из SubclassWindow) для ссылки создаётся тултип, в который записывается адрес ссылки. Если адрес ещё не задан, в тултип запишется метка.
Класс CMultiPaneStatusBarCtrlImplКласс CMultiPaneStatusBar призван облегчить вашу жизнь при работе со строками состояния. Стандартный контрол status bar из набора общих контролов Windows позволяет создать на строке состояния до 256 панелей, в которых можно отображать текст и иконки. Но он не предоставляет никаких средств для автоматического перемещения этих панелей. Программисту на чистом API приходится передвигать их вручную всякий раз, когда строка состояния изменяет свой размер. В MFC эту работу берёт на себя класс CStatusBar. А в WTL вам поможет класс CMultiPaneStatusBar.