全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1322
推到 Plurk!
推到 Facebook!

關於元件存放與讀取的一段程式碼,偵錯通不過

尚未結案
wnnnnnn6
一般會員


發表:5
回覆:11
積分:3
註冊:2004-11-24

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-11-27 13:12:36 IP:61.182.xxx.xxx 未訂閱
我做了一個MDI的程式,Form1是主窗體,Form2、Form3是子窗體,我想在Form2中名字是“保存”的元件項中寫程式碼,把Form2和裡面的元件保存起來,存放在硬碟上;在名字是“開啓”的元件項中寫程式碼,把上面儲存的Form2的介面開啓。爲此,我寫了下面的程式碼: //保存
var
  BinStream:TMemoryStream;
  i:integer;
begin
  if savedialog1.Execute then
  try
    BinStream:=TMemoryStream.Create;
    i:=form2.ComponentCount-1;
    for  i:=form2.ComponentCount-1 downto 0 do
    begin
    BinStream.WriteComponent(form2.Components[i]);
    end;
    BinStream.Seek(0, soFromBeginning);
    BinStream.SaveToFile( pchar(savedialog1.FileName));      finally
    BinStream.Free
  end;
end;
//開啓
var
  BinStream:TmemoryStream;
  i:integer;
begin
  BinStream := TmemoryStream.Create;
  if opendialog1.Execute then
  try       BinStream.LoadFromFile(pchar(opendialog1.FileName));
   BinStream.Seek(0, soFrombeginning);
   i:=form2.ComponentCount-1;
   for  i:=form2.ComponentCount-1 downto 1 do
   begin
   form2.Components[i].Free;
   end;
   for i:=0 to form2.ComponentCount-1 do
   binstream.ReadComponent(form2.Components[i]);      finally
   BinStream.Free
  end;
end;
現在的問題是:程式執行後,點“保存”時可以透過,沒問題; 點“開啓”卻出現出現了下面的問題: 1、Form2上面只顯示一個元件。這個程式顯示的是Lable1,別的元件都不顯示。如果讓Form2只剩Lable1元件, 則執行後Lable1的Caption內容值將顯示在Form2的標題列的位置; 2、Form2開啓後,按它上面的功能表項,都沒有反應; 3、如果再增加一個“結束”功能表項,則該功能表項的名字出現在Lable1的位置。 咄咄怪事!請幫我尋找一下原因吧,謝謝了!(爲了便於偵錯程式,窗體Form2上就有一個DBGrid可視控制項) 發表人 - wnnnnnn6 於 2004/11/27 13:19:53
hahalin
版主


發表:295
回覆:1698
積分:823
註冊:2002-04-14

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-11-27 20:15:52 IP:218.170.xxx.xxx 未訂閱
 readcomponent的作用是將現有的component重新讀入設定值     以您的例子來說     1.writecomponent一次只寫入一個component而已     2.將form2的component都free後,讀取進來也沒有目的地的component存在了.     delphi的help有這兩段code,給您參考看看    
    function ComponentToString(Component: TComponent): string;    var
  BinStream:TMemoryStream;
  StrStream: TStringStream;
  s: string;
begin
  BinStream := TMemoryStream.Create;
  try
    StrStream := TStringStream.Create(s);
    try
      BinStream.WriteComponent(Component);
      BinStream.Seek(0, soFromBeginning);
      ObjectBinaryToText(BinStream, StrStream);
      StrStream.Seek(0, soFromBeginning);
      Result:= StrStream.DataString;
    finally
      StrStream.Free;        end;
  finally
    BinStream.Free
  end;
end;    function StringToComponent(Value: string): TComponent;
var
  StrStream:TStringStream;
  BinStream: TMemoryStream;
begin
  StrStream := TStringStream.Create(Value);
  try
    BinStream := TMemoryStream.Create;
    try
      ObjectTextToBinary(StrStream, BinStream);
      BinStream.Seek(0, soFromBeginning);
      Result := BinStream.ReadComponent(nil);        finally
      BinStream.Free;
    end;
  finally
    StrStream.Free;
  end;
end;    
wnnnnnn6
一般會員


發表:5
回覆:11
積分:3
註冊:2004-11-24

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-11-28 09:10:14 IP:61.182.xxx.xxx 未訂閱
hahalin兄: 謝謝您!按照您的提示我做出來了。但我發現讀寫元件沒有實際的用途!讀寫元件只是把元件讀到檔案裡面,再取出來,跟直接開啓窗體顯示元件沒什麼兩樣。您說是嗎? 我還有一點不明白:1、讀寫元件時是把元件的內容、方法和事件都讀到檔案裡面了嗎?2、讀寫元件的操作物件能不能不能是窗體?
hahalin
版主


