В сегодняшнем разделе графики я решил познакомить тебя с издевательством над
десктопом. Если говорить точнее, мы сегодня научимся на нём рисовать и
запоминать его содержимое. Как всегда, я постараюсь всё хорошенечко растолковать
и показать. Надеюсь, что тебе понравится сегодняшнее занятие.
Для
издевательств нам понадобиться форма с двумя кнопками и одной картинкой. Создай
новый проект и поставь на него две пимпы 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.
Запусти прогу и посмотри на
результат. Если что-то ещё осталось непонятным, то после этого всё станет на
свои места.
Литература по Borland Delphi
|