Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming_Windows_95_Part_I.pdf
Скачиваний:
96
Добавлен:
05.06.2014
Размер:
4.61 Mб
Скачать

270

стилями SS_ETCHEDHORZ, SS_ETCHEDVERT или SS_ETCHEDFRAME для создания рамки с тенью, состоящей из серого и белого цветов.)

Статический класс также включает в себя три стиля текста: SS_LEFT, SS_RIGHT и SS_CENTER. Они предназначены для выравнивания текста соответственно по левому краю, по правому краю и по центру. Текст задается в параметре текста окна функции CreateWindow, и позднее он может быть изменен с помощью функции SetWindowText. Когда оконная процедура кнопки управления статического класса выводит на экран этот текст, она использует функцию

DrawText с параметрами DT_WORDBREAK, DT_NOCLIP и DT_EXPANDTABS. Текст помещается внутрь прямоугольника дочернего окна.

Фоном дочерних окон этих трех стилей обычно является COLOR_BTNFACE, а самого текста — COLOR_WINDOWTEXT. Вы можете обрабатывать сообщения WM_CTLCOLORSTATIC для изменения цвета текста с помощью вызова функции SetTextColor, а для изменения цвета фона текста — с помощью вызова функции SetBkColor, возвращая при этом описатель кисти фона. Это будет вскоре продемонстрировано в программе

COLORS1.

И наконец, статический класс также содержит стили окна SS_ICON и SS_USERITEM. Однако, эти стили не имеют смысла при использовании в качестве дочерних окон управления. К этим стилям мы вернемся при изучении окон диалога.

Класс полос прокрутки

Когда в главе 3 при написании программ серии SYSMETS, мы впервые коснулись темы полос прокрутки (scrollbar), там говорилось о некоторых отличиях между "полосами прокрутки окна" и "полосами прокрутки — элементами управления". В SYSMETS использовались полосы прокрутки окна, которые появлялись в правой и нижней частях окна. Вы добавляете к окну при его создании полосы прокрутки путем включения в стиль окна идентификаторов WS_VSCROLL или WS_HSCROLL, или обоих сразу. Теперь мы готовы создать некие полосы прокрутки, которые являются дочерними окнами управления, и которые могут располагаться в любом месте рабочей области родительского окна. Вы создаете полосы прокрутки, являющиеся дочерними окнами управления, используя предопределенный класс окна "scrollbar", и один из двух стилей для полос прокрутки: SBS_VERTS и BS_HORZ.

В отличие от кнопок — элементов управления (и окон редактирования и списков, которые будут обсуждаться позже), полосы прокрутки — элементы управления не посылают родительскому окну сообщений WM_COMMAND. Вместо этого они, также как и полосы прокрутки окна, посылают ему сообщения WM_VSCROLL и WM_HSCROLL. При обработке сообщений полос прокрутки с помощью параметра lParam вы можете различать сообщения полос прокрутки окна и полос прокрутки — элементов управления. Для полос прокрутки окна lParam равен 0, а для полос прокрутки — элементов управления он является описателем этих полос прокрутки или описателем дочернего окна управления — полосы прокрутки. Что же касается параметра wParam, то значения его старшего и младшего слова для полос прокрутки окна и для полос прокрутки — элементов управления имеют одинаковый смысл.

Несмотря на то, что полосы прокрутки окна имеют фиксированную ширину, для задания размеров полос прокрутки — элементов управления в Windows используются размеры всего прямоугольника, задаваемые при вызове функции CreateWindow (или позже при вызове функции MoveWindow). Вы можете сделать полосы прокрутки управления длинными и узкими, или короткими и широкими.

Если вы захотите создать полосы прокрутки — элементы управления с теми же размерами, что и полосы прокрутки окна, вы можете использовать для получения высоты горизонтальной полосы прокрутки функцию GetSystemMetrics:

GetSystemMetrics(SM_CYHSCROLL);

или для получения ширины вертикальной полосы прокрутки:

GetSystemMetrics(SM_CXVSCROLL);

