Zásady kreslení Kreslení na obrazovku 139



Podobné dokumenty
VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Klíčové pojmy: Události, handlery, třída Graphics, pera, stětce, kreslení vyplněných a nevyplněných objektů.

Struktura třídy, operátory, jednoduché algoritmy, junit. Programování II 2. cvičení Alena Buchalcevová

Prostory jmen. #include<iostream.h> namespace RadimuvProstor { int secti(int a, int b); class Trida { private: int Atribut; public: void metoda();

Algoritmizace a programování

Manuál pro WebRSD. verze 2.0 z

Vizualizace v ArConu (1.část) světla a stíny

Programování v jazyku C# II. 4.kapitola

Uložené procedury Úvod ulehčit správu zabezpečení rychleji

Algoritmizace a programování

TVORBA MULTIMEDIÁLNÍCH PREZENTACÍ. Mgr. Jan Straka

Maturitní témata z předmětu Programování a databázové systémy. pro šk. rok 2012/2013

Obsah přednášky. GDI+ Tvorba vlastních komponent Vlastní kreslení 1/36

Výsledky přijímacích zkoušek

III/2 Inovace a zkvalitnění výuky prostřednictvím ICT. Cyklus while, do-while, dělitelnost, Euklidův algoritmus

ABB i-bus KNX Inteligentní elektroinstalace pro Váš perfektní dům

DATABÁZE DŮLEŽITÉ: Před načtením nové databáze do vaší databáze si prosím přečtěte následující informace, které vám umožní:

3 Vývojová prostředí, základní prvky jazyka Java, konvence jazyka Java

Semestrální práce z NUR Uživatelské rozhraní pro automat MHD. Michal Samek (samekmic)

Kdy (ne)testovat web oční kamerou

Měřidla. Existují dva druhy měření:

Seznámení žáků s pojmem makra, možnosti využití, praktické vytvoření makra.

Příručka pro zadavatele E-ZAK krok za krokem

V této části manuálu bude popsán postup jak vytvářet a modifikovat stránky v publikačním systému Moris a jak plně využít všech možností systému.

Manuál Kentico CMSDesk pro KDU-ČSL

Obrázek. Základní popis, zadání úkolu. Struktura tříd,

4. cvičení: Pole kruhové, rovinné, Tělesa editace těles (sjednocení, rozdíl, ), tvorba složených objektů

Tekla Structures Multi-user Mode

Obsah 1. Grafický manuál firmy 2. Podklady grafického manuálu 3. Varianty loga 4. Logo a logotyp

Školní kolo soutěže Mladý programátor 2016, kategorie A, B

NÁVOD K OBSLUZE. Obj. č.:

TECHNICKÉ KRESLENÍ A CAD

Ovládání TV platformy a funkce Chytrá TV

Vzdělávání a podpora pedagogických pracovníků ZŠ a SŠ při integraci ICT do výuky POČÍTAČOVÁ GRAFIKA - 1 -

ISZR Referenční agent.net

Zálohování a obnova Uživatelská příručka

Úvod do problematiky dlouhodobé ochrany digitálních dokumentů - díl 4.

Rozšířená nastavení. Kapitola 4

primární tlačítko (obvykle levé). Klepnutí se nejčastěji používá k výběru (označení) položky nebo k otevření nabídky.

Aplikované úlohy Solid Edge. SPŠSE a VOŠ Liberec. Ing. Jana Kalinová [ÚLOHA 01 ÚVOD DO PROSTŘEDÍ OBJEMOVÁ SOUČÁST; PŘÍKAZ SKICA A JEJÍ VAZBENÍ]

Uživatelská dokumentace

Informační a komunikační technologie. 1.4 Data, informace, komprimace

DUM 10 téma: Nástroje malování

Online travel solutions s.r.o. YONAD.CZ. Uživatelská příručka. Verze červen 2009

Nástroje produktivity

1.2.7 Druhá odmocnina