發表:295
回覆:1698
積分:823
註冊:2002-04-14

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-11-28 14:40:45 IP:218.170.xxx.xxx 未訂閱
你如果耐心看一下我從help抓出來貼上的code,應該就可以比較清楚一點了,讀就是讀,把設定值讀出來,寫就是寫,把設定值寫入, 操作的對象可以是窗體,Form也是TComponent的後代類別
wnnnnnn6
一般會員


發表:5
回覆:11
積分:3
註冊:2004-11-24

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-11-28 15:56:54 IP:61.182.xxx.xxx 未訂閱
我明白了,是把設定值寫入和讀出呀。下面是我把窗體FORM2中的元件寫入到文件和從文件中讀出的程式,執行沒問題。但我把操作物件該成窗體FORM2,就出問題了。您能幫我看看哪裡出錯嗎? 讀寫窗體FORM2中的元件的程式(這個沒有問題): procedure TForm2.N4Click(Sender: TObject); //保存 var BinStream:TMemoryStream; begin if savedialog1.Execute then try BinStream:=TMemoryStream.Create; BinStream.WriteComponent(form2.Image1); BinStream.WriteComponent(form2.Label1); BinStream.WriteComponent(form2.ComboBox1); BinStream.WriteComponent(form2.CheckBox1); BinStream.WriteComponent(form2.Label2); BinStream.Seek(0, soFromBeginning); BinStream.SaveToFile( pchar(savedialog1.FileName)); finally BinStream.Free end; end; procedure TForm2.N3Click(Sender: TObject); //打开 var BinStream:TmemoryStream; begin BinStream := TmemoryStream.Create; if opendialog1.Execute then try BinStream.LoadFromFile(pchar(opendialog1.FileName)); BinStream.Seek(0, soFrombeginning); binstream.ReadComponent(form2.Image1); BinStream.ReadComponent(Form2.Label1); BinStream.ReadComponent(form2.ComboBox1); BinStream.ReadComponent(form2.CheckBox1); BinStream.ReadComponent(form2.Label2); finally BinStream.Free end; end; 讀寫FORM2的程式: procedure TForm2.N4Click(Sender: TObject); //保存 var BinStream:TMemoryStream; begin if savedialog1.Execute then try BinStream:=TMemoryStream.Create; BinStream.WriteComponent(form2); BinStream.Seek(0, soFromBeginning); BinStream.SaveToFile( pchar(savedialog1.FileName)); finally BinStream.Free end; end; procedure TForm2.N3Click(Sender: TObject); //打开 var BinStream:TmemoryStream; begin BinStream := TmemoryStream.Create; if opendialog1.Execute then try BinStream.LoadFromFile(pchar(opendialog1.FileName)); BinStream.Seek(0, soFrombeginning); binstream.ReadComponent(form2); finally BinStream.Free end; end; 系統卻提示錯誤:元件已經存在;如果把元件釋放後,再讀出FORM2,則提示:List index out of bounds(5)。請問:這個該怎樣解決?怎樣能夠讀寫窗體FORM2呢?
hahalin
版主


發表:295
回覆:1698
積分:823
註冊:2002-04-14

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-11-28 21:42:29 IP:218.170.xxx.xxx 未訂閱
1.http://delphi.ktop.com.tw/topic.php?TOPIC_ID=7326 請記得要程式碼縮排 2.我自己所能理解的是 savecomponent只能針對單一的component來動作 至於form2的childcontorl是不能存入的 3.readcomponent的起動點放在form2之外,比較沒有問題.
wnnnnnn6
一般會員


發表:5
回覆:11
積分:3
註冊:2004-11-24

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-11-29 08:17:57 IP:61.182.xxx.xxx 未訂閱
您能否再詳細的說明一下?我對“至於form2的childcontorl是不能存入的”和“3.readcomponent的起動點放在form2之外,比較沒有問題.”還是有點不太理解。
hahalin
版主


