前言
以前喜歡沒事做做網頁,不怕各位見笑,都是很簡單的那種靜態的,有一個很頭疼的問題就是字體的選擇,
而且很多軟件在做的時候看不到字體的例子,現在學了點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
本文配套源碼