Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
УП02_Органы управления.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
576 Кб
Скачать

2.3.6. Пример обработки сообщений от полос прокрутки

Задача. В окне приложения создать две полосы прокрутки (горизонтальную и вертикальную) для управления размерами двух прямоугольников (черного по горизонтали и темно-серого по вертикали).

Решение данной задачи полностью происходит в функции окна приложения, представленного листингом 2.4.

Листинг 2.4. Полоса прокрутки – орган управления

#include <windows.h>

BOOL RegClass(WNDPROC, LPCTSTR, UINT);

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

HINSTANCE hInstance;

TCHAR szClassName[] = TEXT("ScrollClass");

TCHAR szTitle[] = TEXT("Полоса прокрутки – орган управления");

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow)

{

MSG msg;

HWND hwnd;

hInstance = hInst;

if (!RegClass(WndProc, szClassName, COLOR_WINDOW))

return FALSE;

if (!(hwnd = CreateWindow(szClassName, szTitle, WS_OVERLAPPEDWINDOW, 194, 50, 246, 350, 0, 0, hInstance, NULL)))

return FALSE;

ShowWindow(hwnd, SW_SHOWNORMAL);

UpdateWindow(hwnd);

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 = (LPCTSTR)NULL;

wc.lpszClassName = szName;

return (RegisterClass(&wc) != 0);

}

LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )

{

static HWND hxScroll, hxStatic, hyScroll, hyStatic;

static int nxPos, nxMin, nxMax, nyPos, nyMin, nyMax;

switch (msg)

{

case WM_CREATE:

{

hxScroll = CreateWindow(TEXT("scrollbar"), NULL,

WS_CHILD | WS_VISIBLE | SBS_HORZ,

20, 60, 200, 25, hwnd, (HMENU)-1, hInstance, NULL);

nxPos = 100; nxMin = 1; nxMax = 200;

SetScrollRange(hxScroll, SB_CTL, nxMin, nxMax, TRUE);

SetScrollPos(hxScroll, SB_CTL, nxPos, TRUE);

hxStatic = CreateWindow(TEXT("static"), NULL,

WS_CHILD | WS_VISIBLE | SS_BLACKRECT,

20, 40, nxPos, 15, hwnd, (HMENU)-1, hInstance, NULL);

hyScroll = CreateWindow(TEXT("scrollbar"), NULL,

WS_CHILD | WS_VISIBLE | SBS_VERT,

20, 100, 90, 200, hwnd, (HMENU)-1, hInstance, NULL);

nyPos = 100; nyMin = 1; nyMax = 200;

SetScrollRange(hyScroll, SB_CTL, nyMin, nyMax, TRUE);

SetScrollPos(hyScroll, SB_CTL, nyPos, TRUE);

hyStatic = CreateWindow(TEXT("static"), NULL,

WS_CHILD | WS_VISIBLE | SS_GRAYRECT,

130,100, 90, nyPos, hwnd, (HMENU)-1, hInstance, NULL);

return 0;

}

case WM_HSCROLL:

{

switch (LOWORD(wParam))

{

case SB_PAGERIGHT: { nxPos+=10; break; }

case SB_LINERIGHT: { nxPos+=1; break; }

case SB_PAGELEFT: { nxPos-=10; break; }

case SB_LINELEFT: { nxPos-=1; break; }

case SB_TOP: { nxPos = nxMin; break; }

case SB_BOTTOM: { nxPos = nxMax; break; }

case SB_THUMBPOSITION:

case SB_THUMBTRACK: { nxPos = HIWORD(wParam); break; }

default: break;

}

if (nxPos > nxMax) nxPos = nxMax;

if (nxPos < nxMin) nxPos = nxMin;

SetScrollPos(hxScroll, SB_CTL, nxPos, TRUE);

if (nxPos==nxMax)

EnableScrollBar(hxScroll, SB_CTL, ESB_DISABLE_RIGHT);

MoveWindow(hxStatic, 20,40, nxPos, 15, TRUE);

return 0;

}

case WM_VSCROLL:

{

switch (LOWORD(wParam))

{

case SB_PAGERIGHT: { nyPos+=10; break; }

case SB_LINERIGHT: { nyPos += 1; break; }

case SB_PAGELEFT: { nyPos-=10; break; }

case SB_LINELEFT: { nyPos-=1; break; }

case SB_TOP: { nyPos = nyMin; break; }

case SB_BOTTOM: { nyPos = nyMax; break; }

case SB_THUMBPOSITION:

case SB_THUMBTRACK: { nyPos = HIWORD(wParam); break; }

default: break;

}

if (nyPos > nyMax) nyPos = nyMax;

if (nyPos < nyMin) nyPos = nyMin;

SetScrollPos(hyScroll, SB_CTL, nyPos, TRUE);

MoveWindow(hyStatic, 130,100, 90, nyPos, TRUE);

return 0;

}

case WM_DESTROY: { PostQuitMessage(0); return 0;}

}

return DefWindowProc(hwnd, msg, wParam, lParam);

}

