Статья: Работа с регионами в Visual C++

Статья: Работа с регионами в Visual C++




⚡ 👉🏻👉🏻👉🏻 ИНФОРМАЦИЯ ДОСТУПНА ЗДЕСЬ ЖМИТЕ 👈🏻👈🏻👈🏻




























































В Win32 API есть набор функций для работы с регионами. При помощи регионов Вы можете создавать различные поверхности, используя только стандартные геометрические фигуры. Ну а дальше всё зависит от Вашей выдумки.
Это всего лишь тип данных, означающий "хэндл региона". Такой хэндл потребуется для каждого региона, с которым Вы захотите работать.
HRGN hRegion = CreateRectRgn(x,y,x+128,y+128);
После завершения работы с регионом, необходимо удалить объект, связанный с регионом при помощи функции DeleteObject().
CombineRgn, CreateEllipticRgn, CreateEllipticRgnIndirect, CreatePolygonRgn, CreatePolyPolygonRgn, CreateRectRgn, CreateRectRgnIndirect, CreateRoundRectRgn, EqualRgn, ExtCreateRegion, FillRgn, FrameRgn, GetPolyFillMode, GetRegionData, GetRgnBox, InvertRgn, OffsetRgn, PaintRgn, PtInRegion, RectInRegion, SetPolyFillMode.
Это основные функции, которые предназначены для создания и работы с регионами. Как видно из названий, регионы можно создавать круглые, квадратные, а также любой другой формы.
При помощи этой функции можно прикрепить регион к любому окну. Например, после использования этой функции, окно может выглядеть следующим образом:
Чтобы проделать такое с окном, понадобятся следующие функции:
// эта функция создаёт круглый регион.
int nLeftRect, // x-координата верхнего-левого угла
int nTopRect, // y-координата верхнего-левого угла
int nRightRect, // x-координата нижнего-правого угла
int nBottomRect // y-координата нижнего-правого угла
// эта функция совмещает два региона
HRGN hrgnDest, // хэндл конечного региона
HRGN hrgnSrc1, // хэндл исходного региона
HRGN hrgnSrc2, // хэндл исходного региона
int fnCombineMode // режим совмещения регионов
// эта функция прикрепляет регион к окну.
// чтобы убрать регион с окна, надо вместо хэндла региона поставить NULL.
HWND hWnd, // хэндл окна, на которое будет установлен регион
BOOL bRedraw // флаг перерисовки окна
Ну а теперь взглянем на реальный код, который демонстрирует создание окна, изображение которого приведено выше:
// --------------------------------------------------
// Используем отрицательную начальную координату, чтобы наш элипс
// --------------------------------------------------
HRGN hRegion1 = CreateEllipticRgn(20,-20,190,150);
// --------------------------------------------------
// создаём ещё один круглый регион в другом месте.
// --------------------------------------------------
HRGN hRegion2 = CreateEllipticRgn(140,100,300,240);
// --------------------------------------------------
// склеиваем два региона, чтобы сделать новый регион.
// итоговый регион будет помещён в region1,
// в функции CombineRgn() можно использовать набор операций RGN_.
// --------------------------------------------------
CombineRgn(hRegion1, hRegion1, hRegion2, RGN_OR);
// --------------------------------------------------
// --------------------------------------------------
SetWindowRgn(hWnd, hRegion1, true);
// --------------------------------------------------
// --------------------------------------------------
Чтобы вернуть окно в нормальное состояние (без региона), воспользуйтесь следующей функцией:
Тема скинов довольно популярна в программировании. При помощи скинов мы можем придать стандартному окну привлекательный вид:
Для этого необходим битмап, который заполнит всё окно. На приведённой картинке используется окно размером 320х240 и такого же размера битмап.
Давайте создадим небольшое демонстрационное приложение. Ниже приведены шаги, которые потребуется проделать:
2 - Создаём контекст устройства для скина и выбираем в нём битмап;
3 - Создаём переключатель между нормальным режимом и скином;
4 - Скрываем заголовок окна и блокируем изменение его размеров в режиме скина;
5 - Показываем заголовок окна и разблокируем его при выходе из режима скина;
6 - Обрабатываем перерисовку скина в сообщении WM_PAINT;
7 - Обрабатываем сообщение WM_LBUTTON, чтобы пользователь мог перетаскивать окно за любую часть в режиме скина;
// -----------------------------------------------------------------------
// загружаем битмап скина из ресурса
// -----------------------------------------------------------------------
hSkinBmp = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_SKIN));
Как видно из кода, ничего сложного. Конечно можно загружать картинки других форматов, но это тема другой статьи.
2 - Создаём контекст устройства для скина и выбираем в нём битмап:
// -----------------------------------------------------------------------
// создаём контекст устройства для скина
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
hOldBmp = (HBITMAP)SelectObject(dcSkin, hSkinBmp);
Не забудьте освободить эти объекты перед тем как Ваше приложение завершит свою работу.
3 - Создаём переключатель между нормальным режимом и скином:
Этот фрагмент кода необходмо поместить в главную оконную процедуру в обработчик сообщения WM_KEYDOWN. Здесь используются две небольшие собственные функции RegionMe() и UnregionMe() для переключения режима.
4 - Скрываем заголовок окна и блокируем изменение его размеров в режиме скина:
// ------------------------------------------------------------------------
// Создаём основной регион и устанавливаем его на окно.
// ------------------------------------------------------------------------
// --------------------------------------------------
// создаём круглый регион и используем отрицательную
// координату, чтобы регион захватил заголовок окна.
// --------------------------------------------------
HRGN hRegion1 = CreateEllipticRgn(20,-20,190,150);
OffsetRgn(hRegion1, GetSystemMetrics(SM_CXBORDER)*4, GetSystemMetrics(SM_CYCAPTION));
// --------------------------------------------------
// создаём второй регион в другом месте.
// --------------------------------------------------
HRGN hRegion2 = CreateEllipticRgn(140,100,300,240);
OffsetRgn(hRegion2, GetSystemMetrics(SM_CXBORDER)*4, GetSystemMetrics(SM_CYCAPTION));
// --------------------------------------------------
// совмещаем два региона по принципу:
// --------------------------------------------------
CombineRgn(hRegion1, hRegion1, hRegion2, RGN_OR);
// --------------------------------------------------
// прикрепляем итоговый регион к окну
// --------------------------------------------------
SetWindowRgn(hWnd, hRegion1, true);
// --------------------------------------------------
// --------------------------------------------------
// --------------------------------------------------
// изменяем стиль окна (избавляемся от заголовка)
// --------------------------------------------------
DWORD dwStyle = GetWindowLong(hWnd, GWL_STYLE);
dwStyle &= ~(WS_CAPTION|WS_SIZEBOX);
SetWindowLong(hWnd, GWL_STYLE, dwStyle);
// --------------------------------------------------
// перерисовываем окно, а так же убираем рамку окна, чтобы
// чтобы нельзя было менять его размер
// --------------------------------------------------
SetWindowPos(hWnd, NULL, 0,0,320,242, SWP_NOMOVE|SWP_NOZORDER);
// --------------------------------------------------
// устанавливаем флажок, только для того, чтобы приложение знало об изменении.
// --------------------------------------------------
5 - Показываем заголовок окна и разблокируем его при выходе из режима скина:
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// --------------------------------------------------
// --------------------------------------------------
// --------------------------------------------------
// меняем стиль окна (снова показываем заголовок)
// --------------------------------------------------
DWORD dwStyle = GetWindowLong(hWnd, GWL_STYLE);
SetWindowLong(hWnd, GWL_STYLE, dwStyle);
// --------------------------------------------------
// перерисовываем окно и возвращаем на место рамку окна, чтобы можно было
// --------------------------------------------------
SetWindowPos(hWnd, NULL, 0,0,320,240, SWP_NOMOVE|SWP_NOZORDER);
// --------------------------------------------------
// --------------------------------------------------
6 - Обрабатываем перерисовку скина в сообщении WM_PAINT:
TextOut(ps.hdc, 115,90, "Press SPACE", 11);
Функция SkinMe() вызывается только в том случае, если приложение находится в режиме скина (bRegioned).
Функция SkinMe() выглядит следующим образом:
BitBlt(dc, 0,0,320,240, dcSkin, 0,0, SRCCOPY);
7 - Обрабатываем сообщение WM_LBUTTON, чтобы пользователь мог перетаскивать окно за любую часть в режиме скина:
// ---------------------------------------------------------
// Посылаем сообщение окну, чтобы оно думало, что кликнули по его заголовку.
// ---------------------------------------------------------
if (bRegioned) SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION,NULL);
Естевственно, что это сообщение посылается только когда окно в режиме скина.
Простые геометрические фигурки это конечно хорошо. А что делать, если надо создать регион сложной формы, например в виде руки:
Чтобы проделать подобное, нам прийдётся наваять небольшую функцию, которая будет сканировать битмап и создавать из него попиксельно регион с прозрачностью. Далее такой регион будет достаточно прицепить к окну.
// ----------------------------------------------------------------------
// Функция сканирует битмап и возвращает необходимый нам регион.
// Освободить объект региона нужно будет самостоятельно...
// ----------------------------------------------------------------------
HRGN ScanRegion(HBITMAP pBitmap, BYTE jTranspR, BYTE jTranspG, BYTE jTranspB)
BYTE *pPixels = Get24BitPixels(pBitmap, &wBmpWidth, &wBmpHeight);
hRgn = CreateRectRgn(0,0,wBmpWidth,wBmpHeight);
if (!hRgn) { delete pPixels; return NULL; }
// ---------------------------------------------------------
// ---------------------------------------------------------
if (jRed == jTranspR && jGreen == jTranspG && jBlue == jTranspB)
// удаляем прозрачный цвет из региона
hTmpRgn = CreateRectRgn(x,y,x+1,y+1);
CombineRgn(hRgn, hRgn, hTmpRgn, RGN_XOR);
Как видно из кода, сперва создаётся квадратный регион такого же размера как и битмап, переданный в функцию как параметр. Затем происходит сканирование каждого пикселя и, если находится пиксель такого же цвета как и указанный, то этот пиксель исключается из региона.
Для демонстрации вышеописанного алгоритма была создана утилита RegionCreator, которая представляет собой консольное приложение работающее с графическими файлами.
Запускается эта утилитка следующим образом:
regioncreator < bitmap.bmp > < r > < g > < b >
r,g,b : прозрачный цвет (в десятичном виде: 255 255 255)
После того, как битмап будет обработан утилиткой, его можно поместить в приложение как ресурс и загрузить следующим образом:
HRSRC hrSkin = FindResource(hInstance, MAKEINTRESOURCE(IDB_SKIN),"BINARY");
// загружаемстандартный "BINARY" ресурс.
LPRGNDATA pSkinData = (LPRGNDATA)LoadResource(hInstance, hrSkin);
HRGN rgnSkin = ExtCreateRegion(NULL, SizeofResource(NULL,hrSkin), pSkinData);
После этого, регион достаточно будет прицепить к окну. И не забудьте удалить регион перед завершением приложения командой DeleteObject(rgnSkin).
В заключении, неплохо было бы заключить весь вышеприведённый материал в класс, чтобы код удобнее читался:

Название: Работа с регионами в Visual C++
Раздел: Рефераты по информатике, программированию
Тип: статья
Добавлен 04:22:06 25 марта 2007 Похожие работы
Просмотров: 53
Комментариев: 16
Оценило: 3 человек
Средний балл: 5
Оценка: неизвестно   Скачать

Срочная помощь учащимся в написании различных работ. Бесплатные корректировки! Круглосуточная поддержка! Узнай стоимость твоей работы на сайте 64362.ru
Если Вам нужна помощь с учебными работами, ну или будет нужна в будущем (курсовая, дипломная, отчет по практике, контрольная, РГР, решение задач, онлайн-помощь на экзамене или "любая другая" учебная работа...) - обращайтесь: https://clck.ru/P8YFs - (просто скопируйте этот адрес и вставьте в браузер) Сделаем все качественно и в самые короткие сроки + бесплатные доработки до самой сдачи/защиты! Предоставим все необходимые гарантии.
Привет студентам) если возникают трудности с любой работой (от реферата и контрольных до диплома), можете обратиться на FAST-REFERAT.RU , я там обычно заказываю, все качественно и в срок) в любом случае попробуйте, за спрос денег не берут)
Да, но только в случае крайней необходимости.

Статья: Работа с регионами в Visual C++
Реферат: Птахи Прикарпаття
Курсовой Финансовые Отношения
Курсовая работа по теме Воздушно-транспортные системы нового поколения США, Европы
Реферат: Основные средства и фонды предприятия
Субъекты Предпринимательского Права Реферат
Отчет по практике по теме Система верхнего привода буровых установок
Острый афтозный стоматит и лейкоплакия
Реферат На Тему Экология Дома
Реферат: Порушення антимонополького законодавства Незаконне збирання з метою використання або використан
Автореферат На Тему Судово-Медична Діагностика Раптової Кардіальної Смерті За Допомогою Комплексу Лабораторних Досліджень
Замятин Мы Аргументы К Итоговому Сочинению
Сахарный Диабет Курсовая Работа Введение
Реферат: An Explanation Of The Basis For The
Сочинение Про Лес Осенью 5 Класс
Строительные Предприятия Курсовая
Курсовая работа по теме Разработка положения о проведении смотра-конкурса на звание 'Лучший командир отделения'
Контрольная работа по теме Маркетинговые исследования реализации цифровых фотоаппаратов
Реферат: Теоретико-методологічні засади навчання обдарованих студентів у педагогічних університетах
Дипломная работа по теме Женщина в политике: история и современность
Реферат по теме Понятие и порядок формирования уставного капитала
Реферат: Волчьи следы
Доклад: Редакция
Реферат: Петропавловский бой

Report Page