Файл smartpad/toolbar.hpp
#include <windows.h>
#include <windowsx.h>
#include <mem.h>
// Прототип функции окна TOOLBAR LRESULT CALLBACK _export ToolbarWndProc(HWND, UINT, WPARAM, LPARAM);
// ====================================================== // Определение класса TbMain // ====================================================== class TbMain { public: // Идентификатор приложения static HINSTANCE hInst;
// Идентификаторы кнопок в различном состоянии static HBITMAP hbmpUp[20]; // исходное состояние static HBITMAP hbmpDown[20]; // нажатые static HBITMAP hbmpGrayed[20]; // заблокированные
// Идентификатор родительского окна, создавшего TOOLBAR static HWND hwndParent;
// Идентификатор первой кнопки в TOOLBAR static int nFirstId; };
// ====================================================== // Определение класса Toolbar // ====================================================== class Toolbar { RECT rcParent; // размеры родительского окна RECT rcToolbar; // размеры TOOLBAR ATOM aWndClass; // атом для кода возврата char szClassName[20]; // имя класса HWND hwndToolbar; // идентификатор окна TOOLBAR HWND hButton[20]; // идентификаторы кнопок int errno; // код ошибки
public:
// ====================================================== // Вычисление размеров окна TOOLBAR // ====================================================== void GetRect(void) { rcToolbar.left = GetRectLeft();
rcToolbar.top = GetRectTop();
rcToolbar.right = GetRectRihgt();
rcToolbar.bottom = GetRectBottom();
}
// ====================================================== // Регистрация класса для окна TOOLBAR // ====================================================== virtual BOOL RegisterWndClass(void) { WNDCLASS wc; // структура для регистрации класса окна
memset(&wc, 0, sizeof(wc));
wc.style = 0; wc.lpfnWndProc = (WNDPROC) ToolbarWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = TbMain::hInst; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszMenuName = (LPSTR)NULL;
// Определяем кисть для закрашивания окна wc.hbrBackground = GetBrush();
// Имя класса lstrcpy(szClassName, "FrolovAVToolBar");
wc.lpszClassName = (LPSTR)szClassName;
// Регистрация класса aWndClass = RegisterClass(&wc);
return (aWndClass != 0);
}
// ====================================================== // Создание дочернего окна, которое будет использоваться // для размещения кнопок TOOLBAR // ====================================================== void CreateTbWindow(void) { hwndToolbar = CreateWindow( szClassName, // имя класса окна NULL, // заголовок окна WS_CHILDWINDOW | WS_VISIBLE, // стиль окна rcToolbar.left, // указываем расположение rcToolbar.top, // и размеры окна rcToolbar.right, rcToolbar.bottom, TbMain::hwndParent, // идентификатор родительского окна 0, // идентификатор меню TbMain::hInst, // идентификатор приложения NULL);
// указатель на дополнительные параметры }
// ====================================================== // Устанавливаем ширину окна TOOLBAR // ====================================================== void SetWidth(int nWidth) { RECT rcOld;
GetClientRect(hwndToolbar, &rcOld);
MoveWindow(hwndToolbar, rcOld.left, rcOld.top, nWidth, rcOld.bottom, TRUE);
}
// ====================================================== // Вставляем кнопку в TOOLBAR // ====================================================== BOOL InsertButton(UINT nPosition, LPCSTR lpszBmpUp, LPCSTR lpszBmpDown, LPCSTR lpszBmpGrayed) { // Загружаем указанные в параметрах функции изображения TbMain::hbmpUp[nPosition] = LoadBitmap(TbMain::hInst, lpszBmpUp);
TbMain::hbmpDown[nPosition] = LoadBitmap(TbMain::hInst, lpszBmpDown);
TbMain::hbmpGrayed[nPosition] = LoadBitmap(TbMain::hInst, lpszBmpGrayed);
// Создаем орган управления - кнопку, которую // рисует родительское окно. В нашем случае это будет // окно TOOLBAR hButton[nPosition] = CreateWindow("button", NULL, WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, GetBtnX(nPosition), // определяем расположение кнопки GetBtnY(nPosition), // исходя из ее номера GetBmpWidth(), // ширина кнопки GetBmpHeigt(), // высота кнопки hwndToolbar, // родительское окно для кнопки
// Идентификатор кнопки (HMENU)(nPosition + TbMain::nFirstId),
TbMain::hInst, NULL);
return TRUE; }
// ====================================================== // Конструктор для класса Toolbar // ====================================================== Toolbar( HINSTANCE hInst, HWND hwndParent, int nFirstid);
// ====================================================== // Деструктор для класса Toolbar // ====================================================== ~Toolbar();
// Проверка признака ошибки int Error(void) { return errno; }
// Определение координат окна TOOLBAR virtual int GetRectLeft(void) { return 0; } virtual int GetRectTop(void) { return 0; } virtual int GetRectRihgt(void) { return rcParent.right; } virtual int GetRectBottom(void) { return 26; }
// Определение кисти для окна TOOLBAR virtual HBRUSH GetBrush(void) { return GetStockBrush(LTGRAY_BRUSH);
}
// Определение расположения кнопки исходя из ее номера virtual int GetBtnX(int nPosition) { return 3 + (nPosition * 30);
}
virtual int GetBtnY(int nPosition) { return 3; }
// Определение размеров кнопки virtual int GetBmpWidth(void) { return 30; } virtual int GetBmpHeigt(void) { return 20; } };
В этом файле определен также класс TbMain, все члены которого описаны как статические. Такой класс можно использовать вместо набора глобальных переменных, что улучшает структуру программы.
В классе TbMain хранится идентификатор приложения hInst, три массива, в которых хранятся идентификаторы изображений bitmap для кнопок в исходном (hbmpUp), нажатом (hbmpDown) и заблокированном (hbmpGrayed) состоянии, идентификатор родительского окна, на поверхности которого создается Toolbar, идентификатор самой левой кнопки в окне Toolbar (nFirstId). Все перечисленные выше переменные должны быть доступны для методов класса Toolbar и для функции окна Toolbar.
В классе Toolbar определены переменные, предназначенные для хранения размеров родительского окна и окна Toolbar, имени класса Toolbar, идентификаторов кнопок, кода ошибки.
Метод GetRect предназначен для определения размеров дочернего окна Toolbar, на поверхности которого создаются кнопки. Этот метод вызывает функции GetRectLeft, GetRectTop, GetRectRight, GetRectBottom, определяющие соответственно расположение левой, верхней, правой и нижней границ дочернего окна.
Вы можете создать свой класс как дочерний для класса Toolbar и переопределить все или некоторые из перечисленных функций, создав, например, вертикальный Toolbar.
Метод RegisterWndClass регистрирует класс для дочернего окна Toolbar. Этот метод использует функцию GetBrush для определения кисти, используемой для закраски поверхности дочернего окна. В классе Toolbar используется светло-серая кисть. Создавая собственный класс на базе класса Toolbar вы можете переопределить функцию GetBrush и закрасить поверхность дочернего окна в любой цвет.
Метод CreateTbWindow создает дочернее окно Toolbar. Перед вызовом этого метода необходимо с помощью метода GetRect определить размеры и расположение дочернего окна органа управления Toolbar.
Для того чтобы при изменении размеров основного окна обеспечить соответствующее изменение размеров окна Toolbar, в классе Toolbar определен метод SetWidth. Единственный параметр nWidth должен содержать значение новой ширины окна. Метод SetWidth необходимо вызывать из функции главного окна приложения (или другого окна, на поверхности которого расположен Toolbar) при обработке сообщения WM_SIZE.
Если вы создаете вертикальный Toolbar, вы можете определить в своем классе, созданном на базе класса Toolbar, функцию SetHeight, изменяющую высоту дочернего окна Toolbar.
Для вставки в Toolbar кнопки вы должны вызвать метод InsertButton.
Параметр NPosition определяет расположение кнопки на поверхности Toolbar и идентификатор кнопки, передаваемый в родительское окно через параметр wParam сообщения WM_COMMAND. Идентификатор кнопки зависит от расположения кнопки в окне Toolbar и определяется при помощи следующего выражения:
nPosition + TbMain::nFirstId
Таким образом, самой левой кнопке в горизонтальном органе управления Toolbar соответствует идентификатор TbMain::nFirstId, значение которого вы задаете при вызове конструктора класса Toolbar:
Toolbar( HINSTANCE hInst, HWND hwndParent, int nFirstid);
Дополнительно вы должны указать конструктору идентификатор текущей копии приложения hInst и идентификатор родительского окна, на поверхности которого расположен Toolbar. Определение конструктора и деструктора класса Toolbar находится в файле toolbar.cpp (листинг 1.13).
Среди других методов, определенных в классе Toolbar, отметим метод GetBtnX. Этот метод используется для вычисления X-координаты кнопки в окне Toolbar в зависимости от ее номера. Если вы создаете свой Toolbar на базе класса Toolbar, вы можете использовать другой алгоритм размещения кнопок, переопределив эту функцию, а также функцию GetBtnY, предназначенную для вычисления Y-координаты кнопки.
По умолчанию для кнопок используются изображения bitmap размером 30 х 20 пикселов. Если вам нужны кнопки другого размера, переопределите методы GetBmpWidth и GetBmpHeight.
В файле toolbar.cpp (листинг 1.13) находятся определения некоторых методов класса Toolbar, членов класса TbMain и функции дочернего окна Toolbar.