hur.cn - 华软网

 热门搜索

如何在CFormView中实现打印功能啊?

  作者:未知    来源:网络    更新时间:2010/11/24
我是个菜鸟,在CFormView中实现打印这个问题困扰了我好一会。看到的对照好的回答以下:

程念陵 蔡 璇

  在Microsoft Visual C++中,CFormView是一个非常有用的视类,CFormView类允许在视中放置控制,进一步能够放置ActiveX控件,而且能够利用ResourceWizard直接举行编辑。然则,CFormView不支持打印及打印预览,咱们能够利用考屏功能将CFormView的窗口打印出来。


  (一)、 定义可打印的CFormView类


  首先,利用ClassWizard生成一个新类CPrintView ,继承于CFormView类,在CPrintView中定义以下变量:

  CRect m_rect; //保存获得的打印机打印区域巨细

  CBitmap* m_pBmp; //屏幕拷贝为一个CBitmap

  CDC* m_pMemDC; //一个内存设备环境,兼容与打印机的设备环境

  BOOL m_bFlag; //一个BOOL变量,用于决意只创建m_pBmp和m_pMemDC一次

  然后,重载以下函数:

  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*);


  (二)、 在CPrintView类的构造函数中初始化变量


  CPrintView::CPrintView() : CFormView(CPrintView::IDD)

  {

   m_pMemDC = new CDC;

   m_pBmp = new CBitmap;

   m_bFlag = FALSE;

   //{{AFX_DATA_INIT(CPrintView)

   // NOTE: the ClassWizard will add member initialization here

   //}}AFX_DATA_INIT

  }


  (三)、 重载CPrintView::OnBeginPrinting()函数


  void CPrintView::OnBeginPrinting(CDC* pDC, CPrintInfo* /*pInfo*/)

  {

  m_pMemDC-〉CreateCompatibleDC(pDC); //创建兼容与打印机设备环境的内存设备环境,将内存设备环境的指针保存留m_pMemDC中

  CClientDC dc(this); //获得窗口用户区的设备环境,保存留dc中

  CRect rect;

  GetClientRect(rect); //获得窗口用户区的矩形区域,保存留rect中

  m_pMemDC-〉SetMapMode(MM_ANISOTROPIC); //设置映照方式为

  MM_ANISOTROPIC

  m_pMemDC-〉SetWindowExt(dc.GetDeviceCaps(LOGPIXELSX),

  dc.GetDeviceCaps(LOGPIXELSY));

  m_pMemDC-〉SetViewportExt(m_pMemDC-〉GetDeviceCaps(LOGPIXELSX),

  m_pMemDC-〉GetDeviceCaps(LOGPIXELSY)); //设置坐标系

  if (m_bFlag == FALSE)

  {

  m_pBmp-〉CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());

  } //创建兼容与dc的CBitmap

  m_pMemDC-〉SelectObject(m_pBmp); //选择GDI对象

  dc.DPtoLP(rect); //将设备坐标转换为逻辑坐标

  m_rect = rect; //保存窗口用户区矩形

  m_pMemDC-〉BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);

  //将dc复制到m_pMemDC

  if (m_bFlag == FALSE)

  m_bFlag = TRUE; //判断是否第一次运行

  }


  (四)、 重载CPrintView::OnPrint()函数


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

  {

  pDC-〉SetMapMode(MM_ANISOTROPIC); //设置打印机设备环境的坐标系为

   MM_ANISOTROPIC

  pDC-〉SetWindowExt(m_pMemDC-〉GetDeviceCaps(LOGPIXELSX),

  m_pMemDC-〉GetDeviceCaps(LOGPIXELSY));

  pDC-〉SetViewportExt(pDC-〉GetDeviceCaps(LOGPIXELSX), //设置坐标系

  pDC-〉GetDeviceCaps(LOGPIXELSY));

  pDC-〉StretchBlt(0,0,m_rect.Width(),m_rect.Height(),

  m_pMemDC,0,0,m_rect.Width(),m_rect.Height(),SRCCOPY); //在打印机设备环境中绘制内存设备环境中的图形

  }


  (五)、 需要将析构函数改写


  CPrintView::~CPrintView()

  {

  delete m_pMemDC; //删除内存设备环境

  delete m_pBmp; //删除CBitmap的指针

  }    

那么在完成了这五个步骤之后呢,接下来如何在“打印”“打印预览”这两个菜单项里增加怎样的代码啊?

 

