国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
Delphi – 在DLL中保存并創(chuàng)建MDI子窗體
很多人認(rèn)為,在Delphi的DLL中加載MDI子窗體時(shí),需要注意保存并恢復(fù)Delphi全局變量(Application和Screen)對(duì)象。其實(shí),根本沒(méi)有辦法在DLL中加載MDI子窗體。

原文出處:http://delphi.about.com/library/weekly/aa020805a.htm

    在開(kāi)發(fā)復(fù)雜的應(yīng)用系統(tǒng)時(shí),把系統(tǒng)分為各個(gè)模塊分而制之是一種很平常的策略,這樣就可以使得每個(gè)模塊負(fù)責(zé)一套業(yè)務(wù)邏輯。模塊可以是一個(gè)DLL,在需要的時(shí)候,主程序可以調(diào)用這個(gè)DLL以使用該模塊。

    當(dāng)你開(kāi)發(fā)一個(gè)MDI應(yīng)用程序,并希望把該應(yīng)用程序分割成各個(gè)模塊時(shí),自然會(huì)有這樣的疑問(wèn):“如何將MDI子窗體創(chuàng)建在DLL中,以使得在必要的時(shí)候能夠被主程序調(diào)用?”

    如果你已經(jīng)知道如何在DLL中創(chuàng)建非MDI子窗體的窗體,并且也知道如何從主程序調(diào)用這個(gè)DLL中的窗體時(shí),你或許會(huì)認(rèn)為問(wèn)題已經(jīng)得到了解決,但事實(shí)并非如此。

    如何讓DLL中的MDI子窗體得知哪個(gè)窗體是它的父窗體(以便讓其能夠以子窗體的形式展現(xiàn)出來(lái))?用于創(chuàng)建該子窗體的Application對(duì)象(位于父窗體所在的應(yīng)用程序中)與你在DLL中獲得的Application對(duì)象根本就是兩回事情,不僅如此,兩者的Screen對(duì)象也不相同。

 

想要在DLL中保存并創(chuàng)建MDI子窗體?沒(méi)門(mén)!

    就如你所看到的這個(gè)標(biāo)題所說(shuō)的一樣,根本就沒(méi)有辦法在DLL中保存并創(chuàng)建MDI子窗體,然后讓MDI應(yīng)用程序去調(diào)用它?;蛘吣銜?huì)說(shuō),你已經(jīng)在網(wǎng)上找到一些資料,上面顯示如何保存并傳遞Application對(duì)象,以使得DLL中的MDI子窗體能夠被創(chuàng)建于正確的MDI父窗體中,其實(shí)這種做法并不奏效,至少在Delphi 5以上的版本中不會(huì)奏效。

 

那么解決方案是什么呢?

    如果你非要在DLL中保存并創(chuàng)建MDI子窗體,那么你需要在主程序(MDI應(yīng)用程序)和DLL生成的時(shí)候,與運(yùn)行時(shí)包(runtime package)一起生成。這樣做就確保了主程序和DLL使用了共同的ApplicationScreen對(duì)象,并使用了相同的RTLVCL實(shí)例。為了100%確保“安全”,你應(yīng)該使用包,而不是DLL。

 

包中的MDI子窗體:唯一正確的解決方案

    Delphi的包是一種特殊的DLL,它僅用于Delphi的應(yīng)用程序。如果你的應(yīng)用程序模塊是使用包的形式開(kāi)發(fā)而不是DLL,那么所有的模塊都會(huì)共享同一個(gè)內(nèi)存管理機(jī)制,包括了VCL全局對(duì)象(例如ApplicationScreen)以及RTLVCL在內(nèi)存中的同一代碼拷貝。

 

包中的MDI子窗體:實(shí)例

    現(xiàn)在來(lái)看一個(gè)實(shí)例,首先,我們將創(chuàng)建一個(gè)MDI應(yīng)用程序:

1、  創(chuàng)建一個(gè)新的MDI應(yīng)用程序。你可以使用MDI應(yīng)用程序創(chuàng)建向?qū)В?/span>File - New - Other - Projects - MDI Application

