請問如何存取元件屬性,不是用文字檔或資料庫的方法的方法? |
尚未結案
|
tommyli0913
一般會員 發表:9 回覆:19 積分:5 註冊:2004-02-02 發送簡訊給我 |
各位先進大大,小弟有一個奇怪的問題,就是我在form上有一個TComboBox及一個TImage元件,此程式每次開啟或關閉時就必須將最後一次的值打開或儲存起來。目前我是將這些元件的屬性用AssignFile 儲存到一個文字檔,另外我也曾經將這些屬性儲到access資料庫中,但是這些地方很容易被使用者打開來修改而造成程式無法正常開啟。
所以我想是否有什麼方法可以將這些元件屬性直接儲存到一個安全的地方且不要像"儲存文字檔"方式一定要用while迴圈將參數一行一行Writeln到文字檔中。在開始程式時也不想要像"開啟檔案"方式一定要用while迴圈將參數一行一行讀出並放入元件屬性中,最好能關閉程式時一次就將屬性自動儲存起來,開啟程式時一次就將屬性自動放到它該放的地方。 我的問題比較奇怪些,希望各位先進大大能指點小弟一下,謝謝啦!
|
bigdogchina
版主 發表:238 回覆:523 積分:312 註冊:2003-04-28 發送簡訊給我 |
tommyli0913大大,您好!
小弟也曾經爲這種問題困擾過,我是利用對註冊表的Read/Write來實現的,請您看看下面的這個例子:是在程式結束時將Form的大小,位置以及TComboBox最後一次的值放入註冊表中,然後在程式開始時,將值在讀出來:
...... uses Registry; ...... procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); var Reg: TRegistry; sPath: String; iWidth,iHeight,iLeft,iTop,iComboBoxIndex: Integer; begin sPath := '\Software\KTop'; iWidth := Form1.Width; iHeight := Form1.Height; iLeft := Form1.Left; iTop := Form1.Top; iComboBoxIndex := ComboBox1.ItemIndex; Reg := TRegistry.Create; try Reg.RootKey := HKEY_LOCAL_MACHINE; Reg.OpenKey(sPath,True); Reg.WriteInteger('frmWidth',iWidth); Reg.WriteInteger('frmHeight',iHeight); Reg.WriteInteger('frmLeft',iLeft); Reg.WriteInteger('frmTop',iTop); Reg.WriteInteger('comboBoxIndex',iComboBoxIndex); finally Reg.CloseKey; Reg.Free; end; end; procedure TForm1.FormCreate(Sender: TObject); var Reg: TRegistry; sPath: String; iWidth,iHeight,iLeft,iTop,iComboBoxIndex: Integer; begin sPath := '\Software\KTop'; Reg := TRegistry.Create; try Reg.RootKey := HKEY_LOCAL_MACHINE; Reg.OpenKey(sPath,True); iWidth := Reg.ReadInteger('frmWidth'); iHeight:= Reg.ReadInteger('frmHeight'); iLeft := Reg.ReadInteger('frmLeft'); iTop := Reg.ReadInteger('frmTop'); iComboBoxIndex := Reg.ReadInteger('comboBoxIndex'); finally Reg.CloseKey; Reg.Free; end; Form1.Width := iWidth; Form1.Height:= iHeight; Form1.Left := iLeft; Form1.Top := iTop; ComboBox1.ItemIndex := iComboBoxIndex; end; end.這個方法有點笨,如果要保存的屬性很多的話,豈不是要累死呀!您可以考慮自己定義一個資料結構,然後在Read/Write到註冊表裏。 我也是一知半解,如有謬誤,請先進多多指教! < class="code"> =============== 人生在勤,不索何获? ===============
------
人生在勤,不索何获? |
Mickey
版主 發表:77 回覆:1882 積分:1390 註冊:2002-12-11 發送簡訊給我 |
可以參考運用 TStream :
procedure TForm1.FormDestroy(Sender: TObject); var FS:TFileStream; begin FS := TFileStream.Create('combobox1.res',fmCreate); try FS.WriteComponent(ComboBox1); finally FS.Free; end; end; procedure TForm1.FormCreate(Sender: TObject); var FS:TFileStream; begin if FileExists('combobox1.res') then begin FS := TFileStream.Create('combobox1.res',fmOpenRead); try FS.ReadComponent(ComboBox1); finally FS.Free; end; end; end; 看了一下, 有現成的 Procedure 可以用: procedure TForm1.FormDestroy(Sender: TObject); begin WriteComponentResFile('combobox1.res',combobox1); end; procedure TForm1.FormCreate(Sender: TObject); begin if FileExists('combobox1.res') then ReadComponentResFile('combobox1.res',combobox1); end;發表人 - Mickey 於 2004/05/18 09:06:02 |
Fishman
尊榮會員 發表:120 回覆:1949 積分:2163 註冊:2006-10-28 發送簡訊給我 |
Hi tommyli0913, 這裡有篇Justmade 版大的範例程式,你參考看看 【發表】在 Runtime 直接將資料存進 Exe
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=31613
----------------------------------
小弟才疏學淺,若有謬誤尚請不吝指教
----------------------------------
------
Fishman |
tommyli0913
一般會員 發表:9 回覆:19 積分:5 註冊:2004-02-02 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
Take a look at Orpheus http://sourceforge.net/projects/tporpheus/ There are components for properties storage, e.g. TOvcComponentState, TOvcFormState, TOvcPersistentState, TOvcRegistryStorage, TOvcIniFileStorage, etc.
|
Fishman
尊榮會員 發表:120 回覆:1949 積分:2163 註冊:2006-10-28 發送簡訊給我 |
Hi tommyli0913, 那天看了 Mickey 版大的寫法,興起了與你相同的問題,因此測了一下,已有初步做法,但是仍然有些許的問題,在此一併提出與大家共同探討 做法:
1.Override 該 form 的 Create 事件,並從存檔中讀出各個 Component 的屬性
2.Override 該 form 的 Detroy 事件進行存檔或刪檔(視該 Form 是否 Create 成功) 範例程式:
http://delphi.ktop.com.tw/loadfile.php?TOPICID=15806200&CC=353500 問題點:
1.Form Create 失敗會將屬性檔刪除,無法保留最後狀態
2.程式新增元件或刪除元件,即使程式已更新,但是仍然出來舊的畫面 不知各位大大是否有解?
----------------------------------
小弟才疏學淺,若有謬誤尚請不吝指教
----------------------------------
------
Fishman |
Mickey
版主 發表:77 回覆:1882 積分:1390 註冊:2002-12-11 發送簡訊給我 |
試試看:
procedure TForm1.FormDestroy(Sender: TObject); var FS:TFileStream; i:integer; begin FS := TFileStream.Create(Self.Name '.res', fmCreate); try for i := 0 to ComponentCount - 1 do FS.WriteComponentRes(Components[i].Name, Components[i]); finally FS.Free; end; end; procedure TForm1.FormCreate(Sender: TObject); var FS:TFileStream; i:integer; C:TComponent; begin if FileExists(Self.Name '.res') then begin FS := TFileStream.Create(Self.Name '.res',fmOpenRead); try for i := 0 to ComponentCount - 1 do begin try FS.ReadComponentRes(Components[i]); except end; end; finally FS.Free; end; end; end; 引言: 1.Form Create 失敗會將屬性檔刪除,無法保留最後狀態 2.程式新增元件或刪除元件,即使程式已更新,但是仍然出來舊的畫面1. try...except...end 可以 bypass 讀取 Resource 失敗的 TComponent. 2. 或許可以考慮 Resource File 的 File Name 中, 含入 EXE 的版本資訊. PS. 個人不太認同, 將 Resource 回存到 EXE File 中, 原因: 1. EXE 的版本...失去意義. 2. 再也無法"還原"到初始狀態. 發表人 - Mickey 於 2004/05/26 22:20:35 |
conundrum
尊榮會員 發表:893 回覆:1272 積分:643 註冊:2004-01-06 發送簡訊給我 |
|
Fishman
尊榮會員 發表:120 回覆:1949 積分:2163 註冊:2006-10-28 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |