Читать интересную книгу Delphi. Трюки и эффекты - Валерий Борисок

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 27 28 29 30 31 32 33 34 35 ... 59

Hide;

//сохраняем текущее изображение экрана

Captured := BitBlt(hdcCompatible, 0, 0, bmpWidth, bmpHeight,

hdcScreen, 0, 0, SRCCOPY);

//показываем наше окно

Show;

end;

В итоге мы создали довольно простое приложение, которое способно получать изображение всего Рабочего стола. Результат работы приложения приведен на рис. 6.3.

Рис. 6.3. Результат работы приложения «Захват изображения»

6.9. Альфа-смешивание

Здесь мы рассмотрим пример, иллюстрирующий, как осуществлять альфа-смешивание точечного рисунка. Мы создадим приложение, в котором окно делится на три горизонтальные области. Затем создается точечный рисунок с альфа-смешиванием в каждой из областей окна следующим образом:

• в верней области постоянная альфа = 50  %, но нет никакой исходной альфы;

• в средней области постоянная альфа = 100 % и исходная альфа = 0 %;

• в нижней области постоянная альфа = 75 % и исходная альфа переменная.

Добавим в описание нашей формы процедуру со следующим форматом заголовка:

...

procedure DrawAlphaBlend(hWnd: HWND; hdcwnd: HDC);

В самой процедуре объявим ряд переменных, которые нам понадобятся в процессе работы. Объявление приведено в листинге 6.9.

...

Листинг 6.9.

Объявление переменных

var

hCurDC: HDC; //описатель контекста устройства,

//который мы создадим

bf: BLENDFUNCTION; //запись альфа-смешивания

hbmp: HBITMAP; //дескриптор точечного рисунка

bmi: BITMAPINFO; //заголовок точечного рисунка

pvBits: Pointer; //pointer to DIB section

ulWindowWidth, ulWindowHeight: ULONG; //ширина/высота

//клиентской области

ulBitmapWidth, ulBitmapHeight: ULONG; //ширина/высота

//точечного рисунка

rt: TRect; //используется для получения размера

//клиентской области

x,y: Integer; //циклические переменные

ubAlpha: UCHAR; //используется для создания

//прозрачного градиента

ubRed: UCHAR;

ubGreen: UCHAR;

ubBlue: UCHAR;

fAlphaFactor: Real;

r, g, b: UCHAR;

В самом начале процедуры осуществляем подготовку необходимых данных для альфа-смешивания. Данные содержат информацию о требуемых размерах, а также необходимые данные точечного рисунка. Рассмотрите листинг 6.10 с необходимыми комментариями.

...

Листинг 6.10.

Подготовка необходимых данных

//получаем размеры клиентской области

Windows.GetClientRect(hWnd, rt);

//рассчитываем ширину и высоту клиентской области

ulWindowWidth := rt.right – rt.left;

ulWindowHeight := rt.bottom – rt.top;

if (ulWindowWidth = 0) or (ulWindowHeight = 0) then

Exit;

//делим окно на три горизонтальные области

ulWindowHeight := ulWindowHeight div 3;

//создаем контекст устройства для нашего точечного рисунка

hCurDC := CreateCompatibleDC(hdcwnd);

ZeroMemory(@bmi, sizeof(BITMAPINFO));

//Устанавливаем параметры точечного рисунка.

//Указываем ширину и высоту точечного рисунка для каждой

//из трех горизонтальных областей

//равными 60 % ширины и высоты главного окна.

//Смешивание в центре каждой из этих трех областей

with bmi.bmiHeader do

begin

biSize := sizeof(BITMAPINFOHEADER);

biWidth := ulWindowWidth – (ulWindowWidth div 5) * 2;

ulBitmapWidth := biWidth;

biHeight := ulWindowHeight – (ulWindowHeight div 5) * 2;

ulBitmapHeight := biHeight;

biPlanes := 1;

biBitCount := 32; //четыре восьмибитных составляющих

biCompression := BI_RGB;

biSizeImage := ulBitmapWidth * ulBitmapHeight * 4;

