Операционная система Windows 95 для программиста© Александр Фролов, Григорий ФроловТом 22, М.: Диалог-МИФИ, 1993, 271 стр. 2.2. Орган управления StatusbarПроцедура создания органа управления Statusbar намного проще процедуры создания Toolbar . Вы можете создать Statusbar либо с помощью функции CreateWindowEx на основе класса окна STATUSCLASSNAME , либо воспользоваться специально предназначенной для этого функцией CreateStatusWindow. В первом случае вы можете создать Statusbar, например, так: hwndSb = CreateWindowEx( 0L, // расширенный стиль окна STATUSCLASSNAME, // класс окна для Statusbar "", // заголовок окна отсутствует WS_CHILD | WS_BORDER | // стиль окна WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0, // координаты, ширина, высота hWnd, // идентификатор родительского окна (HMENU)IDS_STATUSBAR, // идентификатор Statusbar hInst, // идентификатор приложения NULL ); // доп. данные для окна Обратите внимание на стиль SBARS_SIZEGRIP . Если Statusbar имеет этот стиль, его правый нижний угол принимает вид, показанный на рис. 2.2.
Рис. 2.2. Орган управления Toolbar , имеющий стиль SBARS_SIZEGRIP Во втором случае вы должны вызвать функцию CreateStatusWindow , прототип которой приведен ниже: HWND CreateStatusWindow( LONG style, // стиль окна LPCTSTR lpszText, // текст для первой области Statusbar HWND hwndParent, // идентификатор родительского окна UINT wID // идентификатор Statusbar ); Обычно создание органов управления Statusbar и Toolbar выполняется приложением при обработке функцией главного окна сообщения WM_CREATE. При создании Statusbar вы можете также использовать стиль CCS_TOP . При этом окно Statusbar будет расположено в верхней части родительского окна. Очевидно, этот стиль нельзя комбинировать со стилем SBARS_SIZEGRIP , так как во-первых, такой орган управления будет выглядеть очень странно, а во-вторых, он не будет работать так, как этого ожидает пользователь. Определение режима работы StatusbarОрган управления Statusbar может работать в двух режимах - стандартном и упрощенном. В первом режиме приложение может разделить окно Statusbar на несколько областей для раздельного вывода в эти области текста или графической информации. В упрощенном режиме приложение может выводить в окно Statusbar только текстовую информацию, причем разделение этого окна на несколько областей невозможно. Орган управления Statusbar переводится из стандартного режима в упрощенный и обратно при помощи сообщения SB_SIMPLE , которое мы рассмотрим немного позже. В процессе переключения содержимое области стандартного режима не исчезает, так как соответствующие данных хранятся в разных местах для разных режимов. Разделение Statusbar на областиДля того чтобы разделить Statusbar на несколько областей достаточно сразу после создания послать ему сообщение SB_SETPARTS : SendMessage(hwndSb, SB_SETPARTS, 3, (LPARAM)ptWidth); Через параметр wParam передается количество областей (в нашем примере создается три области). Параметр lParam должен содержать адрес массива ширин областей Toolbar : int ptWidth[3]; // таблица ширин для Statusbar Количество элементов в массиве должно быть равно количеству областей, на которые делится Statusbar. Однако это еще не все. При обработке сообщения WM_SIZE вы должны выполнить повторное определение областей: void WndProc_OnSize(HWND hwnd, UINT state, int cx, int cy) { SendMessage(hwndTb, WM_SIZE, cx, cy); SendMessage(hwndSb, WM_SIZE, cx, cy); ptWidth[0] = cx/2; ptWidth[1] = cx/2 + cx/4; ptWidth[2] = -1; SendMessage(hwndSb, SB_SETPARTS, 3, (LPARAM)ptWidth); return FORWARD_WM_SIZE(hwnd, state, cx, cy, DefWindowProc); } Когда обработчик сообщения WM_SIZE передает сообщение WM_SIZE органам управления Toolbar и Statusbar, они устанавливают размеры своих окон. Затем необходимо подготовить массив ширин областей Statusbar. В элемент массива вы можете записать либо позицию правой границы области от левого края окна Statusbar, либо значение -1. В последнем случае правая граница области простирается до правого края окна Statusbar. Запись текста в область StatusbarДля записи текста в область Statusbar необходимо использовать сообщение SB_SETTEXT : SendMessage(hwndSb,SB_SETTEXT,0, (LPARAM)"Statusbar, Part 1"); SendMessage(hwndSb, SB_SETTEXT,1 | SBT_NOBORDERS, (LPARAM)""); Через параметр wParam передается номер области,
который может быть скомбинирован при помощи
логической операции ИЛИ с одной из констант,
определяющих внешний вид области:
Через параметр lParam передается указатель на строку текста, которая должна быть записана в область. Текстовая строка может быть пустой. Если необходимо выполнить выравнивание текста по центру или по правому краю, вы можете включить в текстовую строку символы табуляции \t. Текст, расположенный после первого символа табуляции, выравнивается по центру, после второго - по правому краю области. Рисование графического изображения в области StatusbarЕсли в сообщении SB_SETTEXT указать константу SBT_OWNERDRAW , родительское окно, создавшее Statusbar, может нарисовать в соответствующей области любое изображение или написать текст любым шрифтом, используя всю мощь графического интерфейса GDI. Ниже мы привели фрагмент кода, который загружает из ресурсов приложения битовое изображение и передает его идентификатор через параметр lParam сообщения SB_SETTEXT . При этом номер области, в которой будет нарисовано это изображения, комбинируется с константой SBT_OWNERDRAW : hSbLogoBmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SBLOGO)); SendMessage(hwndSb, SB_SETTEXT, 2 | SBT_OWNERDRAW, (LPARAM)hSbLogoBmp); Когда область Statusbar должны быть перерисована, родительское окно получает сообщение WM_DRAWITEM . Параметр wParam этого сообщения содержит идентификатор органа управления, которое послало сообщение, или ноль, если сообщение пришло от меню. В нашем случае через wParam будет передаваться идентификатор органа управления Statusbar. Параметр lParam содержит указатель на структуру типа DRAWITEMSTRUCT (описание полей приведено для Statusbar): typedef struct tagDRAWITEMSTRUCT { UINT CtlType; // не используется UINT CtlID; // идентификатор окна Statusbar UINT itemID; // номер области, которая будет перерисована UINT itemAction; // не используется UINT itemState; // не используется HWND hwndItem; // идентификатор окна Statusbar HDC hDC; // идентификатор контекста отобаржения RECT rcItem; // координаты области DWORD itemData; // значение lParam сообщения SB_SETTEXT } DRAWITEMSTRUCT; Обработчик сообщения WM_DRAWITEM должен проверить содержимое поля CtlID - в этом поле должен находится идентификатор Statusbar. Далее обработчик может выполнить рисование, пользуясь контекстом отображения hDC в области, координаты которой передаются через поле rcItem. При этом обработчик сообщения WM_DRAWITEM может воспользоваться содержимым поля itemData, которое равно значению параметра lParam сообщения SB_SETTEXT. Через этот параметр можно передать, например, идентификатор изображения, которое должно быть нарисовано в области Statusbar, идентификатор шрифта, которым должен быть написан текст в этой области или любая другая информация. Ниже мы привели фрагмент исходного текста приложения Smart Application, который рисует в самой правой области Statusbar небольшое графическое изображение: void WndProc_OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT * lpDrawItem) { if(lpDrawItem->CtlID == IDS_STATUSBAR) { LPDRAWITEMSTRUCT lpDis; HDC hdcMem; HBITMAP hbmOld; BITMAP bm; lpDis = (LPDRAWITEMSTRUCT)lpDrawItem; hdcMem = CreateCompatibleDC(lpDis->hDC); hbmOld = SelectObject(hdcMem, hSbLogoBmp); GetObject(hSbLogoBmp, sizeof(bm), &bm); BitBlt(lpDis->hDC, lpDis->rcItem.left, lpDis->rcItem.top, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY); SelectObject(hdcMem, hbmOld); DeleteDC(hdcMem); } return FORWARD_WM_DRAWITEM(hwnd, lpDrawItem, DefWindowProc); } Если вы незнакомы с понятиями контекста отображения, не умеете работать с битовыми графическими изображениями или никогда не пользовались функцией BitBlt, мы рекомендуем вам обратиться к 14 тому "Библиотеки системного программиста", который называется "Графический интерфейс GDI в Microsoft Windows". Если вам нужно нарисовать непрямоугольное или частично прозрачное изображение, недостаточно выбрать в качестве цвета фона цвет окна Statusbar, так как пользователь может легко изменить цветовую гамму оболочки Microsoft Windows 95. В этом случае мы рекомендуем вам использовать более сложные процедуры рисования с использованием растровых операций ROP . Всю необходимую для этого информацию, а также пример приложения (которое называется BMPLOGO) вы найдете в 14 томе "Библиотеки системного программиста". Сообщения для StatusbarВ этом разделе мы перечислим и кратко опишем сообщения, специально предназначенные для работы с органом управления Statusbar. Полную информацию вы сможете найти в справочной системе SDK. SB_SETMINHEIGHTУстановка минимальной высоты области окна Statusbar, которая используется для отображения текста или рисования изображений. wParam = (WPARAM) minHeight; // минимальная высота в пикселах Значение параметра lParam должно быть равно нулю. SB_SETTEXTЗапись текста в заданную область окна Statusbar. wParam = (WPARAM) iPart | uType; // область и тип отображения lParam = (LPARAM) (LPSTR) szText; // адрес строки Через параметр iPart передается номер области. Этот номер может комбинироваться при помощи логической операции ИЛИ с одной из нескольких констант, описанной нами ранее в разделе " Запись текста в область Statusbar". Через параметр szText передается адрес строки текста. Если используется константа SBT_OWNERDRAW, параметр сообщения lParam служит для передачи произвольного 32-разрядного значения, например, идентификатора битового изображения. SB_SETPARTSУстановка количества областей и определение правой границы каждой области. wParam = (WPARAM) nParts; // количество областей lParam = (LPARAM) (LPINT) aWidths; // границы Это сообщение мы подробно описали в разделе " Разделение Statusbar на области". SB_SIMPLEПереключение органа Statusbar из стандартного режима в упрощенный и обратно. wParam = (WPARAM) (BOOL); // флаг режима Параметр lParam должен быть равен нулю. Если флаг fSimple принимает значение TRUE, Statusbar переключается в упрощенный режим. если FALSE - возвращается в стандартный режим. Отметим, что в упрощенном режиме родительское окно не может рисовать в единственной области окна Statusbar. Поэтому упрощенный режим пригоден только для отображения текстовых сообщений. SB_GETBORDERSОпределение ширины горизонтальной и вертикальной рамки окна Statusbar. lParam = (LPARAM) (LPINT) aBorders; // адрес массива Параметр wParam должен быть равен нулю. Перед тем как послать окну Statusbar сообщение SB_GETBORDERS, вы должны подготовить массив из трех переменных типа int. В первый элемент массива будет записана ширина горизонтальной рамки, во второй - ширина вертикальной рамки, и в третий - ширина рамки между прямоугольниками. SB_GETPARTSОпределение количества областей в окне состояния и координат правых границ этих областей. wParam = (WPARAM) nParts; // количество областей lParam = (LPARAM) (LPINT) aRightCoord; // массив координат Через параметр nParts передается количество областей, информация о координатах правых границ которых записывается в массив aRightCoord. Функция SendMessage, пославшая сообщение SB_GETPARTS, возвращает количество существующих в окне Statusbar областей или нуль при ошибке. SB_GETRECTОпределение границ заданной области в окне Statusbar. wParam = (WPARAM) iPart; // номер области lParam = (LPARAM) (LPRECT) lprc; // границы области Границы области, номер которой задан через параметр iPart, передается приложению через структуру типа RECT. Адрес этой структуры должен быть указан в параметре lprc перед посылкой сообщения. SB_GETTEXTИзвлечение текста из заданной области Statusbar. wParam = (WPARAM) iPart; // номер области lParam = (LPARAM) (LPSTR) szText; // адрес буфера для текста Функция SendMesage возвращает в младшем 16-разрядном слове длину текста, в старшем, константу 0, SBT_NOBORDERS, SBT_POPOUT или SBT_RTLREADING. Если родительское окно само рисует внутри области при обработке сообщения WM_DRAWITEM, возвращается 32-разрядное значение, которое было передано при посылке сообщения SB_SETTEXT. Перед тем как извлекать текст из области Statusbar, необходимо определить размер буфера для записи соответствующей текстовой строки. Это можно сделать при помощи сообщения SB_GETTEXTLENGTH, описанного ниже. SB_GETTEXTLENGTHОпределение длины строки для заданной области окна Statusbar. wParam = (WPARAM) iPart; // номер области Значение параметра lParam должно быть равно нулю. Функция SendMesage возвращает точно такое же значение, как и для сообщения SB_GETTEXT. |