div.main {margin-left: 20pt; margin-right: 20pt}
Работаем с рабочим столом
Virtual Reality
В сегодняшнем разделе графики я решил
познакомить тебя с издевательством над
десктопом. Если говорить точнее, мы сегодня
научимся на нём рисовать и запоминать его
содержимое. Как всегда, я постараюсь всё
хорошенечко растолковать и показать. Надеюсь,
что тебе понравится сегодняшнее занятие.
Для издевательств нам понадобиться форма с двумя
кнопками и одной картинкой. Создай новый проект и
поставь на него две пимпы TButton и один штука TImage.
Приступим? Для первой кнопки напишем в событии
OnClick :
procedure TForm1.Button1Click(Sender: TObject);
var
ScreenDC:HDC;
begin
ScreenDC := GetDC(0);
Rectangle(ScreenDC, 10, 10, 200, 200);
ReleaseDC(0,ScreenDC);
end;
С помощью этой процедуры я рисую прямо на
десктопе. Во время рисования, мне насрать на все
запущенные приложения. Если они попадаются под
руку, то рисование происходит поверх них.
Теперь о содержимом. Я объявляю переменную ScreenDC
типа HDC. HDC - это контекст рисования в windows, и
работает почти так же, как и TCanvas (чуть позже ты
увидешь связь). С помощью функции GetDC(0) я
возвращаю контекст окна указанного в скобках. Но
в этих скобках стоит 0 (ноль), а это значит, что мне
нужен глобальный контекст, то есть самого
десктопа.
Далее, я вызываю функцию Rectangle, она похожа на ту,
что мы использовали раньше TCanvas.Rectangle. Есть только
одно отличие - первый параметр теперь, это
контекст устройства, а затем идут координаты
прямоугольника. Это связано с тем, что раньше мы
рисовали через объект TCanvas, а сейчас будем
рисовать средствами GDI Windows. Скажу по секрету :)
TCanvas.Rectangle всего лишь вызывает Rectangle из Windows API и
подставляет нужный контекст устройства и
размеры. Сейчас мы сами сделаем это, без помощь
TCanvas.
После рисования, я освобождаю больше не нужный
мне контекст через функцию ReleaseDC. Такие вещи
обязательно надо освобождать, чтобы не засорять
память.
Если ты захочешь рисовать не на десктопе, а
внутри определённого окна, то в этой процедуре
нужно поправить только первую строчку. А именно,
в качестве параметра GetDC передавать указатель на
окно. Сразу возникает вопрос: "Как узнать
указатель окна чужой проги?". Для этого можно
воспользоваться функцией FindWindow (с ней мы уже
знакомились в предыдущих номерах).
Сейчас можно запустить прогу и посмотреть на
результат, а мы я пока перейду ко второй пимпе.
Для неё мы напишем следующий текст:
procedure TForm1.Button2Click(Sender: TObject);
var
Canvas:TCanvas;
ScreenDC:HDC;
begin
ScreenDC := GetDC(0);
Canvas:=TCanvas.Create();
Canvas.Handle:=ScreenDC;
Image1.Canvas.Copyrect(Rect(0,0,Image1.Width,Image1.Height),
Canvas, Rect(0,0,Screen.Width,Screen.Height));
ReleaseDC(0,ScreenDC);
Canvas.Free;
end;
Сразу скажу, что здесь я получаю копию десктопа.
Первая строка такая же, как и в предыдущей
процедуре. Я точно также получаю контекст
десктопа. Потом я создаю новую переменную Canvas
типа ТCanvas (знакомый нам контекст рисования).
Потом я связываю их между собой с помощью
простого присваивания в Canvas.Handle:=ScreenDC. Теперь мой
TCanvas указывает на декстоп, и я могу рисовать на
нём, привычными нам методами.
Далее, я получаю копию экрана и записываю её в
картинку TImage с помощью функции Copyrect у контекста
рисования картинки (Image1.Canvas.Copyrect). Эта функция
выглядит так:
procedure CopyRect(
Dest: TRect; //Размеры получаемого изображения
Canvas: TCanvas;//Контекст, из которого будет
копироваться
Source: TRect//Размеры исходного изображения
);
CopyRect производит копирование изображения и
одновременное масштабирование из размеров Source в
Dest.
В качестве первого параметра идут размеры
получаемого изображения. Размеры передаются в
виде переменной типа TRect. TRect - это простая запись,
которая содержит четыре параметра:
TRect = record
Left, Top, Right, Bottom: Integer;
end;
С этим типом мы ещё не знакомы. Если хорошенько
рассмотреть, то можно заметить сходство с
объявлением объектов. Это так. Записи - это
маленькие объекты, но не имеющие методов (процедур
и функций), а только параметры любого типа. Все
параметры общедоступны и внутри записи нельзя
использовать директивы private, protected или public.
Для получения такого типа и использую функцию Rect
которая создаёт TRect. В качестве параметров
выступают соответствующие размеры Rect(0, 0, Image1.Width,
Image1.Height).
Второй параметр - контекст рисования Canvas, который
у нас ассоциирован с контекстом десктопа. Из него
и будет происходить копирование.
Третий параметр - размеры исходного изображения.
И в самом конце, я освобождаю контекст рисования
десктопа ReleaseDC(0,ScreenDC); и Canvas.Free.
Запусти прогу и посмотри на результат. Если что-то
ещё осталось непонятным, то после этого всё
станет на свои места.
|