Print and preview Design Based on CEditView in VC

Source: Internet
Author: User
Tags drawtext
 
 

The visual structure of the MFC Document in Visual C ++ provides a framework for printing and previewing program structures, this allows you to print and preview document content or images simply by adding relevant code to overload functions such as onprint or ondraw. However, if the program is only used to display and print the content of the ASCII document, there is no need to start from scratch. If you can design the program based on the ceditview framework, you can get twice the result with half the effort.

  I. functions and features of ceditview Program Framework

When you use MFC Appwizard (exe) to create a single or multi-document application, in step 6 of the wizard, select the base class of the View class as ceditview, the application can automatically display, edit, search and replace documents, cut, copy and paste clipboard, print, and print and preview documents. (For example, the ex_prn1 application is created here)

However, ceditview also has the following defects:

(1) ceditview does not support WYSIWYG editing.

(2) ceditview only displays text in a single font and does not support characters in special formats.

(3) The total number of texts that ceditview can hold is limited. In 32-bit windows, the maximum value is 1 MB.

(4) The print and print preview functions are barely supported.

Therefore, it is necessary to carry out more in-depth program design on the basis of ceditview, especially in printing and print preview.

  Ii. Program Design for print and print preview

The complete print and print preview design includes controlling the margin and line spacing, designing the header and footer, controlling the print font, selecting the print mode, printing multiple pages, and previewing. Fortunately, ceditview has implemented the multi-page printing and preview functions. Therefore, we only need to add the page margin settings, header and footer, and control the print font, it will certainly meet the needs of most ASCII document printing.

1. Set the margins

The margin refers to the distance between the printed text area and the printing paper border, including the left, right, and top and bottom margins. You can refer to the value of m_rectdraw, a member variable of cprintinfo. However, the value of m_rectdraw indicates the valid printing area, which has a certain margin between it and the printing area, this margin is caused by the printer itself, so it is called the physical margin, and these physical margins are different in different sizes of paper, so you must first obtain these values. In this case, you need to call the global function getdevicecaps. Its prototype is as follows:

Int getdevicecaps (HDC, int nindex );

HDC is used to specify the device environment handle, and nindex is used to specify the parameter index to be obtained. For printers, it often requires the following predefined values:

Horizontal resolution of logpixelsx printer

Vertical resolution of logpixelsy printer

Actual width of physicalwidth printing paper

Physicalheight the actual height of the printed paper

Physicaloffsetx physical left margin of the actually printable Area

Physicaloffsety physical top margin of the actually printable Area

It should be noted that if the size of a printing paper is A4 (210x297mm) and the resolution of the printer is 300x300 dpi, when the parameter value of the specified function is physicalwidth, the returned value is 210mm instead of 2480. The result is calculated as follows: first, the unit of millimeters is converted to inches, that is, 210mm to 8.267 inch, and then multiplied by 300 dpi.

The following function code is used to set the page margin and calculate the physical margin of the page:

Void CEx_Prn1View: SetPageMargin (CDC * pDC, CPrintInfo * pInfo, int l, int t, int r, int B)
// L, t, r, and B indicate the top left and bottom right margins, respectively, in the unit of 0.1
{
Int nOldMode = pDC-> GetMapMode ();
PDC-> SetMapMode (MM_LOMETRIC );
// Calculate the unit of a device. The value is 0.1mm.
Double scalex= 254.0/(double) GetDeviceCaps (
PDC-> m_hAttribDC, LOGPIXELSX );
Double scaleY = 254.0/(double) GetDeviceCaps (
PDC-> m_hAttribDC, LOGPIXELSY );
Int x = GetDeviceCaps (pDC-> m_hAttribDC,
PHYSICALOFFSETX );
Int y = GetDeviceCaps (pDC-> m_hAttribDC,
PHYSICALOFFSETY );
Int w = GetDeviceCaps (pDC-> m_hAttribDC,
PHYSICALWIDTH );
Int h = GetDeviceCaps (pDC-> m_hAttribDC,
PHYSICALHEIGHT );
Int nPageWidth = (int) (double) w * scaleX + 0.5 );
// Paper width, in the unit of 0.1
Int nPageHeight = (int) (double) h * scaleY + 0.5 );
// Paper height, in 0.1mm
M_nPhyLeft = (int) (double) x * scaleX + 0.5 );
// Left physical distance, in the unit of 0.1
M_nPhyTop = (int) (double) y * scaleY + 0.5 );
// Physical top margin, in 0.1
PDC-> DPtoLP (& pInfo-> m_rectDraw );
CRect rcTemp = pInfo-> m_rectDraw;
RcTemp. NormalizeRect ();
M_nPhyRight = nPageWidth-rcTemp. Width ()-
M_nPhyLeft; // The physical right margin, in the unit of 0.1
M_nPhyBottom = nPageHeight-rcTemp. Height ()-
M_nPhyTop; // physical bottom margin, in the unit of 0.1
// Adjust the margins if they are smaller than the physical margins.
If (l <m_nPhyLeft) l = m_nPhyLeft;
If (t <m_nPhyTop) t = m_nPhyTop;
If (r <m_nPhyRight) r = m_nPhyRight;
If (B <m_nPhyBottom) B = m_nPhyBottom;
// Calculate and adjust the size of pInfo-> m_rectDraw
PInfo-> m_rectDraw.left = l-m_nPhyLeft;
PInfo-> m_rectDraw.top =-t + m_nPhyTop;
PInfo-> m_rectDraw.right-= r-m_nPhyRight;
PInfo-> m_rectDraw.bottom + = B-m_nPhyBottom;
PDC-> LPtoDP (& pInfo-> m_rectDraw );
PDC-> SetMapMode (nOldMode );
// Restore the original ing mode
}

