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

http://tech.ddvip.com   2006年07月23日    社区交流

本文详细介绍一个简单字体察看器的实现

  本文示例源代码或素材下载

  前言

  以前喜欢没事做做网页,不怕各位见笑,都是很简单的那种静态的,有一个很头疼的问题就是字体的选择,

  而且很多软件在做的时候看不到字体的例子,现在学了点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 TextCaption输入文字
Edit BoxIDIDC_EENTERED
Static TextCaption字体列表
List BoxIDIDC_LFONTS
Group BoxCaption示例
Static TextID

  Caption

IDC_DISPLAY

  NULL

Command Button

  

ID

  Caption

IDC_BEXIT

  退出

  注意在 Group Box 内部有一个 Static Text 和 Group Box 内部一样大,用来显示文字。

  为控件添加变量:

  

对象名称类别类型
IDC_DISPLAYm_ctlDisplay

  m_strDiaplay

Control

  Value

Cstatic

  CString

IDC_LFONTSm_ctlFontList

  m_strFontName

Control

  Value

ClistBox

  CString

IDC_EENTEREDm_strSampTextValueCString

  为 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

作者:shirlyang    责编:豆豆技术应用

正在加载评论...