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