電子書籍の厳選無料作品が豊富!

今、Visual C++ のMFCで、デスクトップイメージをメモリに取り込むプログラムを作り始めています。

DeskTopWindowをいじるのははじめてです。

とりあえず、MFCのAppWizardで、SDIのスケルトンを作り、まずは、テストのため、メニューバーの表示のところに、ID_VIEW_TESTというのをつくって、ここで、キャプチャーしようとしました。

そして、簡単に、


void CMainFrame::OnViewTest()
{
CRect rect;
CWnd*pwWnd = GetDesktopWindow();
pwWnd->GetClientRect( &rect );
CDC* pwDC = pwWnd->GetDC();

CBitmap bm;
bm.CreateCompatibleBitmap( pwDC, rect.Width(), rect.Height() );

unsigned char *colorBuf;
colorBuf = (unsigned char *)malloc( sizeof( unsigned char ) * rect.Width() * rect.Height() * 3 );

bm.GetBitmapBits( rect.Width() * rect.Height() * 3, colorBuf );

pwWnd->ReleaseDC( pwDC );
}

というプログラムを作り、colorBufの中身をみたら、どうやってもすべてゼロになっています。

rectには、ちゃんとデスクトップサイズが入っています。

なにが悪いのでしょうか。

A 回答 (4件)

 こんばんは。



 デスクトップイメージをbmに対して描画していないのが原因なのではないでしょうか。
 CreateCompatibleBitmap()と言うのは、あくまで指定したデバイスコンテキストと同一のフォーマットを持ったビットマップを作成するだけですので、イメージまで複写してくれる訳ではありません。
 自前でビットブロック転送をしてイメージを複写する必要があります。

 以下で改善しませんか。

void CMainFrame::OnViewTest()
{
CRect rect;
CWnd* pwWnd = GetDesktopWindow();
pwWnd->GetClientRect( &rect );
CDC* pwDC = pwWnd->GetDC();

CBitmap bm;
bm.CreateCompatibleBitmap( pwDC, rect.Width(), rect.Height() );

//デスクトップイメージをbmへ描写する
CDC memDC;
memDC.CreateCompatibleDC(pwDC);
CGdiObject* pOld = memDC.SelectObject(&bm);
memDC.BitBlt(0, 0, rect.Width(), rect.Height(), pwDC, 0, 0, SRCCOPY);
memDC.SelectObject(pOld);
memDC.DeleteDC();

//受け取りバッファに必要なバイトサイズを受け取る
const DWORD dwBytes = bm.GetBitmapBits( 0, NULL );

//実際に割り当てる
unsigned char *colorBuf = (unsigned char *)malloc(dwBytes);

//イメージをバッファに受け取る
bm.GetBitmapBits( dwBytes, colorBuf );

pwWnd->ReleaseDC( pwDC );

for(DWORD dw = 0; dw < dwBytes; ++dw)
{
if(colorBuf[dw] != 0)
{
//此処で確認
}
}
}

この回答への補足

確認してみました。

colorBuf内に入っている値をもとに、SDIの画面に描画させてみたら、ちゃんと、デスクトップの絵が表示されました。

ありがとうございました。


CDC* pwDC = pwWnd->GetDC();
の直後にためしに、pwDC->GetPixel(x, y)
で値をとってみても、FFFFFFFFしか返ってこなかったのはなぜなのでしょうか。
もしよろしければ、教えてください。

補足日時:2009/08/20 11:36
    • good
    • 0
この回答へのお礼

お返事ありがとうございました。
とりあえず、このプログラムでやってみたら、colorBufに値が入っていますね。
正しい値かどうか、ちょっとじっくり調べてみます。

それにしても、
CDC* pwDC = pwWnd->GetDC();
の直後にためしに、pwDC->GetPixel(x, y)
で値をとってみても、FFFFFFFFしか返ってこなかったのは、なぜなのでしょうか。

お礼日時:2009/08/20 11:14

 こんにちは。

