11.04.2014 Views

Advanced MFC Programming

Advanced MFC Programming

Advanced MFC Programming

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Chapter 12. Screen Capturing & Printing<br />

Before printing begins, function CView::OnBeginPrinting(…) will be called. A CDC type pointer and a<br />

CPrintInfo type pointer will be passed to this function, from which we can obtain the information of<br />

current printing status. If we need to prepare something before the printing starts, we can override this<br />

function. This function is necessary because there exist some applications whose printing output is different<br />

from what is displayed in the client window. For example, if we are programming a video editing<br />

application, what can be displayed in the client window is usually one of a series of images. When the user<br />

does the printing, we actually want to print all the images. In this case, we must create either DIB or DDB<br />

data before the printing starts. Function CView::OnBeginPrinting(…) is a best place to implement such<br />

kind of preparation: we can create GDI objects, allocate memory, set device mapping modes, and so on.<br />

Since the GDI objects and memory prepared here are solely used for printing, after the printing is done, we<br />

must destroy them. Function CView::OnEndPrinting(…) is designed for this purpose, it will be called when<br />

the printing task is over.<br />

When the printing is undergoing, function CView::OnPrint(…) will be called. We can use CDC type<br />

pointer passed to this function to output objects to the printing device, this is the same with outputting<br />

objects to display device.<br />

Sample 12.4\GDI<br />

Sample 12.4\GDI is based on sample 12.3\GDI. In this sample the printing is handled in function<br />

CGDIView::OnPrinting(…), and CGDIView::OnDraw(…) is only responsible for painting the client window.<br />

Since we can use the DIB stored in the document for printing, we do not need to do any preparation in<br />

function CGDIView::OnBeginPring(…). Within function CGDIView::OnPrinting(…), we first need to obtain<br />

the DIB and palette from the document, and set the mapping mode to MM_LOMETRIC, which will map one<br />

logical unit to 0.1 mm. Then we need to select the palette into the target DC, call function<br />

::StretchDIBits(…) to copy the image to target device. Please note that after the mapping mode is set to<br />

MM_LOMETRIC, the direction of y axis is upward. When calling function ::StretchDIBits(…), we must set<br />

the output vertical dimension on the target device to a negative value if the origin is still located at (0, 0):<br />

……<br />

……<br />

::StretchDIBits<br />

(<br />

pDC->GetSafeHdc(),<br />

0,<br />

0,<br />

lpBi->bmiHeader.biWidth,<br />

-lpBi->bmiHeader.biHeight,<br />

0,<br />

0,<br />

lpBi->bmiHeader.biWidth,<br />

lpBi->bmiHeader.biHeight,<br />

(LPSTR)lpBi+dwBitOffset,<br />

lpBi,<br />

DIB_RGB_COLORS,<br />

SRCCOPY<br />

);<br />

Now no matter what type of printer we use, the output dimension will be the same. The only difference<br />

between the output from two different types of printers may be the image quality: for printers with high<br />

DPIs, we will see a smooth image; for printers with low DPIs, we will see undesirable image.<br />

Although the printing ratio is fixed for this sample, the user can still modify it through File | Print<br />

Setup… command. In the Print Setup dialog box, the user can also select printer, paper size and the<br />

printing ratio. The maximum printing ratio that can be set by the user is 400%. This may cause the output<br />

image unable to fit within the target device. In this case, we need to print one image on separate pages.<br />

383

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!