---华软 网友回答---
这篇博客是介绍在对话框中实现打印和打印预览功能的
原理是一样的
你能够参照一下
http://blog.csdn.net/xianglitian/archive/2010/10/23/5960970.aspx
---华软网友回复---
看了一下,好像帮助布什很大。如果能够把它先酿成位图再打印出来,根据这个原理那么不论是对话框照旧单文档的CFormview应该都能够吧。我现在做的单文档。这个原理应该也适用于我这里吧。就是不知道怎么调用重写的那些函数?
---华软网友回复---
    我在重写了这些函数之后又在菜单栏里加了两个菜单项“打印”和“打印预览”。那么在重写了这些的基础上我应该怎样写这两个菜单项的命令响应函数呢?
    
     写完上面的五部编译没有毛病了的。
---华软网友回复---
将我例子中的按钮消息的代码写到“打印预览”的菜单消息中能够实现打印预览功能
打印对照简单
在菜单中执行

C++">CPrintFramep	pPrintFrame	= new CPrintFrame(this);
pPrintFrame->DoPrint();
delete pPrintFrame;

---华软网友回复---
引用楼主 xiao8qiang8qiang8 的回复:
我是个菜鸟,在CFormView中实现打印这个问题困扰了我好一会。看到的对照好的回答以下:

那么在完成了这五个步骤之后呢,接下来如何在“打印”“打印预览”这两个菜单项里增加怎样的代码啊?


程念陵 蔡 璇

在Microsoft Visual C++中,CFormView是一个非常有用的视类,CFormView类允许在视中放置控制,进一步能够放置ActiveX控件,而且能够利用ResourceWizard直接举行编辑。然则,CFormView不支持打印及打印预览,咱们能够利用考屏功能……


重载完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 增加上。
---华软网友回复---
按照你说的这三部加了,可是点击打印和打印预览这两个菜单项时会有毛病警告啊。然后就退出程序了。这是怎么回事呢?
---华软网友回复---
引用 4 楼 xianglitian 的回复:
将我例子中的按钮消息的代码写到“打印预览”的菜单消息中能够实现打印预览功能
打印对照简单
在菜单中执行


C/C++ code
CPrintFramep    pPrintFrame    = new CPrintFrame(this);
pPrintFrame->DoPrint();
delete    pPrintFrame;


这个CPrintFramep 是什么啊 你自定义的一个什么类吗?我把最后的p改成星号“*”好像也不行啊。
---华软网友回复---
引用 5 楼 dubiousway 的回复:
引用楼主 xiao8qiang8qiang8 的回复:
我是个菜鸟,在CFormView中实现打印这个问题困扰了我好一会。看到的对照好的回答以下:

那么在完成了这五个步骤之后呢,接下来如何在“打印”“打印预览”这两个菜单项里增加怎样的代码啊?


程念陵 蔡 璇

在Microsoft Visual C++中,CFormView是一个非常有用的视类,CFormView类允许在视中……


我重载的是onprint()函数,然则那个菜单项的响应函数是OnFilePrint(),它好像照旧没有调用打印功能啊。会不会是这个原因啊?
---华软网友回复---
引用 8 楼 xiao8qiang8qiang8 的回复:
我重载的是onprint()函数,然则那个菜单项的响应函数是OnFilePrint(),它好像照旧没有调用打印功能啊。会不会是这个原因啊?

引用 5 楼 dubiousway 的回复:
引用楼主 xiao8qiang8qiang8 的回复:
我是个菜鸟,在CFormView中实现打印这个问题困扰了我好一会。看到的对照好的回答以下:

那么在完成了这五个步骤之后呢,接下来如何在“打印”“打印预览”这两个菜单项里增加怎样的代码啊?


程念陵 蔡 璇

在Microsoft Visual C++中,CFormView是……


。。。

sorry. 我习气了。。。老觉得classwizard增加简单。

你把通过classwizard增加的OnFilePrint 和 OnFilePrintPreview 都删除巴。

只需把
ON_COMMAND(ID_FILE_PRINT,CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView::OnFilePrintPreview)
这两行如果没有的话,在消息应映照里补上,应该没问题了。这两个函数CView都有了
---华软网友回复---
调用顺序是:

onFilePrint->
OnPreparePrinting->
onBeginPrinting
OnPrepareDC->
OnPrint(OnDraw)->(换页)-〉OnPrepareDC(循环)
OnEndPrinting


---华软网友回复---
现在我就是按照你说的这类弄了,呵呵,照旧毛病警告,然后就停止运行了,呵呵,无语了。
---华软网友回复---
void CCeshi::OnDraw(CDC* pDC) 
{
// TODO: Add your specialized code here and/or call the base class

}

BOOL CCeshi::OnPreparePrinting(CPrintInfo* pInfo) 
{
// TODO: call DoPreparePrinting to invoke the Print dialog box

return CFormView::OnPreparePrinting(pInfo);
}

