Creeaza.com - informatii profesionale despre


Cunostinta va deschide lumea intelepciunii - Referate profesionale unice
Acasa » scoala » informatica » c
Tiparire si Previzualizare

Tiparire si Previzualizare


Tiparire si Previzualizare


Bazele tiparirii si previzualizarii in MFC

Cerinte pentru acest curs:

T Contextul de dispozitiv;

T Arhitectura Document/View, aplicatii tip SDI;

T Tratarea mesajelor simple de mouse;



T defilarea orizontala si/sau verticala (optional).

Obiective:

v  determinarea obiectelor folosite de catre MFC pentru tiparire si previzualizare;

v  determinarea ordinii de apel al functiilor implicate in tiparire si previzualizare;

v  determinarea elementelor ce identifica pagina de tiparit, etc.

Lectia se va desfasura in laborator. Drept exercitiu independent: sa se adauge codul necesar pentru a realiza defilarea orizontala si/sau verticala.

Pentru invatarea manevrarii contextului de dispozitiv se poate propune construirea unei aplicatii care sa deseneze graficul unei functii. Se vor avea in vedere toate situatiile posibile unde poate fi desenat graficul functiei astfel incat sa fie ocupata cat mai bine zona client (pentru un grafic ce apare numai in cadranul IV se va desena numai acest cadran si graficul, etc.).

Vom exemplifica tiparirea si vizualizarea pe baza unui exemplu.

Se creaza o aplicatie cu arhitectura Document/View si tip SDI (restul setarilor ramanand cele implicite) si cu suport pentru print/preview.

Numele proiectului este Print1.

Prima modificare.

In functia CPrint1View::OnDraw() adaugam:

pDC->Rectangle(20, 20, 220, 220);

Se va desena un dreptunghi (cu marimile masurate in pixeli). (20,20) reprezinta coltul din stanga sus al dreptunghiului, iar (220,220) reprezinta coltul din dreapta jos al dreptunghiului. Deci marimea laturilor dreptunghiului este 200 pe 200 pixeli.

Coltul din stanga sus al zonei client are coordonatele (0,0), axa Ox este pe orizontala, axa Oy este pe verticala.

Aceasta aplicatie poate produce vizualizarea si tiparirea documentului.

Scalarea

Documentul listat si cel afisat pe ecran nu are aceeasi dimensiune (nu arata la fel) pentru ca imprimanta foloseste unitatea de masura, dots, iar pe ecran se foloseste pixelul, si acestea au marimi diferite (200 dots # 200 pixeli).

Acest lucru este descris de modul de mapare (implicit MM_TEXT).

Daca dorim sa scalam imaginea tiparita la o anumita dimensiune, trebuie sa alegem diferite moduri de mapare.

Moduri de mapare

Mode

Unit

X

Y

MM_HIENGLISH

0.001 inch

Increases right

Increases up

MM_HIMETRIC

0.01 millimeter

Increases right

Increases up

MM_ISOTROPIC

User-defined

User-defined

User-defined

MM_LOENGLISH

0.01 inch

Increases right

Increases up

MM_LOMETRIC

0.1 millimeter

Increases right

Increases up

MM_TEXT

Device pixel

Increases right

Increases down

MM_TWIPS

1/1440 inch

Increases right

Increases up

Lucrul cu grafice in modul MM_TEXT devine o problema cand imprimantele si ecranele au un numar diferit de dots/pixeli pe pagina.

Un mod de mapare mai bun pentru lucrul cu grafice este MM_LOENGLISH, care foloseste ca unitate de masura a suta parte dintr-un inch. Pentru a folosi acest mod de mapare, folosim functia SetMapMode():

pDC->SetMapMode(MM_LOENGLISH);

pDC->Rectangle(20, -20, 220, -220);

Atentie la originea axelor si la sensul acestora (cresterea luix si a lui y) Cand vom tipari documentul de mai sus vom obtine un dreptunghi cu laturile exact de 2 inch.

Tiparirea mai multor pagini

MFC trateaza tiparirea documentului (mai putin bitmap-uri). Functia OnDraw() din clasa pentru vizualizare realizeaza desenarea pe ecran cat si tiparirea la imprimanta. Lucrurile se complica cand documentul are mai multe pagini sau alte tratari speciale (informatii de inceput si de sfarsit de pagina).

Exemplificare:

Vom modifica aplicatia astfel incat sa desenam mai multe dreptunghiuri care sa nu incapa pe o pagina.

Adaugam o variabila membru (int m_numrects) la clasa document care va memora numarul de dreptunghiuri care se vor desena si pe care o initializam in constructor.

Pe mesajul WM_LBUTTONDOWN vom incrementa aceasta variabila, iar pe mesajul WM_RBUTTONDOWN vom decrementa aceasta variabila. Codul pentru cele doua functii este dat mai jos:

print1View.cpp --CPrint1View::OnLButtonDown()

void CPrint1View::OnLButtonDown(UINT nFlags, CPoint point)

print1View.cpp --CPrint1View::OnRButtonDown()

void CPrint1View::OnRButtonDown(UINT nFlags, CPoint point)

CView::OnRButtonDown(nFlags, point);

Rescriem functia OnDraw() astfel:

print1View.cpp --CPrint1View::OnDraw()

void CPrint1View::OnDraw(CDC* pDC)

Vedem ce se intampla in PrintPreview. Codul din PrintPreview (in acest moment) nu stie cum sa afiseze mai multe pagini.

Determinarea numarului de pagini se face in functia OnBeginPrinting().

print1View.cpp --CPrint1View::OnBeginPrinting()

void CPrint1View::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)

OnBeginPrinting() are doi parametri: un pointer la un context de dispoztiv al imprmantei si un pointer la un obiect CPrintInfo. Pentru ca versiunea implicita nu se refera la acesti doi pointeri, numele parametrilor sunt comentati pentru a preveni mesajele de avertizare la compilare.

void CPrint1View::OnBeginPrinting(CDC* /*pDC*/ , CPrintInfo* /*pInfo*/)

Pentru a seta numarul paginii, trebuie sa accesam ambele obiecte CDC* si CPrintInfo, deci va trebui sa scoatem comentariile de la cesti doi parametri.

Trebuie sa avem urmatoarele informatii:

inaltimea paginii;

numarul de dots pe inch.

Inaltimea paginii o obtinem printr-un apel al functiei GetDviceCaps(), care furnizeaza informatii despre posibilitatile contextului de dispozitiv. Avem nevoie de rezolutia verticala (numarul de dots tiparibili de la inceputul paginii pana la sfarsitul ei), deci vom furniza ca parametru constanta VERTRES, in functia GetDeviceCaps(). Constanta HORZRES in aceeasi functie ne furnizeaza rezolutia orizontala.

GetDeviceCaps() accepta un numar de 29 de constante diferite (a se vedea help-ul).

In exemplul nostru, pentru a sti cate dreptunghiuri incap pe o pagina, trebuie sa stim inaltimea dreptunghiului in dots, deci va trebui sa impartim dots pe pagina la dots pe dreptunghi.

Stim ca fiecare dreptunghi este inalt de 2 inch cu un spatiu de 20/100 intre fiecare dreptunghi. Distanta totala de la inceputul desenarii unui dreptunghi pana la urmatorul este de 2.2 inch.

Apelul GetDeviceCaps(LOGPIXELSY) ne da numarul de dots pe inch pentru imprimanta (care este atasata la sistem)., care inmultita cu 2.2 ne da dots pe dreptunghi.

Ruland aplicatia vom observa ca desi in previzualizare avem doua pagini, la listare vom obtine pagina 1 de doua ori.

Trecerea de la o pagina la alta este urmatorul pas.

Setarea originii

Va trebui sa furnizam informatia privitoare la inceputul unei noi pagini. Pentru acest lucru, vom rescrie functia OnPrepareDC().

Adaugam aceaceasta functie la clasa de vizualizare cu ClassWizard. Codul este:

print1View.cpp --CPrint1View::OnPrepareDC()

void CPrint1View::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)

CView::OnPrepareDC(pDC, pInfo);

Cadrul de lucru MFC, apeleaza aceasta functie inainte de afisa datele pe ecran sau a le scrie la imprimanta. Acelasi cod realizeaza previzualizarea cat si tiparirea datelor. Daca aplicatia previzualizeaza datele nu este nevoie sa schimbam procesarea efectuata de OnPrepareDC(). Cod necesar este numai pentru tiparire, de aceea folosim functia IsPrinting() pentru a determina daca actiunea este de tiparire sau nu.

Daca tiparim documentul, trebuie sa determinam care pagina trebuie tiparita, adica sa stabilim pagina curenta. Pentru aceasta avem nevoie de inaltimea in dots a paginii de tiparit, deci un nou apel al functiei GetDeviceCaps().

In continuare trebuie sa detrerminam originea noului viewport (pozitia coordonatelor (0,0)) pentru afisare. Schimband originea, dam informatia necesara cadrului de lucru MFC, pentru a sti de unde sa inceapa tiparirea datelor.

Pentru prima pagina originea este (0,0); pentru pagina a doua, originea este mutata in jos cu numarul de dots pe pagina. In general, componenta verticala este marimea paginii inmultita cu pagina curenta minus 1. Numarul paginii este mentinut intr-o variabila membru a clasei CPrintInfo.

Dupa ce calculam noua origine, vom seta aceasta in cadrul contextului de dispozitiv apeland functia SetViewportOrg().

Se va rula aplicatia cu aceste ultime modificari efectuate.

MFC si Tiparirea

Alte functii importante in procesul de tiparire sunt:

Printing Functions of a View Class

Function

Description

OnBeginPrinting()

Override this function to create resources, such as fonts, that you need for printing the document. You also set the maximum page count here.

OnDraw()

This function serves triple duty, displaying data in a frame window, a print preview window, or on the printer, depending on the device context sent as the function's parameter.

OnEndPrinting()

Override this function to release resources created in OnBeginPrinting().

OnPrepareDC()

Override this function to modify the device context used to display or print the document. You can, for example, handle pagination here.

OnPreparePrinting()

Override this function to provide a maximum page count for the document. If you don't set the page count here, you should set it in OnBeginPrinting().

OnPrint()

Override this function to provide additional printing services, such as printing headers and footers, not provided in OnDraw().

Pentru a tipari documentul se apeleaza mai intai OnPreparePrinting() care apeleaza DoPreparePrinting() care la randul ei este responsabila pentru afisarea boxei de dialog Print si creaza contextul de dispozitiv pentru imprimanta selectata.

print1View.cpp --CPrint1View::OnPreparePrinting() as Generated by AppWizard

BOOL CPrint1View::OnPreparePrinting(CPrintInfo* pInfo)

Folosind pointerul la obiectul CPrintInfo, putem face aici diverse initializari. Trebuie cercetata clasa CPrintInfo.

Members of the CPrintInfo Class

Member

Description

SetMaxPage()

Sets the document's maximum page number.

SetMinPage()

Sets the document's minimum page number.

GetFromPage()

Gets the number of the first page that users selected for printing.

GetMaxPage()

Gets the document's maximum page number, which may be changed in OnBeginPrinting().

GetMinPage()

Gets the document's minimum page number, which may be changed in OnBeginPrinting().

GetToPage()

Gets the number of the last page users selected for printing.

m_bContinuePrinting

Controls the printing process. Setting the flag to FALSE ends the print job.

m_bDirect

Indicates whether the document is being directly printed.

m_bPreview

Indicates whether the document is in print preview.

m_nCurPage

Holds the current number of the page being printed.

m_nNumPreviewPages

Holds the number of pages (1 or 2) being displayed in print preview.

m_pPD

Holds a pointer to the print job's CPrintDialog object.

m_rectDraw

Holds a rectangle that defines the usable area for the current page.

m_strPageDesc

Holds a page-number format string.

Cand functia DoPreparePrinting() afiseaza boxa de dialog Print, utilizatorul poate seta o parte din datele membru ale clasei CPrintInfo. In mod obisnuit, ultimul apel trebuie facut pentru SetMaxPage() inainte ca DoPreparePrinting() sa afiseze boxa de dialog Print. Daca nu putem determina numarul de pagini pana cand nu avem un DC pentru imprimanta selectata, trebuie sa asteptam pana cand obtinem acest context de dispozitiv. In mod normal contextul de dispozitiv al imprimantei se creaza la selectia acesteia in cadrul acestei boxe de dialog.

Dupa OnPreparePrinting(CDC*, CPrintInfo*), MFC apeleaza OnBeginPrinting(), care este un alt loc potrivit pentru a seta numarul maxim de pagini, dar si locul pentru a crea resurse, cum ar fi fonturi, necesare pentru a completa job-ul de tiparire.

In continuare, MFC apeleaza OnPrepareDC() pentru prima pagina a documentului. Aceasta constituie inceputul buclei care se executa o data pentru fiecare pagina a documentului. In OnPrepareDC() putem controla care parte din intreg documentul se tipareste, ca fiind pagina curenta. Aici vom seta originea viewportului pentru document.

Dupa OnPrepareDC(), MFC apeleaza OnPrint() pentru a tipari pagina curenta. In mod normal, OnPrint() apeleaza OnDraw() cu un parametru pointer la CDC, care automat redirecteaza iesirea spre imprimanta. Putem rescrie OnPrint() pentru a controla modul cum documentul este tiparit. Putem tipari headers si footers in OnPrint() si apoi sa apelam versiunea de baza a lui OnDraw() pentru a tipari pagina curenta. Pentru a preveni vesriunea din clasa de baza ca sa nu rescrie headers si footers, restrictionam zona tiparibila prin setarea variabilei m_rectDraw din obiectul CPrintInfo la un dreptunghi care nu acopra headers si footers.

Versiune posibila OnPrint() cu Headers si Footers

void CPrint1View::OnPrint(CDC* pDC, CPrintInfo* pInfo)

Se poate renunta la apelul lui OnDraw() in OnPrint(), creind cod suplimentar, ca in exemplul de mai jos.

Versiune posibila OnPrint() fara OnDraw()

void CPrint1View::OnPrint(CDC* pDC, CPrintInfo* pInfo)

Dupa ce MFC a terminat de tiparit ultima pagina, apeleaza functia OnEndPrinting(), unde putem distruge orice resursa de care nu mai avem nevoie.





Politica de confidentialitate


creeaza logo.com Copyright © 2024 - Toate drepturile rezervate.
Toate documentele au caracter informativ cu scop educational.