自己動手寫元件-User_Controller Design 範例:控制 ini檔

自己動手寫元件-User_Controller Design 範例:控制 ini檔

說明:雖然delphi已經把控制ini檔(應用程式初始化檔)的類別包裝(iniFiles.TIniFile)好了,
因為還沒寫過元件,所以先用簡單的方式,加深自己的觀念。

【結果】

imageimageimage

【步驟】

image>>image(自訂類別名稱與存放路徑)

【內容】

   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.