MainInstance と HInstance の違いは?TipTip 独自に作成したカーソルを使いたい で説明しましたように、カーソルリソースやアイコンリソースなどを実行ファイルに $R 指令でリンクした場合、リソースを読み込むにはインスタンスハンドルなるものが必要になります。 VCL には2種類のインスタンスハンドルを保持するグローバル変数があります。MainInstance と HInstance です。どちらを使うべきなのでしょうか? たいていは MainInstance でよいのですが、DLL やパッケージを使う場合はちょっと話が違ってきます。
解説アプリケーションは一般に、実行ファイル(EXE)、DLL、パッケージから構成されますが、これらはモジュールと呼ばれます。インスタンスハンドルはモジュール固有のもので、モジュール毎に異なる値になります。
つまり EXE, DLL, パッケージはそれぞれ異なるインスタンスハンドルを持つわけです。リソースはモジュールにリンクされるので、リソースをロードするには正しいインスタンスハンドルを指定する必要があります。 MainInstance は System ユニットに、HInstance は SysInit ユニットで宣言されているグローバル変数です。これはともにインスタンスハンドルを保持していますが、
になっています。つまり HInstance はりソースをロードしようとしているコードが属するモジュールのインスタンスハンドルを保持しているわけです。 VCLのSystemユニットとSysInitユニットはともにUses節で指定しなくとも自動的に使われるユニットですが、その性質はパッケージを使うと大きな違ってきます。 System ユニットはパッケージ VCL50.bpl(Delphi 5), VCL60.bpl(Delphi6)に含まれ、パッケージを使う全てのモジュールは Systemユニット内のコードとデータを共有します。一方 SysInit ユニット は必ず各モジュールに個別にリンクされ共有されません。 パッケージを使うと MainInstance はパッケージ VCL50.bpl/VCL60.bpl の中に有り、実行ファイル(EXE)は MainInstance を自分のインスタンスハンドルで初期化します。一方 HInstance は各モジュールが自分のインスタンスハンドルをセットします。従って
ということになります。注意してください MainInstance は Delphi 3 で導入されましたが、その理由はパッケージです。パッケージは DLL の一種で、アプリケーションを構成する一部のユニットを DLL 化するためのものです。 ユニットをEXEからパッケージに移す際、ユニットのコードに書き換えが必要になるのは好ましいことでは有りません。このため、EXEにリンクされているリソースを EXE内からでも、パッケージからでも同じようにアクセスできるように導入されたのが MainInstance なのです。 何がパッケージによって共有され、何がされないかを把握しておくことは大切です。最後にSysInit ユニットのいくつかの変数を紹介しておきましょう。
|