クライアント領域をCBitmapに取り込む方法

このQ&Aのポイント
  • VC6.0MFCでクライアント領域(みたまま)をCBitmapに取り込む方法を教えてください。
  • OnPaint関数で描画用のデバイスコンテキストを作成し、クライアント領域のサイズと同じサイズのCBitmapを作成します。
  • 作成したCBitmapのハンドルをクリップボードに設定し、クライアント領域の画像を取り込みます。
回答を見る
  • ベストアンサー

クライアント領域をCBitmapに取り込みたい

VC6.0MFCで クライアント領域(みたまま)を CBitmapに取り込みたいのですがどうすればよいのでしょうか? ためしにダイアログの領域をクリップボードに取り込むコード OnPaint書いたのですが真っ黒の画像しか取り込めていませんでした。 根本的に使うAPIが違うのでしょうか? void CCaptureDlg::OnPaint() {  CPaintDC dc(this); // 描画用のデバイス コンテキスト  CRect cr;  GetClientRect(&cr);  dc.TextOut(0,0,"テスト");  CDC* pDC = new CDC();  pDC->CreateCompatibleDC(&dc);  CBitmap img;  img.CreateCompatibleBitmap(pDC, cr.Width(), cr.Height());  OpenClipboard();  ::EmptyClipboard();  ::SetClipboardData(CF_BITMAP, img.GetSafeHandle());  ::CloseClipboard();  pDC->DeleteDC();  delete pDC;  CDialog::OnPaint(); }

質問者が選んだベストアンサー

  • ベストアンサー
noname#5537
noname#5537
回答No.1

そのソースでは,コピーしてないですね。 BitBlt でコピーすればいいと思います。 OnPaint ではなくて適当なボタンのイベントハンドラで, CClientDC からコピーしてくるほうがいいと思います。

sha-girl
質問者

お礼

ご回答有難うございます。 CBitmapに格納したいのですが BitBltで格納できるのでしょうか? GetBitmapBitsで格納する必要があると聞いたのですが。

sha-girl
質問者

補足

GetBitmapBitsはデータの配列を吐き出すほうですね。 勘違いしてました。

関連するQ&A

  • 非クライアント領域への描画について

    非クライアント領域に文字を書こうとしました。 以下の(2)では書けますが、(1)では書いてくれません。 CPaintDCはクライアント領域でないとダメなのですか? void CMainFrame::OnPaint() { CPaintDC dc(this); // 描画用のデバイス コンテキスト dc.TextOut(0,0,"こんにちは"); ・・・(1) CDC* pDC = GetWindowDC(); pDC->TextOut(100,0,"こんにちは"); ・・・(2) 環境 WIN98 VC++6.0 MFC

  • クライアント領域のコントロールが描画されない

    WindowsXP / VC2005 / VC++ MFCにてダイヤログベースの画像ビューワの作成を行っています。 機能としては、独自形式のバイナリファイルをダイヤログへドラッグ&ドロップすることにより、 メモリに描画した画像をクライアント領域へ転送して表示します。 こちらが疑問点となるところなのですが、その際にもともと配置していた エディットボックスやスピンボタンなどのコントロールが消えてしまいます。 (見えなくてもボタンを押すことはできるので描画の問題と思われます) 1.なぜこのようなことが起こるのでしょうか? 2・また、コントロールを消さないためにはどうすればよいのでしょうか? 上記に関してご回答いただけると幸いです。 個人的な考えとしては、  1.クライアント領域を描画する際にコントロールを消してしまっている  2.再描画することによりコントロールは表示される(但し問題点としてクライアント領域を書き換える際にちらつく) です。 以下該当関数です //------------------------------------------------------------------------------ void CTestBitBltDlg::OnDropFiles(HDROP hDropInfo) { char acFileName[256]; SHORT sRet; memset(acFileName, 0, sizeof(acFileName)); DragQueryFile(hDropInfo, 0, acFileName, sizeof(acFileName)); memcpy( g_acSpriteFileName, acFileName, 256 - 1 ); CRect rc; GetClientRect(&rc); CClientDC dc(this); CDC dcMem; dcMem.CreateCompatibleDC(&dc); CBitmap bmp; bmp.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height()); CBitmap* pOldBmp = dcMem.SelectObject(&bmp); dcMem.FillSolidRect(&rc, RGB(0xC0, 0xC0, 0xC0)); // 本関数にてメインとなるメモリDCへの描画をおこなってます sRet = GetMemoryImage(g_acSpriteFileName, 0, &dcMem); if( sRet == FALSE ){ GetDefaultImage(&dcMem); } dc.BitBlt(0, 0, rc.Width(), rc.Height(), &dcMem, 0, 0, SRCCOPY); dcMem.SelectObject(pOldBmp); //InvalidateRect(FALSE); CDialog::OnDropFiles(hDropInfo); } //------------------------------------------------------------------------------ なお、OnEraseBkgnd関数においてはTRUEのみを返すようにしてます。

  • ダイアログにビットマップを貼り付けた時にフリーズしてしまう

    お世話になります、fujicafeです。 現在、MFCにてダイアログベースのアプリケーションを作成中なのですが、ダイアログにビットマップを貼り付けてOnPaint()で表示するようにプログラムを作成したのですが、何度かダイアログの表示を繰り返すとOnPaintでのビットマップの読み込みが途中まででフリーズしてしまう現象が起きてしまいました。 プログラムは以下のように作成しています void C****Dlg::OnPaint() {  CDC* pDC = this->GetDC(); CDC myDC; CBitmap newbitmap; CBitmap* oldbitmap; CRect rc; GetClientRect(rc); newbitmap.LoadBitmap(IDB_BITMAP); myDC.CreateCompatibleDC( pDC ); oldbitmap=myDC.SelectObject( &newbitmap ); pDC->BitBlt( 0, 0, rc.Width(), rc.Height(), &myDC, 0, 0, SRCCOPY ); myDC.SelectObject(oldbitmap); } としています。 初めにこのダイアログを表示時は、ちゃんとビットマップが表示されるのですが、他のダイアログでこのダイアログを表示させた時にビットマップが上半分まで表示されて、動作がフリーズしてしまう現状です。 なにかよい打開策がありましたら、教えていただけたらと思っています。宜しくお願いいたします。

  • CreateCompatibleDCを初期化時にしたい(MFC)

    MFCでJPEG画像を表示するプログラムを OnPaint() の中に書いていたのですが・・・  : bool m_bImageMemDCInit; CImage m_Image; CBitmap *m_pImageBitmap; CDC m_ImageMemDC;  :  : void CChildView::OnPaint() {  CPaintDC dc(this);  if(!m_bImageMemDCInit){   m_bImageMemDCInit = true;   // イメージをロード   m_Image.Load("test.jpg");   m_pImageBitmap = CBitmap::FromHandle(m_Image);   m_ImageMemDC.CreateCompatibleDC(&dc);   m_ImageMemDC.SelectObject(m_pImageBitmap);  }  // 描画  dc.BitBlt(0, 0, 256, 256, &m_ImageMemDC, 0, 0, SRCCOPY); } このように、Load や CreateCompatibleDC などの初期化にあたる処理を、起動時に1度しか処理しないように書いています。 しかし、このプログラムではあまりに汚い。どうにかして PreCreateWindow などの初期化関数内に書きたいのですが、CreateCompatibleDC 関数で CPaintDC* を渡す必要があるので、OnPaint 関数内に書かざるを得ないのです。 (Loadだけなら初期化関数内に移せるのですが・・・) いっそ CreateCompatibleDC を再描画のたびに呼んでもいいのでは? と思い、やってみると異常終了してしまいました。 また、CPaintDC dc(this); を PreCreateWindow 関数内に書いても異常終了しました。 どなたかスマートな方法をご存知でしたら、ご指導願います m(_ _)m

  • Visual C++のStretchBltについて

    こんにちは VC++で壁紙チェンジャーのプログラムを作成していたのですが、壁紙画像をStretchBltをつかってプログラムの中に表示させたいのですが、pDCをつかって呼び出すさいpDC->StretchBlt();の括弧ないは何を記述すればよいのですか?わかるかたいたらご指導ください。参考までに前後の文 OnPaint 省略 else { CRect ClientRect; GetClientRect(ClientRect); BITMAP BMP; HBITMAP h_BMP=(HBITMAP)LoadImage(AfxGetApp()->m_hInstance,_T(m_filename), IMAGE_BITMAP,0,0,LR_LOADFROMFILE); CDC* pDC=this->GetDC(); CDC MemDC; MemDC.CreateCompatibleDC(pDC); HBITMAP h_OLD_BMP=(HBITMAP)::SelectObject(MemDC.m_hDC,h_BMP); ::GetObject(h_BMP,sizeof(BITMAP),&BMP); //////////////////////////////        ここ→pDC->StretchBlt(); ////////////////////////////// ::SelectObject(MemDC.m_hDC,h_OLD_BMP); MemDC.DeleteDC();

  • ダイアログの表示と同時に、ピクチャーボックスを塗る方法

    あるサイトの過去ログで以下を見つけました。 エラーは出ませんが、何も起こりません。 このコードは何をしようとしているのでしょうか? ************************* ダイアログ上にピクチャーボックスを配置して、ダイアログの表示と同時に、ピクチャーボックスを塗る方法。 まず、ピクチャコントロールをClassWizardのメンバ変数タブによりm_pictureとして実態を作成します。 その後、 class CPictureDlg { private: CBitmap m_bitmap; // ... }; BOOL CPictureDlg::OnInitDialog() { CDialog::OnInitDialog(); // ... CDC desktopDC; desktopDC.Attach ( ::GetDC ( NULL ) ); CDC memDC; memDC.CreateCompatibleDC ( &desktopDC ); m_bitmap.CreateCompatibleBitmap ( &desktopDC, 100, 100 ); CBitmap *pOldBitmap = memDC.SelectObject ( &m_bitmap ); CRect rcPicture ( 0, 0, 100, 100 ); CBrush brush; brush.CreateStockObject ( WHITE_BRUSH ); memDC.FillRect ( &rcPicture, &brush ); memDC.SelectObject ( pOldBitmap ); m_picture.SetBitmap ( ( HBITMAP ) m_bitmap.GetSafeHandle () ); ReleaseDC ( &desktopDC ); memDC.DeleteDC (); }

  • ウィンドウのフレームの色変更

    <環境> Win98 VC++6.0 MFC よろしくお願いします。 ダイアログのボタン押し下げにて、新規にウィンドウを作成しています。 新規に作成したウィンドウのクライアント領域の色は、 CPaintDC dc(this); // 描画用のデバイス コンテキスト CRect cr; GetClientRect( &cr); dc.FillSolidRect( cr, RGB( 250, 250, 0)); dc.DrawText( moji,cr, DT_SINGLELINE | DT_VCENTER | DT_CENTER); にて変更することが出来ました。 クライアント領域の外側にあるフレームの色も変更したいのですが、 どのようにすれば実現可能でしょうか? ご存知の方、教えてください。お願いします。

  • VC++2010 で線形の描画についてですが・・

    VC++2010 で線形の描画についてまた質問なんですが、以下のように記述すると線ができなく、 点だけが動くプログラムになりました。解決方法がわからないのでよろしくお願いします。 今回のプロジェクトの目的はある機器からデータを取ってきて(1msごとに)それを1msごとに 直線として出力するプロジェクトです 電圧                    ↑          ________ ↑         |          |________→→ ーーーーーーーー  →→時間 ↑↑↑ このような線を出力しなければならないです。 以下がソースになっています。 使用環境VC++2010 MFC test10000Dlg.cpp ちなみにm_lineXとm_lineYはメンバー変数です(double型) ボタンがクリックされたときのイベント SetTimer(0, 1, NULL); void Ctest10000Dlg::OnTimer(UINT_PTR nIDEvent) { UpdateData(); after_datay = sam_data; m_xvEditX = m_lineX; m_xvEditSamd = m_lineY; m_xvEditSami = sam_i++; if(sam_i%200==0) { m_lineY -= 5; sam_i = 0; } m_lineX++; UpdateWindow(); Invalidate(FALSE); } void Ctest10000Dlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 描画のデバイス コンテキスト SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // クライアントの四角形領域内の中央 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // アイコンの描画 dc.DrawIcon(x, y, m_hIcon); } else { //****************************************************************************************************** CRect rect_dlg; GetClientRect(&rect_dlg); CBrush br_black(RGB(0,0,0)); //各色ペン CPen pen_black(PS_SOLID,1,RGB(0,0,0)); CPen pen_gray(PS_DOT,1,RGB(128,128,128)); CPen pen_blue(PS_SOLID,1,RGB(0,0,255)); CPen pen_white(PS_SOLID,1,RGB(255,255,255)); int max_y=1; if(int(m_sin+m_cos+1.0)>max_y) max_y=int(m_sin+m_cos)+1; CDC* pDC=m_pict.GetDC(); //PictureControlの大きさ取得 CRect rect; m_pict.GetClientRect(&rect); //元のブラシをoldbrに保持 CBrush* oldbr=pDC->SelectObject(&br_black); //元のペンをoldpenに保持 CPen* oldpen=pDC->SelectObject(&pen_black); //(1)背景描画(ブラシ白、ペン黒) pDC->Rectangle(&rect); //(2)中心線(黒、実線) pDC->SelectObject(&pen_blue); pDC->MoveTo(10,rect.Height()-10); pDC->LineTo(10,10); pDC->MoveTo(10,rect.Height()-10); pDC->LineTo(rect.Width()-10,rect.Height()-10); pDC->SelectObject(&pen_white); pDC->MoveTo(m_lineX,m_lineY_after); pDC->LineTo(m_lineX+1,m_lineY); pDC->SelectObject(oldbr); pDC->SelectObject(oldpen); m_lineY_after = m_lineY; UpdateData(FALSE); CDialog::OnPaint(); } } ではよろしくお願いします

  • オブジェクトの削除について

    環境 WIN98 VC++6.0 MFC にて オブジェクトを使い終わってから削除している場合としていない場合が有るのですが、どうしてなのですか? 作ったオブジェクトはなんでもかんでも削除したほうが無難な気がしますが、本にのっているコードで削除してない場合も良く見かけます。 <削除していない>//著名な本のコード void Cxxx::OnDraw(CDC* pDC) {  CBitmap bmp;  bmp.LoadBitmap(nID);  略  //bmp.DeleteObject(); //■この記述が無い } <削除している>//ネット上でみかけたコード void CMainFrame::_SetBmp(CWnd* pBox,int nID,int  width,int height) // 単品 {  CDC* pDC=pBox->GetDC();  CDC memDC;  CBitmap bmp;  bmp.LoadBitmap(nID);  memDC.CreateCompatibleDC(pDC);  CBitmap* pOldBmp=memDC.SelectObject(&bmp);  pDC->BitBlt(0,0,width,height,&memDC,0,0,SRCCOPY);  memDC.SelectObject(pOldBmp);  bmp.DeleteObject();  memDC.DeleteDC(); }

  • ちらつきについて

    ゲームをつくっているのですが、画面がちらつくのが気になり、直そうと、ネットで調べたのですが、裏画面に一度、ビットマップを表示させて、それをデバイスコンテキストに転送する?ってやりかたがよくわかりません。 CMyFrameWnd::OnPaint(){ CPaintDC dc(this); CDC MemDC; CBitmap bitmap1; bitmap1.LoadBitmap("IDB_BITMAP1"); ...略 for(j=0;j<30;j++){ for(k=0;k<30;k++){ MemDC.SelectObject(&bitmap1); dc.Blt(j*32,k*32,32,32,&MemDC,0,0,SRCCOPY); } } } 見たいな感じです。なにぶんc,c++始めたばっかりでデバイスコンテキストとかもよくわかってないんでわかりやすい説明お願いします。