Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




Tiparire si Previzualizare

Informatica


Tiparire si Previzualizare




Bazele tiparirii si previzualizarii în MFC

Cerinte pentru acest curs:

Contextul de dispozitiv;

Arhitectura Document/View, aplicatii t 848g63i ip SDI;

Tratarea mesajelor simple de mouse;

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 în tiparire si previzualizare;

v     determinarea elementelor ce identifica pagina de tiparit, etc.

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

Pentru învatarea manevrarii contextului de dispozitiv se poate propune construirea unei aplicatii care sa deseneze graficul unei functii. Se vor avea în vedere toate situatiile posibile unde poate fi desenat graficul functiei astfel încât sa fie ocupata cât mai bine zona client (pentru un grafic ce apare numai în 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 ramânând cele implicite) si cu suport pentru print/preview.

Numele proiectului este Print1.

Prima modificare.

În functia CPrint1View::OnDraw() adaugam:

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

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

Coltul din stânga 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 în modul MM_TEXT devine o problema când 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) Când 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 cât si tiparirea la imprimanta. Lucrurile se complica când documentul are mai multe pagini sau alte tratari speciale (informatii de început si de sfârsit de pagina).

Exemplificare:

Vom modifica aplicatia astfel încât sa desenam mai multe dreptunghiuri care sa nu încapa 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 în 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 întâmpla în PrintPreview. Codul din PrintPreview (în acest moment) nu stie cum sa afiseze mai multe pagini.

Determinarea numarului de pagini se face în 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:

înaltimea paginii;

numarul de dots pe inch.

Înaltimea 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 începutul paginii pâna la sfârsitul ei), deci vom furniza ca parametru constanta VERTRES, în functia GetDeviceCaps(). Constanta HORZRES în aceeasi functie ne furnizeaza rezolutia orizontala.

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

În exemplul nostru, pentru a sti câte dreptunghiuri încap pe o pagina, trebuie sa stim înaltimea dreptunghiului în dots, deci va trebui sa împartim dots pe pagina la dots pe dreptunghi.

stim ca fiecare dreptunghi este înalt de 2 inch cu un spatiu de 20/100 între fiecare dreptunghi. Distanta totala de la începutul desenarii unui dreptunghi pâna 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 înmultita cu 2.2 ne da dots pe dreptunghi.

Rulând aplicatia vom observa ca desi în 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 începutul 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 înainte de afisa datele pe ecran sau a le scrie la imprimanta. Acelasi cod realizeaza previzualizarea cât 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 înaltimea în dots a paginii de tiparit, deci un nou apel al functiei GetDeviceCaps().

În continuare trebuie sa detrerminam originea noului viewport (pozitia coordonatelor (0,0)) pentru afisare. Schimbând originea, dam informatia necesara cadrului de lucru MFC, pentru a sti de unde sa înceapa tiparirea datelor.

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

Dupa ce calculam noua origine, vom seta aceasta în cadrul contextului de dispozitiv apelând functia SetViewportOrg().

Se va rula aplicatia cu aceste ultime modificari efectuate.

MFC si Tiparirea

Alte functii importante în 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 întâi OnPreparePrinting() care apeleaza DoPreparePrinting() care la rândul 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.

Când functia DoPreparePrinting() afiseaza boxa de dialog Print, utilizatorul poate seta o parte din datele membru ale clasei CPrintInfo. În mod obisnuit, ultimul apel trebuie facut pentru SetMaxPage() înainte ca DoPreparePrinting() sa afiseze boxa de dialog Print. Daca nu putem determina numarul de pagini pâna când nu avem un DC pentru imprimanta selectata, trebuie sa asteptam pâna când obtinem acest context de dispozitiv. În mod normal contextul de dispozitiv al imprimantei se creaza la selectia acesteia în 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.

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

Dupa OnPrepareDC(), MFC apeleaza OnPrint() pentru a tipari pagina curenta. În 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 în 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() în OnPrint(), creind cod suplimentar, ca în 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.




Document Info


Accesari: 932
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2025 )