КАК использовать строку состояния?

Итак, что же такое строка состояния? Это небольшое окно, занимающее нижнюю часть главного окна приложения. В большинстве программ под управлением Windows имеется строка состояния. В программе Microsoft Internet Explorer в строке состояния отображаются текущие данные открытия Web-страничек. Когда страничка полностью загружена, в строке состояния пишется: "Готово". Когда вы наводите мышь на гиперссылку, текст в строке меняется на текст этой ссылки. Некоторые Web-программисты пишут на языках Java и Java Script небольшие шалости - например бегущая строка, в которое бегут процентики и надпись: "Форматирование винчестера: 50% завершено". И число процентов быстро возрастает.
Кроме того, часто в программах, предназначенных для длительного использования - например в текстовых редакторах, часто в строке состояние показана текущая дата, время и день недели.
В строке состояния также можно отображать маленькие иконки, подсказки и многое другое.
Для удобства использования строки состояния вы можете разделить её на секции. Например при работе с файлами вы можете в одной секции указывать размер файла, а в другое - оставшееся свободное место на диске.
Стиль секций также может меняться. Текст может быть как вдавленным, так и выпуклым.
При перемещении главного окна, строка состояния должна перемещаться вместе с ним и изменять размеры вместе с ним, растягиваясь или сужаясь.


Что можно делать со строкой состояния?

1. Создание строки
HWND CreateStatusWindow(LONG style, LPCSTR lpszText,
HWND hwndParent, UINT wID);

style - стиль окна
lpszText - указатель на текст в окне
hwndParent - родительское окно
wID - идентификатор строки состояния



2. Разделение строки на секции. Для разделение строки состояния на секции, нужно создать массив с размерами разделителей:
int pParts[3];

cx=LOWORD(lParam);

pParts[0]=cx-200;
pParts[1]=cx-100;
pParts[2]=cx;


Потом мы посылаем сообщение SB_SETPARTS с указанием количества разделителей и массива их длин.

SendMessage(hStatus, SB_SETPARTS, 3, (LPARAM)pParts);

3. Для вывода текста в строку состояния
нужно послать сообщение SB_SETTEXT с указанием ячейки (третий аргумент) и текста.
SendMessage(hStatus, SB_SETTEXT, 1, (LONG)Buf);

Итак, в путь!
1. Создайте новый проект типа Win32 Application. Назовите проект Status и нажмите Ок. В следующем окне выберите "A typical Hello World Application". Нажмите Finish. Ок.
2. В нашей программе в строке состояния, поделенной на секции будут отображаться текущая дата и время. Для этого разделим строку состояния на три части. Текущие дату и время мы будем получать каждую секунду с помощью системного таймера и функции GetLocalTime().
3. Добавьте в список заголовочных файлов файл commctrl.h - библиотеку общих элементов управления.
4. Выберите в меню Project->Add to Project->Files.... Укажите в окне "Открыть" файл comctl32.lib, находящийся в папке: ...\Microsoft Visual Studio\VC98\Lib\. В списке файлов должен появиться новый файл - статическая библиотка общих элементов управления
5. В начале исходного кода программы добавьте макроопределение идентификатора строки состояния:

#define ID_STATUS 200

6. В функции окна объявим следующие переменные:

static HWND hStatus; //идентификатор окна строки состояния
static int pParts[3]; //массив частей строки состояния
static short cx; //вспомогательная переменная для вычисления координат

SYSTEMTIME st; //структура системной даты и времени
int day, month, year, sec, min, hour; //вспомогательные переменные
char Buf[256]; //строковый буфер

7. Для создания строки состояния в обработчике сообщения WM_CREATE запишем:

hStatus=CreateStatusWindow(WS_CHILD|WS_VISIBLE, " ", hWnd, ID_STATUS);

Эта строка создаёт новое дочернее окно - строку состояния, родительским окном которого является окно hWnd, а идентификатор ID_STATUS, объявленный выше.
Далее мы посылаем окну сообщение SB_SETTEXT, чтобы записать в первую секцию слово "Готово".

SendMessage(hStatus, SB_SETTEXT, 0, (LONG)"Готово");

Здесь же надо инициализировать таймер.

SetTimer(hWnd, 1, 1000, NULL);

Здесь мы создали таймер, родительским окном которого является hWnd, идентификатор 1, период 1000 мс или 1 сек. Так как часы изменяют своё время с периодичностью в 1 сек, следует задать именно этот период. Но если вы не хотите, чтобы часы мигали каждую секунду, отвлекая и раздражая, можете изменить период на 3-5 сек.


