网上第一本以TXT格式的VC++深入详解孙鑫的书.全文全以TXT格式,并每一章节都分了目录,清晰易读

源代码在线查看: 10.4 字体对话框.txt

软件大小: 956 K
上传用户: kzdai22
关键词: TXT VC 目录
下载地址: 免注册下载 普通下载 VIP

相关代码

				10.4 字体对话框
				下面为 Graphic程序添加字体对话框应用,该对话框类似于我们已经在对话框资源的属性对话框中
				所看到的字体对话框,如图 10.15所示。
				与上面的颜色对话框一样,字体对话框的创建也很简单,因为 MFC也提供了一个相应的类 : 
				CFontDialog.该类的派生层次结构如图 10.16所示,由此可知该类派生于 CDialog.所以,其也是一
				个对话框类。
				图 10.15字体对话框 
				CFontDialog类的构造函数如下所示:
				CFontDialog( 
				LPLOGFONT lplflnitial = NULL , 
				DWORD dwFlags = CF_EFFECTS I CF_SCREENFONTS , 
				CDC* pdcprinter = NULL , 
				CWnd* pParentWnd = NULL 
				. 
				该函数有四个参数,含义分别如下所述: 
				. lpltinitial 
				指向LOGFONT结构体的指针,允许用户设置一些字体的特征。 
				. dwFlags 
				主要设置一个或多个与选择的字体相关的标记。 
				. pdcPrinter 
				指向打印设备上下文的指针。 
				. pParentWnd 
				指向字体对话框父窗口的指针。
				由 CFontDialog类的构造函数的声明可知,它的参数都有默认值,因此在构造字体对话框时可以不
				用指定任何参数。
				字体对话框的创建与前面的颜色对话框的一样,首先构造一个字体对话框对象,然后调用该对象的
				DoModal函数显示这个对话框即可。因此再为Graphic程序增加一个菜单项用来显示字体对话框,将
				其ID设置为: IDM_FONT, Caption设置为:字体。接着为其增加一个命令响应,并选择 CGraphicView
				类对此菜单项命令做出响应。然后在此响应函数
				中添加创建井显示字体对话框的代码,结果如例 10-19所示。
				例10-19 
				图 10.16 CFontDialog类的派生层次结构图 
				
				void CGraphicview: :OnFont() 
				
				CFontDialog dlg; 
				
				dlg.DoModal() ; 
				下面我们要实现这样的功能:当用户通过字体对话框选择某种字体后,程序应该把当
				前选择保存起来,然后在 CGraphicView类中利用此字体将用户选择的字体名称显示出来。例如如果
				用户选择的是黑体,那么在程序中就创建黑体这种字体,再利用这种字体把字体名称:"黑体"显示出
				来。 
				CFontDialog类有一个 CHOOSEFONT结构体类型的数据成员: m_cf CHOOSEFONT 结构体的定义如例 
				10-20所示。 
				例 10-20
				
				typedef struct { DWORD lStructSizei HWND hwndOwner i HDC hDCi LPLOGFONT lpLogFonti INT 
				iPointSizei DWORD Flagsi COLORREF rgbColorsi LPARAM lCustDatai LPCFHOOKPROC lpfnHooki 
				LPCTSTR lpTemplateNamei HINSTANCE hlnstancei LPTSTR lpszStylei WORD nFontTypei 工 NT 
				nSizeMini 工 NT nSizeMaxi 
				1 CHOOSEFONT, *LPCHOOSEFONTi 
				
				其中成员 lpLogFont是指向逻辑字体 (LOGFONT类型)的指针。 LOGFONT结构的定义如例 10-21所示。
				例 10-21 
				
				typedef struct tagLOGFONT { // lf 
				
				LONG lfHeight i 
				LONG lfWidthi 
				LONG lfEscapementi 
				LONG lfOrientationi 
				LONG lfWeighti 
				BYTE l fItalic; 
				BYTE lfUnderlinei 
				BYTE lfStrikeOuti 
				BYTE lfCharSeti 
				BYTE lfOutPrecisioni 
				BYTE lfClipPrecisioni 
				BYTE lfQualitYi 
				BYTE lfPitchAndFamilYi 
				TCHAR lfFaceName[LF_FACESIZE]i 
				} LOGF咱 ONTi
				其中成员lfFaceName中存放的就是字体的名称。也就是说,可以通过此成员得到宇
				字体的名称。
				至于字体对象的创建,首先可以利用CFont类构造一个字体对象,然后利用CFont类的
				CreateFontIndirect成员函数根据指定特征的逻辑字体 (LOGFONT类型〉来初始化这个字体对象。该
				函数的声明形式如下所示: 
				BOOL CreateFontIndirect(const LOGFONT* lpLogFont); 
				CreateFontIndirect函数的功能就是利用参数 lpLogFont指向的LOGFONT结构体中的一些特征来初
				始化CFont对象。
				为了保存用户选择的字体,首先为 Graphic工程的 CGraphicView类增加一个 CFont成员变量: m 
				font,再增加一个CString类型的成员: m s位FontName,用来保存所选字体的名称,井将这两个变
				量的访问权限都设置为私有的。然后在 CGraphicView类的构造函数中将m strFontName变量初始化
				为空,代码如下所示: 
				m_strFontName=""; 
				
				说明:读者在练习时,可以对m_font变量也进行初始化,为它创建一种默
				认的字体。
				然后在CGraphicView类的 OnFont函数中进行判断,如果用户单击的是字体对话框的 OK按钮,就用
				所选字体信息初始化m font对象,井保存所选字体的名称。具体代码如例 10-22所示。
				例IJ 10-22 
				
				1. void CGraphicView : :OnFont() 
				
				2. { 
				
				3. CFontDialog dlg ; 
				
				4. if (IDOK==dlg . DoModal () ) 
				
				5. { 
				
				6. m_font.CreateFontlndirect(dlg.m_cf.lpLogFont); 
				
				
				7. m_strFontName=dlg.m_cf.lpLogFont->lfFaceName; 
				
				
				8. } 
				
				9. } 
				
				
				接下来,在视类窗口中把字体名称用选择的字体显示出来。这可以在 CGraphicView 类的OnDraw函
				数中实现,因此在上述OnFont函数中,在第7行代码之后需要调用Invalidate函数让窗口无效,这样
				当下一次发生WM PAINT消息时,窗口就会进行重绘。 CGraphicView类OnDraw函数的最终代码如例 
				10-23所示。
				例 10-23 
				
				void CGraphicview: :OnDraw(CDC* pDC) 
				{ CGraphicDoc* pDoc = GetDocument() ; ASSERT_VALID(pDoc) ; // TODO : add draw code for nat
				ive data here 
				CFont *pOldFont=pDC->SelectObject (τtn-font); 
				pDC->TextOut (O, O, ffi_strFont Name) ; 
				pDC->SelectObject (pOldFont) ; 
				在上述例 10-23所示代码中,首先把用户选择的新字体选入设备上下文,然后在窗口的(0, 0)处显
				示所选字体的名称,最后再把先前的字体选入设备上下文。 
				Build井运行 Graphic程序。选择【绘图\字体】菜单项,这时将打开字体对话框,可以选择任一种
				字体、字形,还可以指定字体的大小。例如字体选择隶书,字形选择粗体,大小指定为20 (如图 10.17
				所示),然后单击字体对话框的OK按钮,这时在视类窗口中就可以看到用选定的字体、字形和大小输
				出了所选字体的名称:"隶书",如图 10.18所示。
				图 10.17选定字体 图 10.18用选定的字体显示所选字体名称
				可是当再次选择【绘图飞字体】菜单项后,程序将出现非法操作。这是因为当第一次选择字体后, 
				OnFont函数中就把m font对象与这种字体资源相关联了(上述例 10-22所示 OnFont函数第6行代码
				的结果〉。当再次选择一种字体后, OnFont函数又会试图把m_font对象与新字体资源相关联,这时
				当然就会出错。因此,程序中应该进行一个判断,如果 m font对象已经与一个字体资源相关联了,
				首先就需要切断这种关联,释放该字体资源,然后才能与新资源相关联。
				要想释放先前的资源,可以利用CGdiObject类 (CPen, CFont, CBitmap, CBrush都派生于该类)的
				DeleteObject成员函数来实现。该函数通过释放所有为WindowsGDI对象所分配的资源,从而删除与
				CGdiObject对象相关联的WindowsGDI对象,同时与CGdiObject对象相关的存储空间并不会受此调用
				影响。这句话的意思是要读者注意区分Windows GDI 和CGdiObject对象。后者是一个类的对象,而
				前者是一种资源对象,就好像窗口类的对象和窗口的关系一样,例如视类对象和视类窗口,它们之
				间的联系在于视类对象有一个数据成员: m hWnd保存了窗口资源的句柄值。同样地, CGdiObject
				类的对象和Windows GDI 资源对象是两个不同的概念,它们之间也是通过一个数据成员来维系的。
				当删除Windows GDI资源对象后,对于CGdiObject类所定义的对象来说,并不受影响,只是它们之间
				的联系被切断了。
				如果想判断 m font对象是否已经与某个字体资源相关联了,最简单的方法就是利用 CGdiObject对
				象的数据成员m_hObject来判断,该变量保存了与CGdiObject对象相关联的 Windows GDI资源的句
				柄。如果己经有关联了,则调用DeleteObject释放这个字体资源,
				382 . 
				
				因此,在上述如例 10-22所示OnFont函数的第6行代码前添
				
				加下述代码: 
				
				然后再与新的资源相关联。
				
				if(~font.ID_hObject) 
				
				ID_font.DeleteObject(); 
				
				解
				详
				
				一叫 
				
				再次运行Graphic程序,这时可以发现多次打开字体对话框选择字体,程序一切正确。
				
							

相关资源