Entering Passive Mode

< 1 2 3 4 5 6 7 8 9... >

ホストの改善 #1: 構想を練る

次のステップに進むか。

現状のホストには大きな制限がある。
それはリソースの問題だ。

スクリーンセーバーの名前とアイコンは、
ホストに Windows のリソースとして埋め込まれる。
これらは、プラグインで置き換えることはできない。

これにより生じる制約は以下の 2 つ。
・表示するスクリーンセーバーの名前を変えられない
・スクリーンセーバーのアイコンを変えられない。

音楽 CD の寿命

音楽 CD の寿命ってどんなもんなんだろ。

今日、お気に入りの CD の 2 曲目で音飛びが発生。
傷やほこりが原因で、針が同じ場所に戻される
昔のレコード版のような現象。
それも 5 秒おきくらいに 3 箇所で同時に。

音飛びの原因と言えば、以下の 2 種類であることが多い。
1 つはレーベル側の傷による記録層の損傷、
1 つは読み取り側にある樹脂の傷による反射性能低下。

ホストの作成 #8: 動作テスト

スクリーンセーバー

描画コードとの連携も完成したので、
ちゃんと動作するかテストしてみる。

実行してみると、画面の中央に、
「Hello World!」と表示されたことが確認できた。

……これだけだと短すぎるので、もう少し書くか。

このスクリーンセーバーの実行は
C++ ネイティブアプリと違い、起動に多少時間がかかる。

C++/CLI #7: IDisposable と delete

突如現れた delete 構文。
この delete の意味するのは何なんだろうか。

まず、昨日のコードから、大事な部分を引用していこう。

    Graphics ^g = Graphics::FromHdc(...);
    try {
        ...
    } finally {
        delete g;
    }

ホストの作成 #7: 描画コードを呼ぶ

Create/Destroy の準備ができたので、
本題となる Dispatcher::Paint の実装を行う。

    void Dispatcher::Paint(HWND hwnd) {

        // 描画開始
        PAINTSTRUCT ps;
        BeginPaint(hwnd, &ps);

        try {

C++/CLI #6: GCHandle の参照を解放する

GCHandle::Alloc でハンドルに ID を割り当てると、
数値として取り扱えるようになるので便利だが、
不要になった時にはちゃんと解放しなければならない。

これを怠ると、ハンドルへの参照が残ってしまうので、
オブジェクトがガベッジコレクションされなくなり、
メモリリークを引き起こす要因となる。

GCHandle::Alloc で参照したハンドルを解放するためには、
どこかで GCHandle::Free を呼ぶ必要がある。

C++/CLI #5: safe_cast

GCHandle を使って割り当てた ID はただの数値なので、
利用するときにはハンドルに戻さなければならない。

ID からハンドルに戻すのは、
ハンドルから ID に変換した時と逆の手順を踏めば良い。


    // ウィンドウのユーザデータから ID を取得
    LONG_PTR value = GetWindowLongPtr(hwnd, GWLP_USERDATA);
    void *pointer = reinterpret_cast<void *>(value);

C++/CLI #4: ハンドルを数値に変換する

ハンドル型の値は演算も変換もできないため、
そのままではスコープを超えて、
オブジェクトを保持することが困難である。

グローバル領域に変数を確保し、
ハンドル型の値を保持する手はあるが、
変数の可視性を高めてしまうのは、
保守性に劣り、見通しも悪くなるのでやりたくない。

ではどうすれば良いか。

C++/CLI #3: gcnew で動的確保

次に作るのは、描画コードの呼び出しだ。

Configure メソッドを作成した際は、
「HelloSaver saver;」という形で変数を宣言した。

この場合、saver 変数のスコープは、
Configure メソッドの内部なので、
メソッドから戻る直前に変数がスコープから外れ、
自動的にデストラクタが呼び出されて解放される。

でも、描画コードの呼び出し部分の実装は、
Configure のような単発の呼び出しではなく、
Create => Paint => Destroy の流れとなる。

ホストの作成 #6: 連携テスト

まだ Configure メソッドしか作っていないが、
設定画面を表示させるコードは完成した。
描画用のコードを書いてないので、
スクリーンセーバーの実行テストはできないが、
とりあえず設定画面が表示されるか確認してみたい。

まずは、Dispatcher.cpp をコンパイルしておく。

$ cl /c /W4 /clr /FoDispatcher.obj Dispatcher.cpp

エラーがなければリンクする。

< 1 2 3 4 5 6 7 8 9... >
このページのトップへ戻る
© 2008 Project Loafer/Project Fireball and all blog writers. Powered by Nucleus CMS