Chinaunix首页 | 论坛 | 博客
  • 博客访问: 588773
  • 博文数量: 752
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 5005
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 14:47
文章分类

全部博文(752)

文章存档

2011年(1)

2008年(751)

我的朋友

分类:

2008-10-13 16:42:36

一个简单字体察看器的实现

作者:



前言
  以前喜欢没事做做网页,不怕各位见笑,都是很简单的那种静态的,有一个很头疼的问题就是字体的选择,
而且很多软件在做的时候看不到字体的例子,现在学了点VC++于是就像自己动手做一个。也算是我这个初学者的一个
小小的笔记,希望对像我一样的菜鸟有一些帮助。

介绍
  通过本文,希望能学到一点有关windows各个组件的消息传递的知识。学习如何建立可用字体的列表,学会
如何指定使用的字体,如何动态改变字体。
用到的函数:EnumFontFamiliesEx。在MSDN中是这样写的:

int EnumFontFamiliesEx(
  HDC hdc,                          // handle to DC
  LPLOGFONT lpLogfont,              // font information
  FONTENUMPROC lpEnumFontFamExProc, // callback function
  LPARAM lParam,                    // additional data
  DWORD dwFlags                     // not used; must be 0
);       
在Windows操作系统中的每一个枚举函数都需要传递一个回调函数的地址作为自变量,所以这个函数也不例外。

步骤
  首先建立一个MFC项目,命名为FontsView,并且添加各种组件如图:



然后对各个组件进行修改:
对象 属性 设置
Static Text Caption 输入文字
Edit Box ID IDC_EENTERED
Static Text Caption 字体列表
List Box ID IDC_LFONTS
Group Box Caption 示例
Static Text ID
Caption
IDC_DISPLAY
NULL
Command Button
 
ID
Caption
IDC_BEXIT
退出

  注意在 Group Box 内部有一个 Static Text 和 Group Box 内部一样大,用来显示文字。
为控件添加变量:

对象 名称 类别 类型
IDC_DISPLAY m_ctlDisplay
m_strDiaplay
Control
Value
Cstatic
CString
IDC_LFONTS m_ctlFontList
m_strFontName
Control
Value
ClistBox
CString
IDC_EENTERED m_strSampText Value CString

为 IDC_EEXIT 添加事件代码:(注:斜体部分为输入内容):

void CFontsViewDlg::OnBnClickedBexit() 
{ 
     // TODO: 在此添加控件通知处理程序代码 
     OnOK(); 
}      
好了,到此为止,基本的框架已经建好了,下一步需要建立字体列表。首先要添加回调函数来获得每个字体列表:
// FontsViewDlg.h : 头文件 
// 
#pragma once 
#include "afxwin.h" 
int CALLBACK MyEnumFontProc(ENUMLOGFONTEX* lpelf,NEWTEXTMETRICEX* lpntm,DWORD nFontType,long lParam);       
然后再向FontsViewDlg.cpp中添加回调函数的定义:
int CALLBACK MyEnumFontProc(ENUMLOGFONTEX* lpelf,NEWTEXTMETRICEX* lpntm,DWORD nFontType,long lParam) 
{ 
     CFontsViewDlg* pWnd=(CFontsViewDlg*) lParam; 
     if(pWnd) 
     { 
         pWnd->m_ctlFontList.AddString(lpelf->elfLogFont.lfFaceName); 
         return 1; 
     } 
     return 0; 
}      
我们还要构建一个函数来获取操作系统中的字体列表:选择Class View面板,选择CfontsViewDlg类,添加函数,函数名设为FillFontList,访问类型Private。
void CFontsViewDlg::FillFontList(void) 
{ 
     int iCurCount; 
     CString strCurFont; 
     CString strPrevFont=""; 
     LOGFONT lf; 
     lf.lfCharSet=DEFAULT_CHARSET; 
     lf.lfFaceName[0]=NULL; 
     lf.lfPitchAndFamily=0; 
     m_ctlFontList.ResetContent(); 
     CClientDC dc(this); 
     ::EnumFontFamiliesEx((HDC) dc,&lf,(FONTENUMPROC) MyEnumFontProc,(LPARAM) this,0); 
     for (iCurCount=m_ctlFontList.GetCount();iCurCount > 0;iCurCount--) 
     { 
         m_ctlFontList.GetText((iCurCount-1),strCurFont); 
         if (strCurFont==strPrevFont) 
         { 
              m_ctlFontList.DeleteString((iCurCount-1)); 
         } 
         else 
         { 
              strPrevFont=strCurFont; 
         } 
     } 
}      
编辑 OnInitDialog 函数来调用 FillFontList 函数:
BOOL CFontsViewDlg::OnInitDialog() 
{ 
     CDialog::OnInitDialog(); 
 
     // 将\“关于...\”菜单项添加到系统菜单中。 
     (略) 
     SetIcon(m_hIcon, TRUE);          // 设置大图标 
     SetIcon(m_hIcon, FALSE);         // 设置小图标 
 
     // TODO: 在此添加额外的初始化代码 
     FillFontList(); 
     
     return TRUE;  // 除非设置了控件的焦点,否则返回 TRUE 
}      
好了,现在可以编译一下,看看有什么结果发生了:)