2、  確保主窗體的FormStyle屬性已經(jīng)設(shè)置為fsMDIForm

3、  添加一個(gè)MainMenu控件,使其只有一個(gè)用于從包中加載子窗體的菜單項(xiàng)

4、  確保在生成應(yīng)用程序的時(shí)候,是和運(yùn)行時(shí)包一起生成的。在Project – Options菜單中,選擇Packages選項(xiàng)卡,然后選中“Build with run-time packages”選項(xiàng)。你至少要選中rtl包和vcl

在真正編碼前,首先生成該包,并且向其添加一個(gè)MDI子窗體

1、  創(chuàng)建一個(gè)新的運(yùn)行時(shí)包

2、  向包添加一個(gè)TForm對(duì)象,確保該對(duì)象的FormStyle屬性已經(jīng)設(shè)置為fsMDIChild

3、  添加一個(gè)導(dǎo)出過(guò)程,用于創(chuàng)建子窗體的實(shí)例:

procedure TPackageMDIChildForm.FormClose
  (Sender: TObject; 
   var Action: TCloseAction);
begin
  //since this is an MDI child, make sure 
  //it gets closed when the user 
  //clicks the x button.
  Action := caFree;
end;
 
procedure ExecuteChild;
begin
  TPackageMDIChildForm.Create(Application);
end;
 
exports
  //NOTE!! The export name 
  //is CASE SENSITIVE
  ExecuteChild;
  
end.

 

    重新回到MDI主程序,以下是MDI主窗體的所有代碼:

type

  //signature of the "ExecuteChild"

  //procedure from the Package

  TExecuteChild = procedure;

 

  TMainForm = class(TForm)

   ...

  private

    PackageModule : HModule;

    ExecuteChild : TExecuteChild;

    procedure PackageLoad;

  end;

 

var

  MainForm: TMainForm;

 

implementation

{$R *.dfm}

 

procedure TMainForm.PackageLoad;

begin

  //try loading the package

  //(let's presume it's in the same

  //folder, where the main app. exe is)

  PackageModule := LoadPackage('MDIPackage.bpl');

 

  //if loaded, try locating

  //the ExecuteChild procedure

  if PackageModule <> 0 then

  try

    @ExecuteChild := GetProcAddress(PackageModule,

                                    'ExecuteChild');

  except

    //display an error message if we fail

    ShowMessage ('Package not found');

  end;

end;

 

//menu click

procedure TMainForm.mnuCallFromDLLClick

(Sender: TObject);

begin

  //lazzy load package

  if PackageModule = 0 then PackageLoad;

 

  //if the ExecuteChild procedure

  //was found in the package, call it

  if Assigned(ExecuteChild) then ExecuteChild;

end;

 

procedure TMainForm.FormDestroy(Sender: TObject);

begin

  //if the package was loaded,

  //make sure to free the resources

  if PackageModule <> 0 then

    UnloadPackage(PackageModule);

end;

 

    上面的代碼中,選中菜單項(xiàng)時(shí),主程序動(dòng)態(tài)地加載了所需的包(使用PackageLoad過(guò)程),并且在應(yīng)用程序終止的時(shí)候卸載了已經(jīng)加載的包。最后,在運(yùn)行時(shí),我們得到了一個(gè)能夠正確加載并運(yùn)行包中MDI子窗體的應(yīng)用程序。

    最后需要說(shuō)明的是,在使用runtime package模塊化應(yīng)用程序時(shí),你必須將所需的包與應(yīng)用程序的exe文件一起發(fā)布。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
MDI Application共享Delphi和BCB DLL插件的問(wèn)題
Delphi 調(diào)用dll中的窗體
DELPHI下自定義包的作用,開(kāi)發(fā)以及包文件的安裝配置位置
delphi中關(guān)于tapplication類(lèi)的詳解
Delphi 6 程序員代碼編寫(xiě)標(biāo)準(zhǔn)指南一
窗體集合(針對(duì) Visual Basic 6.0 用戶(hù))
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服