case WM_CREATE:
hStatus=CreateStatusWindow(WS_CHILD|WS_VISIBLE, "Готово", hWnd, ID_STATUS);
SendMessage(hStatus, SB_SETTEXT, 0, (LONG)"Готово");
SetTimer(hWnd, 1, 1000, NULL);

break;

8. Но такая строка состояния будет существовать отдельной жизнью от главного окна. Кроме того, мы не разделали её на части. Вставим в обработчик сообщения WM_SIZE - изменение размеров главного окна функцию MoveWindow, которая будет старательно перемещать строку состояния вслед за главным окном.

MoveWindow(hStatus, 0,0,0,0, TRUE);

Дальше мы узнаем ширину главного окна:

cx=LOWORD(lParam);

Занесём в массив pParts координаты секций, на которые поделим строку состояния.

pParts[0]=cx-130;
pParts[1]=cx-60;
pParts[2]=cx;


Для разделения строки состояния на 3 перегородки, пошлём окну сообщение SB_SETPARTS. Массив pParts - параметры перегородок.
SendMessage(hStatus, SB_SETPARTS, 3, (LPARAM)pParts);

//Измененеи размеров окна
case WM_SIZE:
MoveWindow(hStatus, 0,0,0,0, TRUE);
cx=LOWORD(lParam);
pParts[0]=cx-130;
pParts[1]=cx-60;
pParts[2]=cx;
SendMessage(hStatus, SB_SETPARTS, 3, (LPARAM)pParts);

break;

9. Уже почти всё готово. Только наша строка не знает, который сейчас час. Напишем обработчик сообщения
WM_TIMER.
У нас уже создан экземпляр структуры SYSTEMTIME.

SYSTEMTIME st;

Функция GetLocalTime заполняет эту структуру текущими и датой и временем на момент своего вызова.

GetLocalTime(&st);

Запишем в наши переменные значения этих полей:

day=st.wDay;
month=st.wMonth;
year=st.wYear;
hour=st.wHour;
min=st.wMinute;
sec=st.wSecond;

Запишем в буфер эти значения и запишем в секцию текст буфера:

sprintf(Buf, "%02d:%02d:%02d", day, month, year);
SendMessage(hStatus, SB_SETTEXT, 1, (LONG)Buf);


Вот, как выглядит этот обработчик целиком:

case WM_TIMER:
GetLocalTime(&st);
day=st.wDay;
month=st.wMonth;
year=st.wYear;
hour=st.wHour;
min=st.wMinute;
sec=st.wSecond;

sprintf(Buf, "%02d:%02d:%02d", day, month, year);
SendMessage(hStatus, SB_SETTEXT, 1, (LONG)Buf);

sprintf(Buf, "%02d:%02d:%02d", hour, min, sec);
SendMessage(hStatus, SB_SETTEXT, 2, (LONG)Buf);

break;

10. Удалите обработчик сообщения WM_PAINT, который нам не потребуется.
11. Вот, как выглядит функция окна целиком:

//Функция окна
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

static short cx; //вспомогательная переменная
static int pParts[3]; //массив частей строки состояния
static HWND hStatus; //идентификатор окна
SYSTEMTIME st; //экземпляр структуры
int day, month, year, sec, min, hour; //переменные даты и времени
char Buf[256]; //строковый буфер


switch (message)
{

//Изменение размеров окна
case WM_SIZE:
MoveWindow(hStatus, 0,0,0,0, TRUE);
cx=LOWORD(lParam);
pParts[0]=cx-130;
pParts[1]=cx-60;
pParts[2]=cx;
SendMessage(hStatus, SB_SETPARTS, 3, (LPARAM)pParts);

break;

case WM_CREATE:
hStatus=CreateStatusWindow(WS_CHILD|WS_VISIBLE, "Готово", hWnd, ID_STATUS);
SendMessage(hStatus, SB_SETTEXT, 0, (LONG)"Готово");
SetTimer(hWnd, 1, 1000, NULL);
break;

case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);

//Обработка элементов меню
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;

//Сообщение таймера
case WM_TIMER:
GetLocalTime(&st);
day=st.wDay;
month=st.wMonth;
year=st.wYear;
hour=st.wHour;
min=st.wMinute;
sec=st.wSecond;

sprintf(Buf, "%02d:%02d:%02d", day, month, year);
SendMessage(hStatus, SB_SETTEXT, 1, (LONG)Buf);

sprintf(Buf, "%02d:%02d:%02d", hour, min, sec);
SendMessage(hStatus, SB_SETTEXT, 2, (LONG)Buf);

break;

case WM_DESTROY:
PostQuitMessage(0);
KillTimer(hWnd,1);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}


12. Запустите программу!

 

Назад Главная Вперёд

Сайт управляется системой uCoz