Тема: Работа с изображением фона(получить фон, используя MapBackground)
Пример показывает возможность спроецировать данные фона на адресное пространство процесса с помощью системной функции MapBackground для последующей работы с этим изображением.
Процитирую справку:
Спроецированные данные доступны на чтение и запись.
Размер данных фона равен 3*xsize*ysize. Изменение размеров фона блокируется на время работы с спроецированными данными.
Цвет каждого пикселя хранится как 3-байтовая величина BBGGRR.
Пиксели фонового изображения записываются последовательно слева направо, сверху вниз.
Размер можно узнать с помощью системной функции GetBackgroundSize.
И далее в этом примере фоновое изображение выводится в окно.
После окончания работы с фоновым изображением закрыть проекцию данных фона на адресное пространство процесса можно с помощью системной функции UnmapBackground.
В кратце суть, как это можно сделать:
var
BackgroundSize: TSize;
Background: Pointer;
.........
BackgroundSize := GetBackgroundSize;
Background := MapBackground;
DrawImage(Background^, 0, 0, BackgroundSize.Width, BackgroundSize.Height);
UnmapBackground(Background);
В примере используется DrawImageEx с workaround-ом против рисования на правой и нижней границе окна(известный баг ядра: обсуждалось и есть варианты решения).
Окно изменяемого размера — его можно растягивать.
program MapUnmapBackground;
uses
KolibriOS;
var
WndWidth, WndHeight: LongWord;
WndLeft, WndTop: LongInt;
ThreadInfo: TThreadInfo;
BackgroundSize: TSize;
Background: Pointer;
procedure On_Redraw;
procedure DrawBackgroundImageToWindow;
var
W, H, Pad: LongWord;
begin
if LongInt(TBox(ThreadInfo.Client).Height) > -1 then
begin
if TBox(ThreadInfo.Client).Width > BackgroundSize.Width then
begin
W := BackgroundSize.Width;
Pad := 0;
end
else
begin
W := TBox(ThreadInfo.Client).Width;
Pad := (BackgroundSize.Width - TBox(ThreadInfo.Client).Width) * 3;
end;
if TBox(ThreadInfo.Client).Height > BackgroundSize.Height then
H := BackgroundSize.Height
else
H := TBox(ThreadInfo.Client).Height;
DrawImageEx(Background^, 0, 0, W, H, 24{бита}, nil, Pad);
end;
end;
begin
BeginDraw;
DrawWindow(WndLeft, WndTop, WndWidth, WndHeight, 'Map\Unmap Background', $00FFFFFF,
WS_SKINNED_SIZABLE + WS_CLIENT_COORDS + WS_CAPTION, CAPTION_MOVABLE);
GetThreadInfo($FFFFFFFF, ThreadInfo);
BackgroundSize := GetBackgroundSize;
Background := MapBackground;
DrawBackgroundImageToWindow;
UnmapBackground(Background);
EndDraw;
end;
begin
HeapInit;
with GetScreenSize do
begin
WndHeight := Height div 2;
WndWidth := Width div 2;
WndLeft := (Width - WndWidth) div 2;
WndTop := (Height - WndHeight) div 2;
end;
SetEventMask(EM_REDRAW + EM_BUTTON);
while True do
case WaitEvent of
REDRAW_EVENT:
On_Redraw;
BUTTON_EVENT:
Break;
end;
end.
Прикладываю скомпилированный пример MapUnmapBackground.kex
Модератор: офтопик вырезан, никому не прилетело из-за истечения сроков по причине длительного отсутствия модератора.