Print and print previews are often used in general software development, and for the document/view (Doc/view) framework in VC6.0, the default print and print previews are easy to use. However, if the application is based on a dialog box, there is no way to take advantage of this convenience. In many cases, dialog-based programs also require print and print preview capabilities. So what should we do? This is the problem that this article will solve.
1 Implementation Printing
In the dialog box application does not have MFC's visual and framework interaction, in order to achieve print and print preview must directly obtain the printer's device environment handle, you can set the Cpringdialog class constructor parameters, get the printer's device environment handle. Using this handle to convert to a pointer, the print task is implemented according to the print process.
(1) Derive the main window class Cmyframewnd from the CFrameWnd class to join the project, this class will be used as the control class to implement the program printing and printing pre.
(2) Add print and print preview related functions in Cmyframewnd, for convenience, the default print and Print preview virtual function names are the same in the CView view class. But these functions are added as member functions, not overloads. The print and OnPrint functions are mainly introduced here.
The print function is a printing control function that pops up the Print dialog box to get user settings information, such as printer, paper size, and so on. There is also a printer DC and set up DOCINFO structure, which contains the input and output file name and some other information, the StartDoc function to which the structure is used as a parameter. Also set the print area, call the print function, and so on
void Cmyframewnd::P rint ()
{
CDC DC;
CPrintDialog PrintDlg (FALSE);
if (Printdlg.domodal ()!= Idok)
Eject the Print dialog box to get the user settings parameter
Return
dc. Attach (PRINTDLG.GETPRINTERDC ());
Bind a printer DC to the CDC
Dc.m_bprinting=true;
DocInfo di; Initialize the printer's DocInfo
memset (&di,0,sizeof (DocInfo));
Di.cbsize=sizeof (DocInfo);
BOOL BPRINTINGOK=DC. StartDoc (&DI); Start a print task
CPrintInfo Info;
Info.m_rectDraw.SetRect (0,0,DC. GetDeviceCaps (Horzres),
C.getdevicecaps (vertres));
Set Print Area size
OnBeginPrinting (&dc,&info); Print initialization
for (UINT page = Info. GetMinPage (); Page < = Info.
GetMaxPage () && Bprintingok; page++)
{
dc. StartPage (); Start a new print page
Info.m_ncurpage=page;
OnPrint (&dc,&info); Print
Bprintingok= (DC. EndPage () > 0); Print Page End
}
OnEndPrinting (&dc,&info); Releasing resources after printing is complete
if (Bprintingok)
dc. EndDoc (); End of a print task
Else
dc. AbortDoc (); Terminate Print task
dc. Detach (); Free Printer DC
}
The OnPrint function mainly sets the mapping parameters and invokes the function of the dialog box's drawing function, as follows:
void Cmyframewnd::onprint (CDC *pdc,cprintinfo *pinfo)//
{
if (!PDC | |!pinfo) return;
CFont *poldfont=pdc->selectobject (&m_printerfont);
Setting mapping parameters and boundaries
Pdc->setmapmode (Mm_anisotropic);
Pdc->setwindowext (m_logicalpagesize);
Pdc->setviewportext (m_papersize);
Pdc->setwindoworg (-left_margin*m_charsize.cx,0);
Pdc->setwindoworg (0,0);
Pdc->selectobject (Poldfont);
}
2 Implementing Print Preview
The above functions can already be printed, to achieve print preview, but also to do some work. Since the execution of the print preview function relies on the CView and CFrameWnd framework, we create a temporary framework class and view class, and then call the default function of the temporary view class OnFilePrint and Onfileprintpreview.
(1) derive the CMyView class from the CView class to join the project. and overload the related print and print preview functions in the CMyView class. This class is mainly used to pass onbeginprinting,onprint,onendprinting and other related functions.
(2) Create a Frame and view window with a CSingleDocTemplate object in the PrintPreview function of the control class, where the view class CMyView is not displayed because it is immediately obscured by the Preview view (Preview view). m_pMainWnd to point to the new CFrameWnd so that the preview class can use it as the main frame. The initial value of the m_pMainWnd is saved, and when the preview is finished, the m_pMainWnd is restored to its original value. Of course, to include header file MyView.h in the control class. The specific procedures are as follows:
void Cmyframewnd::P rintpreview ()
{
if (M_bprintpreview)//preview marker
{
AfxGetApp ()->m_pmainwnd->setfocus ();
Return
}
cframewnd* poldframe= (cframewnd*) afxgetthread ()->m_pmainwnd;
Poldframe->showwindow (Sw_hide);
m_pMainWnd initial value is saved, original frame is hidden
if (!m_ptemplate)
{
M_ptemplate = new CSingleDocTemplate (Idr_menu,
NULL, Runtime_class (CFrameWnd), Runtime_class (CMyView)); Create a CSingleDocTemplate Object
AfxGetApp ()->adddoctemplate (m_ptemplate);
}
CFrameWnd * Pframewnd = m_ptemplate->
CreateNewFrame (Null,null);
Establishment of a temporary framework
M_bprintpreview=true; Print Preview
M_ptemplate-> initialupdateframe (Pframewnd, NULL,
FALSE);
CMyView * PView = (CMyView *) Pframewnd->
GetActiveView ();
pview->m_pctrlframe=this;
pview->m_poldframe=poldframe;
AfxGetApp ()->m_pmainwnd=pframewnd;
Pframewnd->showwindow (sw_showmaximized);
Show temporary frame
Pview->onfileprintpreview ();
Call CView default Print preview
}
Now we can see the preview window. But there is a small problem, the buttons on the toolbar are not automatically updated. This is because the dialog application does not have the OnIdle () function, and it is through this function in the SDI or MDI application that the WM_IDLEUPDATECMDUI message is sent to update the toolbar. So we have to send this message ourselves. First, we want to include AfxPriv.h to allow the program to recognize WM_IDLEUPDATECMDUI messages. Just like this:
BOOL Cszydlg::continuemodal ()
{
if (M_grid.m_bprintpreview)
AfxGetApp ()->m_pmainwnd->
Sendmessagetodescendants (Wm_idleupdatecmdui,
(WPARAM) True,0,true,true);
return Cdialog::continuemodal ();
}
The dialog based application does not contain the source file for print preview, so add the afxprint.rc to the project. Open the resource file in Notepad first, find #include afxres.rc in the 3 textinclude section, and add it below:
"#include" "afxprint.rc" "//Printing/print preview resources\ r\ n"
Then to the end of the resource file, locate #include afxres.rc, and add it below:
#include afxprint.rc//printing/print Preview Resources
Finally, add a response function to the dialog class for the Print button (that is, the id_file_print message):
Begin_message_map (Cmydlg,cdialog)
{{Afx_msg_map (CMyDlg)
...
}}afx_msg_map
On_command (Id_file_print,onfileprint)//Message response function
End_message_map ()
3 Conclusion
dialog box application is concise, can better exchange information with the user, so the application is very extensive. On this basis to achieve print and print preview can better meet the needs of users, has a certain practical value. To achieve print and print preview, the most critical part is to try to get its device environment handle according to the specific requirements of the program, and then follow the print and print preview process to achieve specific print and print preview tasks. In the development of the "centrifugal Pump performance test System", in accordance with the above method of successful implementation of the print and print preview. Interested readers can also be based on their own needs on this basis to achieve their desired print and print preview function.
Reference documents
[1] (US) Kruglinski DJ. vc++6.0 Technical Insider [M]. Beijing: Tsinghua University Press, 1999.
[2] Wang Hui, et. Proficient in Visual C++6.0[m]. Beijing: Electronics Publishing House, 1999.
Implementation steps:
1. Add four documents to the project first, and #include "PrintFrame.h" in CprintDlg.cpp.
2. In CprintDlg.h, add three messages
Protected
Generated message map functions
{{afx_msg (cprint)
virtual void OnOK ();
}}afx_msg
Lresult onbeginprinting (WPARAM wparam,lparam LPARAM);
Lresult onendprinting (WPARAM wparam,lparam LPARAM);
Lresult Onmyprint (WPARAM wparam,lparam LPARAM);
Declare_message_map ()
3. In the CprintDlg.cpp,
Begin_message_map (Cprint, CDialog)
{{Afx_msg_map (cprint)
}}afx_msg_map
On_message (wm_begin_printing,onbeginprinting)
On_message (wm_end_printing,onendprinting)
On_message (Wm_my_print,onmyprint)
End_message_map ()
4. Add three functions to CprintDlg.cpp
Lresult Cprint::onmyprint (WPARAM WPARAM, LPARAM LPARAM)//will be printed written to this
{
cdc* PDC = (cdc*) WParam;
cprintinfo* pinfo = (CPrintInfo *) LParam;
Pdc->moveto (100,200);
Pdc->lineto (500,600);
return TRUE;
}
Lresult cprint::onbeginprinting (WPARAM wparam,lparam LPARAM)
{
cdc* PDC = (cdc*) WParam;
cprintinfo* pinfo = (CPrintInfo *) LParam;
return TRUE;
}
Lresult cprint::onendprinting (WPARAM wparam,lparam LPARAM)
{
return TRUE;
}
4. void Cprint::onok ()//Print Preview button
{Cprintframe *pframe = new cprintframe;//001
Pframe->m_pcallerdlg = this;
Pframe->create (NULL, "Curve Print Preview", Ws_overlappedwindow,crect (0,0,0,0));//002
Pframe->m_pview->onmyprintpreview ();
Cdialog::onok ();
}