DataLife Engine > Delphi > Рисуем на десктопе
Рисуем на десктопе12 января 2008. Разместил: Fen-Omen |
|
ellipeses.rar [18.75 Kb] (cкачиваний: 102)
Для начала нужно создать в Delphi новое приложение File – New – Application. Далее закрываем окно Uses1.pas, т.к. писать мы будем на чистом API, и такая легкая и удобная в обращении VCL нам не понадобится. Открываем окно с кодом программы Project – View Source и вставляем туда следующий код: program Konfetti; uses Windows; var ScreenDC: hDC; BrushHandle, OldBrushHandle: HBRUSH; PenHandle, OldPenHandle: HPEN; color:cardinal; x,y,z,t:integer; begin ScreenDC := GetDC(0); randomize; z:=0; repeat color:=random(16777215); PenHandle := CreatePen(PS_SOLID, 1, color); OldPenHandle := SelectObject(ScreenDC, PenHandle); BrushHandle := CreateSolidBrush(color); OldBrushHandle := SelectObject(ScreenDC, BrushHandle); x:=Random(1027); y:=Random(768); t:=random(6); Ellipse(ScreenDC,x,y,x+t,y+t); z:=z+1; sleep(7); until z=4000; SelectObject(ScreenDC, OldBrushHandle); DeleteObject(BrushHandle); SelectObject(ScreenDC, OldPenHandle); DeleteObject(PenHandle); ReleaseDC(0,ScreenDC); end. Теперь запустим программу. Рабочий стол буквально завалило разноцветными конфетти. Разберем по порядку, как мы этого добились: Для начала мы объявили переменную ScreenDC типа hDC, которая будет указывать на десктоп. Потом переменные BrushHandle, OldBrushHandle которые будут служить указателями на кисть и PenHandle, OldPenHandle, на карандаш, соответственно. Зачем, я расскажу ниже. Как не трудно догадаться, color будет хранить значение цвета, а x,y,z,t будут служить как раз таки для самой прорисовки конфети. В самом начале программы, мы получаем контекст непосредственно рабочего стола - ScreenDC := GetDC(0), включаем генерацию случайных (псевдослучайных) чисел, и указываем z (кол-во конфетти) равным нулю. Запускаем блок repeat, будет повторять весь код, расположенный ниже, пока не выполнится условие until. Для начала создадим кисть и карандаш: PenHandle := CreatePen(PS_SOLID, 1, color); OldPenHandle := SelectObject(ScreenDC, PenHandle) BrushHandle := CreateSolidBrush(color); OldBrushHandle := SelectObject(ScreenDC, BrushHandle); Затем уже обозначаем координаты прорисовки объекта, в нашем случае эллипса. Тут надо сделать небольшую заметку. Объект вообще прорисовывается по четырем координатам: Ellipse(ScreenDC,x1,y1,x2,y2) Первым параметром у нас идет контекст рабочего стола, это понятно. Координаты x1, y1 отвечают за начало прорисовки объекта, а x2, y2 - координаты, до которых он будет прорисовываться. Допустим, если использовать функцию с такими параметрами: Ellipse(ScreenDC,500,500,505,505) то у нас получится круг размером всего лишь в 5 пикселей. Он будет рисоваться слева направо. Если же мы зададим такие координаты Ellipse(ScreenDC,500,500,300,250), у нас он будет прорисовываться наоборот, справа налево, и в итоге получится самый настоящий эллипс огромных размеров. Таким образом, за размер конфетти в нашем коде отвечает переменная t. Сразу после прорисовки, идет запись еще одного объекта в копилку переменной z, и ожидание в течении 7 миллисекунд. Как только число снежинок достигнет 3к штук, операция повторения будет прервана (until z=3000;). Затем нам нужно в обязательном (ну если не обязательном, то очень рекомендуемом) порядке отчистить память от наших указателей на кисти и рабочий стол: SelectObject(ScreenDC, OldBrushHandle); DeleteObject(BrushHandle); SelectObject(ScreenDC, OldPenHandle); DeleteObject(PenHandle); ReleaseDC(0,ScreenDC); Вообще, чтобы нарисовать эллипс нам не нужно было создавать ни кистей, ни карандаша. Но в случае если бы мы не создали карандаш, наш круг (в данном случае красного цвета) был бы обведен черным цветом, что нам совсем не нужно. В том же случае, если бы мы не создали карандаш, круг внутри был бы белым. Если нужно нарисовать просто белый круг, (по идее, мы создавали эллипс, но так как обе координаты конечные его координаты одинаково удалены от начальных, то мы получаем круг), даже не нужно создавать кисть и карандаш. Тогда рисование эллипса сведется всего к нескольким строчкам кода: programm Ellipse; uses Windows; var ScreenDC: hDC; begin ScreenDC := GetDC(0); Ellipse(ScreenDC,50,50,88,88); ReleaseDC(0,ScreenDC); end. Можно, например, также сделать прорисовку объектов прямо под курсором, и при перемещении мыши, будет эффект собственноручного рисования на рабочем столе. Для этого надо объявить дополнительную переменную типа TPoint, которая как раз будет хранить координаты курсора. В получении координат курсора нам поможет API-функция getcursorpos: program MouseGraf; uses Windows; var ScreenDC: hDC; BrushHandle, OldBrushHandle: HBRUSH; PenHandle, OldPenHandle: HPEN; color:cardinal; pos:Tpoint; graf:boolean; begin color:=255; repeat ScreenDC := GetDC(0); PenHandle := CreatePen(PS_SOLID, 1, color); OldPenHandle := SelectObject(ScreenDC, PenHandle); BrushHandle := CreateSolidBrush(color); OldBrushHandle := SelectObject(ScreenDC, BrushHandle); getcursorpos(pos); // получаем координаты мыши Ellipse(ScreenDC,pos.X,pos.Y,pos.X+5,pos.Y+5); SelectObject(ScreenDC, OldBrushHandle); DeleteObject(BrushHandle); SelectObject(ScreenDC, OldPenHandle); DeleteObject(PenHandle); ReleaseDC(0,ScreenDC); until graf; end. Запустив эту программу, мы наблюдаем следующее: перемещая мышь, мы тем самым прорисовываем линию вдоль траектории перемещения. Кстати, может быть, кто-то захочет автоматизировать этот процесс. Можно сидеть, откинувшись на спинку стула, и смотреть за тем, как мышь сама елозит по Десктопу, выводя какие-нибудь слова. Для этого существует API-функция setcursorpos(x,y). Например, создадим программу, которая будет рисовать букву "П". Код программы приведен ниже. Она не очень отличается от тех, что мы разбирали выше, поэтому не будем пояснять ее действие. program P_Graff; uses Windows; var ScreenDC: hDC; BrushHandle, OldBrushHandle: HBRUSH; PenHandle, OldPenHandle: HPEN; color:cardinal; pos:TPoint; begin ScreenDC := GetDC(0); color:=255; PenHandle := CreatePen(PS_SOLID, 1, color); OldPenHandle := SelectObject(ScreenDC, PenHandle); BrushHandle := CreateSolidBrush(color); OldBrushHandle := SelectObject(ScreenDC, BrushHandle); setcursorpos(500,300); getcursorpos(pos); repeat setcursorpos(pos.x,pos.Y+1); getcursorpos(pos); Ellipse(ScreenDC,pos.x,pos.y,pos.x+11,pos.y+11); sleep(15); until pos.Y=450; setcursorpos(500,300); getcursorpos(pos); repeat setcursorpos(pos.x+1,pos.Y); getcursorpos(pos); Ellipse(ScreenDC,pos.x,pos.y,pos.x+11,pos.y+11); sleep(15); until pos.X=600; setcursorpos(600,300); getcursorpos(pos); repeat setcursorpos(pos.x,pos.Y+1); getcursorpos(pos); Ellipse(ScreenDC,pos.x,pos.y,pos.x+11,pos.y+11); sleep(15); until pos.y=450; // освобождаем память от созданного карандаша и кисти SelectObject(ScreenDC, OldBrushHandle); DeleteObject(BrushHandle); SelectObject(ScreenDC, OldPenHandle); DeleteObject(PenHandle); // освобождаем память от указателя на рабочий стол ReleaseDC(0,ScreenDC); end. Ну вот и все ). Приветствуем критику статьи. Ждем Ваших вопросов и комментариев. |