我们已经有了系统的字体列表。接下来我们要对输入对话框做一下处理。编辑 OnInitDialog 函数,为它增加以下代码:
BOOL CFontsViewDlg::OnInitDialog() 
{ 
     CDialog::OnInitDialog(); 

     ...

     // 将\“关于...\”菜单项添加到系统菜单中。 

     ...

     SetIcon(m_hIcon, TRUE);          // 设置大图标 
     SetIcon(m_hIcon, FALSE);         // 设置小图标 
     // TODO: 在此添加额外的初始化代码 
     FillFontList(); 
     m_strEntered="大家好"; 
     m_strDisplay=m_strEntered; 
     UpdateData(FALSE); 
     return TRUE;  // 除非设置了控件的焦点,否则返回 TRUE 
}      
为IDC_EENTERED添加EN_CHANGE事件消息函数:
void CFontsViewDlg::OnEnChangeEentered() 
{ 
     // TODO:  如果该控件是 RICHEDIT 控件,则它将不会 
     // 发送该通知,除非重写 CDialog::OnInitDialog() 
     // 函数并调用 CRichEditCtrl().SetEventMask(), 
     // 同时将 ENM_CHANGE 标志“或”运算到掩码中。 
? 
     // TODO:  在此添加控件通知处理程序代码 
     UpdateData(TRUE); 
     m_strDisplay=m_strEntered; 
     UpdateData(FALSE); 
}      
OK,再编译一下看看:)



  虽然有了显示,但是它还不能根据选定字体来进行变换,所以我们必须添加一个变量来设置和改变字体。在CFontsViewDlg类中添加一个变量,变量类型为CFont变量名设为m_fSetFont,访问类型为Private。再添加一个函数,用来显示和选用字体。在CFontsViewDlg类中,添加函数,类型设为void,函数名为 SetMyFont,访问为 Private。代码如下:
void CFontsViewDlg::SetMyFont(void) 
{ 
     CRect rRect; 
     
     if(m_strFontName.GetLength()>0) 
     { 
         m_ctlDisplay.GetWindowRect(&rRect); 
         m_fSetFont.Detach(); 
          m_fSetFont.CreateFont((rRect.Height()-5),
          			0,0,0,FW_NORMAL,
          			0,
          			0,
          			0,
          			DEFAULT_CHARSET,
				OUT_CHARACTER_PRECIS,
				CLIP_CHARACTER_PRECIS,
				DEFAULT_QUALITY,
				DEFAULT_PITCH|FF_DONTCARE,
				m_strFontName); 
         m_ctlDisplay.SetFont(&m_fSetFont); 
     } 
}      
最后给 IDC_LFONTS 添加一个 LBN_SELCHANGE 事件消息函数就大功告成了:
void CFontsViewDlg::OnLbnSelchangeLfonts() 
{ 
     // TODO: 在此添加控件通知处理程序代码 
     UpdateData(TRUE); 
     SetMyFont(); 
}     


  基本上要实现的功能都有了,如果大家还想进一步完善,可以具体参考以下MSDN对CreateFont函数的定义,然后对他进行参数传递,就能实现诸如斜体,改变字号,下画线等功能。

编译环境:WindowsXP+ Microsoft Visual C++ .NET
 
希望能和各位高手多多交流我的 Email:   QQ:16199995


--------------------next---------------------

挺不错的!我现在正想在自己的软件中加入自己的字体选择对话框。用的上!谢了! ( licoo 发表于 2005-4-9 12:40:00)
 
像word一样的列表效果 

需要源代码与我联系 k_badboy@sohu.com ( 鬼龙之舞 发表于 2004-5-21 10:54:00)
 
很有用,很感谢! ( pjohn 发表于 2004-5-14 15:14:00)
 
老兄可真实向我这样的菜鸟的福音啊!
收益非浅  多谢!! ( yshm 发表于 2004-4-16 0:25:00)
 
老兄可真实向我这样的菜鸟的福音啊!
收益非浅  多谢!! ( yshm 发表于 2004-4-16 0:25:00)
 
像Word的字体表列框一样直接显示出字体就更好了!不知哪位前辈做过呢!?能否提供一下代码!? ( Simonos 发表于 2004-4-5 9:35:00)
 
哈,原来要做图,要察看字体,别的都不是很好用,本来打算自己做个,但这方面的东西太少了,后来只好用了fontview做的不错。老兄的东西值得好好看看。。。。
( 39sky 发表于 2004-4-4 14:26:00)
 
顶... ( Thornbird 发表于 2004-4-2 16:10:00)
 
.......................................................

--------------------next---------------------

阅读(241) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~