Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект лекций Часть II.doc
Скачиваний:
14
Добавлен:
20.11.2018
Размер:
1.48 Mб
Скачать

5.5.2. Панель для выбора цветов

Для создания стандартной панели выбора цветов вызывают функцию ChooseColor: BOOL ChooseColor( LPCHOOSECOLOR Ipcc);

Параметр Ipcc указывает на структуру типа CHOOSECOLOR, которая содержит данные инициализации панели. После выбора цвета в панели эта структура дополняется данными о выбранных цветах.

Если пользователь нажал кнопку ОК панели, возвращаемое значение отлично от нуля, а поле rgbResult структуры будет содержать RGB-значение выбранного цвета.

В случае отмены выбора или при ошибке возвращаемое значение равно нулю.

Эта панель не работает с палитрой цветов.

Структура CHOOSECOLOR описана следующим образом:

typedef struct

{ DWORD IStructSize; ;

HWND hwndOwner;

HWND hlnstance;

COLORREF rgbResult;

COLORREF IpCustColors;

DWORD Flags;

LPARAM ICustData;

LPCCHOOKPROC IpfnHook;

LPCTSTR IpTemplateName;

} CHOOSECOLOR;

Поля структуры CHOOSECOLOR имеют следующее назначение:

1. IStructSize - длина структуры CHOOSECOLOR в байтах.

2. hwndOwner - дескриптор окна - владельца панели.

3. hlnstance - дескриптор блока памяти с шаблоном панели (если уста­новлен флаг CCENABLETEMPLATEHANDLE) или дескриптор эк-

земпляра приложения, содержащего шаблон панели (если установлен флаг CCENABLETEMPLATE). Иначе значение этого поля игнори­руется.

4. rgbResult содержит значение начальной установки цвета (если установлен флаг CC_RGBINIT). Иначе значения rgbResult и начальной установки цвета нулевые. После нажатия кнопки ОК на панели зна­чение rgbResult будет замененр значением выбранного цвета.

5. IpCustColors - массив для набора из 16 дополнительных значений цвета, в который можно записать различные значения цвета, нажимая кнопку "Добавить в набор" на панели.

6. Поле Flags служит для инициализации панели. Его значение обычно

Флаг

Значение

CC_ANYCOLOR

В наборе базисных цветов отображать все доступные цвета

CC_FULLOPEN

При активизации панели отображать до­полнительные органы управления. Иначе для отображения этих органов нужно на­жать кнопку "Определить цвет"

CC_PREVENTFULLOPEN

Отключить кнопку "Определить цвет"

CC_RGBINIT

По умолчанию использовать значение цвета, указанное в поле rgbResult

CC_SOLIDCOLOR

В наборе базисных цветов отображать только сплошные цвета

7. ICustData задает данные для функции, идентифицированной полем lpfhHook.

8. IpfnHook указывает на функцию обработки прерываний, которая может обрабатывать сообщения для панели выбора цвета.

9. IpTemplateName указывает на строку с именем ресурса шаблона па­нели в экземпляре приложения, дескриптор которого задан полем hlnstance.

Задача. Главное меню приложения содержит раздел "Цвет" со стро­ками "Задать цвет" и "Выход". Верхнюю половину рабочей области за­нимает прямоугольник черного цвета, а нижнюю половину - 16 прямо­угольников различных цветов спектра, начиная от красного, плавно пе­реходя к зеленому и заканчивая синим цветом.

При выборе строки "Задать цвет" создать стандартную панель для выбора цветов. Выбрать набор 16 различных цветов для закрашивания

прямоугольников в нижней половине рабочей области. Для закрашива­ния верхнего прямоугольника использовать тот цвет, который был до­бавлен в набор последним.

В случае отмены выбора цвета набор 16 цветов оставить прежним, а верхний прямоугольник закрасить белым.

Перо для границ всех прямоугольников толщиной 5 пикселей. Со­ставляющие цвета пера всегда вдвое меньше составляющих цвета закра­шивания верхнего прямоугольника.

Листинг 6.fr. Эксперименты с панелью выбора цветов.

#include <windows.h>

#define CM_GET_COLOR 1001

#define CM_FILE_QUIT 1003

BOOL RegClass(WNDPROC, LPCTSTR, UINT);

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

HINSTANCE hInstance;

char szClass[]="Cotors";

char szTitle[]="Выбор цвета";

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstance, LPSTR IpszCmdLine, int nCmdShow)

