如何自定义常见打印对话框的 MFC 应用程序中

如何自定义常见打印对话框的 MFC 应用程序中,第1张

要向应用程序.rc 文件,请从 Commdlg.rc 复制 PRINTDLGORD 对话框框模板 (ID 是 1538),请按这些步骤 *** 作。

请注意 在 Visual C++ 4 x 和 5.0 中, 此对话框框模板位于文件 Include\Prnsetup.dlg。 在 Visual C++6.0 中此文件位于 MSDN 光盘上 \Samples\Vc98\Mfc\General\Clipart。 在 Microsoft Visual C++.NET 中此文件位于 MSDN 光盘上的 \Samples\Vc\Mfc\General\Clipart 文件夹。

打开 Commdlg.rc。

启用剪切和粘贴的项目资源文件中的资源:

如果您使用 Visual C++.NET 请在资源编辑器模式 (而不是默认资源视图模式中) 中打开项目.rc 文件。 为此,关闭资源视图窗口项目的。 解决方案资源管理器窗口中找到您项目.rc 文件。 右键单击解决方案资源管理器窗口中的.rc 文件,然后单击打开方式。 在打开方式对话框中,单击以选中该燃余程序用来打开该.rc 文件的资源编辑器,然后单击打开。

如果您使用的 Visual C++ 4 x 或 5.0,添加行 # include"Windows.h"Include\prnsetup.dlg 文件的顶部。 保存并关闭该文件。 重新打开它作为"资源"框文件打开对话框中使用打开。

在 Commdlg.rc 文件的资源编辑器窗口,单击 PRINTDLGORD 对话框资源、 单击 <>,然后单击 <>。 PRINTDLGORD ID 是 1538。 头文件 Dlgs.h 中定义此 PRINTDLGORD 符号。

您项目的.rc 文件的资源编辑器窗口中, 右键单击对话框,然后单击粘贴。 现在,保存并关闭项目.rc 文件,在资源编辑器窗口中,然后重然后重新打开项目的默认资源视图窗口。 如果要使用 Visual C++6.0,有复制资源的任何上下文菜单。 在文件菜单上单击打开以打开该 Commdlg.rc 文件槐此,然后打开您的项目的资源视图菜单。 选择在 Commdlg.rc 的 1538 的资源 ID、 按下该 Ctrl 键,然后将 Commdlg.rc 窗口中的对话框框资源拖放到资源视图窗口。

在 <>菜单上单击 <>。

<>菜单与上下文相关。 资源视图处于活动状态时,不会出现在 <>菜单。 切换到解决方案资源管理器,然后在项目菜单上单击 <>。

展开 MFC 类别 MFC 类模板,单击然后单击 <>。

使用 MFC 类向导添加用于此对话框框模板如 CMyPrintDialog 的 Visual C++ 类。 从 CPrintDialog 派生此新的类。

如果您使用的 Visual C++6.0,请在 <>菜单上单击<>。

<>菜单与上下文相关。 资源视图处于活动状态时,不会出现在 <>菜单。 切换到 ClassView,然后在<>菜单上单击 <>。 为类键入名称,设置为 <>的<>,然后单击 <皮明滚>。

从 CDialog 的所有引用都更改为新创建的类的页眉和实现文件中的 CPrintDialog 中。 请注意此步骤不需要如果您已直接从 CPrintDialog 派生您的类。

因为 CPrintDialog 的构造函数不同于 CDialog,修改 CMyPrintDialog 的构造函数使用以下代码: 注意: 此步骤如果不是必需您已直接从 CPrintDialog 中派生您的类.

// Header file of CMyPrintDialog.

class CMyPrintDialog : public CPrintDialog

{

// Construction.

public:

// The arguments to the following constructor closely match

// CPrintDialog. Note the difference in the second argument.

CMyPrintDialog(BOOL bPrintSetupOnly,

// TRUE for Print Setup, FALSE for Print Dialog.

DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES |

PD_HIDEPRINTTOFILE,

// Combination of flags. Refer to the Windows SDK

// documentation for PRINTDLG structure for a

// description of all the flags that can be used.

CWnd* pParentWnd = NULL)

// Rest of the class declaration.

...

DECLARE_MESSAGE_MAP()

}

// Implementation file of CMyPrintDialog.

CMyPrintDialog::CMyPrintDialog(BOOL bPrintSetupOnly,

DWORD dwFlags /* = PD_ALLPAGES | PD_USEDEVMODECOPIES |

PD_HIDEPRINTTOFILE */,

CWnd* pParentWnd /* = NULL */)

: CPrintDialog(bPrintSetupOnly, dwFlags, pParentWnd)

{

//{{AFX_DA

TA_INIT(CMyPrintDialog)

// NOTE: the ClassWizard will add member initialization here.

//}}AFX_DA

TA_INIT

}

进行任何所需更改为复制的对话框框模板和关联的源代码中。 注意: 不要删除任何存在原始对话框框模板中的控件。 删除该控件,可导致问题的 CPrintDialog DoDataExchange 在功能。 相反,禁用不需要的控件,或在 CPrintDialog 派生类的重写 On

InitDialog 成员函数中隐藏它们。

修改 CView 派生类 (是例如 CMyView) 通过使用下面的代码中使用自定义的打印对话框:

// Implementation file of the view (for example, in myview.cpp).

...

#include "MyPrintDialog.h" // Include the CMyPrintDialog header file.

...

// Override On

PreparePrinting of the CView-derived class as below:

BOOL CMyView::On

PreparePrinting(CPrintInfo* pInfo)

