
- •Уп. 5. Панель инструментов и строка состояния
- •5.1. Панель инструментов
- •5.1.1. Создание панели инструментов
- •5.1.2. Управление состоянием кнопок панели
- •5.1.3. Вывод подсказок в панели инструментов
- •5.2. Строка состояния
- •5.2.1. Создание строки состояния
- •5.2.2. Сообщения о меню в строке состояния
- •Контрольные вопросы
- •Упражнения
5.2. Строка состояния
Строку состояния используют для отображения текстов о текущем состоянии приложения. Функции для работы со строкой состояния, как и функции для работы с панелью инструментов, объявлены в файле commctrl.h и описаны в файле comctl32.dll.
5.2.1. Создание строки состояния
Для создания окна строки состояния вызывают специальную функцию CreateStatusWindow:
HWND CreateStatusWindow(
LONG style,
LPCTSTR lpszText,
HWND hwndParent,
UINT wID);
Она в нижней части окна hwndParent создает окно строки состояния и возвращает его дескриптор.
Параметры:
style – стиль окна строки состояния. Обязательно содержит комбинацию стилей WS_CHILD | WS_VISIBLE.
lpszText – указатель на текст, изначально отображаемый в строке состояния, может быть равен NULL.
hwndParent – дескриптор родительского окна.
wID – идентификатор окна строки состояния. Процедура окна использует wID для идентификации сообщений от строки состояния.
Задача. Создать строку состояния из трех секций. При нажатии левой и правой клавиш мыши в секциях отображать различный текст.
Листинг 5.4. Приложение со строкой состояния
#include <windows.h>
#include <commctrl.h>
#pragma comment (lib, "comctl32.lib")
#define ID_STATUS 200
BOOL RegClass(WNDPROC, LPCTSTR, UINT);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE hInstance;
TCHAR szClass[] = TEXT("StatusClass");
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
MSG msg;
HWND hMainWnd;
hInstance = hInst;
if (!RegClass(WndProc, szClass, COLOR_WINDOW)) return FALSE;
hMainWnd = CreateWindow(szClass, TEXT("Строка состояния"), WS_VISIBLE | WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, NULL);
if (!hMainWnd) return FALSE;
while (GetMessage(&msg, 0, 0, 0)) DispatchMessage(&msg);
return msg.wParam;
}
BOOL RegClass(WNDPROC Proc, LPCTSTR szName, UINT brBackground)
{
WNDCLASS wc;
wc.style = wc.cbClsExtra = wc.cbWndExtra = 0;
wc.lpfnWndProc = Proc;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(brBackground + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = szName;
return (RegisterClass(&wc) != 0);
}
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND hStatus;
static int pParts[3];
static short cx;
switch (msg)
{
case WM_SIZE:
{
MoveWindow(hStatus, 0, 0, 0, 0, TRUE);
cx=LOWORD(lParam);
pParts[0]=cx-200;
pParts[1]=cx-100;
pParts[2]=cx;
SendMessage(hStatus, SB_SETPARTS, 3, (LPARAM)pParts);
return 0;
}
case WM_CREATE:
{ hStatus = CreateStatusWindow(WS_CHILD | WS_VISIBLE, TEXT("Готово"), hwnd, ID_STATUS); return 0; }
case WM_LBUTTONDOWN:
{
SendMessage(hStatus, SB_SETTEXT, 0, (LONG)TEXT("Первая секция строки состояния"));
SendMessage(hStatus, SB_SETTEXT, 1, (LONG)TEXT("Сообщение 2"));
SendMessage(hStatus, SB_SETTEXT, 2, (LONG)TEXT("Сообщение 3"));
return 0;
}
case WM_RBUTTONDOWN:
{
SendMessage(hStatus, SB_SETTEXT, 0, (LONG)TEXT("Сообщение 1"));
SendMessage(hStatus, SB_SETTEXT, 1, (LONG)TEXT("Нет сообщения"));
SendMessage(hStatus, SB_SETTEXT, 2, (LONG)TEXT(""));
return 0;
}
case WM_DESTROY: { PostQuitMessage(0); return 0; }
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
Проанализируем это приложение.
Функция окна приложения содержит описания дескриптора для окна строки статуса hStatus и массива pParts:
static HWND hStatus;
static int pParts[3];
Массив pParts нужен для разбиения окна строки состояния на 3 секции (имя массива и количество секций могут быть другими).
На этапе создания окна приложения создают и окно строки состояния:
hStatus = CreateStatusWindow(WS_CHILD | WS_VISIBLE,
"Готово", hwnd, ID_STATUS);
Здесь второй аргумент "Готово" будет по умолчанию отображен в первой секции. Этот аргумент может быть указан как NULL. Тогда строка состояния изначально не содержит никакого текста.
При любых изменениях размеров окна перемещают окно строки состояния:
MoveWindow( hStatus, 0, 0, 0, 0, TRUE);
Как и в случае панели инструментов, все координаты перемещения могут быть равны нулю. Предопределенная функция окна строки состояния всегда размещает строку состояния в нижней части рабочей области родительского окна. Ширина строки состояния при этом равна ширине рабочей области.
Далее определены координаты правых границ секций:
cx = LOWORD(lParam);
pParts[0] = cx-200;
pParts[1] = cx-100;
pParts[2] = cx;
Например, правая граница первой секции равна сх-200. Окну строки состояния сообщают о количестве и правых границах секций:
SendMessage( hStatus, SB_SETPARTS, 3, (LPARAM)pParts);
После нажатия левой клавиши мыши над рабочей областью окна приложения во все секции строки состояния записывают тексты сообщений: "Первая секция строки состояния", "Сообщение 2" и "Сообщение 3":
SendMessage( hStatus, SB_SETTEXT, 0,
(LONG)"Первая секция строки состояния");
SendMessage( hStatus, SB_SETTEXT, 1, (LONG)"Сообщение 2");
SendMessage( hStatus, SB_SETTEXT, 2, (LONG)"Сообщение 3");
Здесь третий аргумент вызова функции SendMessage равен номеру секции. Причем номер первой секции равен 0.
Аналогично обрабатывают нажатие правой клавиши мыши.