{ MSG msg; HWND hwnd;

::hInstance=hInstance;

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

return FALSE;

if (!(hwnd = CreateWindow(szClass, szTitle, WS_OVERLAPPEDWINDOW|WS_VISIBLE,

CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

0,0, hInstance, NULL))) 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=CS_HREDRAW | CS_VREDRAW;

wc.cbClsExtra=wc.cbWndExtra=0;wc.lpfnWndProc=Proc;

wc.hInstance = hInstance;

wc.lpszClassName=szName;

wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

wc.hbrBackground = (HBRUSH)(brBackground + 1);

wc.lpszMenuName=NULL;

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

BOOL CreateMenuItem(HMENU hMenu, char *str, UINT uIns, UINT uCom, HMENU hSubMenu, BOOL flag, UINT fType)

{ static MENUITEMINFO mii;

mii.cbSize=sizeof(MENUITEMINFO);

mii.fMask = MIIM_STATE | MIIM_TYPE | MIIM_SUBMENU | MIIM_ID;

mii.fType = fType; mii.fState= MFS_ENABLED;

mii.dwTypeData = str; mii.cch=sizeof(str);

mii.wID=uCom; mii.hSubMenu=hSubMenu;

return InsertMenuItem(hMenu, uIns, flag, &mii); }

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

{ static HMENU hMainMenu, hColorMenu;

static CHOOSECOLOR cc;

static COLORREF clf, clfCust[16];

static short cx,cy;

switch (msg) {

case WM_SIZE:

{ cx=LOWORD(lParam); cy=HIWORD(lParam); return 0;}

case WM_CREATE:

{ hMainMenu=CreateMenu();

hColorMenu=CreatePopupMenu();

int i=0;

CreateMenuItem( hColorMenu, "&3адать цвет", i++,

CM_GET_COLOR, NULL, FALSE, MFT_STRING);

CreateMenuItem( hColorMenu, NULL, i++, 0, NULL, FALSE, MFT_SEPARATOR);

CreateMenuItem( hColorMenu, "&Выход", i++,

CM_FILE_QUIT, NULL, FALSE, MFT_STRING);

i=0;

CreateMenuItem(hMainMenu,"&Цвет",i++, 0,

hColorMenu,FALSE, MFT_STRING);

SetMenu(hwnd,hMainMenu);

DrawMenuBar(hwnd);

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

clfCust[i]=RGB(255-i*15, 50+48*i-3*i*i, i*15);

cc.lStructSize = sizeof(CHOOSECOLOR);

cc.lpCustColors = clfCust;

return 0;

}

case WM_PAINT: {

PAINTSTRUCT ps;

HDC hdc = BeginPaint(hwnd, &ps);

HBRUSH hbrush = CreateSolidBrush(clf);

HBRUSH hOldBrush=(HBRUSH)SelectObject(hdc, hbrush);

HPEN hpen = CreatePen(PS_SOLID, 5, clf/2);

HPEN hOldPen = (HPEN)SelectObject(hdc, hpen);

short w=cx/16, h=cy/2;

Rectangle(hdc, 0,0, cx, h);

for(int i=0;i<16;i++)

{hbrush = CreateSolidBrush(clfCust[i]);

SelectObject(hdc, hbrush);

Rectangle(hdc, w*i, h, w*i+w, cy);

SelectObject(hdc, hOldBrush);

DeleteObject(hbrush);

}

SelectObject(hdc, hOldPen); DeleteObject(hpen);

EndPaint(hwnd, &ps);

return 0;

}

case WM_COMMAND: {

switch (LOWORD(wParam)) {

case CM_GET_COLOR:

{ if(!ChooseColor(&cc)) clf=RGB(255,255,255);

else clf = cc.rgbResult;

InvalidateRect(hwnd, NULL, TRUE);

return 0;}

case CM_FILE_QUIT:

{ DestroyWindow(hwnd); return 0; }

}

return 0;

}

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

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

}

Задача создания панели полностью решена в теле функции окна при­ложения. Рассмотрим основные шаги.

1. Описана структура типа CHOOSECOLOR: static CHOOSECOLOR cc;

I. Описаны переменные для работы со структурам v*. static COLORREF elf, ctfCust[16],

Они предназначены для работы с полями структуры соответственно с именами rgbResult и lpCustColors. Причем переменная elf будет всегда использована для закрашивания верхнего прямоугольника и выбора цве­та пера. А массив clfCust будет использован для закрашивания 16 прямо­угольников в нижней половине рабочей области.

3. При обработке сообщения WMCREATE инициализированы те поля структуры ее, которые не будут изменены в процессе работы с пане­лями, и поле lpCustColors: cclStructSize = sizeof(CHOOSECOLOR); cclpCustColors = clfCust; for (i=0; i<16; i++) clfCust[i]=RGB(255-i*15,50+48*i-3Ti, i*15);

Последний цикл задан для записи в массив clfCust 16 приближенно вычисленных значений цветов спектра.

4. При обработке сообщения WMPAINT установленные значения цве­тов переменных elf, clfCust используются для создания кистей: hbrush = CreateSolidBrush(clf);

hbrush = Create SolidBrush(clf С ust[i]);

Цвет пера устанавливают таким образом, что все его составляющие здвое меньше составляющих цвета elf: hpen = CreatePen(PS_SOUD, 5, clf/2); 5. При выборе строки меню "Задать цвет" создается панель для выбора

набора цветов:

if (!ChooseCo!or(&cc)) clf=RGB(255,255,255); else elf = cc.rgbResult;

Если работа с панелью завершилась отменой выбора, то переменной elf присваивают значение белого цвета. Иначе эта переменная принимает значе­ние, поля rgbResult. В это поле панель записывает то значение цвета, которое было выбрано последним, независимо от того, какой элемент набора допол­нительных цветов был выбран последним. В любом случае посылают сооб­щение о необходимости перерисовки всей рабочей области: InvalidateRectfhwnd, NULL, TRUE);