自己動手寫元件-User_Controller Design 範例:控制 ini檔
說明:雖然delphi已經把控制ini檔(應用程式初始化檔)的類別包裝(iniFiles.TIniFile)好了,
因為還沒寫過元件,所以先用簡單的方式,加深自己的觀念。
【結果】
【步驟】
【內容】
1: unit InICtrl;
2:
3: interface
4:
5: uses
6: SysUtils, Classes, IniFiles, Forms, Dialogs, DesignIntf, DesignEditors;
7: {DesignIntf, DesignEditors 這兩個單元為"屬性編輯器"}
8: type
9: TIniPath = type String;
10: //宣告屬性編輯器,讓ini檔可以用"對話框"的方式選取
11: TIniPathProperty = class(TStringProperty)
12: public
13: function GetAttributes: TPropertyAttributes; override;
14: procedure Edit; override;
15: end;
16: TIniInfo = Record
17: FileName:String;
18: FilePath:String;
19: end;
20: //定義事件處理方法
21: TBeforeWriteEvent = TNotifyEvent;
22: TBeforeReadEvent = TNotifyEvent;
23: TBeforeEraseSection = TNotifyEvent;
24: TBeforeDeleteKey = TNotifyEvent;
25: TAfterWriteEvent = TNotifyEvent;
26: TAfterReadEvent = TNotifyEvent;
27: TAfterEraseSection = TNotifyEvent;
28: TAfterDeleteKey = TNotifyEvent;
29:
30: TIniCtrl = class(TComponent)
31: private
32: IniFile:TIniFile; //內部處理ini檔的核心
33: FIniInfo: TIniInfo; //ini檔存放資訊 ;路徑、檔名
34: FBeforeWriteEvent: TBeforeWriteEvent;
35: FBeforeReadEvent: TBeforeReadEvent;
36: FBeforeEraseSection: TBeforeEraseSection;
37: FBeforeDeleteKey: TBeforeDeleteKey;
38: FAfterWriteEvent: TAfterWriteEvent;
39: FAfterReadEvent: TAfterReadEvent;
40: FAfterEraseSection: TAfterEraseSection;
41: FAfterDeleteKey: TAfterDeleteKey;
42: FAutoCreateIni: Boolean;
43: FIniPath: TIniPath;
44: function AssignIniFile(IniInfo:TIniInfo):Boolean; //查驗ini檔是否可用,並進行初始化
45: procedure SetAutoCreateIni(const Value: Boolean);
46: procedure SetIniInfo(const Value: TIniPath);
47: { Private declarations }
48: protected
49: { Protected declarations }
50: procedure DoBeforeWrite(sender: TObject);dynamic;
51: procedure DoBeforeRead(sender: TObject);dynamic;
52: procedure DoBeforeEraseSecton(sender: TObject);dynamic;
53: procedure DoBeforeDeleteKey(sender: TObject);dynamic;
54: procedure DoAfterWrite(sender: TObject);dynamic;
55: procedure DoAfterRead(sender: TObject);dynamic;
56: procedure DoAfterEraseSecton(sender: TObject);dynamic;
57: procedure DoAfterDeleteKey(sender: TObject);dynamic;
58: public
59: { Public declarations }
60: (*_讀ini文件_*)
61: Function INI_LOAD(const Section, Ident:string; Default: String):string; overload;
62: Function INI_LOAD(const Section, Ident:string; Default: Integer):Integer; overload;
63: Function INI_LOAD(const Section, Ident:string; Default: Double):Double; overload;
64: Function INI_LOAD(const Section, Ident:string; Default: Boolean):Boolean; overload;
65: Function INI_LOAD(const Section, Ident:string; Default: TDateTime):TDateTime; overload;
66: (*_寫INI文件_*)
67: procedure INI_SAVE(const Section, Ident:string; Value:String);overload;
68: procedure INI_SAVE(const Section, Ident:string; Value:Integer);overload;
69: procedure INI_SAVE(const Section, Ident:string; Value:Double);overload;
70: procedure INI_SAVE(const Section, Ident:string; Value:Boolean);overload;
71: procedure INI_SAVE(const Section, Ident:string; Value:TDateTime);overload;
72: {*檢驗ini*}
73: function SectionExists(const Section: string): Boolean;
74: procedure EraseSection(const Section: string);
75: procedure DeleteKey(const Section, Ident: String);
76: procedure UpdateFile;
77: constructor Create(AOwner: TComponent); override;
78: destructor Destroy; override;
79: published
80: { Published declarations }
81: //提供元件使用者設定ini檔的存放位置
82: property IniPath:TIniPath read FIniPath write SetIniInfo;
83: //當ini檔不存在時是否自動建立
84: property AutoCreateIni:Boolean read FAutoCreateIni write SetAutoCreateIni Stored True;
85: //提供元件使用者執行ini檔操作前後處理事件
86: property BeforeWrite: TBeforeWriteEvent read FBeforeWriteEvent write FBeforeWriteEvent;
87: property BeforeRead: TBeforeReadEvent read FBeforeReadEvent write FBeforeReadEvent;
88: property BeforeEraseSection: TBeforeEraseSection read FBeforeEraseSection write FBeforeEraseSection;
89: property BeforeDeleteKey: TBeforeDeleteKey read FBeforeDeleteKey write FBeforeDeleteKey;
90: property AfterWrite: TAfterWriteEvent read FAfterWriteEvent write FAfterWriteEvent;
91: property AfterRead: TAfterReadEvent read FAfterReadEvent write FAfterReadEvent;
92: property AfterEraseSection: TAfterEraseSection read FBeforeEraseSection write FAfterEraseSection;
93: property AfterDeleteKey: TAfterDeleteKey read FAfterDeleteKey write FAfterDeleteKey;
94: end;
95:
96: procedure Register;
97:
98: implementation
99:
100: uses Math;
101:
102: procedure Register;
103: begin
104: RegisterComponents('xCommVCL', [TIniCtrl]);
105: RegisterPropertyEditor(TypeInfo(TIniPath),TIniCtrl,'',TIniPathProperty);
106: //註冊屬性編輯器(屬性類別, 元件類別, 屬性名, 屬性編輯器類別)
107: end;
108:
109: { TIniPathProperty }
110:
111: procedure TIniPathProperty.Edit;
112: begin
113: with TOpenDialog.Create(Application) do
114: begin
115: try
116: Filter:='應用程式初始化檔|*.ini';
117: if Execute then SetStrValue(FileName);
118: finally
119: Free;
120: end;
121: end;
122: end;
123:
124: function TIniPathProperty.GetAttributes: TPropertyAttributes;
125: begin
126: Result:= [paDialog];//以對話框的方式開啟
127: end;
128:
129: //建構子
130: constructor TIniCtrl.Create(AOwner: TComponent);
131: begin
132: inherited Create(AOwner);
133: end;
134: //解構
135: destructor TIniCtrl.Destroy;
136: begin
137: if Assigned(IniFile) then
138: IniFile.FreeInstance;
139: inherited Destroy;
140: end;
141:
142: //Before
143: procedure TIniCtrl.DoBeforeDeleteKey(sender: TObject);
144: begin
145: if Assigned(FBeforeDeleteKey)then
146: TBeforeDeleteKey(FBeforeDeleteKey)(Sender);
147: end;
148:
149: procedure TIniCtrl.DoBeforeEraseSecton(Sender: TObject);
150: begin
151: if Assigned(FBeforeEraseSection)then
152: TBeforeEraseSection(FBeforeEraseSection)(Sender);
153: end;
154:
155: procedure TIniCtrl.DoBeforeRead(Sender: TObject);
156: begin
157: if Assigned(FBeforeReadEvent) then
158: TBeforeReadEvent(FBeforeReadEvent)(Sender);
159: end;
160:
161: procedure TIniCtrl.DoBeforeWrite(Sender: TObject);
162: begin
163: if Assigned(FBeforeWriteEvent) then
164: TBeforeWriteEvent(FBeforeWriteEvent)(Sender);
165: end;
166: //After
167: procedure TIniCtrl.DoAfterDeleteKey(sender: TObject);
168: begin
169: if Assigned(FAfterDeleteKey)then
170: TAfterDeleteKey(FAfterDeleteKey)(Sender);
171: end;
172:
173: procedure TIniCtrl.DoAfterEraseSecton(Sender: TObject);
174: begin
175: if Assigned(FAfterEraseSection)then
176: TAfterEraseSection(FAfterEraseSection)(Sender);
177: end;
178:
179: procedure TIniCtrl.DoAfterRead(Sender: TObject);
180: begin
181: if Assigned(FAfterReadEvent) then
182: TAfterReadEvent(FAfterReadEvent)(Sender);
183: end;
184:
185: procedure TIniCtrl.DoAfterWrite(Sender: TObject);
186: begin
187: if Assigned(FAfterWriteEvent) then
188: TAfterWriteEvent(FAfterWriteEvent)(Sender);
189: end;
190: {------------read Integer------------}
191: function TIniCtrl.INI_LOAD(const Section, Ident: String;
192: Default: Integer): Integer;
193: begin
194: if AssignIniFile(FIniInfo)then
195: begin
196: DoBeforeRead(Self);
197: Result:=IniFile.ReadInteger(Section,Ident,Default);
198: DoAfterRead(Self);
199: end;
200: end;
201:
202: {------------read String------------}
203: function TIniCtrl.INI_LOAD(const Section, Ident: String;
204: Default: String): String;
205: begin
206: if AssignIniFile(FIniInfo)then
207: begin
208: DoBeforeRead(Self);
209: Result:=IniFile.ReadString(Section,Ident,Default);
210: DoAfterRead(Self);
211: end;
212: end;
213:
214: {------------read Boolean------------}
215: function TIniCtrl.INI_LOAD(const Section, Ident: String;
216: Default: Boolean): Boolean;
217: begin
218: if AssignIniFile(FIniInfo)then
219: begin
220: DoBeforeRead(Self);
221: Result:=IniFile.ReadBool(Section,Ident,Default);
222: DoAfterRead(Self);
223: end;
224: end;
225:
226: {------------read Double------------}
227: function TIniCtrl.INI_LOAD(const Section, Ident: String;
228: Default: Double): Double;
229: begin
230: if AssignIniFile(FIniInfo)then
231: begin
232: DoBeforeRead(Self);
233: Result:=IniFile.ReadFloat(Section,Ident,Default);
234: DoAfterRead(Self);
235: end;
236: end;
237:
238: {------------read DateTime-----------}
239: function TIniCtrl.INI_LOAD(const Section, Ident: String;
240: Default: TdateTime): TdateTime;
241: begin
242: if AssignIniFile(FIniInfo)then
243: begin
244: DoBeforeRead(Self);
245: Result:=IniFile.ReadDateTime(Section,Ident,Default);
246: DoAfterRead(Self);
247: end;
248: end;
249:
250: {------------Write Integer------------}
251: procedure TIniCtrl.INI_SAVE(const Section, Ident: String;
252: Value: Integer);
253: begin
254: if AssignIniFile(FIniInfo)then
255: begin
256: DoBeforeWrite(Self);
257: IniFile.WriteInteger(Section,Ident,Value);
258: DoAfterWrite(Self);
259: end;
260: end;
261: {------------Write String------------}
262: procedure TIniCtrl.INI_SAVE(const Section, Ident: String;
263: Value: String);
264: begin
265: if AssignIniFile(FIniInfo)then
266: begin
267: DoBeforeWrite(Self);
268: IniFile.WriteString(Section,Ident,Value);
269: DoAfterWrite(Self);
270: end;
271: end;
272: {------------Write boolean------------}
273: procedure TIniCtrl.INI_SAVE(const Section, Ident: String;
274: Value: Boolean);
275: begin
276: if AssignIniFile(FIniInfo)then
277: begin
278: DoBeforeWrite(Self);
279: IniFile.WriteBool(Section,Ident,Value);
280: DoAfterWrite(Self);
281: end;
282: end;
283: {------------Write Double------------}
284: procedure TIniCtrl.INI_SAVE(const Section, Ident: String;
285: Value: Double);
286: begin
287: if AssignIniFile(FIniInfo)then
288: begin
289: DoBeforeWrite(Self);
290: IniFile.WriteFloat(Section,Ident,Value);
291: DoAfterWrite(Self);
292: end;
293: end;
294: {------------Write DateTime------------}
295: procedure TIniCtrl.INI_SAVE(const Section, Ident: String;
296: Value: TDateTime);
297: begin
298: if AssignIniFile(FIniInfo)then
299: begin
300: DoBeforeWrite(Self);
301: IniFile.WriteDateTime(Section,Ident,Value);
302: DoAfterWrite(Self);
303: end;
304: end;
305:
306: function TIniCtrl.AssignIniFile(IniInfo:TIniInfo): Boolean;
307: var
308: sfileName:String;
309: sfilePath:String;
310: fExePath, fExeNameIni:string;
311: FileHandle: Integer;
312: Label assignFile;
313: begin
314: //若設計者未設定ini檔名路徑時;
315: fExeNameIni:= ChangeFileExt(ExtractFileName(Application.ExeName),'.ini');
316: fExePath:= ExtractFilePath(Application.ExeName);
317: //設定ini檔資訊
318: if IniInfo.FilePath='' then
319: IniInfo.FilePath:= fExePath;
320: if IniInfo.FileName='' then
321: IniInfo.FileName:= fExeNameIni;
322:
323: with IniInfo do
324: begin
325: if not FileExists(FilePath+FileName)and(FAutoCreateIni=False)then
326: begin
327: Raise Exception.Create('設定檔不存在');
328: Result:= False;
329: end
330: else if not FileExists(FilePath+FileName)and(FAutoCreateIni=True)then
331: begin
332: FileHandle:= FileCreate(FilePath+FileName);
333: if FileHandle<>-1 then
334: begin
335: FileClose(FileHandle);
336: goto assignFile;
337: Result:= True;
338: end
339: else
340: begin
341: Exception.Create('自動建立ini檔失敗!');
342: Result:= False;
343: end;
344: end
345: else if FileExists(FilePath+FileName) then
346: begin
347: assignFile:
348: if not Assigned(IniFile)then
349: begin
350: IniFile:=TiniFile.Create(FilePath+FileName);
351: end;
352: Result:= True;
353: end;
354: end;
355: end;
356:
357: procedure TIniCtrl.EraseSection(const Section: string);
358: begin
359: if AssignIniFile(FIniInfo)then
360: begin
361: DoBeforeEraseSecton(Self);
362: IniFile.EraseSection(Section);
363: DoAfterEraseSecton(Self);
364: end;
365: end;
366:
367: procedure TIniCtrl.UpdateFile;
368: begin
369: if AssignIniFile(FIniInfo)then
370: IniFile.UpdateFile;
371: end;
372:
373: procedure TIniCtrl.DeleteKey(const Section, Ident: String);
374: begin
375: if AssignIniFile(FIniInfo)then
376: begin
377: DoBeforeDeleteKey(Self);
378: IniFile.DeleteKey(Section, Ident);
379: DoAfterDeleteKey(Self);
380: end;
381: end;
382:
383: function TIniCtrl.SectionExists(const Section: string): Boolean;
384: begin
385: if AssignIniFile(FIniInfo)then
386: IniFile.SectionExists(Section);
387: end;
388:
389: procedure TIniCtrl.SetAutoCreateIni(const Value: Boolean);
390: begin
391: FAutoCreateIni := Value;
392: end;
393:
394: procedure TIniCtrl.SetIniInfo(const Value: TIniPath);
395: begin
396: with FIniInfo do
397: begin
398: FileName:= ExtractFileName(Value);
399: FilePath:= ExtractFilePath(Value)
400: end;
401: FIniPath:= Value;
402: end;
403:
404:
405: end.