修改打印预览
文档/视图结构默认的打印预览是可以修改的,本实例通过CPreviewView类的派生类CPreView类来修改文档/视图结构默认的打印预览的按钮,使打印预览的界面看起来更加美观。调用DoPrintPreview函数可以修改工具栏。
语法:
BOOL CView::DoPrintPreview(UINT nIDResource,CView* pPrintView,CRuntimeClass* pPreviewViewClass,CPrintPreviewState* pState)
DoPrintPreview语法中的参数说明如表1所示。
表1DoPrintPreview语法中的参数说明
|
参数
|
描述
|
|
nIDResource
|
工具栏
|
|
pPrintView
|
打印视图
|
|
pPreviewViewClass
|
打印预览运行实类
|
|
pState
|
打印预览状态
|
例如,修改文档/视图结构默认的打印预览,程序设计步骤如下:
(1)创建一个基于文档/视图结构的应用程序。
(2)选择工作区窗口的RecourceView选项卡,导入4个图标资源。
(3)新建一个对话框资源,ID改为IDD_TOOLBAR_DIALOG,设置Style属性为Child,设置Border属性为None。向对话框中添加4个按钮控件,分别设置ID属性为AFX_ID_PREVIEW_PRINT、AFX_ID_PREVIEW_PREV、AFX_ID_PREVIEW_NEXT、AFX_ID_PREVIEW_CLOSE,为4个按钮选择Owner draw属性,使按钮允许自绘,对话框资源如图1所示。
.jpg)
图1 对话框资源
(4)以CButton类为基类派生一个CIconBtn类。
(5)以CPreviewView类为基类派生一个CPreView类。在该类的头文件中引用afxpriv.h头文件和IconBtn.h头文件,目的是可以访问CPreviewView类和CIconBtn类。
注意:我们在从CPreviewView类派生子类时,在子类的头文件部分需要引用afxpriv.h头文件,否则编译器无法发现CPreviewView类的声明,也就无法通过编译。
(6)在CPreView类头文件中声明变量,代码如下。
CPrintPreviewState* m_pPreviewState; // CPrintPreviewState类指针
CIconBtn m_Print,m_Before,m_Next,m_Close; //CIconBtn类对象
CImageList m_ImageList; //图像列表指针
(7)添加WM_CREATE消息的处理函数,将4个CIconBtn类对象关联到对话框中的按钮资源,代码如下。
int CPreView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
int retVal = CPreviewView::OnCreate(lpCreateStruct);
CCreateContext* pContext = (CCreateContext*)lpCreateStruct->lpCreateParams;
m_Print.SubclassDlgItem(AFX_ID_PREVIEW_PRINT,m_pToolBar); //发送按钮消息
m_Before.SubclassDlgItem(AFX_ID_PREVIEW_PREV,m_pToolBar); //发送按钮消息
m_Next.SubclassDlgItem(AFX_ID_PREVIEW_NEXT,m_pToolBar); //发送按钮消息
m_Close.SubclassDlgItem(AFX_ID_PREVIEW_CLOSE,m_pToolBar); //发送按钮消息
m_ImageList.Create(16,16,ILC_COLOR24|ILC_MASK,1,0); //创建图像列表
m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1)); //加载图标
m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2)); //加载图标
m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON3)); //加载图标
m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON4)); //加载图标
m_Print.SetImageList(&m_ImageList); //关联图像列表
m_Before.SetImageList(&m_ImageList); //关联图像列表
m_Next.SetImageList(&m_ImageList); //关联图像列表
m_Close.SetImageList(&m_ImageList); //关联图像列表
m_Print.SetImageIndex(0); //设置按钮显示图像
m_Before.SetImageIndex(1); //设置按钮显示图像
m_Next.SetImageIndex(2); //设置按钮显示图像
m_Close.SetImageIndex(3); //设置按钮显示图像
m_pOrigView = (CPrintPreviewView*)pContext->m_pLastView;
ASSERT(m_pOrigView != NULL);
ASSERT_KINDOF(CPrintPreviewView, m_pOrigView);
return 0;
}
(8)在CPrintPreviewView类中为ID_FILE_PRINT_PREVIEW消息添加消息处理函数,代码如下。
void CPrintPreviewView::OnFilePrintPreview()
{
CPrintPreviewState* pState = new CPrintPreviewState;
//修改工具栏
if(!DoPrintPreview(IDD_TOOLBAR_DIALOG, this,RUNTIME_CLASS(CPreView), pState))
{
AfxMessageBox(AFX_IDP_COMMAND_FAILURE); //弹出错误提示
delete pState; //释放指针
}
}
(9)在视图类的头文件中声明变量,代码如下。
int screenx,screeny; //屏幕每英寸像素数
int printx,printy; //打印机每英寸像素数
double ratex,ratey; //打印机与屏幕的像素比率
CFont m_Font; //文本字体
CString str[12]; //保存本文的数组
(10)添加PrintText函数,在该函数中设置打印文本。
(11)重载OnBeginPrinting函数,在该函数中获得打印机每英寸像素数,并技术打印机与屏幕的像素比率,代码如下。
void CPrintView::OnBeginPrinting(CDC* pDC, CPrintInfo* /*pInfo*/)
{
//获取打印机每英寸像素数
printx =pDC->GetDeviceCaps(LOGPIXELSX);
printy =pDC->GetDeviceCaps(LOGPIXELSY);
//计算打印机与屏幕的比率
ratex = (double)printx /screenx;
ratey = (double)printy /screeny;
}
(12)重载OnDraw函数,在应用程序窗口中绘制打印文本,代码如下。
void CPrintView::OnDraw(CDC* pDC)
{
CPrintDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
//获取屏幕每英寸像素数
screenx =pDC->GetDeviceCaps(LOGPIXELSX);
screeny =pDC->GetDeviceCaps(LOGPIXELSY);
PrintText(); //设置打印文本
if(pDC->IsPrinting()) //判断是否打印
{
m_Font.CreatePointFont(int(150*ratex),"宋体"); //创建字体
pDC->SelectObject(&m_Font); //将字体选入设备上下文
for(int i=0;i<12;i++)
{
pDC->TextOut(int(50*ratex),int((30+i*40)*ratey),str[i]); //绘制文本
}
}
else //不打印时
{
m_Font.CreatePointFont(150,"宋体"); //创建字体
pDC->SelectObject(&m_Font); //将字体选入设备上下文
for(int i=0;i<6;i++)
{
pDC->TextOut(50,30+i*40,str[i]); //绘制文本
}
}
m_Font.DeleteObject(); //释放字体
}
程序运行效果如图2所示。
.jpg)
图2 修改文档/视图结构默认的打印预览