Чтение онлайн

на главную

Жанры

Шрифт:

Далее осуществляем описанное ранее альфа-смешивание для каждой из областей. Для первой области в точечном рисунке мы устанавливаем синий цвет точки. Задаем необходимые параметры альфа-смешивания и выполняем его (листинг 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. Системная информация

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

Версия операционной системы

Получение сведений об операционной системе хотя и не является повседневной необходимостью, но все же в некоторых специфичных случаях может пригодиться. Например, когда ваша программа ведет себя по-разному при разных установленных обновлениях Windows. Либо когда вы самостоятельно пишете инсталлятор, который способен устанавливать версии программы, скомпилированные для Windows Me (95, 98) или Windows NT (2000, ХР).

Одним из способов узнать версию Windows является использование API-функции GetVersionEx. Она принимает в качестве параметра структуру OSVERSIONINFO (или OSVERSIONINFOEX, но об этом позже), заполняет поля этой структуры и в случае удачи возвращает ненулевое значение.

Объявление ANSI-версии структуры OSVERSIONINFO в библиотеке Delphi 7 выглядит следующим образом:

...

OSVERSIONINFOA = record

dwOSVersionInfoSize: DWORD; //Размер структуры

dwMajorVersion: DWORD; //Старшая часть версии ОС Windows

dwMinorVersion: DWORD; //Младшая часть версии

dwBuildNumber: DWORD; //Номер сборки операционной системы

dwPlatformId: DWORD; //Идентификатор платформы Windows

szCSDVersion: array[0..127] of AnsiChar; //Дополнительные

//сведения, например, установленный пакет обновлений

end;

Не будем вдаваться в подробное описание возможных значений полей этой структуры: практически все будет ясно из приведенного далее примера. Напомним лишь, чтобы вы не забывали заполнять поле dwOSVersionInf oSize перед вызовом функции GetVersionEx.

Итак, пример обработки данных, помещаемых в структуру OSVERSIONINFO, приведен в листинге 7.1. При загрузке формы элемент управления ListView с именем lvwVerlnf о заполняется сведениями о версии системы, представленными в читабельной форме.

...

Листинг 7.1.

Получение и отображение сведений о Windows

procedure TForm1.FormCreate(Sender: TObject);

var

info: OSVERSIONINFO;

item: TListItem;

begin

//Получаем информацию о версии ОС

info.dwOSVersionInfoSize := SizeOf(info);

GetVersionEx(info);

//Заполняем список информацией о ОС

//..версия ОС

item := lvwVerInfo.Items.Add;

item.Caption := \'Версия системы\

item.SubItems.Insert(0, IntToStr(Integer(info.dwMajorVersion)) +

\'.\' + IntToStr(Integer(info.dwMinorVersion)));

//..номер сборки

item := lvwVerInfo.Items.Add;

item.Caption := \'Сборка\

item.SubItems.Insert(0, IntToStr(Integer(info.dwBuildNumber)));

//..платформа

item := lvwVerInfo.Items.Add;

item.Caption := \'Платформа\

case info.dwPlatformId of

VER_PLATFORM_WIN32s:

//Эмуляция Win32 или Win16

item.SubItems.Insert(0, \'Win16\');

VER_PLATFORM_WIN32_WINDOWS:

//"Классическая" Win32: 95, 98 или Me

item.SubItems.Insert(0, \'Win32\');

VER_PLATFORM_WIN32_NT:

//Ядро NT

item.SubItems.Insert(0, \'WinNT\');

end;

//..дополнительная информация (например, пакет обновлений)

item := lvwVerInfo.Items.Add;

item.Caption := \'Дополнительные сведения\

item.SubItems.Insert(0, info.szCSDVersion);

end;

Возможный результат работы программы (для Windows ХР SP1) приводится на рис. 7.1.

Рис. 7.1. Информация о версии Windows

Теперь снова обратимся к функции GetVersionEx, точнее говоря, к структуре OSVERSIONINFOEX, которая может также передаваться в качестве параметра в функцию. К сожалению, в библиотеке Delphi 7 эта структура не объявлена. Но это можно сделать самостоятельно:

...

OSVERSIONINFOEX = record

dwOSVersionInfoSize: DWORD;

dwMajorVersion: DWORD;

dwMinorVersion: DWORD;

dwBuildNumber: DWORD;

dwPlatformId: DWORD;

szCSDVersion: array[0..127] of AnsiChar;

//Поля, которых нет в OSVERSIONINFO

wServicePackMajor: WORD; //Старшая цифра версии пакета

//обновлений

wServicePackMinor: WORD; //Младшая цифра версии пакета

//обновлений

wSuiteMask: WORD; //Комплектация системы

wProductType: BYTE; //Дополнительная информации об ОС

wReserved: BYTE;

end;

Поделиться:
Популярные книги

Para bellum

Ланцов Михаил Алексеевич
4. Фрунзе
Фантастика:
попаданцы
альтернативная история
6.60
рейтинг книги
Para bellum

Последний рейд

Сай Ярослав
5. Медорфенов
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Последний рейд

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9

Муж на сдачу

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Муж на сдачу

Последняя Арена 7

Греков Сергей
7. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 7

Мастер 7

Чащин Валерий
7. Мастер
Фантастика:
фэнтези
боевая фантастика
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Мастер 7

Иван Московский. Первые шаги

Ланцов Михаил Алексеевич
1. Иван Московский
Фантастика:
героическая фантастика
альтернативная история
5.67
рейтинг книги
Иван Московский. Первые шаги

Случайная жена для лорда Дракона

Волконская Оксана
Фантастика:
юмористическая фантастика
попаданцы
5.00
рейтинг книги
Случайная жена для лорда Дракона

Идеальный мир для Социопата 2

Сапфир Олег
2. Социопат
Фантастика:
боевая фантастика
рпг
6.11
рейтинг книги
Идеальный мир для Социопата 2

Войны Наследников

Тарс Элиан
9. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Войны Наследников

Попаданка для Дракона, или Жена любой ценой

Герр Ольга
Любовные романы:
любовно-фантастические романы
7.17
рейтинг книги
Попаданка для Дракона, или Жена любой ценой

Серые сутки

Сай Ярослав
4. Медорфенов
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Серые сутки

Баоларг

Кораблев Родион
12. Другая сторона
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Баоларг

Кодекс Крови. Книга III

Борзых М.
3. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга III