fontu.pas隱藏代碼
unit Fontu;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Grids, ExtDlgs;
type
tFontData = record
Filename, Fontname: string;
Charset: integer;
end;
tFontDatas= array of tFontData;
TForm1 = class(TForm)
btnSystem: TButton;
btnFolder: TButton;
btnSelectFolder: TButton;
btnSaveBmp: TButton;
btnClose: TButton;
Grid: TDrawGrid;
SavePictureDialog1: TSavePictureDialog;
procedure FormCreate(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure btnSystemClick(Sender: TObject);
procedure btnFolderClick(Sender: TObject);
procedure btnSelectFolderClick(Sender: TObject);
procedure btnSaveBmpClick(Sender: TObject);
procedure btnCloseClick(Sender: TObject);
procedure GridDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
procedure FormDestroy(Sender: TObject);
private
FSystemFonts: tFontDatas;
FFolderFonts: tFontDatas;
FFonts: ^tFontDatas;
FFolder: String;
FShowSystemFont: Boolean;
procedure SetFolder(const Value: String);
procedure SetShowSystemFont(const Value: Boolean);
procedure DrawCell(Canvas: tCanvas; Rect: tRect; Row: integer; Selected: boolean);
function SelectFolder: string;
procedure GetSystemFonts;
procedure GetFolderFonts;
procedure RemovePrivateFonts;
procedure UpdateFonts;
procedure SaveAsBitmap(const Filename: string);
public
property Folder: String read FFolder write SetFolder;
property ShowSystemFont: Boolean read FShowSystemFont write SetShowSystemFont;
end;
var
Form1: TForm1;
implementation
uses
ShlObj, ActiveX;
{$R *.DFM}
const
FontBgColorHl = clNavy;
FontBgColor0 = $00d0eFFF;
FontBgColor1 = $00eFd0FF;
FontColorHl = clWhite;
FontColor0 = clBlack;
FontColor1 = clBlack;
LineHeight1 = 18;
LineHeight2 = 24;
LineHeight3 = 18;
LineSpace1 = 2;
LineSpace2 = 1;
SpaceLeft = 2;
SpaceMiddle = 1;
FirstLineFont = 'Tahoma';
DefaultSample = 'ABCDEFGabcdefg0123456789+-*/&=(){}<>,.?%$#';
FontParam = FR_PRIVATE;
function CharsetName(Charset: integer): string;
begin
case charset of
CHINESEBIG5_CHARSET: Result:='Chinese Big5';
GB2312_CHARSET: Result:='Chinese GB';
ANSI_CHARSET: Result:='Ansi';
DEFAULT_CHARSET: Result:='Default';
SYMBOL_CHARSET: Result:='Symbol';
SHIFTJIS_CHARSET: Result:='Janpanese ShiftJIS';
HANGEUL_CHARSET: Result:='Korean Hanguel';
OEM_CHARSET: Result:='OEM';
JOHAB_CHARSET: Result:='Johab';
HEBREW_CHARSET: Result:='Hebrew: ';
ARABIC_CHARSET: Result:='Arabic';
GREEK_CHARSET: Result:='Greek';
TURKISH_CHARSET: Result:='Turkish';
VIETNAMESE_CHARSET: Result:='Vietnamese';
THAI_CHARSET: Result:='Thai';
EASTEUROPE_CHARSET: Result:='East Europe';
RUSSIAN_CHARSET: Result:='Russian';
BALTIC_CHARSET: Result:='Baltic';
MAC_CHARSET: Result:='MAC';
else Result:='Unknown';
end
end;
procedure GetSampleText(Charset: integer; var Head, Str1, Str2: string);
begin
case Charset of
CHINESEBIG5_CHARSET: Head:='詩中天';
GB2312_CHARSET: Head:='坅笢毞';
SHIFTJIS_CHARSET: Head:=#$90#$9f#138;C';
HANGEUL_CHARSET: Head:='憡臐';
else Head:='';
end;
case Charset of
CHINESEBIG5_CHARSET: Str1:='地闊,一卷與君遊。--歸木淡';
GB2312_CHARSET: Str1:='華屨ㄛ珨橙迵澱蚔﹝ㄜㄜ寥躂筏';
SHIFTJIS_CHARSET: Str1:=''#$95#$97''#$8d#$81'';
HANGEUL_CHARSET: Str1:='夥塋擎 離紫 曖 翎擎 霤腎橫塭';
else Str1:='';
end;
Str2:=DefaultSample;
end;
var
StartDirectryCallBack: string='';
function BrowseDialogCallBack (Wnd: HWND; uMsg: UINT; _lParam, _lpData: LPARAM):
integer stdcall;
var
wa, rect: TRect;
dialogPT: TPoint;
begin
if uMsg=BFFM_INITIALIZED then
begin
SystemParametersInfo(SPI_GETWORKAREA, 0, @wa, 0);
GetWindowRect(Wnd, Rect);
dialogPT.X:=((wa.Right-wa.Left) div 2) -
((rect.Right-rect.Left) div 2);
dialogPT.Y:=((wa.Bottom-wa.Top) div 2) -
((rect.Bottom-rect.Top) div 2);
MoveWindow(Wnd, dialogPT.X, dialogPT.Y,
Rect.Right-Rect.Left, Rect.Bottom-Rect.Top, True);
if StartDirectryCallBack<>'' then
SendMessage(Wnd,BFFM_SETSELECTION, 1, Integer(@StartDirectryCallBack[1]));
end;
Result:=0;
end;
function BrowseDirectory(const Caption: string; const Root: WideString;
var Directory: string): Boolean;
var
WindowList: Pointer;
BrowseInfo: TBrowseInfo;
Buffer: PChar;
RootItemIDList, ItemIDList: PItemIDList;
ShellMalloc: IMalloc;
IDesktopFolder: IShellFolder;
Eaten, Flags: LongWord;
begin
Result:=False;
FillChar(BrowseInfo, SizeOf(BrowseInfo), 0);
if (ShGetMalloc(ShellMalloc)=S_OK) and (ShellMalloc<>nil) then
begin
Buffer:=ShellMalloc.Alloc(MAX_PATH);
try
RootItemIDList:=nil;
if Root <> '' then
begin
SHGetDesktopFolder(IDesktopFolder);
IDesktopFolder.ParseDisplayName(Application.Handle, nil,
POleStr(Root), Eaten, RootItemIDList, Flags);
end;
with BrowseInfo do
begin
hwndOwner:=Application.Handle;
pidlRoot:=RootItemIDList;
pszDisplayName:=Buffer;
lpszTitle:=PChar(Caption);
ulFlags:=BIF_RETURNONLYFSDIRS;
lpfn:=BrowseDialogCallBack;
StartDirectryCallBack:=Directory;
end;
WindowList:=DisableTaskWindows(0);
try
ItemIDList:=ShBrowseForFolder(BrowseInfo);
finally
EnableTaskWindows(WindowList);
end;
Result:= ItemIDList<>nil;
if Result then
begin
ShGetPathFromIDList(ItemIDList, Buffer);
ShellMalloc.Free(ItemIDList);
Directory:=Buffer;
end;
finally
ShellMalloc.Free(Buffer);
end;
end;
end;
function NewStringListItem(const S1, S2: tStrings): string;
var
i: integer;
begin
result:='';
if s2.count<=s1.count then exit;
for i:=0 to s2.Count-1 do
if (s2[i]<>'') and (s2[i][1]<>'@') and (s1.IndexOf(s2[i])<0) then
begin
result:=s2[i];
exit;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Grid.ColWidths[0]:=Grid.ClientWidth;
Grid.DefaultRowHeight:=LineHeight1+LineHeight2+LineHeight3+LineSpace1+LineSpace2;
FFolder:='';
SetLength(FFolderFonts,0);
GetSystemFonts;
FShowSystemFont:=false;
ShowSystemFont:=true;
Grid.DoubleBuffered:=true;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
RemovePrivateFonts;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
Grid.SetBounds(Grid.Left, Grid.Top, ClientWidth-16, ClientHeight-Grid.Top-8);
Grid.ColWidths[0]:=Grid.ClientWidth;
end;
procedure TForm1.btnSystemClick(Sender: TObject);
begin
ShowSystemFont:=true;
end;
procedure TForm1.btnFolderClick(Sender: TObject);
begin
ShowSystemFont:=false;
end;
procedure TForm1.btnSelectFolderClick(Sender: TObject);
begin
Folder:=SelectFolder;
end;
procedure TForm1.btnSaveBmpClick(Sender: TObject);
begin
if SavePictureDialog1.Execute then
SaveAsBitmap(SavePictureDialog1.Filename)
end;
procedure TForm1.btnCloseClick(Sender: TObject);
begin
Close;
end;
procedure TForm1.GridDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
DrawCell(Grid.Canvas, Rect, ARow, gdSelected in State);
end;
procedure TForm1.SetFolder(const Value: String);
begin
if Value='' then exit;
FFolder:=Value;
GetFolderFonts;
if not ShowSystemFont then
begin
FFonts:=@FFolderFonts;
UpdateFonts;
end;
end;
procedure TForm1.SetShowSystemFont(const Value: Boolean);
begin
if FShowSystemFont=Value then exit;
if not Value then
begin
if FFolder='' then Folder:=SelectFolder;
if FFolder='' then exit;
end;
FShowSystemFont:=Value;
btnSystem.enabled:=not FShowSystemFont;
btnFolder.enabled:=FShowSystemFont;
btnSelectFolder.enabled:=not FShowSystemFont;
if FShowSystemFont
then Caption:='Fontlist - System fonts'
else Caption:=format('Fontlist - Fonts in "%s"',[FFolder]);
if FShowSystemFont
then FFonts:=@FSystemFonts
else FFonts:=@FFolderFonts;
UpdateFonts;
end;
procedure TForm1.DrawCell(Canvas: tCanvas; Rect: tRect; Row: integer;
Selected: boolean);
var
HeadStr, Str1, Str2: string;
p: tPoint;
w: integer;
begin
with Canvas do
begin
if Selected
then Brush.Color:=FontBgColorHl
else if Row mod 2=0
then Brush.Color:=FontBgColor0
else Brush.Color:=FontBgColor1;
FillRect(rect);
if Row>=Length(fFonts^) then exit;
if Selected
then Font.Color:=FontColorHl
else if Row mod 2=0
then Font.Color:=FontColor0
else Font.Color:=FontColor1;
SetBkMode(Handle, TRANSPARENT);
Font.Name:=FirstLineFont;
Font.Charset:=DEFAULT_CHARSET;
Font.Height:=LineHeight1;
P:=Rect.TopLeft;
inc(p.x, SpaceLeft);
HeadStr:='Charset: '+CharsetName(fFonts^[Row].Charset);
if fFontS^[Row].Filename<>'' then
HeadStr:=ExtractFilename(fFonts^[Row].Filename)+', '+HeadStr;
HeadStr:=fFonts^[Row].Fontname+' ('+HeadStr+')';
Textout(p.x, p.y, HeadStr);
Font.Name:=fFonts^[Row].Fontname;
inc(p.y, LineHeight1+LineSpace1);
Font.Charset:=fFonts^[Row].Charset;
GetSampleText(fFonts^[Row].Charset, HeadStr, Str1, Str2);
if (Str1='') or (Str2='') then
begin
HeadStr:=HeadStr+Str1+Str2;
Str1:='';
Str2:='';
end;
if HeadStr<>'' then
begin
Font.Height:=LineHeight2+LineSpace2+LineHeight3;
Textout(p.x ,p.y, HeadStr);
Inc(p.x, SpaceMiddle+TextWidth(Headstr));
end;
if Str1<>'' then
begin
Font.Height:=LineHeight2;
Textout(p.x, p.y, Str1);
end;
if Str2<>'' then
begin
Inc(p.y, LineHeight2+LineSpace2);
Font.Height:=LineHeight3;
Textout(p.x, p.y, Str2);
end;
end;
end;
function TForm1.SelectFolder: string;
begin
Result:=FFolder;
if not BrowseDirectory('Please select a font folder', '', result)
then result:='';
end;
procedure TForm1.GetSystemFonts;
var
i, l: integer;
OldFont: tFont;
tm: tagTEXTMETRICA;
begin
SetLength(fSystemFonts,Screen.Fonts.Count);
l:=0;
OldFont:=tFont.Create;
OldFont.Assign(Canvas.Font);
try
for i:=0 to Screen.Fonts.Count-1 do
if Screen.Fonts[i][1]<>'@' then
begin
fSystemFonts[l].Fontname:=Screen.Fonts[i];
fSystemFonts[l].Filename:='';
Canvas.Font.Name:=fSystemFonts[l].Fontname;
GetTextMetrics(Canvas.Handle, tm);
fSystemFonts[l].Charset:=tm.tmCharSet;
inc(l);
end;
Finally
SetLength(fSystemFonts,l);
Canvas.Font.Assign(OldFont);
OldFont.Free;
end;
end;
procedure TForm1.GetFolderFonts;
var
OldFont: tFont;
s1, s2: tstringlist;
procedure AddFiles(const Path, Ext: string);
var
sr: tSearchRec;
tm: tagTEXTMETRICA;
fd: tFontData;
i,j,l: integer;
begin
if FindFirst(Path+Ext, faAnyFile, sr)=0 then
repeat
s1.Assign(Screen.Fonts);
fd.Filename:=Path+sr.Name;
AddFontResourceEx(pchar(fd.Filename), FontParam, nil) ;
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0) ;
s2.Assign(Screen.Fonts);
fd.Fontname:=NewStringListItem(s1, s2);
if fd.Fontname<>'' then
begin
Canvas.Font.Name:=fd.Fontname;
GetTextMetrics(Canvas.Handle, tm);
fd.Charset:=tm.tmCharSet;
l:=length(fFolderFonts);
setlength(fFolderFonts,l+1);
fFolderFonts[l]:=fd;
end else
begin
RemoveFontResourceEx(pchar(fd.Filename), FontParam, nil) ;
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0) ;
end;
until FindNext(sr)<>0;
FindClose(sr);
end;
begin
RemovePrivateFonts;
OldFont:=tFont.Create;
OldFont.Assign(Canvas.Font);
s1:=tStringList.Create;
s2:=tStringList.Create;
try
AddFiles(IncludeTrailingBackslash(FFolder), '*.tt*');
AddFiles(IncludeTrailingBackslash(FFolder), '*.fon');
AddFiles(IncludeTrailingBackslash(FFolder), '*.otf');
finally
s1.Free;
s2.Free;
Canvas.Font.Assign(OldFont);
OldFont.Free;
end;
end;
procedure TForm1.RemovePrivateFonts;
var
i: integer;
begin
for i:=0 to length(fFolderFonts)-1 do
RemoveFontResourceEx(pchar(fFolderFonts[i].Filename), FontParam, nil) ;
SetLength(fFolderFonts, 0);
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0) ;
end;
procedure TForm1.UpdateFonts;
begin
btnSavebmp.enabled:=length(FFonts^)>0;
Grid.RowCount:=length(FFonts^);
Grid.Invalidate;
end;
procedure TForm1.SaveAsBitmap(const Filename: string);
var
bmp: tbitmap;
i, w, lh: integer;
begin
bmp:=tBitmap.Create;
w:=Grid.ClientWidth;
lh:=Grid.DefaultRowHeight;
try
bmp.Width:=w;
bmp.Height:=lh*length(FFonts^);
for i:=0 to length(FFonts^)-1 do
DrawCell(bmp.Canvas, Rect(0, i*lh, w, (i+1)*lh), i, false);
bmp.SaveToFile(Filename);
finally
bmp.Free;
end;
end;
end.