5.díl - Tlač formuláre a ovládacích prvkov Windows Forms
V dnešnom predposlednom dieli doplníme knižnicu MyClass2 kódom pre tlač TexBoxu a LineShape. Hlavičkový súbor MyClass2.h bude obsahovať dve triedy:
//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á trieda je pre tlač Shape ovládacích prvkov.
//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čenie tlače TextBox
Source súbor MyClass2.cpp najprv doplníme funkcií, ktorá má za úlohu orezať prvok mimo tlačiteľnej 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 ; };
Ďalšie funkcie bude tlačiť pozadie plochy tvojho ovládacieho 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ódom funkciu, ktorú sme vytvorili v minulom dieli.
//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; };
Pomocou návrhára vytvoríme nový súbor MyTexty.ha 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
Pre formátovanie textu je použitá funkcia 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
Ďalšie funkcie rieši jednoriadkový 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á funkcia rieši 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čenie tlače LineShape
Postupujeme opačne pri dekódovaní užívateľských prvkov Shape než v uvedenej v ukážke pri ich vytváraní. V demo ukážem tlač prvku LineShape a dekódovanie OvalShape a RectangleShape. Najprv doplníme kód v funkciu PrintShape (......), ktorú sme vytvorili v minulej lekcii.
//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; };
Ďalšie funkcie uskutočniť triedenie z kolekcie ShapeContainer do kolekcií 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(); };
Nabudúce všetko dokončíme.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 90x (80.43 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#