可以封裝數個Form在一個DLL檔嗎 |
尚未結案
|
bill534
一般會員 發表:38 回覆:51 積分:17 註冊:2007-02-22 發送簡訊給我 |
|
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
|
bill534
一般會員 發表:38 回覆:51 積分:17 註冊:2007-02-22 發送簡訊給我 |
library gs1_1;
uses SysUtils, Classes, forms, Windows, Controls, ShareMem, exports gs1EmbeddedFormToPanel index 1, initApplication index 2; //var // OldDllAPP: TApplication; procedure DllEnterPoint(Reason: Integer); begin case Reason of DLL_PROCESS_ATTACH: begin OldDllAPP := Application; end; DLL_PROCESS_DETACH: begin Application := OldDllAPP; end; end; end; begin //DLLProc := @DLLEnterPoint; //DllEnterPoint(DLL_PROCESS_ATTACH); end. unit gs1_forms1; interface uses SysUtils, Classes, Controls, forms, ExtCtrls, gs1_p1, gs1_p101, gs1_p102, gs1_p201, gs1_p406, gs1_p407, gs1_p501, gs1_p502, gs1_p503, gs1_p504, gs1_p506, gs1_p507, gs1_p508, gs1_p509, gs1_p601; // Declare the export function of windows of the main DLL procedure initApplication(AHandle: THandle);StdCall; function gs1EmbeddedFormToPanel(pform: integer; ppanel: Tpanel): Pointer; Stdcall; implementation var gs1Form1: TForm; AppHandle: THandle; procedure initApplication(AHandle: THandle); begin AppHandle := AHandle; end; function gs1EmbeddedFormToPanel(pform: integer; ppanel: Tpanel): Pointer; begin if gs1Form1 <> nil then gs1Form1.Close; if pform = 1 then gs1Form1 := Tfmgs1_p1.Create(application) else if pform = 101 then gs1Form1 := Tfmgs1_p101.Create(application) else if pform = 102 then gs1Form1 := Tfmgs1_p102.Create(application) else if pform = 103 then begin end else if pform = 104 then begin end else if pform = 105 then begin end else if pform = 106 then begin end else if pform = 107 then begin end else if pform = 201 then gs1Form1 := Tfmgs1_p201.Create(application) else if pform = 406 then gs1Form1 := Tfmgs1_p406.Create(application) else if pform = 407 then gs1Form1 := Tfmgs1_p407.Create(application) else if pform = 501 then gs1Form1 := Tfmgs1_p501.Create(application) else if pform = 502 then gs1Form1 := Tfmgs1_p502.Create(application) else if pform = 503 then gs1Form1 := Tfmgs1_p503.Create(application) else if pform = 504 then gs1Form1 := Tfmgs1_p504.Create(application) else if pform = 506 then gs1Form1 := Tfmgs1_p506.Create(application) else if pform = 507 then gs1Form1 := Tfmgs1_p507.Create(application) else if pform = 508 then gs1Form1 := Tfmgs1_p508.Create(application) else if pform = 509 then gs1Form1 := Tfmgs1_p509.Create(application) else if pform = 601 then gs1Form1 := Tfmgs1_p601.Create(application); gs1Form1.Parent := ppanel; gs1Form1.Align := alclient; gs1Form1.BorderStyle := bsNone; gs1Form1.Show; gs1Form1.Visible := true; result := gs1Form1; end; initialization gs1Form1 := nil; finalization end. |
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
建議不要使用 Application 這一類原生全域物件在 DLL 中
DLL 是設計給各種不同編譯結構的程式使用,有其通用性的考量 盡量只使用指標與簡單格式 xxx.Dear 各Form先畫好,在Dll Unit內提供呼叫函數,實作在gs1_forms1(標紅字) gs1_forms1, gs1_p601 in 'gs1_p601.pas' {fmgs1_p601}, gs1_p1 in 'gs1_p1.pas' {fmgs1_p1}, gs1_p101 in 'gs1_p101.pas' {fmgs1_p101}, gs1_p102 in 'gs1_p102.pas' {fmgs1_p102}, gs1_p201 in 'gs1_p201.pas' {fmgs1_p201}, gs1_p406 in 'gs1_p406.pas' {fmgs1_p406}, gs1_p407 in 'gs1_p407.pas' {fmgs1_p407}, gs1_p501 in 'gs1_p501.pas' {fmgs1_p501}, gs1_p502 in 'gs1_p502.pas' {fmgs1_p502}, gs1_p503 in 'gs1_p503.pas' {fmgs1_p503}, gs1_p504 in 'gs1_p504.pas' {fmgs1_p504}, gs1_p506 in 'gs1_p506.pas' {fmgs1_p506}, gs1_p507 in 'gs1_p507.pas' {fmgs1_p507}, gs1_p508 in 'gs1_p508.pas' {fmgs1_p508}, gs1_p509 in 'gs1_p509.pas' {fmgs1_p509}; {$R *.res} // 上述檔案的gs1EmbeddedFormToPanel等,定義在下檔內 gs1Form1.Show; gs1Form1.Visible := true; result := gs1Form1; end; initialization gs1Form1 := nil; finalization end. |
bill534
一般會員 發表:38 回覆:51 積分:17 註冊:2007-02-22 發送簡訊給我 |
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
其實不是很清楚你這樣的寫法call form 真正的目的在那裡, 按我看來,
你這樣的做法, 不如直接以 main form 來架構你底下所有的form, 就樣就直接是delphi 最原始的寫作來執行了, 一樣達到你要call form 的方式 也不會造成很多奇怪的問題! ===================引 用 bill534 文 章=================== library gs1_1; uses ??? SysUtils, ??? Classes, ??? forms, ??? Windows, ??? Controls, ??? ShareMem, ??? exports ??? gs1EmbeddedFormToPanel index 1, initApplication index 2; //var //??? OldDllAPP: TApplication; procedure DllEnterPoint(Reason: Integer); begin ??? case Reason of ??? DLL_PROCESS_ATTACH: ??? begin ??? OldDllAPP := Application; ??? end; ??? DLL_PROCESS_DETACH: ??? begin ??? Application := OldDllAPP; ??? end; ??? end; end; begin ??? //DLLProc := @DLLEnterPoint; ??? //DllEnterPoint(DLL_PROCESS_ATTACH); end. unit gs1_forms1; interface uses ??? SysUtils, Classes, Controls, forms, ExtCtrls, ??? gs1_p1, ??? gs1_p101, gs1_p102, ??? gs1_p201, ??? gs1_p406, gs1_p407, ??? gs1_p501, gs1_p502, gs1_p503, gs1_p504, gs1_p506, gs1_p507, gs1_p508, gs1_p509, ??? gs1_p601; // Declare the export function of windows of the main DLL procedure initApplication(AHandle: THandle);StdCall; function gs1EmbeddedFormToPanel(pform: integer; ppanel: Tpanel): Pointer; Stdcall; implementation var ??? gs1Form1: TForm; ??? AppHandle: THandle; procedure initApplication(AHandle: THandle); begin ??? AppHandle := AHandle; end; function gs1EmbeddedFormToPanel(pform: integer; ppanel: Tpanel): Pointer; begin ??? if gs1Form1 <> nil then ??? gs1Form1.Close; ??? if pform = 1 then ??? gs1Form1 := Tfmgs1_p1.Create(application) ??? else if pform = 101 then ??? gs1Form1 := Tfmgs1_p101.Create(application) ??? else if pform = 102 then ??? gs1Form1 := Tfmgs1_p102.Create(application) ??? else if pform = 103 then ??? begin ??? end ??? else if pform = 104 then ??? begin ??? end ??? else if pform = 105 then ??? begin ??? end ??? else if pform = 106 then ??? begin ??? end ??? else if pform = 107 then ??? begin ??? end ??? else if pform = 201 then ??? gs1Form1 := Tfmgs1_p201.Create(application) ??? else if pform = 406 then ??? gs1Form1 := Tfmgs1_p406.Create(application) ??? else if pform = 407 then ??? gs1Form1 := Tfmgs1_p407.Create(application) ??? else if pform = 501 then ??? gs1Form1 := Tfmgs1_p501.Create(application) ??? else if pform = 502 then ??? gs1Form1 := Tfmgs1_p502.Create(application) ??? else if pform = 503 then ??? gs1Form1 := Tfmgs1_p503.Create(application) ??? else if pform = 504 then ??? gs1Form1 := Tfmgs1_p504.Create(application) ??? else if pform = 506 then ??? gs1Form1 := Tfmgs1_p506.Create(application) ??? else if pform = 507 then ??? gs1Form1 := Tfmgs1_p507.Create(application) ??? else if pform = 508 then ??? gs1Form1 := Tfmgs1_p508.Create(application) ??? else if pform = 509 then ??? gs1Form1 := Tfmgs1_p509.Create(application) ??? else if pform = 601 then ??? gs1Form1 := Tfmgs1_p601.Create(application); ??? gs1Form1.Parent := ppanel; ??? gs1Form1.Align := alclient; ??? gs1Form1.BorderStyle := bsNone; ??? gs1Form1.Show; ??? gs1Form1.Visible := true; ??? result := gs1Form1; end; initialization ??? gs1Form1 := nil; finalization end. |
bill534
一般會員 發表:38 回覆:51 積分:17 註冊:2007-02-22 發送簡訊給我 |
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
這是我一直在使用的方式, 參考看看吧!
建立一個 dll application [code delphi] library Pos; { Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. } uses FastShareMem, ExceptionLog, SysUtils, Classes, DLLver in '..\..\Dll_UT\DLLver.pas', U_VarDef in '..\..\Dll_UT\U_VarDef.pas', U_IBnet in '..\..\Dll_UT\U_IBnet.pas', U_Net in '..\..\Dll_UT\U_Net.pas', UT_SYS in '..\..\Dll_UT\UT_SYS.pas' {SysUT}, P_GetDate in '..\..\Dll_UT\P_GetDate.pas' {Form_GetDate}, P_IBSQLorder in '..\..\Dll_UT\P_IBSQLorder.pas' {Form_IBSQLorder}, ..... 中間太多了, 略... P_PosPrint in '..\Delphi5\P_PosPrint.pas' {Form_PosPrint}, P_PosSourceNo in '..\Delphi5\P_PosSourceNo.pas' {Form_SourceNo}, P_PosSeekstg in '..\Delphi5\P_PosSeekstg.pas' {Form_PosSeekstg}, P_AnslyDP001 in '..\Delphi5\P_AnslyDP001.pas' {Form_DP001show}, P_PosEmppass in '..\Delphi5\P_PosEmppass.pas' {Form_Emppass}, P_OverDate in '..\Delphi5\P_OverDate.pas' {Form_OverDate}, P_FingerInput in '..\Delphi5\P_FingerInput.pas' {Form_FingerInput}, P_UserCheck in '..\Delphi5\P_UserCheck.pas' {Form_UserCheck}, P_PosShowTemp in '..\Delphi5\P_PosShowTemp.pas' {Form_PosShowTemp}, D_Pos in 'D_Pos.pas'; exports DLL_Pos; begin end. [/code] 這是由上支程式去呼叫一支 unit , 有點類似 main form (但不是form), 但裡面也包了數個form [code delphi] unit D_Pos; interface uses Windows, SysUtils, Forms, Classes, StdCtrls, ExtCtrls, Controls, Graphics, ini; function DLL_Pos(dAlias, diniFile, dLoginAry, dDLLpath, eVar5: variant): boolean; stdcall; implementation uses DLLver, U_VarDef, U_Default, UT_SYS, DM_PosPhraseDBF, DM_PosDBF, DM_PosLockDBF, DM_IOrwDBF, DM_IOrwsDBF, DM_PartPosDBF, DM_PartPosLockDBF, DM_PartUpdDBF, DM_LogDBF, P_DateSet, P_UserIBfunc, P_Pos; // 收銀機作業 function DLL_Pos(dAlias, diniFile, dLoginAry, dDLLpath, eVar5: variant): boolean; var sfile, dfile: string; Form1: TForm; Label1: TLabel; Button1, Button2: TButton; Panel1: TPanel; iKey: string; i: integer; overtime: integer; nowtime: integer; begin DLLver.nDLLver:= 'V09.01.014'; DLLver.DebugSL:= TStringList.Create; SysUt:= TSysUt.Create(nil); SysUt.MsgDialog('系統參數資料庫開啟中...請稍候'); sfile:= ExtractFilePath(trim(readINI('DATA','PATHBASIC'))) 'Basic.gd_'; dfile:= trim(readINI('DATA','PATHBASIC')); iKey:= 'Continue'; if (U_Default.SRVrecord.DataIP<>'127.0.0.1') and (U_Default.SRVrecord.DataIP<>'') and (not U_Default.IBfrom.IO) then begin Form1:= TForm.Create(nil); Form1.Height:= 320; Form1.Width:= 380; Form1.Caption:= '系統警告訊息'; Form1.BorderStyle:= bsSingle; Form1.BorderIcons:= []; Form1.Position:= poScreenCenter; Form1.Font.Name:= '細明體'; Form1.Font.Size:= 14; Panel1:= TPanel.Create(Form1); Panel1.Parent:= Form1; Panel1.Height:= 50; Panel1.Align:= alBottom; Label1:= TLabel.Create(Form1); Label1.Parent:= Form1; Label1.Color:= clBlack; Label1.Font.Color:= clRed; Label1.Font.Style:= [fsBold]; Label1.Align:= alClient; Label1.Alignment:= taLeftJustify; Label1.Layout:= tlCenter; Label1.AutoSize:= True; Label1.Caption:= ' ▁▂▃警告▃▂▁' #13 #13 ' 開出的交易資料將無法送回主機'; Button1:= TButton.Create(Form1); Button1.Parent:= Panel1; Button1.Font.Size:= 9; Button1.Caption:= '結束'; Button1.Height:= 40; Button1.Width:= 80; Button1.Top:= 5; Button1.Left:= 10; Button1.ModalResult:= mrCancel; Button2:= TButton.Create(Form1); Button2.Parent:= Panel1; Button2.Font.Size:= 9; Button2.Caption:= '繼續'; Button2.Height:= 40; Button2.Width:= 80; Button2.Top:= 5; Button2.Left:= 280; Button2.ModalResult:= mrOK; case Form1.ShowModal of mrOK :iKey:= 'Continue'; mrCancel:iKey:= 'Terminate'; end; // 記錄異常事件 DM_Log:= TDM_Log.Create(nil); end; if iKey<>'Terminate' then begin SysUt.MsgDialog('收銀資料庫開啟中...請稍候'); DM_PosLock := TDM_PosLock.Create(nil); DM_PartPos := TDM_PartPos.Create(nil); DM_PartPosLock:= TDM_PartPosLock.Create(nil); DM_PartUpd := TDM_PartUpd.Create(nil); DM_IOrw := TDM_IOrw.Create(nil); DM_IOrws := TDM_IOrws.Create(nil); DM_PosPhrase := TDM_PosPhrase.Create(nil); if DM_Log=nil then DM_Log:= TDM_Log.Create(nil); if Form_Wait <> nil then FreeandNil(Form_Wait); SysUt.MsgDialog('權限資料設定中...請稍候'); U_VarDef.fuserid:= U_VarDef.LoginID; U_VarDef.fmenuid:= '111'; Form_UserIBfunc:= TForm_UserIBfunc.Create(nil); for i:= 1 to 99 do U_Default.rightpri[i]:= Form_UserIBFunc.UserFunc(U_VarDef.fmenuid format('%.2d',[i])); U_VarDef.fmenuid:= '999'; Form_UserIBfunc.SetDefault; for i:= 1 to 99 do U_Default.rightpub[i]:= Form_UserIBFunc.UserFunc(U_VarDef.fmenuid format('%.2d',[i])); FreeAndNil(Form_UserIBfunc); // 指定營業日期 // 如果未被授權(為 True 時), 則不允許修正日期 // 如果隔日未跨指定的時限, 仍歸於本日(須為無權限者有效) if not U_Default.rightpri[70] then begin Form_DateSet:= TForm_DateSet.Create(nil); try Form_DateSet.ShowModal; finally FreeAndNil(Form_DateSet); end; end else begin overtime:= StrtoIntDef(trim(readINI('POS','OVERTIME')),6); nowtime := StrtoIntDef(copy(TimetoStr(Time),1,2),0); if nowtime<=overtime then U_Default.nowdate:= SysUt.GetCDay(Date-1,U_VarDef.cdatedigit,'DAY') else U_Default.nowdate:= SysUt.GetCDay(Date,U_VarDef.cdatedigit,'DAY'); end; SysUt.MsgDialog('收銀系統載入中...請稍候'); Form_Pos:= TForm_Pos.Create(nil); Form_Pos.Top := 0; Form_Pos.Left := 0; Form_Pos.Height:= 735; Form_Pos.Width := 1024; Form_Pos.lblWorkDate.Caption:= SysUt.DayFormat(nowdate,'/',U_VarDef.cdatedigit); DM_Pos:= TDM_Pos.Create(nil); if Form_Wait <> nil then FreeandNil(Form_Wait); try Form_Pos.ShowModal; finally DLLver.DebugSL.Free; FreeAndNil(SysUt); if (U_Default.SRVrecord.DataIP<>'127.0.0.1') and (U_Default.SRVrecord.DataIP<>'') and (not U_Default.IBfrom.IO) then FreeAndNil(DM_Log); FreeAndNil(DM_PosLock); FreeAndNil(DM_PartPos); FreeAndNil(DM_PartPosLock); FreeAndNil(DM_PartUpd); FreeAndNil(DM_IOrw); FreeAndNil(DM_IOrws); FreeAndNil(DM_PosPhrase); if DM_Log<>nil then FreeAndNil(DM_Log); FreeAndNil(Form_Pos); FreeAndNil(DM_Pos); end; end else begin DLLver.DebugSL.Free; FreeAndNil(SysUt); if DM_Log<>nil then FreeAndNil(DM_Log); end; result:= True; end; end. [/code]
編輯記錄
P.D. 重新編輯於 2009-11-22 00:17:34, 註解 無‧
|
bill534
一般會員 發表:38 回覆:51 積分:17 註冊:2007-02-22 發送簡訊給我 |
|
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
你說一run就出錯, 到底錯誤訊息是啥, 都不見你貼出來, 我何苦在一直猜呢?
而且, 出錯時, 你有實際去測試錯在那一行code嗎? 這些都是你應該要先做的基本功 因為程式並非我在寫, 我沒有辦法得到你所有的問題點, 必須由你來告訴我們, 才有辦法幫你解決! 不管有沒有招, 還是要由你做過所有可能引發錯誤的動作後, po上來告訴我們, 所以並非我們要刁難你, 我在本站已經說了很多, 我們不是猜謎高手, 其次, 我謝絕你的"愛", 冷~~~~ 另外, 我發現你的程式有一個地方 ShareMem 要放在第一支, 你放在中間很可能是引發錯誤的問題點! 還有建議使用FastShareMem 取代 ShareMem, 這在xp 或 vista 上有很大的差異, 比較不容易有記憶體的錯誤 上網查一下就可以找到下載點 ===================引 用 bill534 文 章=================== Dear all 我的重點是DLL可以封裝數個以上的FORM嗎? 因為我没用Dll過Form,成功的是一個,數個就會出問題,SO請各位先進幫忙確認我的方法是錯嗎,是對嗎,若錯對的方法有嗎,有招那我繼續下去也才有意義啊!愛你們喔!thk's |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |