Программирование на Delphi - обмен опытом / Работа с регионами

© Зайцев Олег 1998-2004
Лучшая портативная техника. Плееры Камеры Телефоны Компьютеры
Покупателям, пришедшим на www.porta.ru по этой ссылке - дополнительная скидка 1%
Железо | Система | WEB | Компоненты | Графика | Ссылки | Мультимедиа | Сети | Прочее | Реестр | Литература

Статистика

Работа с регионами

Рекомендую:
Главная страница \ Графика \ Работа с регионами

  • Работа с регионами

    Работа с регионами

    Работа с регионами * * Задать вопрос Наверх
    Достаточно давно мне пришлось разработать одну задачку - имитатор РЛС реального времени. Кроме всего прочего в ее составе был имитатор индикатора. Он естественно круглый, рисовать на нем было очень сложно - малейший выход за допустимые пределы приводил к тому, что он становился уже не круглым, а криво-круглым. А скорость развертки - 6 оборотов в минуту. Поэтому я стал искать пути быстрого определения формы области, доступной для рисования. Решением стало применение регионов (в некоторой литературе их называют областями)
    var
     MyRgn, OldRgn : HRGN;
    begin
     MyRgn := CreateEllipticRgn(1,1,50,50);
     // Запомнили старый регион
     OldRgn:=SelectObject(Canvas.handle,MyRgn);
     Canvas.Rectangle(4,4,150,150);
     ------ рисуем ... ---------
     // Восстановили исходный регион
     SelectObject(Canvas.handle,OldRgn);
    end;
    
    Регион позволяет задать на канве область любой формы, и рисовать не задумываясь.

    Создание регионов * * Задать вопрос Наверх
    Регион создается одной из функций API:

    function CreateRectRgn(p1, p2, p3, p4: Integer): HRGN;
    function CreateRectRgnIndirect(const p1: TRect): HRGN; 
    
    Функция CreateRectRgn создает регион прямоугольной формы (параметры задают X, Y для верхнего левого и нижнего правого угла прямоугольника, задающего регион. Функция CreateRectRgnIndirect аналогична функции CreateRectRgn - разница в том, что вместо четырех координат функция получает структуру типа TRect

    function CreateRoundRectRgn(p1, p2, p3, p4, p5, p6: Integer): HRGN; 
    Функция CreateRoundRectRgn аналогична функции CreateRectRgn, но создаваемая прямоугольная область имеет скругленныем углы. p1, p2 - координаты верхнего левого угла, p3, p4 - координаты нижнего правого, p5, p6 - высота и ширина эллипса, применяемого для скругления углов

    function CreatePolygonRgn(const Points; Count, FillMode: Integer): HRGN; 
    Функция CreatePolygonRgn создает регион, ограниченный многоугольником, вершины которого заданы в массиве Points (элемент массива - пара координат x,y). Параметр Count указывает количество точек в массиве, FillMode определяет, какие точки будут принадлежать региону (возможно два режима - ALTERNATE и WINDING)

    function CreatePolyPolygonRgn(const pPtStructs; const pIntArray; p3, p4: Integer): HRGN; 
    Функция CreatePolyPolygonRgn создает регион, состоящий из нескольких регионов. Параметр pPtStruct является массивом массивов точек (что-то типа двумерного массива), pIntArray является массовом, содержащем количество точек (вершин) для каждого из регионов, p3 - количество регионов, p4 - режим заполнения

    function CreateEllipticRgn(p1, p2, p3, p4: Integer): HRGN; 
    function CreateEllipticRgnIndirect(const p1: TRect): HRGN; 
    
    Данные функции создают эллиптический регион (эллепс вписан в прямоугольник, заданный в первом случае кооординатами верхнего левого и нижнего пправого углов, во втором - структурой p1: TRect с теми-же координатами)

     
     int CombineRgn(
       HRGN hrgnDest,    // handle результирующего региона
       HRGN hrgnSrc1,    // handle региона 1
       HRGN hrgnSrc2,    // handle региона 1
       int fnCombineMode // код режима комбинирования регионов
      );
    
    Функция CombineRgn создает новый регион, который является комбинацией исходных. fnCombineMode задает режим работы:
    КодНазначение
    RGN_AND Результирующий регион будет пересечением регионов 1 и 2
    RGN_COPY Результирующий регион будет копией региона 1
    RGN_DIFF Результирующий регион будет фрагментом региона 1, не принадлежащим региону 2
    RGN_OR Результирующий регион будет объдинением региона 1 и 2
    RGN_XOR Результирующий регион будет объединением региона 1 и 2 по XOR (исключающее ИЛИ результат = [регион 1] + [регион 2] - [область пересечения регионов 1 и 2]

    BOOL EqualRgn(
        HRGN hSrcRgn1,	// handle региона 1 
        HRGN hSrcRgn2 	// handle региона 2
       );
    
    Функция EqualRgn проводит сравнение регионов 1 и 2 и возвращает true, если регионы 1 и 2 равны

    Назначение региона окну * * Задать вопрос Наверх
    Назначение региона окну производится при помощи функции:

    int SetWindowRgn(
        HWND hWnd,    // handle окна
        HRGN hRgn,    // handle региона
        BOOL bRedraw  // флаг, управляющий перерисовкой окна после назначения региона
       );
    
    Пример работы с данной функцией:
    var
     Rgn, Rgn1 : HRGN; // Регионы
    begin
     // Настрока размеров окна
     Height := 400;
     Width  := 600;
     // Создание эллиптического региона размером с окно
     Rgn  := CreateEllipticRgn(0, 0, width, height);
     // Создание прямоугольного региона
     Rgn1 := CreateRectRgn(50, 50, 100, 100);
     // Комбинирование регионов по RGN_XOR (сумма за вычетом пересечения)
     CombineRgn(Rgn, Rgn, Rgn1, RGN_XOR);
     // Создание региона
     Rgn1 := CreateRectRgn(250, 250, 100, 100);
     // Комбинирование регионов по RGN_DIFF (Rgn - Rgn1)
     CombineRgn(Rgn, Rgn, Rgn1, RGN_DIFF);
     // Назначение региона текущему окну
     SetWindowRgn(Handle, Rgn, true);
    end;
    
    В результате окно становится эллиптическим, нутри окна есть прозрачная прямоугольная и "дырка", в левом углу к нему пристыкована прямоугольная область (хорошо видна работа CombineRgn в режимме RGN_XOR)


    © Зайцев Олег, "Программирование на Delphi - обмен опытом" 1999-2004. При использовании любых материалов данного сайта необходимо указывать источник информации. Дата обновления: 22.11.2004. Сайт размещен на хостинге AGAVA - Хостинг от AGAVA.ru