end;

//создаем DIB секцию и выбираем точечный рисунок в контексте

устройства

hbmp := CreateDIBSection(hCurDC, bmi, DIB_RGB_COLORS, pvBits,

0, 0);

SelectObject(hCurDC, hbmp);

Далее осуществляем описанное ранее альфа-смешивание для каждой из областей. Для первой области в точечном рисунке мы устанавливаем синий цвет точки. Задаем необходимые параметры альфа-смешивания и выполняем его (листинг 6.11).

...

Листинг 6.11.

Альфа-смешивание верхней области

//в верхней области постоянная альфа = 50 %,

//но исходная альфа отсутствует

//цветовой формат для каждого пиксела 0xaarrggbb

//установим пикселы в синий цвет и альфу в ноль

for y := 0 to ulBitmapHeight – 1 do

for x := 0 to ulBitmapWidth – 1 do

PULONG(Integer(pvBits) +

(x + y * ulBitmapWidth) * sizeof(ULONG))^ := $000000ff;

bf.BlendOp := AC_SRC_OVER;

bf.BlendFlags := 0;

bf.AlphaFormat := 0; //игнорировать исходный альфа-канал

bf.SourceConstantAlpha := $7f; //половина $ff = 50 %

//прозрачности

if not Windows.AlphaBlend(hdcwnd, ulWindowWidth div 5,

ulWindowHeight div 5,

ulBitmapWidth, ulBitmapHeight,

hCurDC, 0, 0, ulBitmapWidth,

ulBitmapHeight, bf) then

begin

DeleteObject(hbmp);

DeleteDC(hCurDC);

Exit;

end;

По аналогии выполняем необходимые действия со средней областью. В центре точечного рисунка прозрачность отсутствует, поэтому там будет только указанный цвет. Установим в центре красный цвет, а остальную часть сделаем синей. Далее опять задаем необходимые параметры альфа-смешивания и выполняем его (листинг 6.12).

...

Листинг 6.12.

Альфа-смешивание средней области

//в средней области постоянная альфа = 100 %, а исходная равна 0

for y := 0 to ulBitmapHeight – 1 do

for x := 0 to ulBitmapWidth – 1 do

if (x > Integer(ulBitmapWidth div 5)) and

(x < (ulBitmapWidth – ulBitmapWidth div 5)) and

(y > Integer(ulBitmapHeight div 5)) and

(y < (ulBitmapHeight – ulBitmapHeight div 5)) then

//в середине точечного рисунка альфа равна нулю,

//это означает, что каждый цветной компонент умножается на 0.

//Таким образом, после альфа-смешивания мы получим 0 * r,

//0x00 * g, 0x00 * b ($00000000)

//установим сейчас цвет пикселов в красный

PULONG(Integer(pvBits) +

(x + y * ulBitmapWidth) * eof(ULONG))^ := $00ff0000

else

//остальную часть точечного рисунка сделаем синей

PULONG(Integer(pvBits) +

(x + y * ulBitmapWidth) * sizeof(ULONG))^ := $000000ff;

bf.BlendOp := AC_SRC_OVER;

bf.BlendFlags := 0;

bf.AlphaFormat := AC_SRC_ALPHA; //используем исходную альфа

bf.SourceConstantAlpha := $ff; //непрозрачный

if not Windows.AlphaBlend(hdcwnd, ulWindowWidth div 5,

ulWindowHeight div 5 + ulWindowHeight, ulBitmapWidth,

ulBitmapHeight,

hCurDC, 0, 0, ulBitmapWidth, ulBitmapHeight, bf) then

begin

DeleteObject(hbmp);

DeleteDC(hCurDC);

Exit;

end;

В последней части происходит градиентное альфа-смешивание. Соответствующий код приведен в листинге 6.13.

...

Листинг 6.13.

Альфа-смешивание нижней области

//нижняя область. Используем альфа = 75 % и переменную исходную альфу

//создаем градиентный эффект, используя исходную альфа

ubRed := $00;

ubGreen := $00;