(Для задания стандартных размеров полосам прокрутки предназначены идентификаторы стиля окон полос прокрутки SBS_LEFTALIGN, SBS_RIGHTALIGN, SBS_TOPALIGN и SBS_BOTTOMALIGN. Однако, эти стили применимы только для полос прокрутки в окнах диалога.

Вы можете установить диапазон и положение полосы прокрутки — элемента управления с помощью тех же вызовов функций, что и для полос прокрутки окна:

SetScrollRange(hwndScroll, SB_CTL, iMin, iMax, bRedraw);

SetScrollPos(hwndScroll, SB_CTL, iPos, bRedraw);

SetScrollInfo(hwndScroll, SB_CTL, &si, bRedraw);

Отличие состоит в том, что для полос прокрутки окна в качестве первого параметра используется описатель главного окна, а в качестве второго SB_VERT или SB_HORZ.

271

Достаточно удивительно то, что системный цвет COLOR_SCROLLBAR более для полос прокрутки не используется. Цвета концевых кнопок и бегунка основаны на COLOR_BTNFACE, COLOR_BTNHIGHLIGHT, COLOR_BTNSHADOW, COLOR_BTNTEXT (для маленьких стрелок), COLOR_BTNSHADOW и COLOR_BTNLIGHT. Цвет большого участка между верхней и нижней концевыми кнопками основан на сочетании цветов COLOR_BTNFACE и COLOR_BTNHIGHLIGHT.

Если вы обрабатываете сообщения WM_CTLCOLORSCROLLBAR, то вы можете возвратить кисть из сообщения для изменения цвета определенной области. Давайте это проделаем.

Программа COLORS1

Для рассмотрения некоторых аспектов использования статических дочерних окон и полос прокрутки, а также для более глубокого изучения цветов, мы будем использовать программу COLORS1, представленную на рис. 8.5. Программа COLORS1 выводит на экран три полосы прокрутки в левой половине рабочей области, помеченные "Red", "Green" и "Blue". Цвет правой половины рабочей области образуется путем сочетания трех исходных цветов, значения которых определяются положением бегунков полос прокрутки. Численные значения этих трех исходных цветов выводятся на экран под тремя полосами прокрутки.

COLORS1.MAK

#-----------------------

# COLORS1.MAK make file

#-----------------------

colors1.exe : colors1.obj

$(LINKER) $(GUIFLAGS) -OUT:colors1.exe colors1.obj $(GUILIBS)

colors1.obj : colors1.c

$(CC) $(CFLAGS) colors1.c

COLORS1.C

/*----------------------------------------

 

COLORS1.C --

Colors Using Scroll Bars

 

(c) Charles Petzold, 1996

----------------------------------------

*/

#include <windows.h> #include <stdlib.h>

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

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

WNDPROC fnOldScr[3];

HWND

hwndScrol[3], hwndLabel[3], hwndValue[3], hwndRect;

int

color[3], iFocus;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)

