天天看點

什麼是運作期包與設計期包

======================================================================

1. 内容簡介

======================================================================

    本文檔深入明了的闡述了什麼是運作期包、設計期包

    同時解釋了産生 DesignIntf 錯誤的原因

======================================================================

2. 正文

======================================================================

    本文以 CnPack.dpk (運作期包)、dclCnPack.dpk (設計期包)為例說明。這

兩個包,一個是運作期包,另一個是設計期包,設計期包包含有元件編輯器。

    元件包通常按運作期包和設計期包兩個包來釋出,其中運作期包中包含了應

用程式編譯實際需要的單元,而元件編輯器、屬性編輯器這些專門為 IDE 設計

期編寫的代碼在應用程式的 exe 中是不需要的,是以元件源碼中會将這些設計

編輯器的代碼放到單獨的 pas 檔案中,這些包含設計期 pas 的單元隻在設計期

包的 dpk 中包含,甚至于那些向 IDE 中注冊元件的 Register 函數也可以不放

在元件單元中。

    設計期包引用了運作期包, Delphi 的包技術是基于 unit 的,實際上

build with runtime package 時,是在連接配接期,将對程式引用到的單元的連接配接

變成對運作包的外部引用。

    這樣來說吧,我們要編寫一個在 IDE 中可以安裝使用的元件,需要有一個

TMyComp 元件的實作,然後有一個 Register 函數将元件注冊到 IDE 控件面闆。

    如果這個元件的屬性需要編輯器,或者元件本身有編輯器,還需要寫一些編

輯器的代碼。這些在 IDE 中用來編輯元件及其屬性的代碼,對應用程式來說是

沒有意義的注冊元件,編輯器的 Register 函數對應用程式也是沒有意義的,

而且這些編輯器是依賴于 IDE 的 ToolsAPI、DesnIntf 等 OTA 單元。

    如果和 TMyComp 的代碼放在一個 pas 中編譯的時候,應用程式就還需要間

接引用到 IDE 的這些 OTA 單元,而事實上這樣處理是不适當的。

    是以開發元件包的作者,就引入了運作期包和設計期包兩個概念,将那些應

用程式需要編譯到 exe 中的源代碼放在元件實作的 pas 單元中,比如

dclCnPack_D7.dpk的内容,裡頭包括的 unit,都是應用程式中用不到的,隻在

IDE 裡頭使用。

    這些 pas 都包含在運作期包的 dpk 檔案中。運作期包在工程選項中,是設

置為 Runtime only 模式。隻能用于運作期,不能進行安裝。是以我們在 IDE

中打開 CnPack_D7.dpk 檔案,點 Install 是會提示錯誤的元件的注冊、編輯器

這些内容,很顯然是要引用到元件本身的代碼的。

    當然,對于單個元件,可能覺得分開寫這兩個單元太麻煩。但對于大型的組

件包,這樣分開設計就很明了了。

    CnPack 的元件代碼結構基本上就是按這個原則來處理的。

    比如包含 TMyComp 元件的代碼在 MyComp.pas 裡,而針對 TMyComp 的元件

注冊和編輯器,則放在 MyCompEditor.pas 裡頭。在 MyCompEditor.pas 中

uses MyComp 這個單元就行了,一份是純運作期包,一份是在運作期包外附加的

設計期代碼。

    Register 函數也應該放在 MyCompEditor.pas 中,這個函數應用程式的

exe 是不調用的。當然,放在 MyComp 中也不會出錯。

    如果隻是注冊元件,由于 RegisterComponents 在 Classes 中定義,是以

沒什麼問題,但是如果要注冊屬性編輯器 RegisterPropertyEditor ,則是在

DesignIntf 中定義的。DesignIntf 這個單元對應用程式來說根本沒有用處的隻

是 IDE 提供的設計期接口。如果将 Register 函數放在元件實作代碼中,間接

引用到單元,就可能導緻使用者在安裝編譯元件時出現找不到DesignIntf 的錯誤,

因為 DesignIntf 等單元預設是不在 IDE 的搜尋路徑中的。

    從 D6 開始,有個設計期的單元沒有放出源碼來(Proxies.dcu),在 D6

以上版本的 DesignEditor.pas 中,實作部分引用到了這個單元,而 Borland

沒有提供源碼,導緻大量元件運作期編譯不過。

    Proxies 這個單元好象是在 dsnIDEXX.bpl 裡頭引用了 DesignEditor 的組

件,安裝到 IDE 中時沒有問題,是因為設計期包是帶 dsnIDE.bpl 編譯的,而

應用程式編譯就通不過了。

    是以我們提倡設計期包與運作期包分開,基本上正規點的元件包都是按這個

方法做的。