WEB开发网
开发学院软件开发Delphi TFontNameComboBox及TFontSizeComboBox的实现 阅读

TFontNameComboBox及TFontSizeComboBox的实现

 2006-02-04 13:39:50 来源:WEB开发网   
核心提示:在用C++ Builder进行程序设计时,很多时候需要在运行状态下更改控件的字体名称或大小,TFontNameComboBox及TFontSizeComboBox的实现,虽然VCL类库中提供了TFontDialog对话框组件,但有时候并不是很方便,在这两个函数中,都用到一个类型为FONTENUMPROC的回调函数,而C
在用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);
    }
}
//---------------------------------------------------------------------------

Tags:TFontNameComboBox TFontSizeComboBox 实现

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接