IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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#

 

Předchozí článek
Tisk formuláře a ovládacích prvků Windows Forms
Všechny články v sekci
Tisk celých formulářů ve Windows Forms
Přeskočit článek
(nedoporučujeme)
Tisk formuláře a ovládacích prvků Windows Forms
Článek pro vás napsal zpavlu
Avatar
Uživatelské hodnocení:
3 hlasů
C# , C++ a assembler
Aktivity