Файл smartpad/toolbar.cpp
#define STRICT #include <windows.h>
#include <windowsx.h>
#include <mem.h>
#include "toolbar.hpp"
LRESULT CALLBACK _export ToolbarWndProc(HWND, UINT, WPARAM, LPARAM);
void DrawButton(LPDRAWITEMSTRUCT lpInfo);
void DrawBitmap(HDC hDC, int x, int y, HBITMAP hBitmap);
// Определяем члены статического класса TbMain HBITMAP TbMain::hbmpUp[20]; HBITMAP TbMain::hbmpDown[20]; HBITMAP TbMain::hbmpGrayed[20]; HWND TbMain::hwndParent; HINSTANCE TbMain::hInst; int TbMain::nFirstId = 0;
// ====================================================== // Конструктор класса Toolbar // ====================================================== Toolbar::Toolbar(HINSTANCE hInstance, HWND hwndParentWindow, int nFirstId) { // Сбрасываем признак ошибки errno = 0;
// Сохраняем идентификатор копии приложения, // идентификатор родительского окна, создавшего // TOOLBAR, и идентификатор первой кнопки в // органе управления TOOLBAR TbMain::hInst = hInstance; TbMain::hwndParent = hwndParentWindow; TbMain::nFirstId = nFirstId;
// Определяем размеры внутренней области // родительского окна GetClientRect(TbMain::hwndParent, &rcParent);
// Определяем размеры дочернего окна, которое // будет использовано для создания органа TOOLBAR GetRect();
// Регистрируем класс для дочернего окна TOOLBAR if(!RegisterWndClass()) { errno = 1; return; }
// Создаем дочернее окно TOOLBAR CreateTbWindow();
if(hwndToolbar == NULL) { errno = 2; return; } }
// ====================================================== // Деструктор класса Toolbar // ====================================================== Toolbar::~Toolbar() { // Уничтожаем дочернее окно TOOLBAR DestroyWindow(hwndToolbar);
}
// ====================================================== // Функция окна ToolbarWndProc для дочернего окна TOOLBAR // ======================================================
LRESULT CALLBACK _export ToolbarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { // Передаем сообщение WM_COMMAND от кнопок в // родительское окно case WM_COMMAND: { SendMessage(TbMain::hwndParent, WM_COMMAND, wParam, lParam);
return 0; }
// Это сообщение приходит при изменении состояния // дочернего окна органа управления, когда окно // нужно перерисовать case WM_DRAWITEM: { // Перерисовываем кнопку DrawButton( (LPDRAWITEMSTRUCT)lParam );
break; } } return DefWindowProc(hwnd, msg, wParam, lParam);
}
// ====================================================== // Функция DrawButton // Перерисовывает кнопку // ====================================================== void DrawButton(LPDRAWITEMSTRUCT lpInfo) { HBITMAP hbm;
// Обрабатываем сообщение WM_DRAWITEM // только если оно поступило от кнопки if(lpInfo->
CtlType != ODT_BUTTON) return;
hbm = TbMain::hbmpUp[(lpInfo->
CtlID) - TbMain::nFirstId];
// Если кнопка выбрана, рисуем ее в нажатом // состоянии if (lpInfo->
itemState & ODS_SELECTED) { hbm = TbMain::hbmpDown[(lpInfo->
CtlID) - TbMain::nFirstId]; }
// Если кнопка неактивна, загружаем идентификатор // изображения кнопки в неактивном состоянии else if (lpInfo->
itemState & ODS_DISABLED) { hbm = TbMain::hbmpGrayed[(lpInfo->
CtlID) - TbMain::nFirstId]; }
// При ошибке ничего не рисуем if(!hbm) return;
// Если кнопка выбрана и ее надо целиком // перерисовать, вызываем функцию DrawBitmap if((lpInfo->
itemAction & ODA_DRAWENTIRE) (lpInfo->
itemAction & ODA_SELECT)) { // Рисуем кнопку DrawBitmap(lpInfo->
hDC, (lpInfo->
rcItem).left, (lpInfo->
rcItem).top , hbm);
} }
Конструктор класса Toolbar сбрасывает признак ошибки errno, инициализирует члены класса TbMain, определяет размеры внутренней области родительского окна, размеры дочернего окна, регистрирует класс дочернего окна и создает само дочернее окно.
Работа деструктор заключается в уничтожении дочернего окна, для чего используется функция DestroyWindow.
Функция дочернего окна ToolbarWndProc обрабатывает сообщение WM_COMMAND, поступающее от кнопок, и формирует это же сообщение для дочернего окна. Кроме того, эта функция обеспечивает работу кнопок, для чего в ней предусмотрены обработчик сообщения WM_DRAWITEM.Этот обработчик вызывает функцию DrawButton, предназначенную для рисования кнопок.
Функция DrawButton рисует кнопку в нужном виде, выбирая идентификаторы соответствующих изображений bitmap из массивов, определенных в классе TbMain. Для рисования изображения вызывается функция DrawBitmap (листинг 1.14). Мы уже пользовались этой функцией.