5.6 公用对话框 在使用Windows的过程中,用户经常会遇到一些常用的有特定用途的对话框。例如,当选择File->Open,会弹出一个文件选择的对话框,用户可以在其中选择想要打开的文件。象文件选择这样的对话框,使用的非常普遍,因此Windows系统本身提供了对该对话框的支持,用户不必自己设计文件选择对话框。与文件选择对话框类似的还有颜色选择、字体选择、打印和打印设置以及正文搜索和替换对话框。这五种对话框均由Windows支持,被称为公用对话框。 MFC提供了一些公用对话框类,它们均是CDialog类的派生类,封装了公用对话框的功能。表5.6列出了MFC的公用对话框类。 表5.6 公用对话框类
通用对话框类使用方便,读者只需知道怎样创建对话框和访问对话框的数据,不必关心它们的内部细节。 5.6.1 CColorDialog类 CColorDialog类用于实现Color(颜色选择)公用对话框。Color对话框如图5.12所示,在Windows的画板程序中,如果用户在颜色面板的某种颜色上双击鼠标,就会显示一个Color对话框来让用户选择颜色。 图5.12 Color对话框
Color对话框的创建与一般的对话框没什么两样:首先是在堆栈上构建一个CColorDialog对象,然后调用CColorDialog::DoModal( )来启动对话框。CColorDialog的构造函数为 CColorDialog( COLORREF clrInit = 0, DWORD dwFlags = 0, CWnd* pParentWnd = NULL );参数clrInit用来指定初始的颜色选择,dwFlags用来设置对话框,pParentWnd用于指定对话框的父窗口或拥有者窗口。 根据DoModal返回的是IDOK还是IDCANCEL可知道用户是否确认了对颜色的选择。DoModal返回后,调用CColorDialog::GetColor()可以返回一个COLORREF类型的结果来指示在对话框中选择的颜色。COLORREF是一个32位的值,用来说明一个RGB颜色。GetColor返回的COLORREF的格式是0x00bbggrr,即低位三个字节分别包含了蓝、绿、红三种颜色的强度。 读者将在后面的章节中看到颜色选择对话框的例子。
5.6.2 CFileDialog类 CFileDialog类用于实现文件选择对话框,以支持文件的打开和保存操作。用户要打开或保存文件,就会和文件选择对话框打交道,图5.13显示了一个标准的用于打开文件的文件选择对话框。用MFC AppWizard建立的应用程序中自动加入了文件选择对话框,在File菜单选Open或Save As命令会启动它们。 图5.13 文件选择对话框 文件选择对话框的创建过程与一般对话框的类似,首先是在堆栈上构建一个CFileDialog对象,然后调用CFileDialog::DoModal( )来启动对话框。文件对话框的构造函数为 CFileDialog( BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL ); 如果参数bOpenFileDialog的值为TRUE,将创建Open(打开文件)对话框,否则就创建Save As(保存文件)对话框。参数lpszDefExt用来指定缺省的文件扩展名。lpszFileName用于规定初始文件名。dwFlags用于设置对话框的一些属性。lpszFilter指向一个过滤字符串,用户如果只想选择某种或某几种类型的文件,就需要指定过滤字符串。参数pParentWnd是指向父窗口或拥有者窗口的指针。过滤字符串有特定的格式,它实际上是由多个子串组成,每个子串由两部分组成,第一部分是过滤器的字面说明,如“Text file (*.txt)”,第二部分是用于过滤的匹配字符串,如“*.txt”,子串的两部分用竖线字符“ | ”分隔开。各子串之间也要用“ | ”分隔,且整个串的最后两个字符必须是两个连续的竖线字符“ || ”。一个典型的过滤字符串如下面所示: char szFilter[]= “All files (*.*)|*.*|Text files(*.txt)|*.txt|Word documents(*.doc)|*.doc||”; 若CFileDialog::DoModal返回的是IDOK,那么可以用表5.7列出的CFileDialog类的成员函数来获取与所选文件有关的信息。 表5.7 CFileDialog类辅助成员函数
5.6.3 CFindReplaceDialog类 CFindReplaceDialog类用于实现Find(搜索)和Replace(替换)对话框,这两个对话框都是非模态对话框,用于在正文中搜索和替换指定的字符串。图5.14显示了一个Find对话框,图5.15显示了一个Replace对话框。 图5.14 Find对话框 图5.15 Replace对话框 由于Find和Replace对话框是非模式对话框,它们的创建方式与其它四类公用对话框不同。CFindReplaceDialog对象是用new操作符在堆中创建的,而不是象普通对话框那样以变量的形式创建。要启动Find/Replace对话框,应该调用CFindReplaceDialog::Create函数,而不是DoModal。Create函数的声明是 BOOL Create( BOOL bFindDialogOnly, LPCTSTR lpszFindWhat, LPCTSTR lpszReplaceWith = NULL, DWORD dwFlags = FR_DOWN, CWnd* pParentWnd = NULL ); 当参数bFindDialogOnly的值为TRUE时,创建的是Find对话框,为FALSE时创建的是Replace对话框。参数lpszFindWhat指定了要搜索的字符串,lpszReplaceWith指定了用于替换的字符串。dwFlags用来设置对话框,其缺省值是FR_DOWN(向下搜索),该参数可以是几个FR_XXX常量的组合,用户可以通过该参数来决定诸如是否要显示Match case、Match Whole Word检查框等设置。参数pParentWnd指明了对话框的父窗口或拥有者窗口。Find/Replace对话框与其它公用对话框的另一个不同之处在于它在工作过程中可以重复同一操作而对话框不被关闭,这就方便了频繁的搜索和替换。CFindReplaceDialog类只提供了一个界面,它并不会自动实现搜索和替换功能。CFindReplaceDialog使用了一种特殊的通知机制,当用户按下了操作的按钮后,它会向父窗口发送一个通知消息,父窗口应在该消息的消息处理函数中实现搜索和替换。 CFindReplaceDialog类提供了一组成员函数用来获得与用户操作有关的信息,如表5.8所示,这组函数一般应在通知消息处理函数中调用。 表5.8 CFindReplaceDialog类的辅助成员函数
CEditView类自动实现了Find和Replace对话框的功能,但MFC AppWizard并未提供相应的菜单命令。读者可以在前面的Register工程的Edit菜单中加入&Find...和&Replace...两项,并令其ID分别为ID_EDIT_FIND和ID_EDIT_REPLACE,则Find/Replace对话框的功能就可以实现。 5.6.4 CFontDialog类 CFontDialog类支持Font(字体)对话框,用来让用户选择字体。图5.16显示了一个Font对话框。Font对话框的创建过程与Color对话框的类似,首先是在堆栈上构建一个CFontDialog对象,然后调用CFontDialog::DoModal来启动对话框。 图5.16 Font对话框 CFontDialog类的构造函数如下所示 CFontDialog( LPLOGFONT lplfInitial = NULL, DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS, CDC* pdcPrinter = NULL, CWnd* pParentWnd = NULL );参数lplfInitial指向一个LOGFONG结构,用来初始化对话框中的字体设置。dwFlags用于设置对话框。pdcPrinter指向一个代表打印机的CDC对象,若设置该参数,则选择的字体就为打印机所用。pParentWnd用于指定对话框的父窗口或拥有者窗口。 若DoModal返回IDOK,那么可以调用CFontDialog的成员函数来获得所选字体的信息,这些函数在表5.9列出。 表5.9 CFontDialog类的辅助成员函数
.6.5 CPrintDialog类 CPrintDialog类支持Print(打印)和Print Setup(打印设置)对话框,通过这两个对话框用户可以进行与打印有关的操作。图5.17显示了一个Print对话框,图5.18显示了一个Print Setup对话框。 图5.17 Print对话框 图5.18 Print Setup对话框 Print和Print Setup对话框的创建过程与Color对话框类似。该类的构造函数是 CPrintDialog( BOOL bPrintSetupOnly, DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_HIDEPRINTTOFILE | PD_NOSELECTION, CWnd* pParentWnd = NULL );参数bPrintSetupOnly的值若为TRUE,则创建的是Print对话框,否则,创建的是Print Setup对话框。dwFlags用来设置对话框,缺省设置是打印出全部页,禁止From和To编辑框(即不用确定要打印的页的范围),PD_USEDEVMODECOPIES使对话框判断打印设备是否支持多份拷贝和校对打印(Collate),若不支持,就禁止相应的编辑控件和Collate检查框。pParentWnd用来指定对话框的父窗口或拥有者窗口。 程序可以调用如表5.10所示的CPrintDialog的成员函数来获得打印参数。 表5.10 CPrintDialog的辅助成员函数
用缺省配置的MFC AppWizard建立的程序支持Print和Print Setup对话框,用户可以在File菜单中启动它们。 5.6.6 公用对话框的使用实例 现在,让我们来测试一下公用对话框的使用。请读者用AppWizard创建一个单文档的MFC应用程序,名为CommonDlg。注意别忘了在AppWizard的第一步中选Single document。 CommonDlg程序要对所有的公用对话框进行了测试。为此,首先要提供用户命令接口。请读者在CommonDlg的菜单资源中插入一个名为&Common的新菜单,这个菜单插在Help菜单之前。然后,在Common菜单中,请按表5.11创建菜单项。 表5.11 Common菜单的菜单项
接下来的工作是编写测试程序的源代码。首先,利用ClassWizard为表5.11的菜单项创建消息处理函数,注意这些处理函数都是CCommonDlgView的成员。接着,请按清单5.10和5.11修改程序。限于篇幅,这里仅列出与测试相关的部分源代码。 清单5.10 头文件CommonDlgView.h class CCommonDlgView : public CView {
. . . . . . #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif
protected: void DispPrintInfo(CPrintDialog& dlg); protected: CFont m_Font; //正文的字体 COLORREF m_ForeColor; //正文的前景色 COLORREF m_BackColor; //正文的背景色
CFindReplaceDialog *m_pFindReplaceDlg; BOOL m_bFindOnly; // Generated message map functions protected:
//Find和Replace对话框通知消息处理函数 afx_msg LRESULT OnFindReplaceCmd(WPARAM, LPARAM lParam); //{{AFX_MSG(CCommonDlgView) afx_msg void OnCommonColor(); afx_msg void OnCommonFont(); afx_msg void OnCommonOpenfile(); afx_msg void OnCommonSavefile(); afx_msg void OnCommonPrint(); afx_msg void OnCommonPrintsetup(); afx_msg void OnCommonFind(); afx_msg void OnCommonReplace(); //}}AFX_MSG DECLARE_MESSAGE_MAP() };
. . . . . .
清单5.11 文件CCommonDlgView.cpp #include "stdafx.h" #include "CommonDlg.h"
#include "CommonDlgDoc.h" #include "CommonDlgView.h"
#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif
IMPLEMENT_DYNCREATE(CCommonDlgView, CView)
//获取对本进程唯一的消息编号 static const UINT nMsgFindReplace = ::RegisterWindowMessage(FINDMSGSTRING);
BEGIN_MESSAGE_MAP(CCommonDlgView, CView) //{{AFX_MSG_MAP(CCommonDlgView) ON_COMMAND(ID_COMMON_COLOR, OnCommonColor) ON_COMMAND(ID_COMMON_FONT, OnCommonFont) ON_COMMAND(ID_COMMON_OPENFILE, OnCommonOpenfile) ON_COMMAND(ID_COMMON_SAVEFILE, OnCommonSavefile) ON_COMMAND(ID_COMMON_PRINT, OnCommonPrint) ON_COMMAND(ID_COMMON_PRINTSETUP, OnCommonPrintsetup) ON_COMMAND(ID_COMMON_FIND, OnCommonFind) ON_COMMAND(ID_COMMON_REPLACE, OnCommonReplace) //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
ON_REGISTERED_MESSAGE(nMsgFindReplace, OnFindReplaceCmd) END_MESSAGE_MAP()
CCommonDlgView::CCommonDlgView() { // TODO: add construction code here
//缺省前景色为黑色,背景色为白色,字体为系统字体 m_ForeColor=0; m_BackColor=0xFFFFFF; m_Font.CreateStockObject(SYSTEM_FONT);
m_pFindReplaceDlg=NULL;
}
void CCommonDlgView::OnDraw(CDC* pDC) { CCommonDlgDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
int x,y; CFont *pOldFont; TEXTMETRIC TM; int textHeight;
//设置正文的字体 pOldFont=pDC->SelectObject(&m_Font); //设置正文的前景色和背景色 pDC->SetTextColor(m_ForeColor); pDC->SetBkColor(m_BackColor);
//计算每行正文的高度 pDC->GetTextMetrics(&TM); textHeight=TM.tmHeight+TM.tmExternalLeading;
//输出正文 x=5;y=5; pDC->TextOut(x,y,"ABCDEFG"); y+=textHeight; pDC->TextOut(x,y,"abcdefg");
//恢复原来的字体 pDC->SelectObject(pOldFont);
}
void CCommonDlgView::OnCommonColor() { // TODO: Add your command handler code here
CColorDialog dlg;
if(dlg.DoModal()==IDOK) { m_BackColor=dlg.GetColor();
//重绘视图 Invalidate(); UpdateWindow(); } }
void CCommonDlgView::OnCommonFont() { // TODO: Add your command handler code here
CFontDialog dlg;
if(dlg.DoModal()==IDOK) { LOGFONT LF;
//获取所选字体的信息 dlg.GetCurrentFont(&LF); m_ForeColor=dlg.GetColor(); //建立新的字体 m_Font.DeleteObject(); m_Font.CreateFontIndirect(&LF);
Invalidate(); UpdateWindow(); } }
void CCommonDlgView::OnCommonOpenfile() { // TODO: Add your command handler code here
//过滤字符串 char szFileFilter[]= "Cpp files(*.cpp)|*.cpp|" "Header files(*.h)|*.h|" "All files(*.*)|*.*||";
CFileDialog dlg(TRUE, //Open对话框 "cpp", //缺省扩展名 "*.cpp", OFN_HIDEREADONLY|OFN_FILEMUSTEXIST, //文件必须存在 szFileFilter, this);
if(dlg.DoModal()==IDOK) { CString str="The full path name is:"; str+=dlg.GetPathName(); AfxMessageBox(str); }
}
void CCommonDlgView::OnCommonSavefile() { // TODO: Add your command handler code here
char szFileFilter[]= "Cpp files(*.cpp)|*.cpp|" "Header files(*.h)|*.h|" "All files(*.*)|*.*||";
CFileDialog dlg(FALSE, //Save对话框 "cpp", "*.cpp", OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, szFileFilter, this);
if(dlg.DoModal()==IDOK) { CString str="The file name is:"; str+=dlg.GetFileName(); AfxMessageBox(str); }
}
void CCommonDlgView::OnCommonPrint() { // TODO: Add your command handler code here
CPrintDialog dlg(FALSE, PD_ALLPAGES); //Print对话框 //设置Print对话框的属性 dlg.m_pd.nCopies=2; dlg.m_pd.nMinPage=1; dlg.m_pd.nMaxPage=50; dlg.m_pd.nFromPage=1; dlg.m_pd.nToPage=50;
if(dlg.DoModal()==IDOK) DispPrintInfo(dlg); }
void CCommonDlgView::OnCommonPrintsetup() { // TODO: Add your command handler code here
CPrintDialog dlg(TRUE) //Print Setup对话框 if(dlg.DoModal()==IDOK) DispPrintInfo(dlg); }
void CCommonDlgView::DispPrintInfo(CPrintDialog& dlg) { CString str; CString temp;
str+="Driver name:"; str+=dlg.GetDriverName(); str+="\nDevice name:"; str+=dlg.GetDeviceName(); str+="\nPort name:"; str+=dlg.GetPortName(); str+="\nNumber of copies:"; temp.Format("%d",dlg.GetCopies()); str+=temp; str+="\nCollate:"; str+=dlg.PrintCollate()?"Yes":"No"; str+="\nPrint all:"; str+=dlg.PrintAll()?"Yes":"No"; str+="\nPrint range:"; str+=dlg.PrintRange()?"Yes":"No"; str+="\nSelection:"; str+=dlg.PrintSelection()?"Yes":"No"; str+="\nFrom page:"; temp.Format("%d",dlg.GetFromPage()); str+=temp; str+="\nTo page:"; temp.Format("%d",dlg.GetToPage()); str+=temp;
AfxMessageBox(str);
}
void CCommonDlgView::OnCommonFind() { // TODO: Add your command handler code here
//判断是否已存在一个对话框 if(m_pFindReplaceDlg) { if(m_bFindOnly) { //若Find对话框已打开,则使之成为活动窗口 m_pFindReplaceDlg->SetActiveWindow(); return; } else //关闭Replace对话框 m_pFindReplaceDlg->SendMessage(WM_CLOSE); } m_bFindOnly=TRUE; //创建Find对话框 m_pFindReplaceDlg=new CFindReplaceDialog; m_pFindReplaceDlg->Create(TRUE,NULL,NULL,FR_DOWN,this); }
void CCommonDlgView::OnCommonReplace() { // TODO: Add your command handler code here
//判断是否已存在一个对话框 if(m_pFindReplaceDlg) { if(!m_bFindOnly) { //若Replace对话框已打开,则使之成为活动窗口 m_pFindReplaceDlg->SetActiveWindow(); return; } else //关闭Find对话框 m_pFindReplaceDlg->SendMessage(WM_CLOSE); } m_bFindOnly=FALSE; //创建Replace对话框 m_pFindReplaceDlg=new CFindReplaceDialog; m_pFindReplaceDlg->Create(FALSE,NULL,NULL,FR_DOWN,this);
}
//Find和Replace对话框通知消息处理函数 LRESULT CCommonDlgView::OnFindReplaceCmd(WPARAM, LPARAM lParam) { //判断对话框是否被关闭 if(m_pFindReplaceDlg->IsTerminating()) m_pFindReplaceDlg=NULL;
return 0; } 让我们先来看看对Color对话框的测试。在CCommonDlgView::OnCommonColor中创建了一个Color对话框,在此处该对话框的用途是为视图中显示的正文指定背景色。在CCommonDlgView的构造函数中将背景色m_BackColor的初值设置为白色(0x00000000)。若DoModal返回IDOK,则调用CColorDialog::GetColor获取用户选择的颜色并将之保存在m_BackColor成员中。然后,调用Invalidate和UpdateWindow函数以重绘视图。这两个函数的说明如下: void Invalidate( BOOL bErase = TRUE ); void UpdateWindow( ); 在CCommonView::OnDraw函数中调用了CDC::SetBkColor来设置背景色。CDC类用于绘图,在后面的几章里将会对其作详细介绍。CDC::TextOut函数用于输出正文。两个函数的说明如下: virtual COLORREF SetBkColor( COLORREF crColor ); BOOL TextOut( int x, int y, const CString& str ); 若用户确认了对文件的选择,那么在文件选择对话框关闭后,程序会将所选文件的文件名或全路径文件名输出到屏幕上。 Find和Replace对话框的创建工作分别由CCommonDlgView::OnCommonFind和CCommonDlgView::OnCommonReplace完成。 在OnCommonFind函数中,首先判断是否已经打开了一个Find/Replace对话框。这个判断是完全必要的,因为Find/Replace对话框是非模态对话框,打开一个对话框后,用户有可能通过菜单再次执行Find或Replace命令。成员m_pFindReplaceDlg是指向CFindReplaceDialog对象的指针,若该指针不为空,则说明对话框已打开。接着,根据成员m_bFindOnly来判断原先打开的是否是Find对话框,如果原先打开的是一个Find对话框,则此时不必创建新的对话框,只需激活已打开的Find对话框就行了;如果原先打开的是一个Replace对话框,则应该先关闭该对话框,然后再创建Find对话框。然后,给m_bFindOnly赋TRUE值,以表明现在打开的是一个Find对话框。最后,创建一个非模态的Find对话框,请注意其过程与创建模态对话框的不同之处: 对话框对象是用new操作符在堆上创建的,而不是以变量的形式创建。 对话框的启动是靠调用Create函数实现的,而不是DoModal函数。 调用CWnd::SetActiveWindow以激活窗口。调用CWnd::SendMessage(WM_CLOSE)来关闭窗口,这是因为WM_CLOSE消息会导致CWnd::DestroyWindow函数的调用。 OnCommonReplace函数的过程与OnCommonFind函数类似。在该函数中,对m_bFindOnly赋值FALSE以表明打开的是Replace对话框。 Find/Replace对话框通知消息的处理函数是CCommonDlgView::OnFindReplaceCmd,这个消息处理函数及消息映射均是手工加入的。请注意在CommonDlgView.cpp文件的开头部分定义了一个静态全局变量nMsgFindReplace static const UINT nMsgFindReplace = :: RegisterWindowMessage( FINDMSGSTRING ); nMsgFindReplace变量用于存放消息码,这个消息是由函数RegisterWindowMessage提供的,该函数的声明为 UINT RegisterWindowMessage(LPCTSTR lpString); 参数lpString是一个消息字符串。调用RegisterWindowMessage函数会返回一个Windows注册消息,注册消息的编码在系统中是唯一的。当有多个应用程序需要处理同一个消息时,应调用该函数注册消息。如果消息是本应用程序专有的,则不必注册。如果两个应用程序使用相同的字符串注册消息,则会返回相同的消息,这样,通过该消息,两个应用程序可以进行通信。 注册消息的消息映射宏是ON_REGISTERED_MESSAGE,在CommonDlgView的消息映射中可以找到它。 在函数OnFindReplaceCmd中应该进行实际的搜索和替换工作,但在本例中该函数什么工作也不作。该函数只是判断一下对话框是否被关闭,若是,则给m_pFindReplaceDlg赋NULL值,以表明对话框已不存在了。 Font对话框的创建由函数CCommonView:: OnCommonFont完成。该函数收集了用户选择的字体的信息,并利用这些信息创建新的字体。成员m_ForeColor用来保存所选字体的颜色,成员m_Font是一个CFont对象,用来保存用户选择的字体。在CCommonView的构造函数中,m_ForeColor被初始化成黑色(0xFFFFFF),m_Font被初始化为系统字体。系统字体的获得是通过调用CGdiObject::CreateStockObject(SYSTEM_FONT)实现的,该函数用于获得系统库存的绘图对象,包括字体、画笔、刷子、调色板等。 在OnCommonFont函数中,主要调用了下列函数: 调用CFontDialog:: GetCurrentFont以获得用户选择字体的信息,该函数的声明为void GetCurrentFont( LPLOGFONT lplf ); 参数lplf是一个指向LOGFONT结构的指针,LOGFONT结构用来存放与字体有关的信息。 调用CFontDialog::GetColor来获得所选字体的颜色(前景色)。 调用CGdiObject:: DeleteObject()来删除存放在CFont对象m_Font中的老字体。 调用CFont::CreateFontIndirect以创建一种字体,该函数的声明是 调用CWnd::Invalidate和CWnd::UpdateWindow重绘视图。 在CCommonView::OnDraw函数中,利用选择的字体和颜色输出两行正文。当视图需要重绘时,OnDraw就会被调用。在OnDraw函数中主要调用了下列函数: 在输出正文前,调用CDC::SelectObject指定输出正文的字体,输出完成后,调用CDC::SelectObject恢复被替换的字体。SelectObject有五个版本,用于为绘图指定画笔、刷子、字体、位图等绘图对象。在用该函数指定绘图对象时,应该把被替换的对象保存起来,在绘图完成后,需要再次调用该函数恢复被替换的绘图对象。如果不进行恢复,则可能会使设备对象CDC中含有非法的句柄。指定字体的SelectObject函数的声明是 调用CDC::SetTextColor来指定正文显示的前景色,该函数的声明为 调用CDC:: GetTextMetrics函数获得与绘图字体有关的各种信息,该函数的声明为 BOOL GetTextMetrics( LPTEXTMETRIC lpMetrics ) const; 参数lpMetrics是一个指向TEXTMETRIC结构的指针,该结构包含有字体的信息,其中tmHeight成员说明了字体的高度,tmExternalLeading成员说明了行与行之间的空白应该是多少。把这两个值相加就得到了每行正文的高度。 调用CDC::TextOut在指定位置输出正文。 在CCommonDlgView::OnCommonPrint和CCommonDlgView::OnCommonPrintsetup()函数中,分别创建了一个Print对话框和Print Setup对话框。在创建Print对话框时,通过CPrintDialog对象的m_pd成员,对对话框进行了一些初始化,这包括对拷贝份数、打印范围等的设置。在两个对话框DoModal返回IDOK后,均调用CCommonDlgView::DispPrintInfo报告打印信息。DispPrintInfo函数的代码较简单,这里就不作解释了。 |