發表:295
回覆:1698
積分:823
註冊:2002-04-14

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-11-29 08:39:32 IP:218.170.xxx.xxx 未訂閱
引言: 您能否再詳細的說明一下?我對“至於form2的childcontorl是不能存入的”和“3.readcomponent的起動點放在form2之外,比較沒有問題.”還是有點不太理解。
3.如果你讓form2上的button做某些事情來更新form2自己本身,這樣的設計比較容易有問題,最好用另外一個form來作啟動. 2.readcomponent只能針對單一component,因此讀取form後,只會讀取form自己本身的屬性,至於form上的物件,就不能讀到了.
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-11-29 09:09:17 IP:202.39.xxx.xxx 未訂閱
引言: 2.readcomponent只能針對單一component,因此讀取form後,只會讀取form自己本身的屬性,至於form上的物件,就不能讀到了.
小弟如果沒記錯的話, ReadComponent 不是只有讀 TForm 本身 Owner 為該 TForm 的 Component 也會 寫/讀 入 TMemoryStream.WriteComponent(Form1); // 把 Form1 與 Owner 為 Form1 的 Component 寫入 TMemoryStream 中 TMemoryStream.ReadComponent(Form1); // 自 TMemoryStream 讀入 Form1 與 Owner 為 Form1 的 Component 而 ReadComponent 或 WriteComponent 中的參數不一定是 TForm 像是 TPanel 也可以 也就是 WriteComponent 如果傳入 Panel1 的話 它會寫入 Panel1 與 Owner 為 Panel1 的 Component 和 TForm 不同的是 TForm 在 ReadComponent/WriteComponent 時除了可讀寫屬性外 也可讀寫 Event 而 TPanel 就沒辦法了, 須要額外手動來讀寫 如果搞錯了, 還請不吝指正!
hahalin
版主


發表:295
回覆:1698
積分:823
註冊:2002-04-14

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-11-29 15:55:38 IP:218.170.xxx.xxx 未訂閱
那請hagar幫忙這位同學解答疑惑了 小弟也可以把握這個機會多參考多學習了...
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-11-29 18:00:53 IP:202.39.xxx.xxx 未訂閱
hahalin 客氣了!  一個一個
hahalin
版主


發表:295
回覆:1698
積分:823
註冊:2002-04-14

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-11-29 20:42:32 IP:218.170.xxx.xxx 未訂閱
一次存取一個form我也有實做經驗 不過 我用dreamcontrol...
hahalin
版主


發表:295
回覆:1698
積分:823
註冊:2002-04-14

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-11-29 20:50:44 IP:218.170.xxx.xxx 未訂閱
最近也在測試LMD的design元件 也不錯 錢花下去,都馬不錯..... 不過 如果只想依賴元件 似乎有失programmer的傲骨
wnnnnnn6
一般會員


發表:5
回覆:11
積分:3
註冊:2004-11-24

發送簡訊給我
#14 引用回覆 回覆 發表時間:2004-12-01 10:01:00 IP:61.182.xxx.xxx 未訂閱
hagar和hahalin 兩位仁兄: 你們都有一次讀寫一個TForm的實做經驗,能否給我一個例子?我做的一次讀寫一個TForm的例子都在上面了,執行通不過,也不知道該怎樣改,不知能否得到兩位仁兄的指教?這裡就先謝謝了!
hahalin
版主


發表:295
回覆:1698
積分:823
註冊:2002-04-14

發送簡訊給我
#15 引用回覆 回覆 發表時間:2004-12-01 10:17:48 IP:218.170.xxx.xxx 未訂閱
1.dream control:dream designer http://www.dream-com.com/designer.html 2.Lmd http://www.lmdinnovative.com/mfs/products/LMDDsg20.php 自己下載試用版下來try try 囉... 總不好我在這幫忙示範如何使用dream control跟LMD吧...
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#16 引用回覆 回覆 發表時間:2004-12-02 21:22:10 IP:202.39.xxx.xxx 未訂閱
引言: hagar和hahalin 兩位仁兄: 你們都有一次讀寫一個TForm的實做經驗,能否給我一個例子?我做的一次讀寫一個TForm的例子都在上面了,執行通不過,也不知道該怎樣改,不知能否得到兩位仁兄的指教?這裡就先謝謝了!
程式碼看來沒問題, 您可以將 Source 上傳到會員求助區. 小弟就用如下的樣子寫, 並不會 List Index out of bounds 的 error
procedure TfrmMain.mmiReadClick(Sender: TObject);
var
  c: TComponent;
  i: integer;
  ms: TMemoryStream;
begin
  ms := TMemoryStream.Create;
  try
    for i := ComponentCount - 1 downto 0 do
    begin
      c := Components[i];
      FreeAndNil(c);
    end;        ms.LoadFromFile('C:\test.bin');
    ms.Position := 0;
    ms.ReadComponent(Self);
  finally
    ms.Free;
  end;
end;    procedure TfrmMain.mmiWriteClick(Sender: TObject);
var
  ms: TMemoryStream;
begin
  btnCompressMdb.Caption := 'Compress Access Mdb';      ms := TMemoryStream.Create;
  try
    ms.WriteComponent(Self);
    ms.Position := 0;
    ms.SaveToFile('C:\test.bin');
  finally
    ms.Free;
  end;
end;
系統時間:2024-07-06 18:12:11
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!