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 />

Using Custom Dialog Template<br />

Like other common dialog boxes, we can use our own dialog template to replace the standard one. This<br />

procedure is similar to that of other common dialog boxes. To use custom dialog template, we need to<br />

make changes to the default values of the following members contained in structure PRINTDLG: 1) Enable<br />

PD_ENABLEPRINTTEMPLATE flag. 2) Assign the custom dialog template name to member<br />

lpPrintTemplateName. 3) Assign the application instance handle to member hInstance.<br />

Sample 12.6-2\GDI is based on sample 12.5-3\GDI and demonstrates how to use programmerprovided<br />

dialog template to implement print dialog box.<br />

The first step of implementing customized print dialog box is to add a new dialog template. We can<br />

copy this dialog template from file “Commdlg.dll” and modify it. Please note that we cannot delete the<br />

original controls contained in the template. If we want to hide certain controls, we can either move them<br />

out of the template, or disable them in the dialog box’s initialization stage. In sample 12.6-2\GDI, the new<br />

dialog template is PRINTDLG. For the purpose of demonstration, no change is made to the original template.<br />

The next step is to derive a class from CPrintDialog. If we double click on the dialog template, we<br />

will be prompted to add a new class for it. Since CPrintDialog is not in the list of base classes, we can first<br />

choose CDialog as the base class and change all the keywords CDialog to CPrintDialog later. Please note<br />

that the constructors of CPrintDialog and CDialog are different, so if we choose automatic method, we<br />

also need to change the constructor created by the Class Wizard. In the sample, the new class is CPrnDlg.<br />

There is no new variable or function added to it because we don’t want to make further modification. The<br />

only thing implemented in the new class is that flags PD_NOPAGENUMS and PD_NOSELECTION are set in the<br />

constructor so that the radio buttons and edit boxes will be disabled. This is the same with sample 12.6-<br />

1\GDI.<br />

The place where we can use this dialog box is still in function CGDIView::OnPreparePrinting(…).<br />

Since there is a default print dialog box implemented, we must delete the old one before we can use our<br />

own. After we allocate memory and implement a new print dialog box, we must assign it to member<br />

CPrintInfo::m_pPD. Also, we must set template name, instance, and enable PD_ENABLEPRINTTEMPLATE<br />

flag. The following shows how the customized print dialog is implemented in function CGDIView::<br />

OnPreparePrinting(…):<br />

……<br />

BOOL CGDIView::OnPreparePrinting(CPrintInfo *pInfo)<br />

{<br />

delete pInfo->m_pPD;<br />

pInfo->m_pPD=new CPrnDlg(FALSE);<br />

pInfo->m_pPD->m_pd.nMinPage=1;<br />

pInfo->m_pPD->m_pd.nMaxPage=0xFFFF;<br />

pInfo->m_pPD->m_pd.hInstance=AfxGetInstanceHandle();<br />

pInfo->m_pPD->m_pd.lpPrintTemplateName=MAKEINTRESOURCE(PRINTDLG);<br />

pInfo->m_pPD->m_pd.Flags|=PD_ENABLEPRINTTEMPLATE;<br />

if(DoPreparePrinting(pInfo) == FALSE)return FALSE;<br />

With the above implementation, the print dialog box will use the custom dialog template PRINTDLG.<br />

Summary<br />

1) To capture the screen, we need to obtain a DC of the desktop window, prepare blank memory bitmap,<br />

and call function CDC::BitBlt(…) to make the copy.<br />

1) For palette devices, we must obtain the system palette after a snapshot is taken. This can be<br />

implemented by creating logical palette using PC_EXPLICIT flags.<br />

1) One logical unit can be mapped to different size on the target device. If we use MM_TEXT mode, one<br />

logical unit will be mapped to one physical unit. We can also use other mapping modes to map one<br />

logical unit to an absolute length.<br />

1) To fit the output within the target device, we need to know the resolution of the device, along with the<br />

number of pixels contained in one inch for both horizontal and vertical directions. These parameters<br />

can be obtained by calling function CDC::GetDeviceCaps(…) and using flags HORZRES, VERTRES,<br />

LOGPIXELSX and LOGPIXELSY.<br />

389

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

Saved successfully!

Ooh no, something went wrong!