TFontNameComboBox及TFontSizeComboBox的实现

在用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

  1<sysutils.hpp>   
  2#include <controls.hpp>   
  3#include <classes.hpp>   
  4#include <forms.hpp>   
  5#include <stdctrls.hpp>   
  6#include <printers.hpp>   
  7#include <math.h>   
  8_ //---------------------------------------------------------------------------  _   
  9int  static  PixelsPerInch;   
 10  
 11_ //  _ _ 下列两个回调函数一定不能为类成员函数  _   
 12bool  __stdcall  EnumFontNameProc(ENUMLOGFONT FAR *lpelf,NEWTEXTMETRICEX FAR *lpntme,    
 13int  FontType, LPARAM lParam);   
 14  
 15bool  __stdcall  EnumFontSizeProc(ENUMLOGFONT FAR *lpelf,NEWTEXTMETRIC FAR *lpntm,    
 16int  FontType, LPARAM lParam);   
 17  
 18_ //---------------------------------------------------------------------------  _   
 19_ /* TODO : TFontNameComboBox  _ 的声明  */    
 20class  PACKAGE TFontNameComboBox :  public  TCustomComboBox    
 21{    
 22private  :    
 23protected  :    
 24void  __fastcall  Build();    
 25public  :    
 26__fastcall  TFontNameComboBox(TComponent* Owner);    
 27__published  :    
 28__property  Style;    
 29__property  Anchors;    
 30__property  BiDiMode;    
 31__property  Color;    
 32__property  Constraints;    
 33__property  Ctl3D;    
 34__property  DragCursor;    
 35__property  DragKind;    
 36__property  DragMode;    
 37__property  DropDownCount;    
 38__property  Enabled;    
 39__property  Font;    
 40__property  ItemHeight;    
 41__property  MaxLength;    
 42__property  ParentBiDiMode;    
 43__property  ParentColor;    
 44__property  ParentCtl3D;    
 45__property  ParentFont;    
 46__property  ParentShowHint;    
 47__property  PopupMenu;    
 48__property  ShowHint;    
 49__property  TabOrder;    
 50__property  TabStop;    
 51__property  Visible;    
 52__property  OnChange;    
 53__property  OnClick;    
 54__property  OnContextPopup;    
 55__property  OnDblClick;    
 56__property  OnDragDrop;    
 57__property  OnDragOver;    
 58__property  OnDrawItem;    
 59__property  OnDropDown;    
 60__property  OnEndDock;    
 61__property  OnEndDrag;    
 62__property  OnEnter;    
 63__property  OnExit;    
 64__property  OnKeyDown;    
 65__property  OnKeyPress;    
 66__property  OnKeyUp;    
 67__property  OnMeasureItem;    
 68__property  OnStartDock;    
 69__property  OnStartDrag;    
 70};    
 71_ //---------------------------------------------------------------------------  _   
 72_ /* TODO : TFontSizeComboBox  _ 的声明  */    
 73class  PACKAGE TFontSizeComboBox :  public  TCustomComboBox    
 74{    
 75private  :    
 76AnsiString FFontName;    
 77void  __fastcall  SetFontName(AnsiString AFontName);    
 78protected  :    
 79void  __fastcall  Build();    
 80public  :    
 81__fastcall  TFontSizeComboBox(TComponent* Owner);    
 82__published  :    
 83__published  :    
 84__property  AnsiString FontName = {read = FFontName, write = SetFontName};    
 85__property  Style;    
 86__property  Anchors;    
 87__property  BiDiMode;    
 88__property  Color;    
 89__property  Constraints;    
 90__property  Ctl3D;    
 91__property  DragCursor;    
 92__property  DragKind;    
 93__property  DragMode;    
 94__property  DropDownCount;    
 95__property  Enabled;    
 96__property  Font;    
 97__property  ItemHeight;    
 98__property  MaxLength;    
 99__property  ParentBiDiMode;    
100__property  ParentColor;    
101__property  ParentCtl3D;    
102__property  ParentFont;    
103__property  ParentShowHint;    
104__property  PopupMenu;    
105__property  ShowHint;    
106__property  TabOrder;    
107__property  TabStop;    
108__property  Visible;    
109__property  OnChange;    
110__property  OnClick;    
111__property  OnContextPopup;    
112__property  OnDblClick;    
113__property  OnDragDrop;    
114__property  OnDragOver;    
115__property  OnDrawItem;    
116__property  OnDropDown;    
117__property  OnEndDock;    
118__property  OnEndDrag;    
119__property  OnEnter;    
120__property  OnExit;    
121__property  OnKeyDown;    
122__property  OnKeyPress;    
123__property  OnKeyUp;    
124__property  OnMeasureItem;    
125__property  OnStartDock;    
126__property  OnStartDrag;    
127};    
128_ //---------------------------------------------------------------------------  _   
129#endif   
130  
131实现文件   
132_ /*===========================================================================  _   
133_ TFontNameComboBox  _ _ 及  TFontNameSizeComboBox  组件实现文件  _   
134_ 文件名称:  FontComboBox.CPP  _   
135_ _ _ 程序设计:梁生红  _   
136_ 创建日期:  2003-03-20  _   
137_ ===========================================================================*/  _   
138#include <vcl.h>   
139#pragma hdrstop   
140  
141#include "FontComboBox.h"    
142#pragma package(smart_init)    
143_ //---------------------------------------------------------------------------  _   
144static  inline  void  ValidCtrCheck(TFontNameComboBox *)    
145{    
146new  TFontNameComboBox(NULL);    
147}    
148_ //---------------------------------------------------------------------------  _   
149static  inline  void  ValidCtrCheck(TFontSizeComboBox *)    
150{    
151new  TFontSizeComboBox(NULL);    
152}    
153_ //---------------------------------------------------------------------------  _   
154_ /* TODO :  _ 回调函数实现代码  */    
155bool  __stdcall  EnumFontNameProc(ENUMLOGFONT FAR *lpelf,NEWTEXTMETRICEX FAR *lpntme,    
156int  FontType, LPARAM lParam)    
157{    
158char  FontFullName[64];    
159strcpy(FontFullName,lpelf-&gt;elfFullName);    
160if  (((TStrings*)(lParam))-&gt;IndexOf(FontFullName)==-1)    
161((TStrings*)(lParam))-&gt;Add(FontFullName);    
162return  true  ;    
163}    
164_ //----------------------------------------------------------------------------  _   
165bool  __stdcall  EnumFontSizeProc(ENUMLOGFONT FAR *lpelf,NEWTEXTMETRIC FAR *lpntm,    
166int  FontType, LPARAM lParam)    
167{    
168if  (FontType&amp;TRUETYPE_FONTTYPE)    
169{    
170((TStrings*)(lParam))-&gt;Add("8");    
171((TStrings*)(lParam))-&gt;Add("9");    
172((TStrings*)(lParam))-&gt;Add("10");    
173((TStrings*)(lParam))-&gt;Add("11");    
174((TStrings*)(lParam))-&gt;Add("12");    
175((TStrings*)(lParam))-&gt;Add("14");    
176((TStrings*)(lParam))-&gt;Add("16");    
177((TStrings*)(lParam))-&gt;Add("18");    
178((TStrings*)(lParam))-&gt;Add("20");    
179((TStrings*)(lParam))-&gt;Add("22");    
180((TStrings*)(lParam))-&gt;Add("24");    
181((TStrings*)(lParam))-&gt;Add("26");    
182((TStrings*)(lParam))-&gt;Add("28");    
183((TStrings*)(lParam))-&gt;Add("36");    
184((TStrings*)(lParam))-&gt;Add("48");    
185((TStrings*)(lParam))-&gt;Add("72");    
186return  false  ;    
187}    
188else    
189{    
190AnsiString s;    
191int  i,v,v2;    
192v = floor((lpelf-&gt;elfLogFont.lfHeight-lpntm-&gt;tmInternalLeading)*72/PixelsPerInch);    
193s = IntToStr(v);    
194for  (i = 0;i&lt;((TStrings*)(lParam))-&gt;Count-1;i++)    
195{    
196v2 = StrToInt(((TStrings*)(lParam))-&gt;Strings[i]);    
197if  (v2==v)    
198return  true  ;    
199if  (v2&gt;v)    
200{    
201((TStrings*)(lParam))-&gt;Insert(i,s);    
202return  true  ;    
203}    
204}    
205((TStrings*)(lParam))-&gt;Add(s);    
206return  true  ;    
207}    
208}    
209_ //---------------------------------------------------------------------------   
210  
211_   
212_ /* TODO : TFontNameComboBox  _ 实现部分  */    
213__fastcall  TFontNameComboBox::TFontNameComboBox(TComponent* Owner)    
214: TCustomComboBox(Owner)    
215{    
216Sorted =  true  ;    
217if  (!ComponentState.Contains(csDesigning))    
218Build();    
219}    
220_ //---------------------------------------------------------------------------  _   
221void  __fastcall  TFontNameComboBox::Build()    
222{   
223  
224HDC DC = NULL;    
225LOGFONT LogFont;    
226TNotifyEvent OnChangeEvent;   
227  
228OnChangeEvent = OnChange;    
229OnChange = NULL;    
230Items-&gt;Clear();    
231LogFont.lfCharSet = DEFAULT_CHARSET;    
232strcpy(LogFont.lfFaceName,"");    
233LogFont.lfPitchAndFamily = 0;   
234  
235DC = GetDC(GetDesktopWindow());    
236try    
237{    
238EnumFontFamiliesEx(DC,&amp;LogFont,(FONTENUMPROC)(EnumFontNameProc),LPARAM(Items),0);    
239}    
240__finally    
241{    
242ReleaseDC(GetDesktopWindow(),DC);    
243}    
244OnChange = OnChangeEvent;    
245if  (Items-&gt;Count)    
246ItemIndex = 0;   
247  
248}    
249_ //---------------------------------------------------------------------------  _   
250_ /* TODO : TFontSizeComboBox  _ 实现部分  */    
251__fastcall  TFontSizeComboBox::TFontSizeComboBox(TComponent* Owner)    
252: TCustomComboBox(Owner)    
253{    
254Sorted =  false  ;    
255}    
256_ //---------------------------------------------------------------------------  _   
257void  __fastcall  TFontSizeComboBox::SetFontName(AnsiString AFontName)    
258{    
259FFontName = AFontName;    
260if  (!ComponentState.Contains(csDesigning))    
261{    
262Items-&gt;Clear();    
263Build();    
264}    
265}    
266_ //---------------------------------------------------------------------------  _   
267void  __fastcall  TFontSizeComboBox::Build()    
268{    
269TNotifyEvent OnChangeEvent = OnChange;    
270OnChange = NULL;    
271HDC DC = GetDC(GetDesktopWindow());    
272PixelsPerInch = GetDeviceCaps(DC, LOGPIXELSY);    
273try    
274{    
275EnumFontFamilies(DC, FFontName.c_str(), (FONTENUMPROC)(EnumFontSizeProc),LPARAM(Items));    
276}    
277__finally    
278{    
279ReleaseDC(GetDesktopWindow(),DC);    
280}    
281OnChange = OnChangeEvent;    
282if  (Items-&gt;Count)    
283ItemIndex = 0;    
284}    
285_ //---------------------------------------------------------------------------  _   
286namespace  Fontcombobox    
287{    
288void  __fastcall  PACKAGE Register()    
289{    
290TComponentClass classes[2] = {  __classid  (TFontNameComboBox),    
291__classid  (TFontSizeComboBox)};    
292RegisterComponents("Samples", classes, 1);    
293}    
294}    
295_ //---------------------------------------------------------------------------   
296  
297_</vcl.h></math.h></printers.hpp></stdctrls.hpp></forms.hpp></classes.hpp></controls.hpp></sysutils.hpp>
Published At
Categories with Web编程
comments powered by Disqus