GDIビットマップオブジェクト(DDB)

Windows のビットマップにはDIB(デバイス独立ビットマップ)の他に、GDIのオブジェクトとしてのビットマップがあります。
この二つは共にメモリ上に置かれるビットマップですが、DIBが単なる配列として自由に操作できるのに対し、GDIオブジェクトは基本的にその構造を知る事はできずGDI関数を通してのみ操作できる、という違いがあります。

DIBが自分で自由に描ける紙なら、GDIオブジェクトのビットマップは電話や電子メールで連絡を取っている相手(GDI)の手元にある紙、といった感じでしょうか。ただ、この相手は文字の「描き方」を知っている(フォントを持っている)ので、文字を描く時などには便利ですね。DIBに自分で文字を書くとなると、文字の形もいちいち自分で作らないといけませんから。
まあ現在ではDIBに対してもGDI関数を使う方法(DIBSection)があるので、結局はあまり使い道がないかもしれませんが。

GDIオブジェクトのビットマップの使い方

GDIオブジェクトのビットマップを使うには、以下のようにします。

  1. GDIオブジェクトのビットマップを作る
  2. メモリデバイスコンテキストを作る
  3. ビットマップをメモリデバイスコンテキストのビットマップに「選択」する
  4. メモリデバイスコンテキストを使ってビットマップに描画。
  5. BitBlt などの関数でメモリデバイスコンテキストを画面に描く。

メモリデバイスコンテキストとは、メモリ上にあるGDIオブジェクトのビットマップに描画するためのデバイスコンテキストです。ウインドウやスクリーンのデバイスコンテキストに描画すると、その結果は画面やウインドウに描画されますが、GDIオブジェクトのビットマップを含んだ(選択した)メモリデバイスコンテキストに描画すると、 その結果はメモリ上のビットマップに描画されます。

GDIオブジェクトのビットマップは「デバイス依存」なので、ビットマップを作る時にはデバイスコンテキストを指定して、そのデバイスと互換性のあるビットマップを作ります。作り方には、単にデバイスコンテキストとビットマップの大きさをしてして作る方法や、DIBのビットマップをGDIオブジェクトのビットマップに変換する方法などがあるのですが、今回はDIBからGDIオブジェクトのビットマップを作ってみましょう。

  hdcWin=GetDC(hwMain); /* ウインドウのDC を取得 */

  /* DIB とウインドウのDC からビットマップ を作成 */
  hBMP=CreateDIBitmap(hdcWin,(LPBITMAPINFOHEADER)lpDIB,
    CBM_INIT,lpBMP,lpDIB,DIB_RGB_COLORS);

  hdcMem=CreateCompatibleDC(hdcWin); /* hdcWin互換のメモリDC を作成 */

  SelectObject(hdcMem,hBMP); /* メモリDC にビットマップ を選択 */

上の例では、hwMain がウインドウのハンドル、lpDIB がDIBのBITMAPINFO(=BITMAPINFOHEADER)構造体の先頭アドレス、lpBMPがDIBのビットマップのアドレスになっています。

なおGDIオブジェクトのビットマップをDIBからではなく、デバイスコンテキストとビットマップの大きさを指定して作成したい時は、CreateCompatibleBitmap で作ってください。
これで、GDIオブジェクトのビットマップとビットマップに対するメモリデバイスコンテキストが作成されたので、後はhdcMem に対してGDI関数で描画すればビットマップに描画出来ます。また、ビットマップを画面(画面、または画面に表示されているウインドウのデバイスコンテキスト)に描画する時は、BitBlt を使います。

BitBlt(hdc,x,y,256,256,hdcMem,0,0,SRCCOPY);

プログラム

今回のプログラムは、灰色の背景を描いたDIBから作ったビットマップにGDI関数で文字を描きます。表示位置のセンタリング(中央への位置合せ)も行ってみたので、 起動したらマウスでウインドウの大きさを変えてみてください。

プログラムソース表示