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 はコピーすることも考慮されているため、
気にせずに関数に引き渡したり、代入したりすることもできる便利な型である。