Professional Documents
Culture Documents
2005. Przykady
Autor: Mariusz Owczarek
ISBN: 978-83-246-0875-1
Format: B5, stron: 216
Wydawnictwo Helion
ul. Kociuszki 1c
44-100 Gliwice
tel. 032 230 98 63
e-mail: helion@helion.pl
Spis treci
Rozdzia 11.
Obiekt Graphics
kartka do rysowania
Wikszoci komponentw wizualnych VC++ zawiera waciwo Graphics, dziki ktrej
mona rysowa, wypisywa teksty i umieszcza na nich grafiki w postaci bitmapy.
Moesz pomyle o waciwoci Graphics jako o kartce czy ptnie, na ktrym mona
tworzy grafik.
Na pocztku po utworzeniu komponentu jego waciwo Graphics jest pusta. Przed
rozpoczciem rysowania trzeba stworzy obiekt typu Graphics i podpi do tej waciwoci. Dopiero na tym obiekcie mona rysowa. Do tworzenia obiektu Graphics suy
metoda CreateGraphics() wywoywana na komponencie, na ktrym chcemy rysowa.
Oprcz podoa do rysowania niezbdne s take obiekty klasy Pen i Brush, a do wywietlania tekstu take obiekt opisujcy czcionk typu Font.
Pen piro, jakim rysujemy.
Brush (pdzel) rodzaj wypenienia rysowanych obiektw (kolor, dese). Mamy dwa
rodzaje pdzli: SolidBrush to pdzel jednokolorowy, TextureBrush za wypenia obiekty
120
Przykad 11.1.
Po naciniciu przycisku narysuj ukon niebiesk lini na oknie aplikacji.
Rozwizanie
Do nowego projektu aplikacji wstaw przycisk Button.
Po naciniciu przycisku naley utworzy obiekt typu Graphics dla gwnego okna
aplikacji, a nastpnie obiekt pira Pen. Poniewa metoda button1_Click() jest metod
klasy reprezentujcej gwne okno, odwoujemy si do tego okna za pomoc wskanika
this. Teraz mona ju rysowa po oknie, korzystajc z metody obiektu Graphics rysujcej linie. Oto kod metody, ktr naley przypisa do zdarzenia Click:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
Graphics^ g1=this->CreateGraphics();
Pen^ pioro = gcnew Pen(System::Drawing::Color::Aqua);
g1->DrawLine(pioro,10,10,100,100);
}
Zauwa, e piro Pen i pdzel Brush nie s waciwociami obiektu Graphics, ale oddzielnymi obiektami.
Obiekt Graphics posiada wiele metod sucych do rysowania punktw, linii, figur,
a nawet wywietlania caych bitmap z plikw. Zestawienie metod klasy Graphics
podaje tabela 11.1.
Tabela 11.1. Wybrane metody rysujce obiektu Graphics
Metoda
Dziaanie
121
Dziaanie
Clear(Color kolor)
Poniewa metod jest duo i kada ma kilka postaci, tabela 11.1 podaje tylko po jednej
postaci kadej metody, aby moliwe byo zestawienie wszystkich.
122
Przykad 11.2.
Wywietl w oknie programu tekst podany w polu tekstowym. Nie uywaj komponentu
Label.
Rozwizanie
Utwrz nowy projekt aplikacji i wstaw do okna pole tekstowe TextBox oraz przycisk
Button.
Przykad 11.3.
Po naciniciu przycisku wywietl na formularzu wykres ze wsprzdnych podanych
w polach tekstowych.
Rozwizanie
Wstaw do okna aplikacji dziesi pl tekstowych TextBox, dwie etykiety Label i przycisk Button.
Powiksz wymiary okna, a pod waciwoci Text etykiet i przycisku podstaw odpowiednie teksty, tak aby cao wygldaa jak na rysunku 11.3 (na razie bez wykresu
i wpisanych wsprzdnych).
123
Rysunek 11.3.
Aplikacja
do rysowania
wykresw
Po naciniciu przycisku Rysuj wsprzdne bd pobierane z pl tekstowych i przekazywane do tablicy obiektw System::Drawing::PointF, ktre reprezentuj punkty
na paszczynie. Nastpnie narysujemy wykres za pomoc metody DrawCurve(). Pod
zdarzenie Click przycisku podepnij podan metod:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
Graphics^ g1=this->CreateGraphics();
g1->Clear(System::Drawing::Color::FromName("Control"));
array<System::Drawing::PointF>^ punkty = gcnew array
<System::Drawing::PointF>(i);
punkty[0].X=Convert:: oSingle(textBox1-> ext);
punkty[0].Y=(this->Height-30)-Convert:: oSingle(textBox2-> ext);
punkty[1].X=Convert:: oSingle(textBox3-> ext);
punkty[1].Y=(this->Height-30)-Convert:: oSingle(textBox4-> ext);
punkty[2].X=Convert:: oSingle(textBoxi-> ext);
punkty[2].Y=(this->Height-30)-Convert:: oSingle(textBox6-> ext);
punkty[3].X=Convert:: oSingle(textBox7-> ext);
punkty[3].Y=(this->Height-30)-Convert:: oSingle(textBox8-> ext);
punkty[4].X=Convert:: oSingle(textBox9-> ext);
punkty[4].Y=(this->Height-30)-Convert:: oSingle(textBox10-> ext);
Pen^ pioro1 = gcnew Pen(System::Drawing::Color::DarkGreen);
g1->DrawCurve(pioro1,punkty);
}
Przykad 11.4.
Po kadym naciniciu przycisku wywietl w oknie prostokt o losowych wsprzdnych, losowych wymiarach i losowym kolorze.
Rozwizanie
Do nowego projektu aplikacji wstaw przycisk Button.
Aby wygenerowa wsprzdne i kolor prostoktw, bdziemy potrzebowa generatora
liczb losowych. Jest to obiekt typu Random, ktry trzeba utworzy, a nastpnie mona
pobiera z niego liczby, uywajc metody Next() tego obiektu. Po wygenerowaniu
liczb prostokt rysujemy za pomoc metody FillRectangle(). Kolor pdzla definiujemy za pomoc trzech liczb losowych okrelajcych skadowe RGB. Oto metoda zdarzenia Click przycisku:
124
Przykad 11.5.
Wywietl w oknie plik rysunek.jpg z lewym grnym rogiem w punkcie (100, 100).
Rozwizanie
Wstaw do aplikacji przycisk Button.
Aby wywietli obrazek, najpierw utworzymy obiekt Image zawierajcy plik rysunek.jpg
(plik o takiej nazwie trzeba wczeniej umieci w folderze programu), a nastpnie wywietlimy go w oknie, uywajc metody DrawImage().
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
Graphics^ g1=this->CreateGraphics();
Image^ obrazek = Image::FromFile("rysunek.jpg");
g1->DrawImage(obrazek,100,100);
}
Piro Pen
Uywany ju przez nas obiekt Pen, czyli piro, daje wiele moliwoci. Za porednictwem waciwoci tego obiektu mona sterowa zarwno gruboci linii, jak i rysowa
linie przerywane, wybiera styl rozpoczcia i zakoczenia linii itp. Najwaniejsze waciwoci przedstawia tabela 11.2.
Przykad 11.6.
Wywietl w oknie kilka linii rysowanych rnymi stylami.
Rozwizanie
Utwrz nowy projekt aplikacji i wstaw do niego przycisk Button.
Po naciniciu przycisku bdziemy zmienia parametry pira i rysowa nim kolejne
linie. Oto metoda dla zdarzenia Click przycisku:
125
Znaczenie
Width
Brush
Color
Kolor linii.
StartCap
EndCap
DashStyle
z kresek i kropek,
System::Drawing::Drawing2D::DashStyle::DashDotDot linia z kreski i dwch
kropek,
System::Drawing::Drawing2D::DashStyle::Dot linia z kropek,
System::Drawing::Drawing2D::DashStyle::Solid linia ciga.
DashCap
DashOffset
126
pioro1->DashOffset = 2;
g1->DrawLine(pioro1,10,110,2i0,110);
Przykad 11.7.
Narysuj na oknie aplikacji dwa wycinki k, jeden wypeniony jednym kolorem i drugi
wypeniony tekstur pobran z pliku rysunek.jpg w uoeniu kafelkowym.
Rozwizanie
Utwrz nowy projekt aplikacji i wstaw do niego przycisk Button.
Po naciniciu tego przycisku utworzymy dwa pdzle: jednokolorowy i teksturowany,
a nastpnie wywietlimy wycinki k za pomoc metody FillPie(). Aby program dziaa, potrzebny jest rysunek rysunek.jpg w folderze programu.
127
Znaczenie
Image
WrapMode
jako pojedyncza,
System::Drawing::Drawing2D::WrapMode:: ileFlipX wywietlanie ssiadujco
Po uruchomieniu i naciniciu przycisku aplikacja moe wyglda tak, jak na rysunku 11.5 (efekt jest zaleny od zawartoci rysunku uytego do teksturowania).
Rysunek 11.5.
Malowanie
pdzlem zwykym
i teksturowanym
128
Znaczenie
Rotate(Single kt)
Przykad 11.8.
Narysuj kwadrat wypeniony tekstur z pliku rysunek.jpg w uoeniu kafelkowym,
tekstura ma by obrcona o 20 stopni i przesunita o 10 punktw w kierunku osi Y.
Rozwizanie
Do nowego projektu aplikacji wstaw przycisk Button.
Do zdarzenia Click przycisku przypiszemy metod, w ktrej utworzymy macierz
transformacji, w tej macierzy zapiszemy odpowiednie transformacje za pomoc metod
Rotate() i Translate(). Nastpnie podstawimy t macierz do waciwoci Transform
pdzla, ktrym pomalujemy kwadrat.
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
Graphics^ g1=this->CreateGraphics();
Image^ obrazek = Image::FromFile("rysunek.jpg");
System::Drawing::Drawing2D::Matrix^ macierz =
gcnew System::Drawing::Drawing2D::Matrix();
macierz->Rotate(20);
macierz-> ranslate(0,10);
SolidBrush^ pedz =
gcnew SolidBrush(System::Drawing::Color::DarkGreen);
extureBrush^ pedz_text = gcnew extureBrush(obrazek);
pedz_text->WrapMode=System::Drawing::Drawing2D::WrapMode:: ile;
pedz_text-> ransform=macierz;
g1->FillRectangle(pedz_text,180,20,100,100);
}
129
Przykad 11.9.
Narysuj na oknie aplikacji dwiecie punktw o losowych wsprzdnych i w losowych
kolorach.
Rozwizanie
W oknie aplikacji umie przycisk Button.
Po klikniciu przycisku utworzymy obiekt Bitmap, na ktrym w ptli for zostanie
umieszczonych dwiecie punktw. Nastpnie ten obiekt zostanie wywietlony na obiekcie Graphics okna aplikacji, czyli punkty pojawi si na tym oknie. Metoda DrawImage()
wymaga argumentu typu Image, a poniewa obiekt bitmapa jest typu Bitmap, trzeba zastosowa konwersj typw. Oto odpowiedni kod:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
System::Int32 wspx;
System::Int32 wspy;
System::Drawing::Color kolor;
Graphics^ g1=this->CreateGraphics();
Random^ liczba_los = gcnew Random();
Bitmap^ bitmapa = gcnew Bitmap(this->Width,this->Height);
for (System::Int32 i=0;i<200;i++) {
wspx=liczba_los->Next(this->Width);
wspy=liczba_los->Next(this->Height);
kolor=System::Drawing::Color::FromArgb(liczba_los->Next(2ii),
liczba_los->Next(2ii), liczba_los->Next(2ii));
bitmapa->SetPixel(wspx,wspy,kolor);
}
g1->DrawImage(dynamic_cast<Image^>(bitmapa),10,10);
}
Rysowanie trwae
odwieanie rysunku
System Windows nie zapamituje zawartoci okien po ich narysowaniu. Zwizane
jest to z oszczdnoci pamici dlatego narysowane obiekty znikaj na przykad po
przykryciu okna rysunku przez inne okno. Kiedy okno jest wywietlane, powtrnie
130
jest odwieane i wszystkie kontrolki s malowane jeszcze raz. Generowane jest wtedy
zdarzenie Paint. Aby rysunek by w dalszym cigu widoczny w oknie, naley go rwnie odwiey. W praktyce oznacza to, e metoda obsugujca zdarzenie Paint powinna rysowa rysunek jeszcze raz.
Przykad 11.10.
Stwrz aplikacj z dwoma polami wyboru CheckBox, niech pierwsze pole wcza i wycza rysunek kwadratu w oknie, a drugie rysunek koa. Rysunek ma by zachowywany po przykryciu okna przez inne okno.
Rozwizanie
Utwrz aplikacj z dwoma polami wyboru. We waciwo Text pierwszego pola wyboru wpisz Kwadrat, a drugiego Koo.
Najpierw napisz metod rysujc koo i kwadrat podanego koloru. Metod umie
w klasie Form1, podobnie jak metody obsugujce zdarzenia.
private: System::Void rysuj_kwadrat(System::Drawing::Color kolor) {
Graphics^ g1=this->CreateGraphics();
Pen^ pioro = gcnew Pen(kolor);
g1->DrawRectangle(pioro,10,10,1i0,1i0);
delete g1;
delete pioro;
}
private: System::Void rysuj_kolo(System::Drawing::Color kolor) {
Graphics^ g1=this->CreateGraphics();
Pen^ pioro = gcnew Pen(kolor);
g1->DrawEllipse(pioro,20,20,130,130);
delete g1;
delete pioro;
}
Teraz czas na obsug zdarzenia Paint. W widoku budowy okna aplikacji (zakadka
Form1.h [Design]) kliknij budowane okno aplikacji, a nastpnie w prawym panelu
przecz si na widok zdarze (ikona byskawicy). Teraz znajd zdarzenie Paint i kliknij je dwukrotnie. Zostaniesz przeniesiony do kodu aplikacji, gdzie utworzy si metoda
Form1_Paint(). Metoda ta bdzie rysowaa figury, gdy bd zaznaczone odpowiednie
pola. Uzupenij j jak niej.
private: System::Void Form1_Paint(System::Object^ sender,
System::Windows::Forms::PaintEventArgs^ e) {
if (checkBox1->Checked)
rysuj_kwadrat(System::Drawing::Color::DarkBlue);
if (checkBox2->Checked)
rysuj_kolo(System::Drawing::Color::DarkBlue);
}
131
Animacje
Animacje najatwiej uzyska, wykorzystujc komponent Timer. Jednym ze sposobw
jest wycieranie rysunku z poprzedniego kroku animacji i rysowanie nowego za kadym
razem, kiedy generowane jest zdarzenie Tick komponentu Timer.
Przykad 11.11.
Napisz program wywietlajcy animowany prostokt w oknie. Prostokt powinien si
porusza w gr i w d przez ca wysoko okna.
Rozwizanie
Utwrz nowy projekt aplikacji i wstaw do niego komponent Timer oraz dwa przyciski.
Przyciski bd suyy do rozpoczcia i zatrzymania ruchu prostokta. We waciwo
Text pierwszego przycisku wstaw Start, a drugiego Stop.
132
Najpierw musimy utworzy dwa pola klasy, ktre bd okrelay aktualn wsprzdn y prostokta i krok jego przesunicia. Pola te zadeklaruj w klasie Form1, tak jak
deklarujemy metody:
private: System::Int16 krok;
private: System::Int16 y;
Na pasku niewidocznych komponentw na dole zakadki projektowania aplikacji zaznacz komponent Timer i przejd do jego zdarze w prawym panelu. Kliknij dwukrotnie
zdarzenie Tick, tworzc metod uruchamian czasomierzem. W tej metodzie bd
rysowane dwa prostokty; jeden w kolorze formularza spowoduje wytarcie prostokta
z poprzedniego kroku, nastpnie bdzie zmieniana wsprzdna i rysowany nowy
przesunity prostokt. Metod zmodyfikuj jak niej.
private: System::Void timer1_ ick(System::Object^ sender, System::EventArgs^ e) {
Graphics^ g1 = this->CreateGraphics();
SolidBrush^ pedzel = gcnew SolidBrush(System::Drawing::Color::Aquamarine);
SolidBrush^ pedz_kas =
gcnew SolidBrush(System::Drawing::Color::FromName("Control"));
g1->FillRectangle(pedz_kas,10,y,100,10);
y=y+krok;
g1->FillRectangle(pedzel,10,y,100,10);
if ((y>100)||(y<1))
krok=-krok;
delete g1;
}
Zmienn krok, ktra okrela przesunicie prostokta w jednej klatce animacji, zainicjalizuj w chwili tworzenia okna. Wykorzystamy do tego zdarzenie FormLoad.
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
krok=2;
}
Pozostao jeszcze zaprogramowanie metod wywoywanych przy naciniciu przyciskw. Pierwszy przycisk bdzie uruchamia Timer, a drugi zatrzymywa.
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
krok=4;
timer1->Start();
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
timer1->Stop();
}