TFontNameComboBox及TFontSizeComboBox的实现

王朝delphi·作者佚名  2006-01-08
宽屏版  字体: |||超大  

在用C++ Builder进行程序设计时,很多时候需要在运行状态下更改控件的字体名称或大小,虽然VCL类库中提供了TFontDialog对话框组件,但有时候并不是很方便。而C++ Builder本身又没有提供类似Word工具栏中的字体名称及大小的选择下拉列表,为方便使用,作者特编写两个字体组件 TFontNameComboBox和TFontSizeComboBox,下简单介绍一下实现的方法及原理。

要想取得系统所支持的字体及字体的大小,需要用到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);

}

}

//---------------------------------------------------------------------------

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
© 2005- 王朝网络 版权所有