線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2669
推到 Plurk!
推到 Facebook!

請問如何存取元件屬性,不是用文字檔或資料庫的方法的方法?

尚未結案
tommyli0913
一般會員


發表:9
回覆:19
積分:5
註冊:2004-02-02

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-05-17 18:38:24 IP:211.76.xxx.xxx 未訂閱
各位先進大大,小弟有一個奇怪的問題,就是我在form上有一個TComboBox及一個TImage元件,此程式每次開啟或關閉時就必須將最後一次的值打開或儲存起來。目前我是將這些元件的屬性用AssignFile 儲存到一個文字檔,另外我也曾經將這些屬性儲到access資料庫中,但是這些地方很容易被使用者打開來修改而造成程式無法正常開啟。 所以我想是否有什麼方法可以將這些元件屬性直接儲存到一個安全的地方且不要像"儲存文字檔"方式一定要用while迴圈將參數一行一行Writeln到文字檔中。在開始程式時也不想要像"開啟檔案"方式一定要用while迴圈將參數一行一行讀出並放入元件屬性中,最好能關閉程式時一次就將屬性自動儲存起來,開啟程式時一次就將屬性自動放到它該放的地方。 我的問題比較奇怪些,希望各位先進大大能指點小弟一下,謝謝啦!
bigdogchina
版主


發表:238
回覆:523
積分:312
註冊:2003-04-28

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-05-17 22:50:34 IP:211.162.xxx.xxx 未訂閱
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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-05-18 08:31:13 IP:218.163.xxx.xxx 未訂閱
可以參考運用 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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-05-18 08:36:48 IP:210.65.xxx.xxx 未訂閱
Hi tommyli0913,    這裡有篇Justmade 版大的範例程式,你參考看看    【發表】在 Runtime 直接將資料存進 Exe  http://delphi.ktop.com.tw/topic.php?TOPIC_ID=31613 ---------------------------------- 小弟才疏學淺,若有謬誤尚請不吝指教 ----------------------------------
------
Fishman
tommyli0913
一般會員


發表:9
回覆:19
積分:5
註冊:2004-02-02

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-05-19 15:15:04 IP:211.76.xxx.xxx 未訂閱
對不起,昨兩天比較忙來晚了,bigdogchina大大您的方法跟小弟目前的方法是很接近的,所以我覺得不太好用說< >。 >,原來圖檔及一些資料也可以直接放入執行檔中說,不過因為小弟目前功力還沒很夠,所以那些方法還不太知道要如何放入我的程式中,不過我正在努力研究中!< >
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-05-19 16:25:09 IP:147.8.xxx.xxx 未訂閱
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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-05-21 13:52:27 IP:210.65.xxx.xxx 未訂閱
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

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-05-26 22:05:36 IP:218.32.xxx.xxx 未訂閱
試試看:
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

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-05-26 22:44:06 IP:61.64.xxx.xxx 未訂閱
個人想法 土法練剛 類似語系的作法 或參考此篇 運用一下 【發表】網咖管理金剛組合版 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=28622 喝喝 庵 標題沒看清楚 不使用外部檔 出槌 不過如果不讓使用者知道 就加個密把 aes 演算 發表人 - conundrum 於 2004/05/26 23:12:44
Fishman
尊榮會員


發表:120
回覆:1949
積分:2163
註冊:2006-10-28

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-05-28 09:28:45 IP:210.65.xxx.xxx 未訂閱
Hi Mickey 版大,    經測試後沒有問題    崇拜你!感謝你!
------
Fishman
系統時間:2024-05-03 23:33:55
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!