酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windows Media Player用の視覚エフェクト(Visualizer)を作ってみるテスト(3)

視覚エフェクト(Visualizer)を作ってみるテスト(2.5)」でDLLからリソースにアクセスする方法が分かりました。今回はリソースに含まれるBitmapをVisualizerとして表示してみます。

まず、リソースの追加から適当なBitmapをインポートします。

リソースビューにビットマップが追加されている事を確認します。

Wizerdから生成したデフォルトの状態ではBMPのリソースは登録されていないので、「IDB_BITMAP1」って名前になります。リソースIDはこれを使用します。

視覚エフェクト(Visualizer)の描画処理は、CSample::Render()で行われていますので、リソースからBMPをロードして表示枠に合わせて表示します。下記のようにコードを変更してみましょう。

  case PRESET_BARS:
  {
#if 1
    // DLLのhInstanceを取得
    HINSTANCE hInstance = ::GetModuleHandle("sample");

    // DLLのリソースから「IDB_BITMAP1」をロード
    HBITMAP hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP1));

    // BMPの大きさを把握
    BITMAP bm = {0};
    ::GetObject(hBitmap, sizeof(BITMAP), (LPVOID)&bm);

    // BMPを表示領域全体に合わせて表示
    HDC hMdc = CreateCompatibleDC(hdc);
    SelectObject(hMdc, hBitmap);

    StretchBlt(hdc, 0, 0, prc->right, prc->bottom,
               hMdc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY );

    // 後始末
    if(hMdc)    ::DeleteObject(hMdc);
    if(hBitmap) ::DeleteObject(hBitmap);
#else
//    // Walk through the frequencies until we run out of levels or drawing surface.
//    for (int x = prc->left; x < prc->right && x < (SA_BUFFER_SIZE-1); ++x)
//    {
//      int y = static_cast<int>(((prc->bottom - prc->top)/256.0f) 
//                               * pLevels->frequency[0][x - (prc->left - 1)]);
//      ::MoveToEx( hdc, x, prc->bottom, NULL );  
//      ::LineTo(hdc, x, prc->bottom - y); 
//    }
#endif
  }
  break;

表示関数内でDLLのhInstanceを取得しリソースをロードしていますが、セオリーに従うのであればDllMain()のhInstanceをグローバルで保持して利用すべきです。ただ、サンプルコードの範囲に処理をまとめておきたいのでこのような書き方になっていますがご了承下さい。

さて、この描画処理を実行するとどうなるでしょうか。

おーっ!表示されました。しかし、チラツキがひどい……ダブルバッファリングしなければいけませんね。