Pomocník diabetika Uživatelská příručka

TIP: Pro vložení konce stránky můžete použít klávesovou zkratku CTRL + Enter.

Operace nad celými tabulkami

1. Orgány ZO jsou voleny z členů ZO. 2. Do orgánů ZO mohou být voleni jen členové ZO starší 18 let.

Slovní úlohy vedoucí na lineární rovnice I

Cílem kapitoly je seznámit studenta se strukturou programu a jeho překladem.

Jednotný vizuální styl: podpis v ové korespondenci.

Aktivity s GPS 3. Měření některých fyzikálních veličin

Novela zákona o DPH a změny v programu Účtárna k

Ėlektroakustika a televize. TV norma ... Petr Česák, studijní skupina 205

INFORMATIKA počítačová grafika- rozdělení

Stále ještě váháte s přihlášením? Když už jsme řádně přihlášeni? Jak bude turnaj koncipován?

O D B O R O V É S D R U Ž E N Í Ž E L E Z N I Č Á Ř Ů Republiková rada seniorů JEDNACÍ ŘÁD. 1. Úvodní ustanovení

Android Elizabeth. Verze: 1.3

Návod k používání registračního systému ČSLH

Počítačová grafika 2. Opakování. Úprava barev a tónů. Retuše a efekty.

Digitální album návod k použití

P O K Y N Y P R O ZADAVATELE

které je třeba si položit před zakoupením levného CAD programu

STANOVY Klub leteckých modelářů Brno, z.s.

STANDARD 3. JEDNÁNÍ SE ZÁJEMCEM (ŽADATELEM) O SOCIÁLNÍ SLUŽBU

Zadávání tiskových zakázek prostřednictvím JDF a Adobe Acrobat Professional

Záloha a obnovení Uživatelská příručka

TECHNICKÁ UNIVERZITA V LIBERCI

NÁVRHOVÝ PROGRAM VÝMĚNÍKŮ TEPLA FIRMY SECESPOL CAIRO PŘÍRUČKA UŽIVATELE

UŽIVATELSKÁ PŘÍRUČKA PRO INTERNETBANKING PPF banky a.s.

Magnetic Levitation Control

Registr UJO. Příručka pro uživatele. Institut biostatistiky a analýz. Lékařské a Přírodovědecké fakulty Masarykovy univerzity.

WEBMAP Mapový server PŘÍRUČKA PRO WWW UŽIVATELE Hydrosoft Veleslavín, s.r.o., U Sadu 13, Praha 6

2008 Nokia. Všechna práva vyhrazena. Nokia, Nokia Connecting People a Nseries jsou ochranné známky nebo registrované ochranné známky společnosti

POKYNY K VYPLNĚNÍ žádosti o akreditaci rekvalifikačního programu směřujícího k čisté rekvalifikaci

Návod k obsluze Sušák na ruce

Mobilní verze. 109 Jak získat speciální aplikaci pro mobilní telefon. 110 Jak používat Facebook pro dotykové telefony

Microsoft Office Project 2003 Úkoly projektu 1. Začátek práce na projektu 1.1 Nastavení data projektu Plánovat od Datum zahájení Datum dokončení

Těhotenský test pro zrakově postižené Tereza Hyková

PŘÍRUČKA K PŘEDKLÁDÁNÍ PRŮBĚŽNÝCH ZPRÁV, ZPRÁV O ČERPÁNÍ ROZPOČTU A ZÁVĚREČNÝCH ZPRÁV PROJEKTŮ PODPOŘENÝCH Z PROGRAMU BETA

ČÁST PÁTÁ POZEMKY V KATASTRU NEMOVITOSTÍ

Voděodolný tloušťkoměr MG-411. Návod k obsluze

( x ) 2 ( ) Další úlohy s kvadratickými funkcemi. Předpoklady: 2501, 2502