На этапе создания окна приложения создают горизонтальную полосу прокрутки нестандартных размеров и без идентификатора:

hxScroll = CreateWindow("scrollbar", NULL,

WS_CHILD | WS_VISIBLE | SBS_HORZ,

20, 60, 200, 25, hwnd, (HMENU)-1, hInstance, NULL);

Далее устанавливают диапазон перемещения и начальную позицию ползунка:

nxPos = 100;

nxMin = 1;

nxMax = 200;

SetScrollRange(hxScroll, SB_CTL, nxMin, nxMax, TRUE);

SetScrollPos(hxScroll, SB_CTL, nxPos, TRUE);

Затем создают статический орган – закрашенный прямоугольник черного цвета с шириной, равной позиции nxPos ползунка:

hxStatic = CreateWindow("static", NULL,

WS_CHILD | WS_VISIBLE | SS_BLACKRECT,

20, 40, nxPos, 15, hwnd, (HMENU)-1, hInstance,NULL);

Таким же образом создают вертикальную полосу прокрутки и прямоугольник темно-серого цвета.

После запуска приложения на экране появится окно, в рабочей области которого расположены элементы hxStatic, hxScroll, hyScroll и hyStatic (рис. 2.3).

Рис. 2.3. Пример управления полосами прокрутки

Рассмотрим, как работает горизонтальная полоса прокрутки.

При нажатии на кнопку на левом конце полосы поступает сообщение WM_HSCROLL с кодом SB_LINELEFT. При обработке этого сообщения значение nxPos уменьшается на единицу:

nxPos -= 1;

Далее ползунок устанавливают в новую позицию nxPos:

SetScrollPos(hxScroll, SB_CTL, nxPos, TRUE);

и перемещают черный прямоугольник – у окна hxScroll изменяют ширину:

MoveWindow(hxStatic, 20, 40, nxPos, 15, TRUE);

Так же обрабатывают и другие сообщения. Разница лишь в том, что при нажатии на область между кнопкой и ползунком происходит "постраничное" перелистывание – значение nxPos изменяется на 10. При плавном перемещении ползунка поступает сообщение с кодом SB_THUMBTRACK и текущая позиция определяется через старшее слово параметра wParam: nxPos = HIWORD(wParam). После плавной установки ползунка код действия равен SB_THUMBPOSITION и текущая позиция определяется через старшее слово параметра wParam: nxPos = HIWORD(wParam)

В текст включен пример блокирования правой кнопки горизонтальной полосы прокрутки:

if (nxPos==nxMax)

EnableScrollBar(hxScroll, SB_CTL, ESB_DISABLE_RIGHT);

Правая кнопка этой полосы блокируется при достижении крайней правой позиции, и нажатие на эту кнопку не вызывает никакой реакции. Вызов другой функции для этой полосы отменяет блокировку.

Параметры nxPos, nxMin и nxMax, а также шаг изменения значения nxPos на "позицию" или на "страницу" разработчик задает, исходя из потребностей решаемой задачи. В примере эти параметры выбраны с целью наглядного изменения размеров статических органов. В других задачах эти параметры могут быть другими. Например, значение "позиции" может быть равно средней ширине или высоте одного символа установленного шрифта при просмотре документов в окне.

Обработка сообщений от вертикальной полосы прокрутки происходит точно так же.