Lekce 5 - Tisk formuláře a ovládacích prvků Windows Forms
V dnešním předposledním dílu doplníme knihovnu MyClass2 kódem pro tisk TexBoxu a LineShape. Hlavičkový soubor MyClass2.h bude obsahovat dvě třídy:
//MyClass2.h #pragma once #include "MyClassImage.h" #include "MyTexty.h" //.......... //Třída pro tisk TexBoxu a BachgRoundImage formuláře public ref class Class2 : MyClassImage { public: Class2(); void static FnSetGraphics(Graphics^ gr); void static FnRealPageSettingsBounds(Rectangle RealPageSetting); void FnDrawBachgRoundImage(Image ^image, swf::ImageLayout imagelayout, Rectangle rec ); void FnPrintTextBox(swf::TextBox^ tb,int x1, int y1 , int w1 , int h1); private: static Graphics^ graphics; static Rectangle realPageSetting; Rectangle recpom ; bool FnuOrez(Graphics^ gr, int x1, int y1, int w1, int h1, Rectangle recmax ,Rectangle %recpom); Rectangle FnFillRectangle(Color backColor, Rectangle rec ); };
Druhá třída je pro tisk Shape ovládacích prvků.
//MyClass2.h //Třída pro tisk LineShape , OvalShape a RectangleShape //v tvém kódu bude tato třída samostatná pro lepší přehled public ref class Kreslivbshape{ public: void PrintShape(Graphics^ gr, swf::Control ^control, int x, int y , Rectangle rec); private: void NactiPrvkyDoKolekce(ShapeContainer ^shapeContainer); static List<mvb::LineShape^> ^lineShape = gcnew List<mvb::LineShape^>(10); static List<mvb::OvalShape^> ^ovalShape = gcnew List<mvb::OvalShape^>(10); static List<mvb::RectangleShape^> ^rectangleShape = gcnew List<mvb::RectangleShape^>(10); void KresliLine(Graphics^ gr,int xx , int yy , int count); void KresliOval(Graphics^ gr,int xx , int yy, int count); void KresliRectangle(Graphics^ gr, int xx , int yy ,int count); int count; int x0; int y0; Rectangle recMax ; };
Dokončení tisku TextBox
Source soubor MyClass2.cpp nejprve doplníme funkcí, která má za úkol ořezat prvek mimo tisknutelnou plochu:
//MyClass2.cpp //Rectangle %recpom -> v C# je jako ref Rectangle recpom bool Class2::FnuOrez(Graphics^ gr, int x1, int y1, int w1, int h1, Rectangle recmax, Rectangle %recpom) { recpom = Rectangle(x1,y1,w1,h1) ; //Vrací průsečík obou rectangle. Pokud neexistuje vrací vrací emty recpom = Rectangle::Intersect(recpom, recmax); if (recpom.IsEmpty){return false;} //Ovládací prvek je mimo tisknutelnou oblast Rectangle rectTrim = Rectangle::Inflate(recpom, 1, 1); //zvětčí rectangle o 1 pixel gr->Clip = gcnew Region(rectTrim);//Provede oříznutí plochy pro kreslení return true ; };
Další funkce bude tisknout pozadí plochy tvého ovládacího prvku.
//MyClass2.cpp Rectangle Class2::FnFillRectangle(Color backColor, Rectangle rec ) { SolidBrush^ brush = nullptr; try { //prosor zmenšen o ohraničení BorderStyle Rectangle rectBackColor = Rectangle::Inflate(rec, -1, -1); SolidBrush^ brush = gcnew SolidBrush((Color) backColor); graphics->FillRectangle(brush, rectBackColor); return rectBackColor; } finally{delete brush;} };
Doplníme kódem funkci, kterou jsme vytvořili v minulém dílu .
//MyClass2.cpp void Class2::FnPrintTextBox(swf::TextBox^ tb,int x1, int y1 , int w1 , int h1) { MyTextControls^ myTextControls = gcnew MyTextControls; if(FnuOrez(graphics, x1,y1,w1,h1,realPageSetting,this->recpom )) { Rectangle recback = FnFillRectangle((Color)tb->BackColor, this->recpom); //vyplní pozadí if(tb->Multiline) { myTextControls->FntDrawText3(graphics,tb->Lines, (Color) tb->ForeColor, recback, tb->Font,(HorizontalAlignment) tb->TextAlign); } else { graphics->Clip = gcnew Region(this->recpom); myTextControls->FntDrawText2(graphics, tb->Text, (Color) tb->ForeColor, recback, tb->Font, (HorizontalAlignment) tb->TextAlign); graphics->ResetClip(); } //v této ukázce neřešen BorderStyle nastaven FixedSingle Pen^ penb = gcnew Pen(Color::Black,1 ); graphics->DrawRectangle(penb,this->recpom); } return; };
Pomocí návrháře vytvoříme nový soubor MyTexty.h a MyTexty.cpp .
//MyTexty.h #pragma once namespace FormPrintDemo { public ref class MyTextControls sealed { public: MyTextControls(); internal: void FntDrawText3(Graphics^ graphics,array<String^>^ text, Color foreColor, Rectangle rect, Font^ printFont,HorizontalAlignment ha); void FntDrawText2(Graphics^ graphics,String^ text, Color foreColor, Rectangle rect, Font^ printFont, HorizontalAlignment ha); private: StringFormat^ HaAlignment(swf::HorizontalAlignment ha); };//class }//namespace
Pro formátování textu je použita funkce HaAlignment(......)
//MyTexty.cpp #pragma once #include "stdafx.h" #include "MyTexty.h" namespace FormPrintDemo { MyTextControls::MyTextControls(){}; //konstruktor StringFormat^ MyTextControls::HaAlignment(swf::HorizontalAlignment ha) { StringFormat^ sf = gcnew StringFormat( StringFormatFlags::NoClip ); switch (ha) { case HorizontalAlignment::Left: sf->Alignment = StringAlignment::Near; break; case HorizontalAlignment::Center: sf->Alignment = StringAlignment::Center; break; case HorizontalAlignment::Right: sf->Alignment = StringAlignment::Far; break; default: sf->Alignment = StringAlignment::Near; break; } return sf; };//HaAlignment } //namespace
Další funkce řeší jednořádkový text (je zjednodušená)
//MyTexty.cpp void MyTextControls::FntDrawText2(Graphics^ graphics,String^ value, Color foreColor, Rectangle rect, Font^ printFont, HorizontalAlignment ha) { if(String::IsNullOrEmpty(value)){return;} float fHeigth = printFont->GetHeight(graphics); rect.Y = (int) (rect.Y + (rect.Height - fHeigth) / 2.0F); SolidBrush^ brush = gcnew SolidBrush(foreColor); StringFormat^ sf = HaAlignment(ha); graphics->DrawString(value, printFont, brush, rect, sf); if(brush != nullptr) {delete brush;} if(sf != nullptr) {delete sf;} };
Poslední funkce řeší multiline text (zjednodušená )
//MyTexty.cpp void MyTextControls::FntDrawText3(Graphics^ graphics,array<String^>^ text, Color foreColor, Rectangle rect, Font^ printFont,HorizontalAlignment ha) { int count = text->Length; if(count <= 0){return;} float fHeigth = printFont->GetHeight(graphics); rect.Y = (int) (rect.Y + fHeigth / 3.0F); StringFormat^ sf = HaAlignment(ha); SolidBrush^ brush = gcnew SolidBrush(foreColor); for ( int i = 0; i < count; i++ ) { graphics->DrawString(text[i], printFont, brush, rect, sf); rect.Y += (int) fHeigth ; } };
Dokončení tisku LineShape
Postupujeme opačně při dekódování uživatelských prvků Shape než v uvedené v ukázce při jejich vytváření. V demo ukáži tisk prvku LineShape a dekódování OvalShape a RectangleShape. Nejprve doplníme kód v funkci PrintShape(......) , kterou jsme vytvořili v minulé lekci.
//MyClass2.cpp void Kreslivbshape::PrintShape(Graphics^ gr, swf::Control ^control, int x, int y , Rectangle rec ) { this->x0 = x; this->y0 = y; this->recMax = rec; //vytvořím kolekci a v této budou umístěny všechny Shape uživatelské prvky mvb::ShapeContainer ^shapeContainer = safe_cast<mvb::ShapeContainer^>(control); //vysoká kvalita tisku gr->SmoothingMode = SmoothingMode::HighQuality; //načte prvky do kolekcí podle typu prvků NactiPrvkyDoKolekce(shapeContainer); this->count = lineShape->Count; if (this->count > 0) //kresli line KresliLine(gr, this->x0 , this->y0 , this->count); this->count = ovalShape->Count; if (this->count > 0) //kresli elipsu ,kruh KresliOval(gr, this->x0 , this->y0, this->count); this->count = rectangleShape->Count; if (this->count > 0) //kreslí recangle KresliRectangle(gr, this->x0 , this->y0, this->count ) ; gr->SmoothingMode = SmoothingMode::Default; };
Další funkce provede třídění z kolekce ShapeContainer do kolekcí LineShape, RectangleShape a OvalShape.
//MyClass2.cpp void Kreslivbshape::NactiPrvkyDoKolekce(ShapeContainer ^shapeContainer) { this->count = shapeContainer->Shapes->Count; //počet prvlů Shape v kontejneru Type ^type = nullptr; String^ stringType = nullptr; Object^ shape = nullptr; //rozdělí Shape uživatelské prvky for (int i = 0; i < this->count; i++) { shape = shapeContainer->Shapes[i]; type = shape->GetType(); stringType = type->FullName; if (stringType->Equals("Microsoft.VisualBasic.PowerPacks.LineShape")) lineShape->Add(safe_cast<mvb::LineShape^>(shape)); else if (stringType->Equals("Microsoft.VisualBasic.PowerPacks.OvalShape")) ovalShape->Add(safe_cast<mvb::OvalShape^>(shape)); else if (stringType->Equals("Microsoft.VisualBasic.PowerPacks.RectangleShape")) rectangleShape->Add(safe_cast<mvb::RectangleShape^>(shape)); } //zmenší kolekci na daný počet prvků lineShape->TrimExcess(); ovalShape->TrimExcess(); rectangleShape->TrimExcess(); };
Příště vše dokončíme.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 90x (80.43 kB)
Aplikace je včetně zdrojových kódů v jazyce C#