NÁHRADA ŠKODY Rozdíly mezi odpov dnostmi TYPY ODPOV DNOSTI zam stnavatele 1) Obecná 2) OZŠ vzniklou p i odvracení škody 3) OZŠ na odložených v cech

Jak se zúčastnit dražby byty Kbely - duben 2016

Projekt: Inovace oboru Mechatronik pro Zlínský kraj Registrační číslo: CZ.1.07/1.1.08/

DPC-D218ID. Dveřní stanice pro 2D systém videovrátných. Uživatelský manuál

Masarykova univerzita Právnická fakulta

The University of Plymouth

Projekt: Inovace oboru Mechatronik pro Zlínský kraj Registrační číslo: CZ.1.07/1.1.08/

U S N E S E N Í. oprávněného : Ing. Karel Kupka, bytem K. Pokorného 1287/5, Ostrava - Poruba. proti

Přidávání animací do programů

Osvětlení modelového kolejiště Analog / DCC

Aplikované úlohy Solid Edge. SPŠSE a VOŠ Liberec. Ing. Jiří Haňáček [ÚLOHA 03 VYSUNUTÍ TAŽENÍM A SPOJENÍM PROFILŮ.]

WEBDISPEČINK NA MOBILNÍCH ZAŘÍZENÍCH PŘÍRUČKA PRO WD MOBILE

ČEZ Prodej, s.r.o., sídlem Duhová 425/1, 14053, Praha, IČ , zast. David Jünger, Mgr., sídlem 28. října 438/219, 70900, Ostrava

odbor kultury a památkové péče Magistrát města Zlína, náměstí Míru 12 pracoviště Zarámí 4421, Zlín, ivotucek@zlin.eu

Portál pro podávání žádostí o podporu je spuštěn na adrese

Transkript:

4 Zásady kreslení Formuláře jsou sice zručné, zvláště jsou-li naládované příhodnými ovládacími prvky, někdy však zabudované ovládací prvky 1 nestačí na to, aby realizovaly nějaký stav vaší aplikace takový, jaký ho chcete mít. Pak si takový stav budete muset nakreslit sami. Kreslit se může na obrazovku, do souboru, na tiskárnu, ale ať už budete kreslit kamkoliv, budete stále zacházet se stejnými základními prvky barvami, štětci, pery a písmy a se stejnými druhy věcí, které máte nakreslit: tvary, obrázky a řetězce. Kapitolu začneme prozkoumáním základů kreslení na obrazovku a hlavních stavebních kamenů kreslení. Připomínám, že všechny kreslicí techniky, které se probírají zde a v příštích dvou kapitolách, se stejnou měrou týkají ovládacích prvků i formulářů. Informace o budování vlastních ovládacích prvků najdete v kapitole 8: Ovládací prvky. Než začneme, je žádoucí zmínit se o tom, že jmenný prostor System.Drawing je implementovaný nad GDI+ ( Graphics Device Interface+), což je následník GDI. Původní GDI bylo hlavní oporou ve Windows už od dob, kdy vůbec byly nějaké Windows, a poskytovalo abstrakci nad obrazovkami a tiskárnami, aby bylo snadnější psát aplikace s grafickým uživatelským rozhraním, neboli ve stylu GUI ( Graphics User Interface). 2 GDI+ je DLL Win32 ( gdiplus.dll), která se dodává s Windows XP a je k dispozici i pro straší verze Windows. GDI+ je také neřízená (unmanaged) knihovna tříd C++, která obaluje GDI+. Protože třídy ze System.Drawing sdílejí mnohdy stejné názvy s třídami C++ GDI+, klidně se může stát, že při prohlížení tříd.net v online dokumentaci zakopnete o nějaké neřízené třídy. Jedná se o stejné pojmy, ale kódovací detaily jsou velmi odlišné, porovnáme-li neřízený C++ s čímkoli řízeným, takže mějte oči na stopkách. Kreslení na obrazovku Bez ohledu na to, na jaký druh kreslení se chystáte, budete zacházet se stejnou podkladovou abstrakcí, s třídou Graphics ze jmenného prostoru System.Drawing. Třída Graphics poskytuje abstraktní povrch, na který kreslíte, ať už se výsledky vašich kreslicích operací zobrazí na obra- 139