{

static char szAppName[] = "Colors1";

static char *szColorLabel[] = { "Red", "Green", "Blue" };

HWND

hwnd;

int

i;

MSG

msg;

WNDCLASSEX

wndclass;

wndclass.cbSize

= sizeof(wndclass);

wndclass.style

= CS_HREDRAW | CS_VREDRAW;

wndclass.lpfnWndProc

= WndProc;

wndclass.cbClsExtra

= 0;

wndclass.cbWndExtra

= 0;

wndclass.hInstance

= hInstance;

wndclass.hIcon

= LoadIcon(NULL, IDI_APPLICATION);

wndclass.hCursor

= LoadCursor(NULL, IDC_ARROW);

wndclass.hbrBackground

= CreateSolidBrush(0L);

272

wndclass.lpszMenuName

= NULL;

wndclass.lpszClassName

= szAppName;

wndclass.hIconSm

= LoadIcon(NULL, IDI_APPLICATION);

RegisterClassEx(&wndclass);

hwnd = CreateWindow(szAppName, "Color Scroll", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

hwndRect = CreateWindow("static", NULL,

WS_CHILD | WS_VISIBLE | SS_WHITERECT, 0, 0, 0, 0,

hwnd,(HMENU) 9, hInstance, NULL);

for(i = 0; i < 3; i++)

{

hwndScrol[i] = CreateWindow("scrollbar", NULL,

WS_CHILD | WS_VISIBLE | WS_TABSTOP | SBS_VERT, 0, 0, 0, 0,

hwnd,(HMENU) i, hInstance, NULL);

hwndLabel[i] = CreateWindow("static", szColorLabel[i], WS_CHILD | WS_VISIBLE | SS_CENTER, 0, 0, 0, 0,

hwnd,(HMENU)(i + 3), hInstance, NULL);

hwndValue[i] = CreateWindow("static", "0",

WS_CHILD | WS_VISIBLE | SS_CENTER, 0, 0, 0, 0,

hwnd,(HMENU)(i + 6), hInstance, NULL);

fnOldScr[i] =(WNDPROC) SetWindowLong(hwndScrol[i], GWL_WNDPROC, (LONG) ScrollProc);

SetScrollRange(hwndScrol[i], SB_CTL, 0, 255, FALSE);

SetScrollPos (hwndScrol[i], SB_CTL, 0, FALSE);

}

ShowWindow(hwnd, iCmdShow);

UpdateWindow(hwnd);

while(GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage (&msg);

}

return msg.wParam;

}

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

{

static COLORREF crPrim[3] = { RGB(255, 0, 0), RGB(0, 255, 0),

 

RGB(0, 0, 255) };

static HBRUSH

hBrush[3], hBrushStatic;

static int

cyChar;

static RECT

rcColor;

char

szbuffer[10];

int

i, cxClient, cyClient;

switch(iMsg)

 

{

 

273

case WM_CREATE :

for(i = 0; i < 3; i++)

hBrush[i] = CreateSolidBrush(crPrim[i]);

hBrushStatic = CreateSolidBrush(

GetSysColor(COLOR_BTNHIGHLIGHT));

cyChar = HIWORD(GetDialogBaseUnits()); return 0;

case WM_SIZE :

cxClient = LOWORD(lParam); cyClient = HIWORD(lParam);

SetRect(&rcColor, cxClient / 2, 0, cxClient, cyClient);

MoveWindow(hwndRect, 0, 0, cxClient / 2, cyClient, TRUE);

for(i = 0; i < 3; i++)

{

MoveWindow(hwndScrol[i],

(2 * i + 1) * cxClient / 14, 2 * cyChar, cxClient / 14, cyClient - 4 * cyChar, TRUE);

MoveWindow(hwndLabel[i],

(4 * i + 1) * cxClient / 28, cyChar / 2, cxClient / 7, cyChar, TRUE);

MoveWindow(hwndValue[i],

(4 * i + 1) * cxClient / 28, cyClient - 3 * cyChar / 2, cxClient / 7, cyChar, TRUE);

}

SetFocus(hwnd); return 0;

case WM_SETFOCUS : SetFocus(hwndScrol[iFocus]); return 0;

case WM_VSCROLL :

i = GetWindowLong((HWND) lParam, GWL_ID);

switch(LOWORD(wParam))

{

case SB_PAGEDOWN : color[i] += 15;

// fall through

case SB_LINEDOWN :

color[i] = min(255, color[i] + 1); break;

case SB_PAGEUP : color[i] -= 15;

// fall through

case SB_LINEUP :

color[i] = max(0, color[i] - 1); break;

case SB_TOP : color[i] = 0; break;

case SB_BOTTOM : color[i] = 255;

274

break;

case SB_THUMBPOSITION : case SB_THUMBTRACK :

color[i] = HIWORD(wParam); break;

default : break;

}

SetScrollPos (hwndScrol[i], SB_CTL, color[i], TRUE);

SetWindowText(hwndValue[i], itoa(color[i], szbuffer, 10));

DeleteObject((HBRUSH)

SetClassLong(hwnd, GCL_HBRBACKGROUND,

(LONG) CreateSolidBrush(

RGB(color[0], color[1], color[2]))));

InvalidateRect(hwnd, &rcColor, TRUE); return 0;

case WM_CTLCOLORSCROLLBAR :

i = GetWindowLong((HWND) lParam, GWL_ID);

return(LRESULT) hBrush[i];

case WM_CTLCOLORSTATIC :

i = GetWindowLong((HWND) lParam, GWL_ID);

if(i >= 3 && i <= 8) // static text controls

{

SetTextColor((HDC) wParam, crPrim[i % 3]); SetBkColor((HDC) wParam, GetSysColor(COLOR_BTNHIGHLIGHT)); return(LRESULT) hBrushStatic;

}

break;

case WM_SYSCOLORCHANGE : DeleteObject(hBrushStatic);

hBrushStatic = CreateSolidBrush(

GetSysColor(COLOR_BTNHIGHLIGHT));

return 0;

case WM_DESTROY : DeleteObject((HBRUSH)

SetClassLong(hwnd, GCL_HBRBACKGROUND,

(LONG) GetStockObject(WHITE_BRUSH)));

for(i = 0; i < 3; DeleteObject(hBrush[i++]));

DeleteObject(hBrushStatic);

PostQuitMessage(0); return 0;

}

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

}

LRESULT CALLBACK ScrollProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)

