5.díl - Tisk formuláře a ovládacích prvků Windows Forms

C# .NET Windows Forms 5.díl - 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.


 

Stáhnout

Staženo 66x (80.43 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

  Aktivity (1)

Článek pro vás napsal zpavlu
Avatar
C# a C++

Jak se ti líbí článek?
Celkem (1 hlasů) :
4444 4


 



 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!