請問要如何將視窗寫成DLL呢? |
答題得分者是:syntax
|
l90425
初階會員 發表:95 回覆:152 積分:49 註冊:2008-04-03 發送簡訊給我 |
|
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
|
l90425
初階會員 發表:95 回覆:152 積分:49 註冊:2008-04-03 發送簡訊給我 |
|
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
|
l90425
初階會員 發表:95 回覆:152 積分:49 註冊:2008-04-03 發送簡訊給我 |
不好意思!感謝大大的提醒!
DLL [code cpp] #include #include #include "Unit1.h" #pragma hdrstop #pragma argsused extern "C" __declspec(dllexport) void __stdcall CreateForm(); extern "C" __declspec(dllexport) void __stdcall DeleteForm(); BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved) { return 1; } //--------------------------------------------------------------------------- void _stdcall CreateForm() { TForm1 *form = new TForm1(0); form->Show(); } //--------------------------------------------------------------------------- void _stdcall DeleteForm() { delete form; form = NULL; } [/code] Project1.exe [code cpp] #include #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; HINSTANCE mydll; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { mydll=LoadLibrary("Project1.dll"); if(mydll) { try{ void (__stdcall *CreateForm)(); CreateForm = (void (__stdcall*)())GetProcAddress(mydll,"CreateForm"); CreateForm(); }catch(...){} } } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { if(mydll) { try{ void (__stdcall *DeleteForm)(); DeleteForm = (void (__stdcall*)())GetProcAddress(mydll,"DeleteForm"); DeleteForm(); }catch(...){} FreeLibrary(mydll); } }[/code] 但是想問大大像下面的那一篇,是如何做到呢? http://delphi.ktop.com.tw/board.php?cid=31&fid=79&tid=51057(MDIChild) 謝謝!!
------
-謝謝大大熱心的回覆!謝謝! |
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
1. DLL 的用意就是要通用與再用,因此必須要 Delphi 的程式可以叫用,C++ 的程式也可以叫用
要做到這樣,就必須要寫無關編譯器的 DLL,所以不要思考將 Form 的 Delphi Class 給外面使用,因為例如 C 看不懂,反之亦然 也就是說,在 DLL 內建立,在 DLL 內動作,在 DLL 內銷毀,我們要做的是,建立「建立、銷毀...等」公用函式,來給外界呼叫 所以你的作法,是非常正確的 (CreatForm, DeleteForm, SetMDI, SetFormText, .......); 如果動作過多(每一動作都建立函式,不經濟也不實際),可以考慮 GetFormHandle 傳到外部,由呼叫方自行處理需要的部分 2. 不過,要是呼叫者沒有主動銷毀 Form 呢,所以建議,可以自己做簡易的記憶體管理,在 DLL 的載入區段 加入一記錄用的 list 或 array or any method,在建立時記錄、銷毀時註銷,最後退出 DLL 時再檢查一次,Free 尚未 Free 的部分 3. MDI Form 並不難,建立的方式與一般無異,傳入 Parent 或將 Child 傳出,然後設定相關的設定如 fsMDIForm,fsMDIChild 如果你不懂 MDI,那先用一般的作法練習,站上搜一下,也有會有範例 但是,使用 DLL 的方式處理時,必須注意 1. 所提到的法則,所以建議作是,傳入要作為 parent 的視窗 Handle,然後,使用 Windows API 來建立 Parent 與 Child 之間的聯繫,這樣就無語言與編譯器的依賴性 (不同編譯器,不同 FrameWork,運作方式是不同的,直接套用,會出現不相容性) 4. 最後,如果你功力進步到「知道自己在做什麼」,那以上規則,不必遵守,也沒差別 「因為你知道自己在做什麼,並明白該動作的結果,會是你想要的」,例如直接修改記憶體位址,也是可以做到 MDI 但是,功力未達者,出錯的機率過大 (其實也沒這必要,殺雞焉用牛刀) ===================引 用 l90425 文 章=================== 不好意思!感謝大大的提醒! DLL [code cpp] #include #include #include "Unit1.h" #pragma hdrstop #pragma argsused extern "C" __declspec(dllexport) void __stdcall CreateForm(); extern "C" __declspec(dllexport) void __stdcall DeleteForm(); BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved) { return 1; } //--------------------------------------------------------------------------- void _stdcall CreateForm() { TForm1 *form = new TForm1(0); form->Show(); } //--------------------------------------------------------------------------- void _stdcall DeleteForm() { delete form; form = NULL; } [/code] Project1.exe [code cpp] #include #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; HINSTANCE mydll; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { mydll=LoadLibrary("Project1.dll"); if(mydll) { try{ void (__stdcall *CreateForm)(); CreateForm = (void (__stdcall*)())GetProcAddress(mydll,"CreateForm"); CreateForm(); }catch(...){} } } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { if(mydll) { try{ void (__stdcall *DeleteForm)(); DeleteForm = (void (__stdcall*)())GetProcAddress(mydll,"DeleteForm"); DeleteForm(); }catch(...){} FreeLibrary(mydll); } }[/code] 但是想問大大像下面的那一篇,是如何做到呢? http://delphi.ktop.com.tw/board.php?cid=31&fid=79&tid=51057(MDIChild) 謝謝!! |
l90425
初階會員 發表:95 回覆:152 積分:49 註冊:2008-04-03 發送簡訊給我 |
感謝syntax大大的熱心說明!
謝謝!! ===================引 用 syntax 文 章=================== 1. DLL 的用意就是要通用與再用,因此必須要 Delphi 的程式可以叫用,C 的程式也可以叫用 要做到這樣,就必須要寫無關編譯器的 DLL,所以不要思考將 Form 的 Delphi Class 給外面使用,因為例如 C 看不懂,反之亦然 也就是說,在 DLL 內建立,在 DLL 內動作,在 DLL 內銷毀,我們要做的是,建立「建立、銷毀...等」公用函式,來給外界呼叫 所以你的作法,是非常正確的 (CreatForm, DeleteForm, SetMDI, SetFormText, .......); 如果動作過多(每一動作都建立函式,不經濟也不實際),可以考慮 GetFormHandle 傳到外部,由呼叫方自行處理需要的部分 2. 不過,要是呼叫者沒有主動銷毀 Form 呢,所以建議,可以自己做簡易的記憶體管理,在 DLL 的載入區段 加入一記錄用的 list 或 array or any method,在建立時記錄、銷毀時註銷,最後退出 DLL 時再檢查一次,Free 尚未 Free 的部分 3. MDI Form 並不難,建立的方式與一般無異,傳入 Parent 或將 Child 傳出,然後設定相關的設定如 fsMDIForm,fsMDIChild 如果你不懂 MDI,那先用一般的作法練習,站上搜一下,也有會有範例 但是,使用 DLL 的方式處理時,必須注意 1. 所提到的法則,所以建議作是,傳入要作為 parent 的視窗 Handle,然後,使用 Windows API 來建立 Parent 與 Child 之間的聯繫,這樣就無語言與編譯器的依賴性 (不同編譯器,不同 FrameWork,運作方式是不同的,直接套用,會出現不相容性) 4. 最後,如果你功力進步到「知道自己在做什麼」,那以上規則,不必遵守,也沒差別 「因為你知道自己在做什麼,並明白該動作的結果,會是你想要的」,例如直接修改記憶體位址,也是可以做到 MDI 但是,功力未達者,出錯的機率過大 (其實也沒這必要,殺雞焉用牛刀)
------
-謝謝大大熱心的回覆!謝謝!
編輯記錄
l90425 重新編輯於 2010-03-24 12:21:29, 註解 無‧
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |