arckép

Neuwirth István

programtervező informatikus MSc – ELTE

Computational and Software Techniques MSc – Cranfield, UK

Elérhetőség
pitta2@gmail.com
+36 30 329 3039

Valid XHTML 1.0 Transitional

Valid CSS!

Nyomtatás – .NET

A Visual Studio .Net környezetben fejlesztett programjainkat könnyen bővíthetjük úgy, hogy az általuk megjelenített tartalmak nyomtathatóak legyenek. Egy szöveg- vagy képszerkesztő programnál ez elvárt képesség, de egy adatbázist kezelő programnál kimutatásokhoz is nélkülözhetetlen. A megvalósítás során szükséges a normál képernyőre rajzolás eszközeinek ismerete.

print dialogHa tekintjük a nyomtatási funkcióval rendelkező programokat, akkor láthatjuk, hogy a nyomtatással kapcsolatban három fő művelet szokott előfordulni: az oldalbeállítás (page setup) a laptájolás, margók, stb. beállításához; a nyomtatási kép vagy nyomtatási előnézet (print preview), amely segítségével megtekinthető, hogy a nyomtatás során az egyes elemek hová kerülnek a lapon, mennyi lapot vesz igénybe a nyomtatás (ez a funkció sokszor hiányzik, leginkább szövegszerkesztő programoknál található meg); végül a nyomtatás (print), amely a további beállításokat (másolatok száma, nyomtató kiválasztása, stb.) követően a szükséges információkat továbbítja a nyomtatóhoz.

A nyomtatással kapcsolatos osztályokat a System.Drawing.Printing névtéren belül találjuk. Néhány előre megírt komponens is a segítségünkre lesz: a PageSetupDialog az oldalbeállításhoz, a PrintPreviewDialog (illetve a PrintPreviewControl) a nyomtatási előnézethez, a PrintDialog (illetve a PrintDocument) a nyomtatáshoz. Ezek nem vizuális megjelenéssel bíró vezérlők, azaz a form-ra húzva őket nem jelennek meg az ablakon, hanem csak egy külön sávban. Hasonlóan például az OpenFileDialog-hoz, ColorDialog-hoz a ShowDialog metódusuk hatására egy Windows-os rendszerablakot dobnak fel. Ezen osztályok többsége lezárt (sealed), azaz belőlük nem származtathatunk, így bővítésük nehézkes. Valójában rendszerhívások csomagolóosztályairól van szó.

A nyomtatás megvalósításához először a fent említett komponenseket az eszköztárról tegyük rá az ablakunkra. A PrintDocument, PageSetupDialog, PrintPreviewDialog és PrintDialog osztályokból példányosított objektumokra a továbbiakban sorban a printDocument, pageSetupDialog, printPreviewDialog és printDialog objektumnevekkel fogunk hivatkozni. A pageSetupDialog, printPreviewDialog és printDialog objektumaink Document tulajdonságának állítsuk be a printDocument objektumunkat, mivel ez reprezentálja majd a nyomtatandó dokumentumot (legyen az bármilyen tartalmú).

A nyomtatás, a nyomtatási előnézet kirajzolása a következő alapelv szerint történik: a printDocument PrintPage eseményekor meghívódó eseménykezelő metódusban átadódik egy PrintPageEventArgs típusú paraméter, amely tartalmazza mindazt, ami a nyomtatáshoz szükséges. A Graphics tulajdonság segítségével ugyanúgy rajzolhatunk, mint azt korábban megszokhattuk. A méretekről, felbontásról a MarginBounds, PageBounds, PageSettings tulajdonságok adnak információt. A HasMorePages tulajdonság segítségével pedig jelezhetjük, ha még van nyomtatandó oldal. Azaz a dokumentumot szükséges valahogyan oldalakra felosztani, és mindegyik oldal tartalmát a PrintPage eseménynél kirajzolni, ha még van oldal, a HasMorePages értékét True-ra állítani. Ugyanezt a mechanizmust használja a printPreviewDialog is, csak ott a kirajzolás eredménye a képernyőre kerül kis bélyegképek formájában. A printPreviewDialog UseAntiAlias értékét állítsuk True-ra, ekkor az előnézetet magasabb felbontású képből képezi le, így az nem lesz „recés”. A PrintPage eseménnyel együtt négy eseménye van mindösszesen a printDocument-nek (BeginPrint a nyomtatási folyamat megkezdésekor, EndPrint a nyomtatási folyamat végén, PrintPage az ismert laponkénti kirajzoláshoz, QueryPageSettings minden lapra, ha a PageSettings tulajdonságot egyedileg szeretnénk beállítani). Végül a printDocument Print() metósusának hívásával indíthatjuk el a tényleges nyomtatási folyamatot.

A mellékelt példában egy tömbben tárolt ecsetekkel kifestett ellipszist rajzolunk annyi oldalra, amennyi a tömb elemszáma. Az ellipszisek kitöltik az oldalt. Természetesen a Graphics osztály DrawString metódusával (és egyéb kapcsolódó függvények segítségével) tetszőleges szövegeket is kirajzolhatunk a lapokra. Ha már megírtunk egy kirajzoló eljárást a programunkhoz, a kibővítéshez csupán az szükséges, hogy a PrintPage eseményen belüli Graphics-re is tudjunk rajzolni, illetve helyesen kezeljük a rendelkezésre álló területet. Kicsit több munka van akkor, ha több lapra kívánunk nyomtatni, de ez is viszonylag könnyen megoldható. Jó nyomtatást!

using System.Collections;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Printing;

...

private Brush[] brushes = new Brush[] { new SolidBrush(Color.Red), 
                                        new HatchBrush(HatchStyle.Cross, Color.Blue), 
                                        new TextureBrush(Image.FromFile(@"C:\WINDOWS\A préri szele.bmp")) };
private IEnumerator iterator;

private void MainForm_Load(object sender, EventArgs e)
{
    iterator = brushes.GetEnumerator();
}

private void printDocument_BeginPrint(object sender, PrintEventArgs e)
{
    iterator.Reset();
    iterator.MoveNext();
}

private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
{
    e.Graphics.FillEllipse((Brush)iterator.Current, e.PageBounds);
    e.HasMorePages = iterator.MoveNext();
}

...

if (brushes.Length > 0)
{
    pageSetupDialog.ShowDialog();
    printPreviewDialog.ShowDialog();
    printDialog.ShowDialog();
    printDocument.Print();
}

...