140 Základy kreslení zovce, uloží do souboru, nebo odešlou na tiskárnu. Třída Graphics je příliš obsáhlá na to, abych ji zde mohl předvést celou, ale budu se k ní v průběhu kapitoly mnohokrát vracet. Jedním ze způsobů, jak lze získat objekt grafiky, je zavolat CreateGraphics, čímž se vytvoří objekt grafiky sdružený s formulářem: bool drawellipse = false; void drawellipsebutton_click(object sender, EventArgs e) { // Indikátor, zda se bude kreslit elipsa nebo ne drawellipse =!drawellipse; Graphics g = this.creategraphics(); try { if( drawellipse ) { // Nakreslí elipsu g.fillellipse(brushes.darkblue, this.clientrectangle); else { // Smaže dříve nakreslenou elipsu g.fillellipse(systembrushes.control, this.clientrectangle); finally { g.dispose(); Poté, co získáme objekt grafiky, můžeme s jeho pomocí kreslit na formulář. Protože tlačítkem přepínáme, zda se bude kreslit elipsa nebo ne, buď nakreslíme elipsu tmavě modrou, nebo použijeme stejnou barvu pozadí, jakou má formulář. To je asi všechno srozumitelné, ale možná se divíte, k čemu tam je ten blok try-finally. Protože objekt grafiky drží podkladový prostředek, který spravuje systém Windows, je na nás, abychom prostředek uvolnili, když skončíme, dokonce i tehdy, když dojde k nějaké výjimce, a to je důvod, proč jsme do kódu zařadili blok try-finally. Třída Graphics, podobně jako mnohé třídy v.net, implementuje rozhraní IDisposable. Když nějaký objekt implementuje rozhraní IDisposable, je to pro klienta takového objektu signál, aby zavolal metodu Dispose rozhraní IDisposable, až s objektem skončí. Dá se tím objektu na vědomí, že nastal čas na uvolnění všech prostředků, které držel, například nějaký soubor nebo databázové připojení. V našem případě implementace metody Dispose rozhraní IDisposable třídy Graphics uvolní podkladový objekt grafiky, který udržovala. Daná záležitost se dá v C# zjednodušit tím, že se blok try-finally nahradí blokem using: void drawellipsebutton_click(object sender, EventArgs e) { using( Graphics g = this.creategraphics() ) {

Základy kreslení 141 g.fillellipse(brushes.darkblue, this.clientrectangle); // g.dispose se zde zavolá automaticky Blok using C# obaluje kód, který obsahuje, blokem try a vždy na konci bloku zavolá metodu Dispose rozhraní IDisposable na objekt, který byl vytvořen v rámci klauzule using. Je to pohodlný zkrácený zápis pro programátory C#. Je to dobrá technika, kterou byste si měli osvojit. Budete se s ní ostatně dost často setkávat v průběhu knihy. Zpracování události Paint Poté, co jsme se dozvěděli, jak správně spravovat prostředky Graphics, máme tu další problém: když se změní velikost formuláře, nebo když ho něčím pokryjeme, a pak zase odkryjeme, elipsa se automaticky nepřekreslí. Zařizuje se to tak, že Windows požádá formulář (a všechny dceřiné ovládací prvky), aby překreslil nově odkrytý obsah přes událost Paint, která poskytuje argument PaintEventArgs: class PaintEventArgs { public Rectangle ClipRectangle { get; public Graphics Graphics { get; bool drawellipse = false; void drawellipsebutton_click(object sender, EventArgs e) { drawellipse =!drawellipse; void DrawingForm_Paint(object sender, PaintEventArgs e) { if(!drawellipse ) return; Graphics g = e.graphics; g.fillellipse(brush, this.clientrectangle); V okamžiku, kdy se odpálí událost Paint, už je pozadí formuláře nakreslené 3, takže jakákoli elipsa, která byla nakreslena při předchozí události Paint, bude pryč; to znamená, že kreslit elipsu musíme jen tehdy, když je indikátor drawellipse nastavený na true. Ovšem, i když indikátor nastavíme tak, že se má elipsa nakreslit, Windows se nedozví, že se stav indikátoru změnil, takže se událost Paint nespustí, a formulář nedostane šanci elipsu nakreslit. Abychom nemuseli mít kreslení elipsy v událostní proceduře Click, a zároveň také v události Paint, musíme požádat o událost Paint, a dát vědět systému Windows, že se formulář má překreslit.

142 Základy kreslení Spouštění události Paint Spuštění události Paint si vyžádáme metodou Invalidate: void drawellipsebutton_click(object sender, EventArgs e) { drawellipse =!drawellipse; this.invalidate(true); // Požádáme Windows o událost Paint // pro formulář a jeho děti Nyní, když uživatel přepne náš indikátor, zavoláme Invalidate, abychom dali Windows na vědomí, že se nějaká část formuláře má překreslit. Protože je však kreslení jednou z nejnákladnějších operací, zpracuje Windows nejdříve jiné události jako jsou pohyby myší, vstup z klávesnice atd. teprve pak odpálí událost Paint, pro případ, že by bylo potřeba překreslit současně více oblastí na formuláři. Abychom se této prodlevy vyvarovali, můžeme zavolat metodu Update, kterou systém Windows donutíme, aby zpracoval událost Paint okamžitě. Protože se rušení platnosti a aktualizace celé klientské oblasti formuláře vyskytují běžně, mají formuláře metodu Refresh, která obě dvě metody kombinuje: void drawellipsebutton_click(object sender, EventArgs e) { drawellipse =!drawellipse; // Dá se udělat jedno nebo druhé this.invalidate(true); // Požádáme Windows o událost Paint // pro formulář a jeho děti this.update(); // Donutí vykonat událost Paint hned teď // Nebo se dá udělat obojí najednou this.refresh(); // Invalidate(true) + Update Jestliže však můžete počkat, je nejlepší nechat systém Windows, aby událost Paint zpracoval po svém. Její opoždění má svůj důvod: je to nejpomalejší věc, kterou systém dělá. Když se vynucuje, aby se všechno překreslovalo hned, eliminují se tím důležité optimalizace. Jestliže sledujete se mnou práci na naší jednoduché ukázce, možná jste potěšeni, že klikáním na tlačítko rozhodujete, zda bude na formuláři elipsa nebo ne, a že když formulář něčím zakryjete, a pak odkryjete, že se formulář překresluje podle očekávání. Když však budete postupně měnit velikost formuláře, budete patrně zděšeni tím, co uvidíte. Ilustrují to obrázky 4.1 a 4.2.

Základy kreslení 143 Obrázek 4.1: Elipsa na formuláři před jeho zvětšením Obrázek 4.2: Elipsa na formuláři poté, co se formulář postupně zvětšuje Na obrázku 4.2 to vypadá, jako kdyby se při zvětšování formuláře elipsa kreslila několikrát, ale ne celá, jen její části. Co se to děje? Když se formulář zvětšuje, kreslí systém Windows jen nově vystavený obdélník, a předpokládá, že existující obdélník není nutné překreslit. Takže i když překreslujeme během každé události Paint celou elipsu, Windows ignoruje vše, co se nachází vně regionu výřezu (clip region) čímž se rozumí ta část formuláře, která se má překreslit a to právě vede na to podivné kreslicí chování. Naštěstí můžeme nastavit styl při požadavku, aby Windows překreslil při zvětšování celý formulář: public DrawingForm() { // Required for Windows Form Designer support InitializeComponent(); // Spustí událost Paint, když se mění velikost formuláře this.setstyle(controlstyles.resizeredraw, true); Formuláře (a ovládací prvky) mají několik kreslicích stylů (dozvíte se o nich víc v kapitole 6: Kreslení pro pokročilé). Styl RedrawSize způsobí, že Windows překreslí celou klientskou oblast vždy, když se změní velikost formuláře. Je to samozřejmě méně efektivní, proto je výchozím chováním Windows to původní chování.

144 Základy kreslení Barvy Doposud jsem kreslil elipsu ve svém formuláři zabudovaným štětcem tmavě modré barvy (DarkBlue). Štětec ( brush), jak uvidíte, se používá pro vyplňování vnitřku tvarů, zatímco perem ( pen) se kreslí hrany tvarů (obvod). Každopádně předpokládejme, že mě úplně neuspokojuje tmavě modrý štětec. Rád bych místo něj použil některou z více než 16 miliónů barev, které ale nebyly pro mě předem zabudované, takže to znamená, že nejprve musím konkretizovat barvu, o kterou se zajímám. Barvy se v.net modelují přes strukturu Color: struct Color { // Bez barvy public static readonly Color Empty; // Zabudované barvy public static Color AliceBlue { get; //... public static Color YellowGreen { get; // Vlastnosti public byte A { get; public byte B { get; public byte G { get; public bool IsEmpty { get; public bool IsKnownColor { get; public bool IsNamedColor { get; public bool IsSystemColor { get; public string Name { get; public byte R { get; // Metody public static Color FromArgb(int alpha, Color basecolor); public static Color FromArgb(int alpha, int red, int green, int blue); public static Color FromArgb(int argb); public static Color FromArgb(int red, int green, int blue); public static Color FromKnownColor(KnownColor color); public static Color FromName(string name); public float GetBrightness(); public float GetHue(); public float GetSaturation(); public int ToArgb(); public KnownColor ToKnownColor(); Objekt Color v zásadě reprezentuje čtyři hodnoty: množství červené, zelené a modré, a množství neprůhlednosti. Na prvky červená, zelená a modrá se často odkazuje najednou jako na RGB

Základy kreslení 145 (red-green-blue). Každý z nich má rozpětí od 0 do 255, přičemž 0 je nejmenší množství barvy, 255 největší množství barvy. Stupeň neprůhlednosti se specifikuje hodnotou alpha, a někdy se přidává k RGB, takže vznikne ARGB ( Alpha-RGB). Hodnota alpha má rozpětí od 0 do 255, přičemž 0 znamená zcela průhledná, 255 kompletně neprůhledná. Objekt Color nevytváříte konstruktorem, ale metodou FromArgb, do které předáte množství červené, zelené a modré barvy: Color red = Color.FromArgb(255, 0, 0); // 255 červená, 0 zelená, 0 modrá Color green = Color.FromArgb(0, 255, 0); // 0 červená, 255 zelená, 0 modrá Color blue = Color.FromArgb(0, 0, 255); // 0 červená, 0 zelená, 255 modrá Color white = Color.FromArgb(255, 255, 255); // bílá Color black = Color.FromArgb(0, 0, 0); // černá Chcete-li specifikovat úroveň průhlednosti, přidejte i hodnotu alpha: Color modra25procentnepruhledna = Color.FromArgb(255*1/4, 0, 0, 255); Color modra75procentnepruhledna = Color.FromArgb(255*3/4, 0, 0, 255); Tři 8bitové hodnoty barev a jedna 8bitová hodnota alpha tvoří čtyři části jediné hodnoty, která definuje 32 bitovou barvu, jakou umějí zpracovat moderní adaptéry displeje. Předáváte-li raději uvedené čtyři hodnoty jako jedinou hodnotu, dá se to udělat jednou z přetížených variant, ale vypadá to odporně, proto byste se tomu měli vyhýbat: // A = 191, R = 0, G = 0, B = 255 Color modra75procentnepruhledna = Color.FromArgb(-1090518785); Známé barvy Často má barva, o kterou se zajímáte, už přidělený dohodnutý název, což znamená, že je dostupná jako jeden ze statických členů Color, jimiž se definují známé barvy, z výčtu KnownColor, nebo názvem: Color blue1 = Color.BlueViolet; Color blue2 = Color.FromKnownColor(KnownColor.BlueViolet); Color blue3 = Color.FromName("BlueViolet"); Kromě 141 barev s názvy jako AliceBlue nebo OldLace, má výčet KnownColor 26 hodnot, které popisují aktuální barvy přiřazené různým částem uživatelského rozhraní Windows, jako jsou barva okraje aktivního okna nebo barva výchozího pozadí ovládacího prvku. Tyto barvy jsou velmi šikovné, když sami něco kreslíte a chcete, aby to bylo v souladu se zbývajícími částmi systému. Systémové barvy výčtu KnownColor jsou vypsané zde: enum KnownColor { // Nesystémové barvy jsem vynechal...

146 Základy kreslení ActiveBorder, ActiveCaption, ActiveCaptionText, AppWorkspace, Control, ControlDark, ControlDarkDark, ControlLight, ControlLightLight, ControlText, Desktop, GrayText Highlight, HighlightText, HotTrack, InactiveBorder, InactiveCaption, InactiveCaptionText, Info, InfoText, Menu, MenuText, ScrollBar, Window, WindowFrame, WindowText, Chcete-li použít některou ze systémových barev, aniž byste museli vytvářet svou vlastní instanci třídy Color, přistupujte k těm, které už byly pro vás vytvořeny a vystaveny jako vlastnosti třídy SystemColors: sealed class SystemColors { // Vlastnosti public static Color ActiveBorder { get; public static Color ActiveCaption { get; public static Color ActiveCaptionText { get; public static Color AppWorkspace { get; public static Color Control { get; public static Color ControlDark { get; public static Color ControlDarkDark { get; public static Color ControlLight { get; public static Color ControlLightLight { get; public static Color ControlText { get; public static Color Desktop { get; public static Color GrayText { get;

Základy kreslení 147 public static Color Highlight { get; public static Color HighlightText { get; public static Color HotTrack { get; public static Color InactiveBorder { get; public static Color InactiveCaption { get; public static Color InactiveCaptionText { get; public static Color Info { get; public static Color InfoText { get; public static Color Menu { get; public static Color MenuText { get; public static Color ScrollBar { get; public static Color Window { get; public static Color WindowFrame { get; public static Color WindowText { get; Následující dva řádky vedou na objekty Color se stejnými hodnotami barev, a můžete je používat, kde je vám libo. Color color1 = Color.FromKnownColor(KnownColor.GrayText); Color color2 = SystemColors.GrayText; Překlad barev Máte-li nějakou svou barvu v jednom z tří jiných formátů HTML, OLE nebo Win32 nebo chcete barvu přeložit do jednoho z těchto formátů, využijte ColorTranslator, jak to vidíte v ukázce pro HTML: Color htmlmodra = ColorTranslator.FromHtml("#0000ff"); string htmltakymodra = ColorTranslator.ToHtml(htmlBlue); Když máte nějaký objekt Color, můžete získat jeho hodnoty průhlednosti, červené, zelené a modré barvy, a také název barvy, ať už je to známá barva nebo systémová barva. Můžete také pomocí těchto hodnot vyplnit a obtáhnout tvary, k čemuž ale potřebujete štětce, resp. pera. Štětce Třída System.Drawing.Brush slouží jako základní třída pro několik druhů štětců, které se používají podle toho, jaké jsou vaše potřeby. Na obrázku 4.3 vidíte pět odvozených tříd štětců, které poskytují jmenné prostory System.Drawing a System.Drawing. Drawing2D.

148 Základy kreslení Obrázek 4.3: Ukázky štětců Obrázek 4.3 byl vytvořen tímto kódem: void BrushesForm_Paint(object sender, PaintEventArgs e) { Graphics g = e.graphics; int x = 0; int y = 0; int width = this.clientrectangle.width; int height = this.clientrectangle.height/5; Brush whitebrush = System.Drawing.Brushes.White; Brush blackbrush = System.Drawing.Brushes.Black; using( Brush brush = new SolidBrush(Color.DarkBlue) ) { g.fillrectangle(brush, x, y, width, height); g.drawstring(brush.tostring(), this.font, whitebrush, x, y); y += height; string file = @"c:\windows\santa Fe Stucco.bmp"; using( Brush brush = new TextureBrush(new Bitmap(file)) ) { g.fillrectangle(brush, x, y, width, height); g.drawstring(brush.tostring(), this.font, whitebrush, x, y); y += height; using( Brush brush = Brush brush = new HatchBrush( new HatchBrush( HatchStyle.Divot, Color.DarkBlue, Color.White) HatchStyle.Divot, Color.DarkBlue, Color.White) ) { g.fillrectangle(brush, x, y, width, height); g.drawstring(brush.tostring(), this.font, blackbrush, x, y); y += height;

Základy kreslení 149 using( Brush brush = new LinearGradientBrush( new Rectangle(x, y, width, height), Color.DarkBlue, Color.White, 45.0f) ) { g.fillrectangle(brush, x, y, width, height); g.drawstring(brush.tostring(), this.font, blackbrush, x, y); y += height; Point[] points = new Point[] { new Point(x, y), new Point(x + width, y), new Point(x + width, y + height), new Point(x, y + height) ; using( Brush brush = new PathGradientBrush(points) ) { g.fillrectangle(brush, x, y, width, height); g.drawstring(brush.tostring(), this.font, blackbrush, x, y); y += height; Barevné štětce Štětec SolidBrush má namíchanou nějakou barvu, kterou se má vyplnit nakreslený tvar. Protože se tyto štětce používají velmi hojně, obsahuje kvůli většímu pohodlí třída Brushes 141 vlastností Brush, jednu pro každou barvu pojmenovanou ve výčtu KnownColors. Tyto vlastnosti jsou šikovné, protože jejich prostředky řídí a udržuje v cache samotný.net, takže se s nimi pracuje poněkud snadněji než se štětci, které vytváříte sami 4 : // Řídí.NET Brush bilystetec = System.Drawing.Brushes.White; // Řídí váš program using ( Brush mujbilystetec = new SolidBrush(Color.White) ) {... Obdobně se 21 z 26 systémových barev výčtu KnownColor poskytuje ve třídě SystemBrushes 5. To se hodí, chcete-li vytvořit štětec s některou ze systémových barev, ale chcete, aby podkladový prostředek zpracovávaly WinForms. Štětce, které nejsou dostupné názvem jako vlastnosti SystemBrushes, jsou dostupné přes metodu FromSystemColor. Vrací štětec, který řídí.net: // Volání Dispose na tento štětec způsobí výjimku Brush stetec = SystemBrushes.FromSystemColor(SystemColors.InfoText);

150 Základy kreslení Štětce s texturou Štětec TextureBrush je vytvořen z nějakého obrázku. Standardně se obrázek používá opakovaně tak, aby vydláždil prostor uvnitř nakresleného tvaru. Toto chování můžete změnit volbou členu výčtu WrapMode. Různé režimy předvádí obrázek 4.4. enum WrapMode { Clamp, // nakreslí pouze jednou Tile, // výchozí TileFlipX, // překlopí obrázek vodorovně podél osy X TileFlipY, // překlopí obrázek svisle podél osy Y TileFlipXY, // překlopí obrázek podél os X a Y Obrázek 4.4: Ukázky různých hodnot WrapMode u štětce s texturou