ubBlue := $ff;

for y := 0 to ulBitmapHeight – 1 do

for x := 0 to ulBitmapWidth – 1 do

begin

ubAlpha := Trunc(x / ulBitmapWidth * 255) and $FF;

fAlphaFactor := ubAlpha / $ff;

r := (Round(ubRed * fAlphaFactor) * (1 shl 16)) and $FF;

g := (Round(ubGreen * fAlphaFactor) * (1 shl 8)) and $FF;

b := Round(ubBlue * fAlphaFactor) and $FF;

PULONG(Integer(pvBits) +

(x + y * ulBitmapWidth) * sizeof(ULONG))^ :=

(ubAlpha shl 24) or //0xaa000000

r or //0x00rr0000

g or //0x0000gg00

b; //0x000000bb

end;

bf.BlendOp := AC_SRC_OVER;

bf.BlendFlags := 0;

bf.AlphaFormat := AC_SRC_ALPHA;

bf.SourceConstantAlpha := $bf;

Windows.AlphaBlend(hdcwnd, ulWindowWidth div 5,

ulWindowHeight div 5 + 2 * ulWindowHeight,

ulBitmapWidth, ulBitmapHeight, hCurDC, 0, 0,

ulBitmapWidth, ulBitmapHeight, bf);

DeleteObject(hbmp);

DeleteDC(hCurDC);

Обработчик события OnPaint нашей формы использует написанную функцию каждый раз, когда требуется ее обновить. Для этого он получает контекст устройства нашей формы, производит заливку фона темно-синим цветом, а после вызывает функцию альфа-смешивания трех областей. Соответствующий исходный код приведен в листинге 6.14.

...

Листинг 6.14.

Обработчик события OnPaint

procedure TfmAlphaBlending.FormPaint(Sender: TObject);

var

hCurDC: HDC;

hCurBrush, hOldBrush: HBRUSH;

begin

hCurDC := GetDC(Handle);

hCurBrush := CreateSolidBrush(RGB(0, 0, 64));

FillRect(hCurDC, Rect(0, 0, Width, Height), hCurBrush);

DrawAlphaBlend(Handle, hCurDC);

DeleteObject(hCurBrush);

ReleaseDC(Handle, hCurDC);

end;

Теперь осталось только взглянуть на результат нашей работы, запустив приложение (рис. 6.4).

Рис. 6.4. Результат работы приложения «Alpha-смешивание точечного рисунка»

На этом закончим рассмотрение работы с графикой в Delphi.

Глава 7 Системная информация и реестр Windows

• Системная информация

• Системное время

• Реестр

Возникала ли у вас необходимость программно определить текущее состояние компьютера или узнать какие-нибудь сведения об операционной системе? Можно только удивляться, как близко – практически «под носом» у программиста – находятся средства для получения системной информации и как сложно о них узнать. Речь идет о средствах, которые всегда доступны при программировании для Windows – функции Windows API.

В данной главе мы рассмотрим некоторые способы, при помощи которых можно «добыть» информацию, касающуюся операционной системы. Это может пригодиться, например, если вы используете в своих приложениях возможности, отличающиеся в различных платформах Windows. Но и не только в этих случаях.

Рассмотренные в данной главе функции Windows API являются самыми обычными во всех смыслах этого слова. Просто они часто упоминаются вскользь либо вообще не упоминаются в книгах для программирования в таких средах, как Borland Delphi.

В примерах представленной вашему вниманию главы, кроме получения информации о самой Windows, некотором оборудовании компьютера, также рассмотрена работа с системным реестром Windows – этакой базой данных, в которой хранится много всего полезного и не очень: от параметров ОС и настроек приложений до сведений о работе компьютера в реальном времени. Правда, по определенным причинам последние сведения хранятся не в реальных, а в виртуальных ключах реестра. Но обо всем по порядку.

7.1. Системная информация

1 ... 27 28 29 30 31 32 33 34 35 ... 59
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Delphi. Трюки и эффекты - Валерий Борисок.

Оставить комментарий