It should be noted that, because the environment ing mode in ceditview is mm_text, that is, the logical coordinates are the same as the device coordinates, you need to use the lptodp and dptolp functions in the logical coordinates (LP) and the device coordinate (DP.

2. header and footer

When printing a document, you often need to print the document title and page number or the header and footer of other content. We know that it is most appropriate to process the header and footer in the onprint function of the View class, because this function is called once every page printing, and only called during the printing process. Sometimes, to avoid overlap with the body, you also need to adjust the value of the member variable m_rectdraw in cprintinfo. For example, the following code:

Void CEx_Prn1View: OnPrint (CDC * pDC, CPrintInfo * pInfo)
{
SetPageMargin (pDC, pInfo, 250,250,250,250 );
// The margins are 25mm.
Int nOldMode = pDC-> GetMapMode ();
PDC-> SetMapMode (MM_LOMETRIC );
PDC-> DPtoLP (& pInfo-> m_rectDraw );
// First set the header font and then print the header
CFont font;
Font. CreateFontIndirect (& m_lfHead );
CFont * oldFont = pDC-> SelectObject (& font );
// Calculate the area drawn by the header
Int nheadmargin = 200; // set the header margin to 20mm.
Crect RC (pinfo-> m_rectdraw );
RC. Top =-nheadmargin + m_nphytop;
RC. Bottom = pinfo-> m_rectdraw.top;
// Set the header content to the printed document name
Cex_prn1doc * pdoc = getdocument ();
Cstring STR = pdoc-> getpathname (); // obtain the full name of the document.
PDC-> drawtext (STR, RC, dt_top | dt_center );
// First set the footer font and then print the footer
Font. Detach ();
Font. createfontindirect (& m_lffoot );
PDC-> SelectObject (& font );
// Calculate the area drawn by the footer
Int nfootmargin = 200; // set the footer margin to 20mm.
RC. Top = pinfo-> m_rectdraw.bottom;
RC. Bottom = RC. Top-(nfootmargin-m_nphybottom );
// Set the footer content to the printed page number
Str. Format ("-% d-", pinfo-> m_ncurpage );
PDC-> drawtext (STR, RC, dt_bottom |
Dt_singleline | dt_right );
PDC-> SelectObject (oldFont); // restore the original font
PDC-> LPtoDP (& pInfo-> m_rectDraw );
PDC-> SetMapMode (nOldMode); // restore the original ing mode
CEditView: OnPrint (pDC, pInfo );
}

In this way, add the following initialization code of the member variables m_lfhead and m_lffont of the logfont type to the constructor of the User View class:

CEx_Prn1View: CEx_Prn1View ()
{
Memset (& m_lfHead, 0, sizeof (LOGFONT); // The Member is 0.
Double fontScale = 254.0/72.0;
// How many 0.1mm a point is equivalent
// Header font
M_lfHead.lfHeight =-(int) (9 * fontScale + 0.5); // 9
M_lfHead.lfWeight = FW_NORMAL;
M_lfHead.lfCharSet = GB2312_CHARSET;
Strcpy (LPSTR) & (m_lfHead.lfFaceName ),
"_ GB2312 ");
// Footer font
M_lfFoot = m_lfHead;
}

Here, after compiling and running the program, open a document and select the "file" | "print preview" menu command to see the effect. However, the font displayed in the document still needs to be set, which is relatively simple. You only need to add a menu item (set as id_view_font), then use classwizard to add the message ing function for this command in the cex_prn1view class, and add the following code:

Void CEx_Prn1View: OnViewFont ()
{
CFontDialog dlg;
If (dlg. DoModal () = IDOK ){
LOGFONT lf;
Dlg. GetCurrentFont (& lf );
HFONT hFont;
HFont =: CreateFontIndirect (& lf );
If (hFont! = NULL)
SendMessage (WM_SETFONT, (WPARAM) hFont );
}
}

3. Reset the tab Value

In ceditview, the default tab value is 8 characters. However, the actual tab value is usually 4 characters, so you need to reset this tab value.

Ceditview: settabstops is a function like this, But msdn does not understand it. What is "the tab value set is in the unit of dialog box points. In fact, you only need to open the source code file viewedit of MFC. CPP shows that the default tab value is 8*4. Obviously, if it is set to 4 characters, the settabstops parameter value should be 4*4, or 16. The code for setting the tab value can be directly added to the cex_prn1view: oninitialupdate function:

Void CEx_Prn1View: OnInitialUpdate ()
{
CEditView: OnInitialUpdate ();
SetTabStops (4*4); // set a stop bit to 4 characters
}

Run the program again. The final result is shown in.

  

  Iii. Conclusion

By adding the set page margin, header and footer, and changing the font and Tab value in ceditview, the Code volume is not small, in addition, it mainly meets the requirements for displaying and printing the content of common ASCII documents.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.