{

int i = GetWindowLong(hwnd, GWL_ID);

switch(iMsg)

275

{

case WM_KEYDOWN : if(wParam == VK_TAB)

SetFocus(hwndScrol[(i +

(GetKeyState(VK_SHIFT) < 0 ? 2 : 1)) % 3]);

break;

case WM_SETFOCUS : iFocus = i; break;

}

return CallWindowProc(fnOldScr[i], hwnd, iMsg, wParam, lParam);

}

Рис. 8.5 Программа COLORS1

Программа COLORS1 включает в работу свои дочерние окна. В программе используется 10 дочерних окон управления: три полосы прокрутки, 6 окон статического текста, и один статический прямоугольник. Программа COLORS1 обрабатывает сообщения WM_CTLCOLORSCROLLBAR для закрашивания внутренних участков трех полос прокрутки в красный, зеленый и голубой цвета, а также сообщения WM_CTLCOLORSTATIC для окрашивания статического текста.

Вы можете изменять состояние полос прокрутки либо с помощью мыши, либо с помощью клавиатуры. Вы можете использовать программу COLORS1 как инструмент для экспериментов с цветами и выбора наиболее привлекательного (или, если вам так хочется, самого некрасивого) цвета для ваших Windows-программ. Вид экрана программы COLORS1 показан на рис. 8.6, к сожалению, цвета печатной страницы представляют собой лишь варианты серого.

Рис. 8.6 Вид экрана программы COLORS1

Программа COLORS1 не обрабатывает сообщений WM_PAINT. Фактически вся работа в программе COLORS1 выполняется дочерними окнами.

Цвет правой половины рабочей области окна фактически является цветом фона окна. Статическое дочернее окно со стилем SS_WHITERECT занимает левую половину рабочей области. Три полосы прокрутки являются дочерними окнами управления стиля SBS_VERT. Эти полосы прокрутки расположены в верхней части дочернего окна SS_WHITERECT. Еще шесть статических дочерних окон стиля SS_CENTER (выравнивание по центру) обеспечивают индикацию названий цветов и их значений. Программа COLORS1 строит обычное перекрывающееся окно и десять дочерних окон в функции WinMain при помощи функции CreateWindow. Окна SS_WHITERECT и SS_CENTER используют класс окна "static"; в трех полосах прокрутки используется класс окна

"scrollbar".

Первоначально параметры, определяющие положение х и у, ширину и высоту окна функции CreateWindow устанавливаются в 0, поскольку они зависят от размера рабочей области, который еще не известен. Оконная процедура программы COLORS1 с помощью вызова функции MoveWindow изменяет размеры всех десяти

Соседние файлы в предмете Операционные системы