要想取得系統所支持的字體及字體的大小,需要用到Windows SDK中的EnumFontFamiliesEx或EnumFontFamilIEs函數。這兩個函數的函數原型如下:
int EnumFontFamilIEsEx(
HDC hdc, // handle to device context
LPLOGFONT lpLogfont,// pointer to logical font information
FONTENUMPROC lpEnumFontFamExProc, // pointer to callback function
LPARAM lParam, // application-supplIEd data
DWord dwFlags // reserved; must be zero
);
int EnumFontFamilIEs(
HDC hdc, // handle to device control
LPCTSTR lpszFamily, // pointer to family-name string
FONTENUMPROC lpEnumFontFamProc,// pointer to callback function
LPARAM lParam// address of application-supplIEd data
);
這兩個函數的功能基本相同,但相對而言EnumFontFamilIEsEx函數提供了更多的字體信息。在這兩個函數中,都用到一個類型為FONTENUMPROC的回調函數,該函數的原型如下:
int CALLBACK EnumFontFamProc(
ENUMLOGFONT FAR *lpelf, // pointer to logical-font data
NEWTEXTMETRIC FAR *lpntm, // pointer to physical-font data
int FontType, // type of font
LPARAM lParam // address of application-defined data
);
這兩個函數更詳細的說明請參考MSDN。 下面是組件的簡單實現代碼:
/*===========================================================================
TFontNameComboBox及TFontNameSizeComboBox組件頭文件
文件名稱:FontComboBox.H
程序設計:梁生紅
創建日期:2003-03-20
===========================================================================*/
#ifndef FontComboBoxH
#define FontComboBoxH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <StdCtrls.hpp>
#include <printers.hpp>
#include <Math.h>
//---------------------------------------------------------------------------
int static PixelsPerInch;
//下列兩個回調函數一定不能為類成員函數
bool __stdcall EnumFontNameProc(ENUMLOGFONT FAR *lpelf,NEWTEXTMETRICEX FAR *lpntme,
int FontType, LPARAM lParam);
bool __stdcall EnumFontSizeProc(ENUMLOGFONT FAR *lpelf,NEWTEXTMETRIC FAR *lpntm,
int FontType, LPARAM lParam);
//---------------------------------------------------------------------------
/* TODO : TFontNameComboBox的聲明 */
class PACKAGE TFontNameComboBox : public TCustomComboBox
{
private:
protected:
void __fastcall Build();
public:
__fastcall TFontNameComboBox(TComponent* Owner);
__published:
__property Style;
__property Anchors;
__property BiDiMode;
__property Color;
__property Constraints;
__property Ctl3D;
__property DragCursor;
__property DragKind;
__property DragMode;
__property DropDownCount;
__property Enabled;
__property Font;
__property ItemHeight;
__property MaxLength;
__property ParentBiDiMode;
__property ParentColor;
__property ParentCtl3D;
__property ParentFont;
__property ParentShowHint;
__property PopupMenu;
__property ShowHint;
__property TabOrder;
__property TabStop;
__property Visible;
__property OnChange;
__property OnClick;
__property OnContextPopup;
__property OnDblClick;
__property OnDragDrop;
__property OnDragOver;
__property OnDrawItem;
__property OnDropDown;
__property OnEndDock;
__property OnEndDrag;
__property OnEnter;
__property OnExit;
__property OnKeyDown;
__property OnKeyPress;
__property OnKeyUp;
__property OnMeasureItem;
__property OnStartDock;
__property OnStartDrag;
};
//---------------------------------------------------------------------------
/* TODO : TFontSizeComboBox的聲明 */
class PACKAGE TFontSizeComboBox : public TCustomComboBox
{
private:
AnsiString FFontName;
void __fastcall SetFontName(AnsiString AFontName);
protected:
void __fastcall Build();
public:
__fastcall TFontSizeComboBox(TComponent* Owner);
__published:
__published:
__property AnsiString FontName = {read = FFontName, write = SetFontName};
__property Style;
__property Anchors;
__property BiDiMode;
__property Color;
__property Constraints;
__property Ctl3D;
__property DragCursor;
__property DragKind;
__property DragMode;
__property DropDownCount;
__property Enabled;
__property Font;
__property ItemHeight;
__property MaxLength;
__property ParentBiDiMode;
__property ParentColor;
__property ParentCtl3D;
__property ParentFont;
__property ParentShowHint;
__property PopupMenu;
__property ShowHint;
__property TabOrder;
__property TabStop;
__property Visible;
__property OnChange;
__property OnClick;
__property OnContextPopup;
__property OnDblClick;
__property OnDragDrop;
__property OnDragOver;
__property OnDrawItem;
__property OnDropDown;
__property OnEndDock;
__property OnEndDrag;
__property OnEnter;
__property OnExit;
__property OnKeyDown;
__property OnKeyPress;
__property OnKeyUp;
__property OnMeasureItem;
__property OnStartDock;
__property OnStartDrag;
};
//---------------------------------------------------------------------------
#endif
實現文件
/*===========================================================================
TFontNameComboBox及TFontNameSizeComboBox組件實現文件
文件名稱:FontComboBox.CPP
程序設計:梁生紅
創建日期:2003-03-20
===========================================================================*/
#include <vcl.h>
#pragma hdrstop
#include "FontComboBox.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
static inline void ValidCtrCheck(TFontNameComboBox *)
{
new TFontNameComboBox(NULL);
}
//---------------------------------------------------------------------------
static inline void ValidCtrCheck(TFontSizeComboBox *)
{
new TFontSizeComboBox(NULL);
}
//---------------------------------------------------------------------------
/* TODO : 回調函數實現代碼 */
bool __stdcall EnumFontNameProc(ENUMLOGFONT FAR *lpelf,NEWTEXTMETRICEX FAR *lpntme,
int FontType, LPARAM lParam)
{
char FontFullName[64];
strcpy(FontFullName,lpelf->elfFullName);
if(((TStrings*)(lParam))->IndexOf(FontFullName)==-1)
((TStrings*)(lParam))->Add(FontFullName);
return true;
}
//----------------------------------------------------------------------------
bool __stdcall EnumFontSizeProc(ENUMLOGFONT FAR *lpelf,NEWTEXTMETRIC FAR *lpntm,
int FontType, LPARAM lParam)
{
if(FontType&TRUETYPE_FONTTYPE)
{
((TStrings*)(lParam))->Add("8");
((TStrings*)(lParam))->Add("9");
((TStrings*)(lParam))->Add("10");
((TStrings*)(lParam))->Add("11");
((TStrings*)(lParam))->Add("12");
((TStrings*)(lParam))->Add("14");
((TStrings*)(lParam))->Add("16");
((TStrings*)(lParam))->Add("18");
((TStrings*)(lParam))->Add("20");
((TStrings*)(lParam))->Add("22");
((TStrings*)(lParam))->Add("24");
((TStrings*)(lParam))->Add("26");
((TStrings*)(lParam))->Add("28");
((TStrings*)(lParam))->Add("36");
((TStrings*)(lParam))->Add("48");
((TStrings*)(lParam))->Add("72");
return false;
}
else
{
AnsiString s;
int i,v,v2;
v = floor((lpelf->elfLogFont.lfHeight-lpntm->tmInternalLeading)*72/PixelsPerInch);
s = IntToStr(v);
for(i = 0;i<((TStrings*)(lParam))->Count-1;i++)
{
v2 = StrToInt(((TStrings*)(lParam))->Strings[i]);
if(v2==v)
return true;
if(v2>v)
{
((TStrings*)(lParam))->Insert(i,s);
return true;
}
}
((TStrings*)(lParam))->Add(s);
return true;
}
}
//---------------------------------------------------------------------------
/* TODO : TFontNameComboBox實現部分 */
__fastcall TFontNameComboBox::TFontNameComboBox(TComponent* Owner)
: TCustomComboBox(Owner)
{
Sorted = true;
if(!ComponentState.Contains(csDesigning))
Build();
}
//---------------------------------------------------------------------------
void __fastcall TFontNameComboBox::Build()
{
HDC DC = NULL;
LOGFONT LogFont;
TNotifyEvent OnChangeEvent;
OnChangeEvent = OnChange;
OnChange = NULL;
Items->Clear();
LogFont.lfCharSet = DEFAULT_CHARSET;
strcpy(LogFont.lfFaceName,"");
LogFont.lfPitchAndFamily = 0;
DC = GetDC(GetDesktopWindow());
try
{
EnumFontFamilIEsEx(DC,&LogFont,(FONTENUMPROC)(EnumFontNameProc),LPARAM(Items),0);
}
__finally
{
ReleaseDC(GetDesktopWindow(),DC);
}
OnChange = OnChangeEvent;
if(Items->Count)
ItemIndex = 0;
}
//---------------------------------------------------------------------------
/* TODO : TFontSizeComboBox實現部分 */
__fastcall TFontSizeComboBox::TFontSizeComboBox(TComponent* Owner)
: TCustomComboBox(Owner)
{
Sorted = false;
}
//---------------------------------------------------------------------------
void __fastcall TFontSizeComboBox::SetFontName(AnsiString AFontName)
{
FFontName = AFontName;
if(!ComponentState.Contains(csDesigning))
{
Items->Clear();
Build();
}
}
//---------------------------------------------------------------------------
void __fastcall TFontSizeComboBox::Build()
{
TNotifyEvent OnChangeEvent = OnChange;
OnChange = NULL;
HDC DC = GetDC(GetDesktopWindow());
PixelsPerInch = GetDeviceCaps(DC, LOGPIXELSY);
try
{
EnumFontFamilIEs(DC, FFontName.c_str(), (FONTENUMPROC)(EnumFontSizeProc),LPARAM(Items));
}
__finally
{
ReleaseDC(GetDesktopWindow(),DC);
}
OnChange = OnChangeEvent;
if(Items->Count)
ItemIndex = 0;
}
//---------------------------------------------------------------------------
namespace Fontcombobox
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[2] = {__classid(TFontNameComboBox),
__classid(TFontSizeComboBox)};
RegisterComponents("Samples", classes, 1);
}
}
//---------------------------------------------------------------------------