{

// Delete the CPrintDialog object created in the CPrintInfo

// constructor, and substitute with customized print dialog.

delete pInfo->m_pPD

// Construct and substitute with customized print dialog.

pInfo->m_pPD = new CMyPrintDialog(FALSE)

// Set the page range.

pInfo->m_pPD->m_pd.nMinPage = 1 // on

e based page numbers.

pInfo->m_pPD->m_pd.nMaxPage = 0xffff// how many pages is unknown.

// Change the PRINTDLG struct so that the custom print dialog box will

// be used.

pInfo->m_pPD->m_pd.hInstance = AfxGetInstanceHandle()

pInfo->m_pPD->m_pd.lpPrintTemplateName =

MAKEINTRESOURCE(1538)

// Set the Flags of the PRINTDLG structure as shown, else the

// changes will have no effect.

pInfo->m_pPD->m_pd.Flags |= PD_ENABLEPRINTTEMPLATE

// For details about these flags, refer to the SDK documentation

// on the PRINTDLG structure.

return DoPreparePrinting(pInfo)

}

重载完笑皮宏OnPrint不就ok了吗,应该可以打印了阿。

1.

菜单里如果没有打印和打印预览,就用对话框编辑器添加上,

注意ID 分别写 ID_FILE_PRINT 和 ID_FILE_PRINT_PREVIEW

2.

菜单->VIEW->Resource includes 命令:

compile-time ..那个滚动框里

拉到最下面,

看看除了#include "afxres.rc" 之外,有没有#include "afxprint.rc",没有的话,添加上

3

在你的printview.cpp文件里(应该有这个程序文件,没有的话,找那个xxxView.cpp)

找到

BEGIN_MESSAGE_MAP(...,...)。。。碰册END_MESSAGE_MAP()

看看其中,有没有

ON_COMMAND(ID_FILE_PRINT,CView::OnFilePrint)

ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView::OnFilePrintPreview)

没有的话,用classwizard 添加上。握祥

在MFC中CView类已经封装好了打印相关的功能,我们只需要添加一些虚函数并加以处理即可。

需要添加的虚函数有:

public:

virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo = NULL)

protected:

virtual BOOL OnPreparePrinting(CPrintInfo* pInfo)

virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)

virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)

virtual void OnPrint(CDC* pDC, CPrintInfo* pInfo)

virtual void OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView)

其中:

OnPrepareDC是公有类型的,此函数在输出到屏幕时会被调用,在打印和打印预览时也会被调用。

在输出到屏幕时是段拦被CView::OnPaint()调用的,其函数原型为:

void CView::OnPaint()

{

// standard paint routine

CPaintDC dc(this)

OnPrepareDC(&dc)

OnDraw(&dc)

}

而在打印预览时是被:CPreviewView::OnDraw(CDC* pDC)调用的(其函数原型较长,故此忽略).很明显他是为准备设备上下文环境而被调用的。

当然如果在CView的派生类中添加了WM_PAINT事件则输出到屏幕时OnPrepareDC不会被调用。

在打印预览中以上函数调用的顺序为:

OnPreparePrinting-->OnBeginPrinting-->OnPrepareDC-->OnPrint-->OnEndPrintPreview-->OnEndPrinting.

如果在打印预览中窗口有变动则OnPrepareDC-->核则OnPrint重复调改燃棚用.

根据如上过程,我们可以在OnPreparePrinting函数中准备打印信息CPrintInfo* pInfo

在OnPrint中添加打印信息,当然要去掉OnPrint函数中CView::OnPrint(pDC, pInfo)的调用。CView::OnPrint(pDC, pInfo)它会调用CView类中的OnDraw函数,其函数原型是:

void CView::OnPrint(CDC* pDC, CPrintInfo*)

{

ASSERT_VALID(pDC)

// Override and set printing variables based on page number

OnDraw(pDC) // Call Draw

}

如果打印多页的话可以根据CPrintInfo* pInfo的信息在OnPrint函数中进行不同的输出,如:

if(pInfo->m_nCurPage==1){

输出

}

else if(pInfo->m_nCurPage==2){

输出

}

由于打印机的分辨率通常要比屏幕的分辨率大得多。假如同样的一条输出语句,在屏幕上输出为1厘米,在打印机上可能就是很短的距离。因此,在输出打印信息时,需要设置一定的输出比例。可以利用CDC的GetDeviceCaps方法间接获取打印机与屏幕的分辨率。该方法如下:

int GetDeviceCaps(int nIndex)const

参数说明:

nIndex:标识方法返回信息的类型。LOGPIXELSX是当前CDC对象,表示设备水平方向每英寸的像素数量.LOGPIXELSY是当前CDC对象,表示设备垂直方向每英寸的像素数量.

当窗口的CDC对象调用GetDeviceCaps(LOGPIXELSX)方法时,返回的是屏幕水平方向每英寸的像素数量.当打印机的CDC对象调用GetDeviceCaps(LOGPIXELSX)方法时,返回的是打印机水平方向每英寸的像素数量.将这两种方法返回的数据相除就可以获得打印机与屏幕的分辨率比率了。

通常可以在CView类的OnDraw方法中获取屏幕每英寸的像素量,代码如下:

screenx=pDC->GetDeviceCaps(LOGPIXELSX)

screeny=pDC->GetDeviceCaps(LOGPIXELSY)

在CView类的OnBeginPrinting方法中获得打印机每英寸的像素数量,代码如下:

printx=pDC->GetDeviceCaps(LOGPIXELSX)

printy=pDC->GetDeviceCaps(LOGPIXELSY)

xrate=(double)printx/screenx

yrate=(double)printy/screeny

在OnDraw函数的输出语句与OnPrint中的输出语句稍微有点变化,如在OnDraw中输出语句为:

pDC->TextOut(100,100,"wjh")

在OnPrint中要改为:

pDC->TextOut((int)100*xrate,(int)100*yrate,"wjh")

当然字体也要放大。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12426148.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存