DIBによる高速描画

[戻る]
のみもんた 2008/09/08(月) 11:44:56
はじめまして、現在MFCダイアログベースで
描画プログラムを作成しています。
扱う画像が大きいため、高速描画が必要なため
DIBを検討しています。
下記のように簡単なプログラムを作成し
ダイアログ上に描画させよとしましたが、
描画できません。
どこが原因かご指摘願います。

開発環境VC++6.0 ダイアログベース WinXP




    // サイズの指定
    int WIDTH = 200;
    int HEIGHT= 100;

    // 定義
    HDC hdc;
    PAINTSTRUCT ps;
    static BITMAPINFO bmpInfo;
    static LPDWORD lpPixel;
    static HBITMAP hBitmap;
    static HDC hMemDC;
    int x,y;
    HWND hWnd;

    //DIBの情報を設定
    bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
    bmpInfo.bmiHeader.biWidth=WIDTH;
    bmpInfo.bmiHeader.biHeight=HEIGHT;
    bmpInfo.bmiHeader.biPlanes=1;
    bmpInfo.bmiHeader.biBitCount=32;
    bmpInfo.bmiHeader.biCompression=BI_RGB;

    // 描画ハンドル取得    
    hWnd =  GetSafeHwnd();
    hdc  =::GetDC(hWnd);
    //DIBSection作成
    hBitmap=CreateDIBSection(hdc,&bmpInfo,DIB_RGB_COLORS,(void**)
&lpPixel,NULL,0);
    hMemDC=CreateCompatibleDC(hdc);

    // 作成したDIBの選択
    SelectObject(hMemDC,hBitmap);
    ::ReleaseDC(hWnd,hdc);

    // DIBに描画
    for(y=1;y<80;y++){
        for(x=1;x<80;x++){
            lpPixel[x+y*WIDTH]=0x00ffff00; // 黄
        }
    }
    // DIBに描画
    ::Rectangle(hMemDC,10,10,40,40);

    //表画面へ転送
    hdc=::BeginPaint(hWnd,&ps);
    ::StretchDIBits
(hdc,0,0,WIDTH,HEIGHT,0,0,WIDTH,HEIGHT,lpPixel,&bmpInfo,DIB_RGB_COLORS,SRCCOPY)
;
    ::BitBlt(hdc,0,0,WIDTH,HEIGHT,hMemDC,0,0,SRCCOPY);
    ::EndPaint(hWnd,&ps);

    // 後片付け
    DeleteDC(hMemDC);
    DeleteObject(hBitmap);

rin 2008/09/08(月) 12:33:47
>ダイアログ上に描画させよとしましたが、
>描画できません。
とは?

のみもんた 2008/09/08(月) 12:45:00
説明不足で申し訳ありません。
ダイアログのDCに描画させると言う事です。

... 2008/09/08(月) 13:07:38
各APIからのエラーチェックが無い様ですが、ここらは全てが正しく終了してますか?

PATIO 2008/09/08(月) 13:13:09
> 説明不足で申し訳ありません。
> ダイアログのDCに描画させると言う事です。

そうではなくて、rinさんが聞いているのは
「描画出来ません」だけではどういう状態なのか分からない
という意味だと思いますよ。
実際の表示上の状態はどのようになっているのでしょう?
全く変化なしとか何か黒い四角が出ているとか。
描画出来ないと言うのを望んだ結果が得られないと言う意味で
とらえると、どういう状態になっているのが説明されていない
と言う事になりませんか?

のみもんた 2008/09/08(月) 13:15:05
はい、目的のハンドルが返って来ています。

のみもんた 2008/09/08(月) 13:43:39
[[解決]]
まったく何も表示されないのですが、
原因がわかりました。
CDCとHDCを混同していました。
FromHandleで対応出来ました。
最終的な表示方法に問題があったようです。
お騒がせしました。

bun 2008/09/08(月) 14:04:24
解放しちゃ駄目です。
>   ::ReleaseDC(hWnd,hdc);
をやめてみてください。

あと、せっかく static にしてるんだったら、
>   static BITMAPINFO bmpInfo;
>   static LPDWORD lpPixel;
>   static HBITMAP hBitmap;
>   static HDC hMemDC;
毎回、Create & Deleteしてたら無駄です。
  static HBITMAP hBitmap = NULL;
とかして、NULLのときだけ Createするようにしましょう。

でも、そうすると、DeleteObject()するタイミングが無くなるんで、
staticじゃなく、メンバ変数にして、ウィンドウが破棄されるタイミングで
DeleteObject()するのが吉。

最後に、
> SelectObject(hMemDC,hBitmap);
SelectObject()したら、元に戻すようにしましょう。
(例)
  HBITMAP hOldBitMap = SelectObject(hMemDC,hBitmap);
    :
  SelectObject(hMemDC,hOldBitMap);

古いスレッドには追加発言できません。