uses IOUtils, Vcl.Styles, vcl.Themes;
procedure TForm1.FormCreate(Sender: TObject);
var
dir, fileName, styleName: string;
begin
//VCL 的样式文件 *.vsf
//在 X:\Program Files\Embarcadero\RAD Studio\9.0\Redist\styles\vcl\
dir := GetEnvironmentVariable('Delphi') + '\Redist\styles\vcl';
{载入所有 *.vsf 文件}
for fileName in TDirectory.GetFiles(dir, '*.vsf') do
TStyleManager.LoadFromFile(fileName);
{将样式名称导入列表}
for styleName in TStyleManager.StyleNames do
ListBox1.Items.Add(styleName);
end;
{修改样式}
procedure TForm1.ListBox1Click(Sender: TObject);
begin
TStyleManager.SetStyle(ListBox1.Items[ListBox1.ItemIndex]);
end;
在Delphi 2005就已經加入了For element in collection do statement語法,可以用來歷遍一個集合、數組等等,下面這個是For in 支持的類型:
# Classes.TList
# Classes.TCollection
# Classes.TStrings
# Classes.TInterfaceList
# Classes.TComponent
# Menus.TMenuItem
# ActnList.TCustomActionList
# DB.TFields
# ComCtrls.TListItems
# ComCtrls.TTreeNodes
# ComCtrls.TToolBar
首先來看一個簡單的例子:}
procedure ShowListStr(StrList: TStrings);
var
tmpStr: String;
begin
for tmpStr in StrList do
ShowMessage(tmpStr); //這樣就可以歷遍整個SrList的值了,比以前用for i to do 快了很多吧
end;
{再看看這個:(數組歷遍)}
type
TIntArray = array[0..9] of Integer;
TGenericIntArray = array of Integer;
var
IntArray1: array[0..9] of Integer = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
IntArray2: array[1..2] of TIntArray = ((11, 12, 13, 14, 15, 16, 17, 18, 19, 20),
(21, 22, 23, 24, 25, 26, 27, 28, 29, 30));
IntArrayTemp: TIntArray;
IGenericIntArray: TGenericIntArray;
i: integer;
begin
for i in IntArray1 do
begin
ShowMessage(IntToStr(i)); //這樣便可以歷遍這個數組,不用再用for High Low等等函數了
end;
for i in IntArray2 do //多維數組的歷遍
for i in IGenericIntArray do
begin
ShowMessage(IntToStr(i));
end;
end;
{看了後是不是覺得歷遍一個數組比以前方便多了.
再看看For in 在字符串中的應用:}
var
C: Char;
Str1,Str2: String;
begin
Str1 := 'Hello Everybody,I am Kevin...';
Str2 := '';
for C in S1 do //這樣就已經歷遍了一個字符串,並進行了拆解...
Str2 := Str2 + C;
if Str1 = Str2 then
ShowMessage('Success!');
end;
{再看看如何歷遍集合型的數據類型的:}
type
TMyThing = (one, two, three);
TMySet = set of TMyThing;
TCharSet = set of Char;
var
MySet: TMySet;
MyThing: TMyThing;
CharSet: TCharSet;
C: Char;
begin
MySet := [one, two, three];
for MyThing in MySet do //歷遍集合
begin
// 做相關的處理
end;
CharSet := [#0..#255];
for C in CharSet do
begin
// 做相關的處理
end;
end.
{下面這個更加有用,歷遍類
這個類必須實現一個公用的方法為:GetEnumerator(),此方法返回的是一個類.而另一個類必須實現一個公用的方法為:MoveNext()和一個名為Current的屬性.方法返回類型為Boolean;看例子:}
type
TMyIntArray = array of Integer;
TMyEnumerator = class
Values: TMyIntArray;
Index: Integer;
public
constructor Create;
function GetCurrent: Integer;
function MoveNext: Boolean; //這個為實現的MoveNext方法
property Current: Integer read GetCurrent;
end;
TMyContainer = class
public
function GetEnumerator: TMyEnumerator; //這個為實現的GetEnumerator的方法.
end;
constructor TMyEnumerator.Create;
begin
inherited Create;
Values := TMyIntArray.Create(100, 200, 300);
Index := -1;
end;
function TMyEnumerator.MoveNext: Boolean;
begin
if Index < High(Values) then
begin
Inc(Index);
Result := True;
end
else
Result := False;
end;
function TMyEnumerator.GetCurrent: Integer;
begin
Result := Values[Index];
end;
function TMyContainer.GetEnumerator: TMyEnumerator;
begin
Result := TMyEnumerator.Create;
end;
var
MyContainer: TMyContainer;
I: Integer;
Counter: Integer;
begin
MyContainer := TMyContainer.Create;
for I in MyContainer do //歷遍,並把TMyEnumerator的Current進行累加...
Inc(Counter, I);
ShowMessage(IntToStr(Counter)); //值為600
end.
{從上面可以看到通過Current就可以實現很大功能了,我們只需把Current的類型變一個,就可以做到很方便的功能.
總結,從For In語法看到,可以給我們編碼時帶來很多方便... }
哈哈,Java和C#里面的For In用起来真爽,我们Delphin也不用眼红了,从D2005起,Delphi里面也有这个功能了.
首先我们要知道哪些类型可以用For In吧,下面就是:
for Element in ArrayExpr do Stmt; 数组
for Element in StringExpr do Stmt; 字符串
for Element in SetExpr do Stmt; 集合
for Element in CollectionExpr do Stmt; 集合
for Element in Record do Stmt; 结构体
我们来看例子:
type
THuangJacky = (hjA,hjB,hjC,hjD);
TJackyHuang = record
a,b,c:Integer;
end;
const
stringExpr='HuangJacky';
arrayExpr:array[0..5] of Integer= (1,2,3,4,5,6);
setExpr:set of THuangJacky = [hjA,hjB,hjD];
procedure TForm1.FormCreate(Sender: TObject);
var
I:Integer;
C:Char;
D:THuangJacky;
F:TComponent;
begin
for c in stringExpr do
ShowMessage(C);
for i in arrayExpr do
ShowMessage(IntToStr(i));
for d in setExpr do
ShowMessage(IntToStr(Ord(d)));
for F in Self do
ShowMessage(f.Name);
end;
是不是很爽呀?哈哈,Delphi也与时俱进呀.
之前写了类助手文章中,老赵问是不是扩展方法,因为对C#没有了解到这么多,所以不知道.
那么我们在Java中要For In必须实现Iterator吧.
那么Delphi的会不会也要呢?
是的,如果我们要自己的类支持For In的话,就必须满足下面的条件:
1 必须有个公共方法GetEnumerator(),这个方法返回值是一个类,接口或者记录体.
2 上面返回的类,接口或者记录体中又必须有公共方法MoveNext(),这个方法的返回值是Boolean.
3 1中返回的类,接口或者记录体中必须有一个只读的属性Current,类型要和集合中的元素一样.
说了这么多,看个例子:
type
TMyIntArray = array of Integer;
TMyEnumerator = class
Values: TMyIntArray;
Index: Integer;
public
constructor Create;
function GetCurrent: Integer;
function MoveNext: Boolean;
property Current: Integer read GetCurrent;
end;
TMyContainer = class
public
function GetEnumerator: TMyEnumerator;
end;
constructor TMyEnumerator.Create;
begin
inherited Create;
Values := TMyIntArray.Create(100, 200, 300);
Index := -1;
end;
function TMyEnumerator.MoveNext: Boolean;
begin
if Index < High(Values) then
begin
Inc(Index);
Result := True;
end
else
Result := False;
end;
function TMyEnumerator.GetCurrent: Integer;
begin
Result := Values[Index];
end;
function TMyContainer.GetEnumerator: TMyEnumerator;
begin
Result := TMyEnumerator.Create;
end;
var
MyContainer: TMyContainer;
I: Integer;
Counter: Integer;
begin
MyContainer := TMyContainer.Create;
Counter := 0;
for I in MyContainer do
Inc(Counter, I);
WriteLn('Counter = ', Counter);
end.
一、遍历 TStrings
--------------------------------------------------------------------------------
var
List: TStrings;
s: string;
begin
List := TStringList.Create;
List.CommaText := 'aaa,bbb,ccc';
for s in List do
ShowMessage(s);
List.Free;
end;
--------------------------------------------------------------------------------
二、遍历数组
--------------------------------------------------------------------------------
var
Arr: array[0..2] of Byte;
i: Integer;
b: Byte;
begin
for i := Low(Arr) to High(Arr) do
Arr[i] := Random(MAXBYTE);
for b in Arr do
ShowMessage(IntToStr(b));
end;
--------------------------------------------------------------------------------
三、遍历子界
--------------------------------------------------------------------------------
{例1}
var
sub: 0..9;
str: string;
begin
str := '';
for sub in [Low(sub)..High(sub)] do
str := str + IntToStr(sub);
ShowMessage(str); {0123456789}
end;
{例2}
type
TSub = 'A'..'G';
var
sub: TSub;
str: string;
begin
str := '';
for sub in [Low(sub)..High(sub)] do
str := str + sub;
ShowMessage(str); {ABCDEFG}
end;
{例3}
var
sub: Byte; {Byte 应该算是个 0..255 的子界}
num: Cardinal;
begin
num := 0;
for sub in [Low(sub)..High(sub)] do
Inc(num, sub);
ShowMessage(IntToStr(num)); {32640}
end;
--------------------------------------------------------------------------------
四、遍历枚举
--------------------------------------------------------------------------------
type
TEnum = (Red,Green,Blue);
var
enum: TEnum;
count: Integer;
begin
count := 0;
for enum in [Low(enum)..High(enum)] do
Inc(count);
ShowMessage(IntToStr(count)); {3}
end;
--------------------------------------------------------------------------------
五、遍历集合
--------------------------------------------------------------------------------
type
TEnum = (Red,Green,Blue,Yellow);
TSet = set of TEnum;
var
set1: set of TEnum;
set2: TSet;
elem: Tenum;
count: Integer;
begin
set1 := [Red, Yellow];
count := 0;
for elem in set1 do Inc(count);
ShowMessage(IntToStr(count)); {2}
set2 := [Red..Yellow];
count := 0;
for elem in set2 do Inc(count);
ShowMessage(IntToStr(count)); {4}
end;
--------------------------------------------------------------------------------
六、遍历字符串
--------------------------------------------------------------------------------
var
str: string;
c: Char;
begin
str := 'ABCD';
for c in str do
ShowMessage(c);
end;