IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

3. diel - Tlač formuláre a ovládacích prvkov Windows Forms

V minulom diele sme končili s trochu teórie a použitých názvov. Pripravíme si našu knižnicu C ++ / CLR: safe pre pokračovanie. V tabuľke je ukážka vplyvu prepínača C ++ / CLR na možnosti programátora. Tu nebudem vysvetľovať jednotlivé možnosti, sú dostatočne popísané na webe.

Možnosti prepínače CLR - Okenné aplikácie v C # .NET vo Windows Forms

Príprava (dll) knižnice Class2

Vo VS otvoríme prieskumník riešenia a myšou prejdeme na MyClass2. Pravé tlačidlo myši otvoríme vlastnosti. Tlačidlom Add.New Referencie ... pridáme Microsoft.Visu­alBasic.Power­.Packs.Stejně pridáme aj System.Window­s.Forms a pridáme System.Drawing, viď obrázok.

Vlastnosti konfigurácie v C# .NET - Okenné aplikácie v C # .NET vo Windows Forms

Znovu prejdeme na Stránky vlastností MyClass2 a prejdeme na Vlastnosti Konfigurácia a v poli
Common Language Runtime Support naklikne: Safe MSIL Common Language Runtime Support (/ clr: safe). Stránky vlastností MyClass2 musia byť nastavené v Konfigurácia na Všetky konfigurácie. Funkcia FnSetGraphics (Graphics ^ gr) a FnRealPageSet­tingsBounds (Rectangle RealPageSetting) sú statické. To znamená, že je len jedna inštancia tejto funkcie bez ohľadu koľkokrát je trieda použitá.

Znovu prikladám obrázok.

vlastnosti konfigurácia - Okenné aplikácie v C # .NET vo Windows Forms

V prieskumníkovi riešení vidíme, že máme Header Files - MyClass2.ha Source Files - MyClass2.cpp.
Tu odporúčam písať kód programu do oboch, nie je to síce nutné, pri väčšom projekte stratíte prehľad a váš program bude zle čitateľný. Do Header súboru zapisujeme iba hlavičky funkcií.

Programujeme v knižnici MyClass2

Prejdeme do knižnice MyClass1 na funkciu PdPrintPage (....), zrušíme komentár u FnSetGraphics (graphics), skopírujeme túto funkciu do schránky, otvoríme MyClass2 a vložíme do Class2.

Upravíme hlavičkový súbor:

#pragma once  //hlavička může být načtena pouze 1x velmi důležité

namespace FormPrintDemo {

    public ref class Class2 //v C# -> public class Class2
    {
    public:
        Class2(); //konstruktor
        void static FnSetGraphics(Graphics^ gr); //hlavička funkce

    private:
        Graphics^ graphics;
    };
}//namespace

Upravíme Source súbor MyClass2.cpp

#include "stdafx.h"
#include "MyClass2.h"

namespace FormPrintDemo {

    Class2::Class2(){};

    void  Class2::FnSetGraphics(Graphics^ gr)
    {
        graphics = gr;  //tělo funkce
    };
}

Doplníme referencie na knižnice v Stdafx.h, budú sa kompilovať iba 1x.

#pragma once

#using <System.dll>
#using <System.Windows.Forms.dll>

using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;
using namespace Microsoft::VisualBasic::PowerPacks;
using namespace System::Drawing::Drawing2D;

namespace sd = System::Drawing ;
namespace swf = System::Windows::Forms;
namespace sri = System::Runtime::InteropServices;

Rovnaký postup bude u funkcie FnRealPageSet­tingsBounds (RealPageSetting); a tiež u funkcie
FnDrawBachgRou­ndImage (control.Backgrou­ndImage, control.Backgrou­ndImageLayout, RealPageSetting);. Vytvoríme ďalší hlavičkový a source súbor MyClassImage.ha MyClassImage.cpp. Hlavičkový súbor MyClass2.h bude vyzerať takto:

#pragma once
#include "MyClassImage.h"

namespace FormPrintDemo {

    public ref class Class2 : MyClassImage  //Class2 dědí z MyClassImage
    {
    public:
        Class2();
    void static FnSetGraphics(Graphics^ gr);
        void static FnRealPageSettingsBounds(Rectangle RealPageSetting);
        void static FnDrawBachgRoundImage(Image ^image, swf::ImageLayout imagelayout, Rectangle rec );

    private:
        static Graphics^ graphics;
        static Rectangle realPageSetting;
    };
}

Source súbor MyClass2.cpp:

#include "stdafx.h"
#include "MyClass2.h"

namespace FormPrintDemo {

    Class2::Class2(){}; //konstruktor

    void  Class2::FnSetGraphics(Graphics^ gr)
    {
        graphics = gr;
    };

    void Class2::FnRealPageSettingsBounds(Rectangle RealPageSetting)
    {
        realPageSetting = RealPageSetting;
    };

    void Class2::FnDrawBachgRoundImage(Image ^image, swf::ImageLayout imagelayout, Rectangle rec )
    {
        if(image == nullptr){return;} //v C# -> null
        DrawBachgRoundImageA(graphics, image, rec, imagelayout );
    };
}//namespace

Obrázok na pozadí pre ovládací prvok

Upravíme súbor MyClassImage.h

#pragma once

namespace FormPrintDemo {

    public ref class MyClassImage
    {
    protected :
        void DrawBachgRoundImageA(Graphics^ gr, Image^ image, Rectangle rec, swf::ImageLayout layout );

    private:
        Brush^ DrawBachgRoundImage(Graphics^ gr, Image^ image, Rectangle rec, swf::ImageLayout layout);
        Image^ backgroundImage;
        ImageLayout imageLayout;
        Image ^image ;
    };
}

Upravíme súbor MyClassImage.cpp

#include "stdafx.h"
#include "MyClassImage.h"

namespace FormPrintDemo {

    void MyClassImage::DrawBachgRoundImageA(Graphics^ gr, Image^ image, Rectangle rec, swf::ImageLayout layout)
    {
        Brush ^imageBrush = DrawBachgRoundImage(gr , image , rec , layout);
    if (imageBrush != nullptr)
    {
      gr->FillRectangle(imageBrush, rec);
          delete imageBrush;
        }
    }//DrawBachgRoundImageA

    Brush^ MyClassImage::DrawBachgRoundImage(Graphics^ graphics, Image^ image, Rectangle rec, swf::ImageLayout layout)
    {
            this->backgroundImage = (Image^) image ;
            TextureBrush ^textureBrush = safe_cast<TextureBrush^>(nullptr);

            if (this->backgroundImage != nullptr)
        {
        double num1 = safe_cast<double>(rec.X);
        double num2 = safe_cast<double>(rec.Y);
                int num3 = 0;
                int num4 = 0;
        Image ^image = this->backgroundImage;
        WrapMode wrapMode = WrapMode::Clamp;
        Bitmap ^bitmap = safe_cast<Bitmap^>(nullptr);
                this->imageLayout = layout;
                switch (this->imageLayout)
        {
                case ImageLayout::Tile:
                    wrapMode = WrapMode::Tile;
                    break;

                case ImageLayout::Center:
                    num3 = rec.Width - this->backgroundImage->Width;
                    if (num3 > 0)
                        num1 = safe_cast<double>(rec.X) + safe_cast<double>(num3) / 2.0;
                    num4 = rec.Height - this->backgroundImage->Height;
                    if (num4 > 0)
                    {
                        num2 = safe_cast<double>(rec.Y) + safe_cast<double>(num4) / 2.0;
                        break;
                    }
                    else
                    break;

                case ImageLayout::Stretch:
                    bitmap = gcnew Bitmap(rec.Width, rec.Height);
                    graphics = Graphics::FromImage(safe_cast<Image^>(bitmap));
                    graphics->DrawImage(image, 0, 0, bitmap->Width, bitmap->Height);
                            delete graphics;
                    break;

                case ImageLayout::Zoom:

                    double num5 = (double)(rec.Width) / safe_cast<double>(image->Width);
                    double num6 = (double)(rec.Height) / (double)(image->Height);
                    if (num5 > num6)
                    {
                        num1 = (double)rec.X + (num5 - num6) * (double)(image->Width) / 2.0;
                        bitmap = gcnew Bitmap(int)(Math::Round(double)(image->Width) * num6)), rec.Height);
                    }
                    else
                    {
                        num2 = safe_cast<double>(rec.Y) + (num6 - num5) * safe_cast<double>
 (image->Height) / 2.0;
                        bitmap = gcnew Bitmap(rec.Width,safe_cast<int(Math::Round(safe_cast<double>(image->Height) * num5)));
                    }
                    graphics = Graphics::FromImage(safe_cast<Image^>(bitmap));
                    graphics->DrawImage(image, 0, 0, bitmap->Width, bitmap->Height);
                            delete graphics;
                    break;
            }//switch

            if (bitmap != nullptr)
            {
                textureBrush = gcnew TextureBrush(safe_cast<Image^>(bitmap), wrapMode);
                delete bitmap;
            }
            else
            textureBrush = gcnew TextureBrush(image, wrapMode);
            Matrix ^transform = textureBrush->Transform;
            transform->Translate(safe_cast<float>(num1), safe_cast<float>(num2));
            textureBrush->Transform = transform;
            }
            return safe_cast<Brush^>(textureBrush);
    }
}

Posledná úprava pred testom bude v Class1 v PdPrintPage (......) takto:

//Image pozadí formuláře (volaná funkce není statická)
FormPrintDemo.Class2 class2 = new Class2();
class2.FnDrawBachgRoundImage(control.BackgroundImage, control.BackgroundImageLayout, RealPageSetting);

Vykonáme zostavenie, ak sme programovali bezchybne:

Sestavení bylo úspěšně dokončeno.
Nové sestavení všeho: 3 úspěšně, 0 se nezdařilo, 0 přeskočeno

Test formuláre

Formulár teraz ozkoušíme:

  • Môžeme meniť farbu pozadia formulára
  • Môžeme zadať Image pozadia (BackgroundImage)
  • Môžeme meniť rozloženie obrázka pozadia (BackgroundIma­geLayout -> None, Tile, Center, Zoom, Stretch)
  • Môžeme zapnú alebo vypnúť zobrazenie ohraničenie na stránke
Test tlače v C# .NET - Okenné aplikácie v C # .NET vo Windows Forms

Nie je možné vysvetľovať činnosť kódu FnDrawBachgRou­ndImage (.....), rozbor kóde by zabral samostatný výklad. Pokračovanie v budúcom diele, kde bude rozobraná logika výberu ovládacích prvkov.


 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 97x (773.96 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

Všetky články v sekcii
Okenné aplikácie v C # .NET vo Windows Forms
Článok pre vás napísal zpavlu
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
C# , C++ a assembler
Aktivity