void CCeshi::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo) 
{
// TODO: Add your specialized code here and/or call the base class

m_pMemDC->CreateCompatibleDC(pDC); //创建兼容于打印机设备环境的内存设备环境,将内存设备环境的指针保存留m_pMemDC中

CClientDC dc(this); //获得窗口用户区的设备环境,保存留dc中

CRect rect;

GetClientRect(rect); //获得窗口用户区的矩形区域,保存留rect中

m_pMemDC->SetMapMode(MM_ANISOTROPIC); //设置映照方式为 MM_ANISOTROPIC

m_pMemDC->SetWindowExt(dc.GetDeviceCaps(LOGPIXELSX),dc.GetDeviceCaps(LOGPIXELSY));

m_pMemDC->SetViewportExt(m_pMemDC->GetDeviceCaps(LOGPIXELSX),m_pMemDC->GetDeviceCaps(LOGPIXELSY)); //设置坐标系

if (m_bFlag == FALSE)

{
m_pBmp->CreateCompatibleBitmap(&dc,rect.Width(),rect.Height()); //创建兼容于dc的CBitmap


m_pMemDC->SelectObject(m_pBmp); //选择GDI对象

dc.DPtoLP(rect); //将设备坐标转换为逻辑坐标

m_rect = rect; //保存窗口用户区矩形

m_pMemDC->BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);//将dc复制到m_pMemDC   

if (m_bFlag == FALSE)

m_bFlag = TRUE;                //判断是否第一次运行


// CFormView::OnBeginPrinting(pDC, pInfo);
}

void CCeshi::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo) 
{
// TODO: Add your specialized code here and/or call the base class

CFormView::OnEndPrinting(pDC, pInfo);
}

void CCeshi::OnPrint(CDC* pDC, CPrintInfo* pInfo) 
{
// TODO: Add your specialized code here and/or call the base class

pDC->SetMapMode(MM_ANISOTROPIC); //设置打印机设备环境的坐标系为 MM_ANISOTROPIC

pDC->SetWindowExt(m_pMemDC->GetDeviceCaps(LOGPIXELSX),m_pMemDC->GetDeviceCaps(LOGPIXELSY));

pDC->SetViewportExt(pDC->GetDeviceCaps(LOGPIXELSX),pDC->GetDeviceCaps(LOGPIXELSY));     //设置坐标系

pDC->StretchBlt(0,0,m_rect.Width(),m_rect.Height(),m_pMemDC,0,0,m_rect.Width(),m_rect.Height(),SRCCOPY); //在打印机设备环境中绘制内存设备环境中的图形

// CFormView::OnPrint(pDC, pInfo);
}


头资料中:
public:
CRect m_rect; //保存获得的打印机打印区域巨细

CBitmap* m_pBmp; //屏幕拷贝为一个CBitmap

CDC* m_pMemDC; //一个内存设备环境,兼容于打印机的设备环境

BOOL m_bFlag; //一个BOOL变量,用于决意只创建m_pBmp和m_pMemDC一次

消息映照里:
         ON_COMMAND(ID_FILE_PRINT,CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView::OnFilePrintPreview)

所以不知道问题在哪了,呵呵?
---华软网友回复---
引用 11 楼 xiao8qiang8qiang8 的回复:
现在我就是按照你说的这类弄了,呵呵,照旧毛病警告,然后就停止运行了,呵呵,无语了。


实在不行,你就重新建立项目吧。建立进程中,别忘了把
Printing and print preview 这个feature 选择上就好了(建立进程中有这一项的选择)

然后你就直接按照 程念陵 蔡 璇 说的 的加上就好了,菜单什么的就不用管了。都已经好了
---华软网友回复---
其实 是现在我对打印的原理和什么设备环境 坐标转换这些内在的理论理解的不是很清楚。我现在才刚接触打印。照旧谢谢你们,我再研讨研讨吧。呵呵。
---华软网友回复---
引用 7 楼 xiao8qiang8qiang8 的回复:
引用 4 楼 xianglitian 的回复:
将我例子中的按钮消息的代码写到“打印预览”的菜单消息中能够实现打印预览功能
打印对照简单
在菜单中执行


C/C++ code
CPrintFramep pPrintFrame = new CPrintFrame(this);
pPrintFrame->DoPrint();
delete pPrintFrame;


这个C……

欠好意思
确实少了个*
而且应该是CPrintFrame
这个类我博客里有说明
---华软网友回复---
按照步骤做了,编译和运行都成功,而且能打印预览,然则关闭打印预览后,再举行预览时,却失利呢?      
华软声明:本内容来自网络,如有侵犯您版权请来信指出,本站立即删除。