最近の記事
- 9/1 - 将棋始めました
- 5/16 - サーバー引っ越し
- 4/24 - 優先順位
- 3/17 - vbNullString と 空文字列 ""
- 3/15 - InputBox 関数の戻り値
- 3/13 - 紙と Excel と VBA
- 3/9 - 未だに Visual Basic 6
- 11/14 - ぼて閉鎖
- 11/9 - 関数オブジェクトの呼び出し
- 9/7 - メソッドとしての関数オブジェクト
Entering Passive Mode
ISaver 実装型一覧に表示できるようになったので、
次は「設定」ボタンで設定画面を呼び出せるようにしたい。
設定画面を呼び出すには、設定ボタンを押した際に、
コンボボックスに選択されている名前に対応した
ISaver 実装型のインスタンスを作れば良いのだ。
コンボボックスに CB_GETCURSEL メッセージを送れば、
現在選択されている項目のインデックス(数値)が得られるので、
その数値を元に Manager クラスのインデクサから Type を得れば良い。
しかしながら、これを行うには少々問題がある。
昨日作った LoadPlugins メソッドにでは、Manager クラスを使ったが、
Manager のインスタンスは、メソッド内のみの寿命だったので、
メソッドを抜けると破棄される。
設定ボタンを押した際に再度 Manager のインスタンスを作成する方法もあるが、
Manager クラスは、そのインスタンスを作成する際に、
プラグイン一覧を検索するので実行効率があまり良くない。
また、コンボボックスに名前の一覧を追加した後に、
新しいプラグインが追加されるようなことがあれば、
設定ボタンを押した際に作成した新しい Manager インスタンスが、
コンボボックスに表示されてる内容と食い違う危険性がある。
これらを回避するためには、Application クラスのフィールドとして、
Manager クラスのインスタンスを保持しておけば良い。
が、ここで別の問題が生じる。
Application クラスは、アンマネージクラスである。
アンマネージクラスは、そのフィールドとして
マネージクラスやマネージクラスのハンドルを保持することはできない。
class Application {
private:
Manager ^manager; // エラー
};
これを解決するためには、以前紹介した GCHandle を使い、
マネージハンドルを void * に置き換えて保持すれば良い。
でも、Manager インスタンスを使う際には、
一々 GCHandle を使って void * からハンドルに変換するのは面倒なので、
ここでは Visual Studio や Windows SDK についてくる、
便利な msclr::gcroot
msclr::gcroot は、GCHandle のラッパ構造体テンプレートであり、
それ自身はアンマネージの構造体だが、
マネージハンドルのように振舞う、スマートポインタの一種である。
#include
class Application {
private:
msclr::gcroot manager; // OK
};
このように宣言しておけば良い。
manager = gcnew Manager(); のように代入も可能だし、
manager->Count; のように、プロパティ等にアクセスすることもできる。
内部では、GCHandle を使って自動的に変換が行われているのである。
msclr::gcroot
気にせずに関数に引き渡したり、代入したりすることもできる便利な型である。
コメント (0 件)