![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
今、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には、ちゃんとデスクトップサイズが入っています。
なにが悪いのでしょうか。
No.3ベストアンサー
- 回答日時:
こんばんは。
デスクトップイメージを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しか返ってこなかったのはなぜなのでしょうか。
もしよろしければ、教えてください。
お返事ありがとうございました。
とりあえず、このプログラムでやってみたら、colorBufに値が入っていますね。
正しい値かどうか、ちょっとじっくり調べてみます。
それにしても、
CDC* pwDC = pwWnd->GetDC();
の直後にためしに、pwDC->GetPixel(x, y)
で値をとってみても、FFFFFFFFしか返ってこなかったのは、なぜなのでしょうか。
No.4
- 回答日時:
こんにちは。
御礼頂きました。以下で試してみましたが、確かに失敗します。
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プログラム専門の書籍であればこの辺りの事情が書かれているかもしれません。
早速のお返事ありがとうございました。
ほんと、CDCに関しては、いつもややこしくて、勉強をするのもめんどくさく、なかなか深く掘り下げて勉強していないので、苦労しております。
ちゃんと勉強しろよ、と自分にいいながら、、、
でも、hDCをとって、成功した、というのは、大変興味深く、勉強になりました。
ありがとうございました。
わたしは、実は、マルチモニタでの画面キャプチャがしたいのです。
このプログラムでは、マルチモニタには対応していないようです。
これもわかりません。
近く、また別途、質問させていただきますので、ご縁があれば、またよろしくお願いいたします。
No.2
- 回答日時:
良く良く考えたら、手元にMFCどころか開発環境自体無かった…。
うろ覚えですが、DCに対してビットマップオブジェクトを選択していないような。
pwDC->SelectObject(&bm)
とかがGetBitmapBitsの前に要らなかったか?って気がします。
古いオブジェクトは保存しておき、処理後に戻す方が良いです。
お返事ありがとうございます。
関係なさそうです。
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の取り方に問題があるのかもしれません。
No.1
- 回答日時:
> rectには、ちゃんとデスクトップサイズが入っています。
であればその後の、
pwDCにデバイスコンテキストの値が入っているか?
bmにCreateCompatibleBitmapした結果は成功しているか?
colorBufへのmallocは成功しているか?
bmにGetBitmapBitsした結果は成功しているか?
など確認するのが一般的なデバッグ方法です。
お返事ありがとうございました。
pwDC, pwWndには、ちゃんと中身も入っています。
CreateCompatibleBitmapは、TRUEを返しています。
mallocは成功しているかどうかわかりませんが、colorBufにはちゃんとアドレスが入っているので大丈夫でしょう。
GetBitmapBitsは、取得したバイト数、3072000を返り値として、返しています。
つまり、とりあえず、すべてのコマンドはちゃんと成功しているように見えます。
なので、何かが抜けているのか、Bitmapへのコピーでどこかが間違っているのか、pwDCの取り方が間違っているのか、、、
わたしもいろいろ調べてみましたが、よくわかりません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 数学 ScilabのMatplotの引数に関する質問です 3 2022/07/26 12:16
- HTML・CSS cssのclipについて 1 2022/12/17 15:03
- スポーツサイクル ogk rect ladiesについて 男性でも使えますか? 1 2023/04/13 05:49
- その他(プログラミング・Web制作) Pythonによる物理の斜方投射の位置座標表示について 2 2023/06/05 12:46
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- その他(プログラミング・Web制作) Pythonにおける物理のシミュレーションでの単位変換について 2 2023/06/02 17:11
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- その他(プログラミング・Web制作) 物理の斜方投射の目盛り線とx軸、y軸の追加について 3 2023/05/26 21:11
- その他(プログラミング・Web制作) 物理の斜方投射で目盛りに数値を入れたい 2 2023/05/27 06:32
- C言語・C++・C# C言語 共用体について コマンドライン引数で値を2つ入力したときに、argv[2]の値をUNI u1 4 2022/04/25 20:34
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
デスクトップイメージをメモリ...
-
コンテキスト依存とは?
-
エクセルで作った新しいウイン...
-
「アイテムは収集されました」...
-
グラフの交点の求め方(Excel)
-
コントロールの書式設定で、“コ...
-
メッセージボックスを大きくす...
-
エクセルのコントロールツール...
-
コンボボックス内の文字サイズ変更
-
VBAのフォント変更(エクセルか...
-
フォントの大きさ
-
ゲームでは結局どっちが良いの?
-
DateTimePickerでに年月までし...
-
ラジオボタンの初期指定
-
MFCでOnPaintのタイミング
-
VB.NET2005 TextBox 高さ(Heig...
-
文字色を変えたい(ACCESS VBA)
-
エクセルである点からの距離で...
-
ドロップダウンリストのフォン...
-
ダイアログ内コントロールの位...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コンテキスト依存とは?
-
画面がチカチカする
-
コントロール内の文字の背景色
-
ダイアログにビットマップを貼...
-
メモリデバイスコンテキスト&...
-
Active Basic 再描写処理
-
PlgBltでの透過
-
パレット番号で塗りつぶし
-
ビットマップ(表示速度とサイズ)
-
PrintScreenしたあとに画像を保...
-
SetWindowRgn()関数について。
-
OpenGLでウィンドウハンドルの取得
-
VC++のTextOutの再描画の仕方
-
usbデバイスとの通信
-
色描画
-
[Active Basic]BitBltで画像を表示
-
BitBlt関数について教えてください
-
VC++でopenGLを利用したい...。
-
クライアント領域をCBitmapに取...
-
ハードコピーをプログラムから...
おすすめ情報