为了能选用不同的字体和大小来输出文本串,须使用作为GDI对象的
CFont类。Windows和常用的字处理软件(如Word)、绘图软件(如CorelDraw)等应用软件会提供多种与设备无关的字体,主要是
TrueType轮廓字体。 CFont类是CGDIObject的派生类:CObject
→ CGDIObject
→ CFont。只有一个缺省构造函数CFont( );在CFont类中,必须用字体创建成员函数CreateFont[Indirect]或CreatePointFont
[Indirect]来初始化。
其中的CreatePointFont提供了创建字体的一种简单方法:
BOOL CreatePointFont( int nPointSize, LPCTSTR lpszFaceName, CDC* pDC = NULL );
参数nPointSize为字体的大小,以0.1点(像素/墨点/磅数)为单位,如汉字的字号与nPointSize值及磅数的对应关系见下表:
汉字字号 |
nPointSize值 |
磅数 |
初号 小初 |
420 360 |
42 36 |
一号 小一 |
260 240 |
26 24 |
二号 小二 |
220 180 |
22 18 |
三号 小三 |
160 150 |
16 15 |
四号 小四 |
140 120 |
14 12 |
五号 小五 |
105 90 |
10.5 9 |
六号 小六 |
75 65 |
7.5 6.5 |
七号 八号 |
55 50 |
5.5 5 |
参数lpszFaceName为字体名称字符串的指针。
若pDC非空,则系统会将设备单位点自动转换为pDC中的映射模式所指定的逻辑单位,如
CFont font;
font.CreatePointFont(160, "宋体");
注意:CFont类的这些逻辑字体创建函数,并不是从无到有创建一个新的GDI字体,而只是从GDI的物理字体库中选择与所设置参数最匹配的字体。为了方便用户选择各种字体参数,可使用字体公用对话框:
汉字的字号与磅数
字体公用对话框
使用字体公用对话框需要用到CFontDialog类。CFontDialog类的构造函数为
CFontDialog( LPLOGFONT lplfInitial = NULL, DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS, CDC* pdcPrinter
= NULL, CWnd* pParentWnd = NULL );
其中,lplfInitial为逻辑字体结构的指针(可用CFont的成员函数GetLogFont来获得,参见《Windows程序设计》),dwFlags为对话框的可选参数,CF_EFFECTS表示对话框中有删除线和下划线复选框与选择颜色的下拉式组合框,CF_SCREENFONTS则使得对话框中只列出系统支持的显示字体。CFontDialog类的常用成员函数有:
virtual int DoModal( ); //
显示对话框,返回IDOK或IDCANCEL
CString GetFaceName( ) const; //
返回字体名称串
int GetSize( ) const; //
返回所选择的字体大小,以0.1点为单位
COLORREF GetColor( ) const; //
返回所选择的字体颜色常用的文本输出函数有TextOut、DrawText和ExtTextOut,它们都是CDC类的成员函数。下面只介绍最简单的TextOut:
BOOL TextOut( int x, int y, const CString& str );
其中,x与y为显示串的左上角坐标,str为要显示的文本串。如:
pDC->TextOut(10, 10, L"Test text");
还可以使用CDC类的成员函数SetTextColor和SetBkColor来分别设置输出文本的前景色和背景色:(缺省的前景色为黑色,背景色空)
virtual COLORREF SetTextColor( COLORREF crColor );
virtual COLORREF SetBkColor( COLORREF crColor );
如: pDC->SetTextColor(RGB(0, 128, 0));pDC->TextOut(10, 30, L"Test
text"); pDC->SetBkColor(RGB(0, 0, 128));pDC->TextOut(10, 50, L"Test text");
创建名为Font的MFC单文档应用程序,在视图类中添加若干字体参数类变量:
CFont font;
CString m_sFontName;
int m_iFontSize;
COLORREF m_colTextColor;
CString m_sStr;
并在构造函数中对它们进行初始化:
m_sFontName = L"宋体";
m_iFontSize = 120;
font.CreatePointFont(m_iFontSize, m_sFontName);
m_colTextColor = RGB(0,0,0);
m_sStr = L"Test text
测试文本";
添加字体设置菜单项ID_FONT_SET及其响应函数,在里面打开公用字体对话框,将用户选择的字体参数保存到视图类的类变量中,创建新的字体对象,并调用重绘窗口函数:
void CFontView::OnFontSet() {
// TODO:
在此添加命令处理程序代码
LOGFONT lf;
font.GetLogFont(&lf);
CFontDialog fontDlg(&lf);
fontDlg.m_cf.rgbColors = m_colTextColor;
if (fontDlg.DoModal() == IDOK)
{
m_sFontName = fontDlg.GetFaceName();
m_iFontSize = fontDlg.GetSize();
m_colTextColor = fontDlg.GetColor();
font.DeleteObject();
font.CreatePointFont(m_iFontSize, m_sFontName);
RedrawWindow();
}
}
创建文本串输入对话框的资源,添加对应的对话框类和编辑控件变量。添加字符串输入菜单项ID_STRING_INPUT及其响应函数,在里面打开输入对话框,将用户输入的字符串保存到视图类的对应类变量中:
void CFontView::OnStringInput() {
// TODO:
在此添加命令处理程序代码
CInputDlg dlg;
dlg.m_sStr = m_sStr;
if (dlg.DoModal() == IDOK)
{
m_sStr = dlg.m_sStr;
RedrawWindow();
}
}
在视图类的OnDraw函数中,选入所设置的字体、设置文本颜色、输出用户的字符串:
void CFontView::OnDraw(CDC* pDC)
{
CFontDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc) return;
// TODO:
在此处为本机数据添加绘制代码
pDC->SelectObject(&font);
pDC->SetTextColor(m_colTextColor);
pDC->TextOut(20, 20, m_sStr);
}
下面是该例程序的编写步骤框图:
在建立项目 (Project)时,选择Siggle document
(SDI单文档界面)或Multiple documents(MDI多文档界面,缺省)而不是Dialog
based(基于对话框)的应用程序,并且选择缺省的Document/View architecture suport?(支持文档-视图体系)的复选框,建立支持文档/视图体系的项目。
应用程序框架会自动生成应用程序类C*App、文档类C*Doc、主框架窗口类CMainFrame、视图类C*View,对多文档界面还有子框架窗口类CChildFrame。在应用程序框架自动生成的C*Doc类的Serialize(系列化)成员函数中使用其输入参数--文档类CArchive的对象ar--来读写文件,读写方法似文件流操作。如
void CWaveDoc::Serialize(CArchive& ar) {
if (ar.IsStoring())
{
// TODO: add storing code here
//写文件 ... ... ar > id;
ar >> fileLen;
... ...
}
}
注意,用>输出或输入的为二进制数据;为了
输出或输入字符串,可以用CArchive类的成员函数:void WriteString( LPCTSTR lpsz
); 或Bool ReadString(CString& rString );。如: char str[80];
sprintf(str, "%d区(%XA1~%XFE):\r\n", a, c1, c1); ar.WriteString(str);
可将重要的读入数据作
为文档类的类变量或数组,供视图类的代码访问和图形输出,也可供文档类自己在写入文件时使用。为了简化RIFF文件中的4字符标识的读写与比较,Windows
SDK在多媒体头文件mmsystem.h中定义了类型FOURCC(Four-Character
Code四字符代码):
typedef DWORD FOURCC;
及其构造宏(用于将4个字符转换成一个FOURCC数据)
FOURCC mmioFOURCC(CHAR ch0, CHAR ch1, CHAR ch2, CHAR ch3);
其定义为MAKEFOURCC宏:
#define
mmioFOURCC(ch0, ch1, ch2, ch3) MAKEFOURCC(ch0, ch1, ch2, ch3);
而MAKEFOURCC宏定义为:
#define MAKEFOURCC(ch0, ch1, ch2, ch3)
\
((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1)
#define ID_RIFFmmioFOURCC('R', 'I', 'F', 'F')
#define ID_WAVEmmioFOURCC('W', 'A', 'V', 'E')
... ...
FOURCC id;
... ... ar >> id; if (id != ID_RIFF) { ... ...
}
... ...
在文件读写过程中,如果出现读写错误或文件的格式与数据不对,可动态创建一个普通的(generic)文件异常类(CFileException)对象,作抛出(throw)处理。例如
if (id != ID_RIFF)
{
::MessageBox(NULL, L"Not RIFF format!", L"Error", MB_OK);
throw(new CFileException(CFileException:: genericException));
}
函数PlaySound可以播放系统声音、声音资源和声音文件,其函数原型为:
BOOL PlaySound(
LPCSTR pszSound,
HMODULE hmod,
DWORD fdwSound
);
其中参数
pszSound的含义与fdwSound的设置有关。
若fdwSound标志设置为SND_ALIAS、SND_FILENAME或SND_RESOURCE,则pszSound为系统事件的别名、文件名或资源ID
若fdwSound标志没有设置这些值,则先在注册表或win.ini中寻找串为pszSound的声音,若没有,则视其为文件名
若pszSound=NULL,则停止播放正在播放的任何声音(同sndPlaySound)。若要停止非波形格式的声音,必须设置fdwSound的标志SND_PURGE
参数hmod
若设置了fdwSound的标志SND_RESOURCE,则hmod为包含pszSound所指定资源的可执行文件的句柄
若没有设置fdwSound的标志SND_RESOURCE,则hmod必须为NULL
fdwSound为标志参数,可以取下列值:
PlaySound函数中的fdwSound参数的值
fdwSound值
对应数值
含义 SND_ASYNC 0x01
异步播放,调用后立即返回(最常用) SND_LOOP 0x08
循环播放,必须与SND_ASYNC标志同用 SND_MEMORY 0x04 lpszSound指向内存中波形声音映像(可以动态生产声音)
SND_NODEFAULT 0x02 找不到指定声音时,不播放缺省的声音 SND_NOSTOP 0x10
如果有声音正在播放,则不播放指定的声音而直接返回 SND_SYNC 0x00
同步播放,直到声音播完后调用