御礼頂きました。

 以下で試してみましたが、確かに失敗します。

CRect rect;
CWnd* pwWnd = GetDesktopWindow();
pwWnd->GetClientRect( &rect );

//デスクトップウィンドウのデバイスコンテキストを取る
CDC* pwDC = pwWnd->GetDC();

//ディスプレイのデバイスコンテキストを取る
HDC hDC = ::CreateDC("DISPLAY", NULL, NULL, NULL);

for(int y = 0; y < rect.Height(); ++y)
{
for(int x = 0; x < rect.Width(); ++x)
{
//成功
const COLORREF color = ::GetPixel(hDC, x, y);
//失敗
const COLORREF color2= pwDC->GetPixel(x, y);
}
}

 デスクトップウィンドウのデバイスコンテキストとディスプレイのデバイスコンテキストは別物の様に見えます。
 流石に此の辺りの詳細を説明してくれる書籍を見つけた事が無い為、此れに関しては当方の理解範囲を超えているので何故だかは分かりません。
 海外から輸入されたwindowsプログラム専門の書籍であればこの辺りの事情が書かれているかもしれません。
    • good
    • 0
この回答へのお礼

早速のお返事ありがとうございました。

ほんと、CDCに関しては、いつもややこしくて、勉強をするのもめんどくさく、なかなか深く掘り下げて勉強していないので、苦労しております。
ちゃんと勉強しろよ、と自分にいいながら、、、

でも、hDCをとって、成功した、というのは、大変興味深く、勉強になりました。
ありがとうございました。

わたしは、実は、マルチモニタでの画面キャプチャがしたいのです。

このプログラムでは、マルチモニタには対応していないようです。
これもわかりません。

近く、また別途、質問させていただきますので、ご縁があれば、またよろしくお願いいたします。

お礼日時:2009/08/20 12:32

良く良く考えたら、手元にMFCどころか開発環境自体無かった…。



うろ覚えですが、DCに対してビットマップオブジェクトを選択していないような。

pwDC->SelectObject(&bm)

とかがGetBitmapBitsの前に要らなかったか?って気がします。
古いオブジェクトは保存しておき、処理後に戻す方が良いです。
    • good
    • 0
この回答へのお礼

お返事ありがとうございます。
関係なさそうです。

CDC* pwDC = pwWnd->GetDC();

で、pwDCを作った後、GetPixelを使ってカラー値をみようと思い、

COLORREFpx[10000];
longlx, ly, l;
lx= ly= 0;
for( l = 0; l < 10000; l++ )
{
px[l]= pwDC->GetPixel( lx++, ly );
if( lx >= 500 )
{
lx= 0;
ly++;
}
}

というソフトを追加してみました。
すると、pxの配列の中身はすべて、0xFFFFFFFFになっていました。
pwDCの取り方に問題があるのかもしれません。

お礼日時:2009/08/19 22:45

> rectには、ちゃんとデスクトップサイズが入っています。



であればその後の、

pwDCにデバイスコンテキストの値が入っているか?
bmにCreateCompatibleBitmapした結果は成功しているか?
colorBufへのmallocは成功しているか?
bmにGetBitmapBitsした結果は成功しているか?

など確認するのが一般的なデバッグ方法です。
    • good
    • 0
この回答へのお礼

お返事ありがとうございました。

pwDC, pwWndには、ちゃんと中身も入っています。
CreateCompatibleBitmapは、TRUEを返しています。
mallocは成功しているかどうかわかりませんが、colorBufにはちゃんとアドレスが入っているので大丈夫でしょう。
GetBitmapBitsは、取得したバイト数、3072000を返り値として、返しています。

つまり、とりあえず、すべてのコマンドはちゃんと成功しているように見えます。

なので、何かが抜けているのか、Bitmapへのコピーでどこかが間違っているのか、pwDCの取り方が間違っているのか、、、

わたしもいろいろ調べてみましたが、よくわかりません。

お礼日時:2009/08/19 21:19

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!