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

關於Package使用時class name開啟表單uses時會發生錯誤!?

尚未結案
skurama
中階會員


發表:88
回覆:127
積分:73
註冊:2002-07-22

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-05-19 10:36:53 IP:61.219.xxx.xxx 未訂閱
請問:    我目前使用Packages來開啟表單,以下function是修改K.top上的範例的 用Class Name建立表單的Function:
//*****************************************
//以註冊名稱,建立DataModule
//*****************************************
function CreateDataModuleByClassName(const ClassName: string): TDataModule;
var dmTemp: TDataModule;
    AClass: TPersistentClass;
begin
  AClass := GetClass(ClassName);
  if (AClass <> nil) then begin
     dmTemp := TComponentClass(AClass).Create(Application) as TDataModule;
     Result := dmTemp;
  end else begin
     //如果找不到該集合名稱,具顯示錯誤錯息
     raise Exception.CreateFmt('無法建立DataModule!'   #13#10   '類別 %s 尚未註冊', [ClassName]);
  end;
end;    //*****************************************
//以註冊名稱,建立表單
//*****************************************
//ClassName : 要被建立的表單名稱
//OpenForm : 目前表單的名稱
//DMClassName : 要開啟的DataModule名稱
procedure CreateFormByClassName(const ClassName: string; OpenForm : TForm; DMClassName : string = '');
var
  AClass: TPersistentClass;
  AForm : TCustomForm;
  ADataModule   : TDataModule;
begin
  ADataModule := nil;
  AForm := nil;      If DMClassName <> '' then         //如果使用者有傳入DataModule時,則先建立DataModule
     ADataModule := CreateDataModuleByClassName(DMClassName);      AClass := GetClass(ClassName);    
  
  if AClass <> nil then begin
     try
        AForm := TControlClass(AClass).Create(Application) as TCustomForm;
        TForm(OpenForm).Hide;
        AForm.ShowModal;
     finally
        TForm(OpenForm).Show;
        AForm.Free;
     End;
  End else
     raise Exception.CreateFmt('無法建立視窗!'   #13#10   '類別 %s 尚未註冊', [ClassName]);      if Assigned(ADataModule) then
     ADataModule.Free;
end;
在我現Load 該Package後, 在MainForm建立FD15(TForm)與FD15DMUnit(TDataModule), CreateFormByClassName('TFD15Form',self,'TFD15DMUnit'); 我確定是先建立dataModule在建立FD15, 並在FD15有use FD15DMUnit, 可是在FD15的Form Show中,我下 FD15DMUnit.Query1.Open; <---- 出現記憶體錯誤。 Access violation at address 036B2D73 in module 'DevelopPkg.bpl' 可是如果把這一行註解掉後可以執行, 表單上的欄位也可以取得該DataModule上Query的資料。 但只要自己下FD15DMUnit.Query1.Open,就會Error, 請問有什麼解決方法,TFD15DMUnit(FD15DMUint).Query1.Open; 我也試過但還是不行。 但如果在Form Create時,自己用 FD15DMUnit := TDataModule.create(application); FD15DMUnit.query1.Open; showmessage(FD15DMUnit.query1.fieldbyname('pk').AsString); 的話就不會錯, 請問為什麼用ClassName建立的DataModule就會能在其他的表單使用, 而使用自己建立的DataModule則可以使用該dataModule中的元件。 有沒有什麼方法是可以ClassName建立但不會發生錯誤的方法。 因為不能在MainForm直接Use其他Package的表單, 要不然主檔仍然會變和大就失去Package的意義了。 可是如果要每次在Form Create自己要去下建立DataModule的話, 自己又決得很麻煩,想說直接呼叫CreateFormByClassName的function, 一次全部都可以啟動的話比較方便。 重點是有些Query必需在Form被建立之前就必需先被啟動。 所以如果是在Form的create時才自己建立DataModule, 則會發生找不到要啟動的Query的資料。 請問有人有遇過這個問題嗎~謝謝? ---------------- 快滿一年程設師, 日日工作寫程式, 每買樂透眼框溼, 望能早成系分師。 ----------------
------
----------------
初出芧房程設師,
左鍵右鼠寫程式,
日扣夜寫眼框溼,
望能早成系分師。
----------------
danny
版主


發表:100
回覆:522
積分:595
註冊:2002-03-11

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-05-19 11:02:14 IP:211.76.xxx.xxx 未訂閱
引言: 我目前使用Packages來開啟表單,以下function是修改K.top上的範例的 用Class Name建立表單的Function:
使用 Delphi Package 有一點要注意(我想Samples裡也是這樣寫, 您可能沒注意到) TFD15DMUnit(FD15DMUnit).Query1.Open 紅色部份是 Class Name, 至於為何要這樣作 ? 我也不知道, 只是這樣才能使用.
------
將問題盡快結案也是一種禮貌!
skurama
中階會員


發表:88
回覆:127
積分:73
註冊:2002-07-22

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-05-19 11:38:44 IP:61.219.xxx.xxx 未訂閱
嗯~~ 有啊,在倒數第十九行(不含簽名檔與空白行), 我也是有試過, 可是仍然是會出現記憶體位址的錯誤~~ 還有其他辦法嗎? ---------------- 快滿一年程設師, 日日工作寫程式, 每買樂透眼框溼, 望能早成系分師。 ----------------
------
----------------
初出芧房程設師,
左鍵右鼠寫程式,
日扣夜寫眼框溼,
望能早成系分師。
----------------
danny
版主


發表:100
回覆:522
積分:595
註冊:2002-03-11

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-05-19 11:55:56 IP:211.76.xxx.xxx 未訂閱
引言: 嗯~~ 有啊,在倒數第十九行(不含簽名檔與空白行), 我也是有試過, 可是仍然是會出現記憶體位址的錯誤~~ 還有其他辦法嗎?
您可以提供比較完整的 Source code 嗎 ? 因為我看不出來您是在那裡 Create DataModule 的. 記得要用〔code〕及〔/code〕(以上記得要用半型字體)將 source code 包起來, 這樣才會容易看程式.
------
將問題盡快結案也是一種禮貌!
skurama
中階會員


發表:88
回覆:127
積分:73
註冊:2002-07-22

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-05-19 13:35:50 IP:61.219.xxx.xxx 未訂閱
在MainForm上一個按鈕建立FD15Form以及FD15DMUnit procedure TMainForm.Button5Click(Sender: TObject); begin CreateFormByClassName('TFD15Form',self,'TFD15DMUnit'); end; 呼叫CreateFormByClassName: procedure CreateFormByClassName(const ClassName: string; OpenForm : TForm; DMClassName : string = ''); var AClass: TPersistentClass; AForm : TCustomForm; ADataModule : TDataModule; begin ADataModule := nil; AForm := nil; If DMClassName <> '' then //如果使用者有傳入DataModule時,則先建立DataModule ADataModule := CreateDataModuleByClassName(DMClassName); AClass := GetClass(ClassName); if AClass <> nil then begin try AForm := TControlClass(AClass).Create(Application) as TCustomForm; TForm(OpenForm).Hide; AForm.ShowModal; finally TForm(OpenForm).Show; AForm.Free; End; End else raise Exception.CreateFmt('無法建立視窗!' #13#10 '類別 %s 尚未註冊', [ClassName]); if Assigned(ADataModule) then ADataModule.Free; end; 其中會呼叫 function CreateDataModuleByClassName(const ClassName: string): TDataModule; var dmTemp: TDataModule; AClass: TPersistentClass; begin AClass := GetClass(ClassName); if (AClass <> nil) then begin dmTemp := TComponentClass(AClass).Create(Application) as TDataModule; Result := dmTemp; end else raise Exception.CreateFmt('無法建立DataModule!' #13#10 '類別 %s 尚未註冊', [ClassName]); end; 而之後會先建立FD15DMUnit,在建立FD15Form, 之後在FD15Form的OnCreate出現錯誤 procedure TFD15Form.FormCreate(Sender: TObject); begin TFD15DMUnit(FD15DMUnit).qryFB05.Open; <--//Error end; LoadPackage的語法和K.Top上的語法一樣~~~ 發表人 - skurama 於 2003/05/19 13:45:50
------
----------------
初出芧房程設師,
左鍵右鼠寫程式,
日扣夜寫眼框溼,
望能早成系分師。
----------------
danny
版主


發表:100
回覆:522
積分:595
註冊:2002-03-11

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-05-19 14:34:12 IP:211.76.xxx.xxx 未訂閱
引言: 在MainForm上一個按鈕建立FD15Form以及FD15DMUnit procedure TMainForm.Button5Click(Sender: TObject); begin CreateFormByClassName('TFD15Form',self,'TFD15DMUnit'); end; 呼叫CreateFormByClassName: procedure CreateFormByClassName(const ClassName: string; OpenForm : TForm; DMClassName : string = ''); var AClass: TPersistentClass; AForm : TCustomForm; ADataModule : TDataModule; begin ADataModule := nil; AForm := nil; If DMClassName <> '' then //如果使用者有傳入DataModule時,則先建立DataModule ADataModule := CreateDataModuleByClassName(DMClassName); AClass := GetClass(ClassName); if AClass <> nil then begin try AForm := TControlClass(AClass).Create(Application) as TCustomForm; TForm(OpenForm).Hide; AForm.ShowModal; finally TForm(OpenForm).Show; AForm.Free; End; End else raise Exception.CreateFmt('無法建立視窗!' #13#10 '類別 %s 尚未註冊', [ClassName]); if Assigned(ADataModule) then ADataModule.Free; end; 其中會呼叫 function CreateDataModuleByClassName(const ClassName: string): TDataModule; var dmTemp: TDataModule; AClass: TPersistentClass; begin AClass := GetClass(ClassName); if (AClass <> nil) then begin dmTemp := TComponentClass(AClass).Create(Application) as TDataModule; Result := dmTemp; end else raise Exception.CreateFmt('無法建立DataModule!' #13#10 '類別 %s 尚未註冊', [ClassName]); end; 而之後會先建立FD15DMUnit,在建立FD15Form, 之後在FD15Form的OnCreate出現錯誤 procedure TFD15Form.FormCreate(Sender: TObject); begin TFD15DMUnit(FD15DMUnit).qryFB05.Open; <--//Error end;
請問您上面這行 FD15Form 是憑什麼知道 FD15DMUnit 的 ? 您產生 FD15Form 也沒有告訴它 FD15DMUnit 的存在啊! 除非 CreateDataModuleByClassName(此 function 有傳回 DataModule) 時要將此 DataModule 告訴 FD15Form. 您這二個 function 如果沒記錯應該是改自我寫的文章, 不過顯然您還不瞭解其意思. 如果要照您原來的方法也可以, 不過要用到 RTTI 的方式將 DataModule 告訴 FD15Form, 這部份請參考 Justmade 版主寫的 "如何欺騙 Delphi 將一般獨立 procedure 指給 Evnet" 另一個方法是 DataModule 在 FD15Form 的 OnCreate 中才 Create DataModule.
------
將問題盡快結案也是一種禮貌!
skurama
中階會員


發表:88
回覆:127
積分:73
註冊:2002-07-22

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-05-19 16:35:41 IP:61.219.xxx.xxx 未訂閱
我原本以為在FD15的Form有Use到該DataModule, 並且利用ClassName建立該DataModule, 該DataModule中的 Var FD15DMUnit : TDataModule中的FD15DMUnit就可以使用。 請問是不是雖然使用CreateDataModuleByClassName建立FD15DMunit, 但是在FD15DMunit的變數FD15DMUnit其實還是指向一個nil, 所以在這個時候跟他要資料的話,就會發生錯誤? 是這個樣子嗎? 對不起,我找不到justmade大大的 ”如何欺騙 Delphi 將一般獨立 procedure 指給 Evnet” 請問大概在哪一個單元,我直接貼在查詢的地方也是沒有辦法找到資料。 ---------------- 快滿一年程設師, 日日工作寫程式, 每買樂透眼框溼, 望能早成系分師。 ---------------- 發表人 - skurama 於 2003/05/19 16:58:24
------
----------------
初出芧房程設師,
左鍵右鼠寫程式,
日扣夜寫眼框溼,
望能早成系分師。
----------------
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-05-19 18:39:06 IP:218.16.xxx.xxx 未訂閱
試試在 FD15Form (及其他所有這類形的 Form) 加一個public變數,叫 myDM (名稱隨意)    定議可以是    myDM : TDataModule; (各 Form 定義一樣但用時要 Type 比較煩) 或 myDM := FD15DMUnit; (各 Form 不同定義但用使直接使用較方便)
uses TypInfo    procedure CreateFormByClassName(const ClassName: string; OpenForm : TForm; DMClassName : string = '');
var
   AClass: TPersistentClass;
   AForm : TCustomForm;
   ADataModule : TDataModule;
begin
   ADataModule := nil;
   AForm := nil;
   If DMClassName <> '' then //如果使用者有傳入DataModule時,則先建立DataModule
      ADataModule := CreateDataModuleByClassName(DMClassName);
   AClass := GetClass(ClassName); 
   if AClass <> nil then begin
      try
         AForm := TControlClass(AClass).Create(Application) as TCustomForm;
          SetObjectProp(AForm,'myDM',ADataModule);
         TForm(OpenForm).Hide;
         AForm.ShowModal;
      finally
         TForm(OpenForm).Show;
         AForm.Free;
      End;
   End else
      raise Exception.CreateFmt('無法建立視窗!'   #13#10   '類別 %s 尚未註冊', [ClassName]);
   if Assigned(ADataModule) then
      ADataModule.Free;
end;
這方法不知成不成,你可以試試,不成別罵我喔 另,”如何欺騙
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-05-19 18:41:45 IP:218.16.xxx.xxx 未訂閱
忘了說 ,這裡也要改 :
procedure TFD15Form.FormShow(Sender: TObject);
begin
   TFD15DMUnit(myDM).qryFB05.Open; //若 myDM : TDataModule
//or
// myDM.qryFB05.Open;   //若 myDM : TFD15DMUnit
end;
發表人 - Justmade 於 2003/05/19 18:43:33
skurama
中階會員


發表:88
回覆:127
積分:73
註冊:2002-07-22

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-05-20 10:51:36 IP:61.219.xxx.xxx 未訂閱
對不請~~ 再請問一下: SetObjectProp要查哪一個Help啊, 我看Delphi help, Delphi Tool, Windows SDK都找不到資料。 請問要查哪一個Help的資料? ---------------- 快滿一年程設師, 日日工作寫程式, 每買樂透眼框溼, 望能早成系分師。 ----------------
------
----------------
初出芧房程設師,
左鍵右鼠寫程式,
日扣夜寫眼框溼,
望能早成系分師。
----------------
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-05-20 11:25:06 IP:218.16.xxx.xxx 未訂閱
Help 沒的.... 你可在 本站 / google 輸入 RTTI 來找資料,也有不少有用的 在這裡 ccchen / 阿子副站 / axsoft / william / timhuang 等等都是此道高手(還有一些我不知道的),我也是初學跟他們學了不少
系統時間:2024-05-15 17:56:01
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!