• 締切済み

CImage::ReleaseDC()のエラーで困っています。

CImage::ReleaseDC()のエラーで困っています。 ウインドウ上に複数の画像を表示し、それぞれ配置や大きさを マウスのD&Dで変えられるようなアプリを作っています。 Visual Studio 2005 C++, MFC 画像はCImageクラスのm_ImageへLoadしてあります。 GetDCでハンドルを取得しているので、ReleaseDCにて開放を 行っていますが、そこで下のエラーになります。 [Second Chance Assertion Failed: File c:\program files\microsoft visual studio 8\vc\atlmfc\include\atlimage.h, Line 1217] 何か解決のヒントになる事がありましたら教えてください。 void CImageButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { (前略) //ウィンドウDC互換Bitmap作成 CBitmap Bmp; Bmp.CreateCompatibleBitmap(pDC, nWidth, nHeight); //メモリDC作成 CDC MemDC; MemDC.CreateCompatibleDC(pDC); //メモリDCにBitmap選択 MemDC.SelectObject(&Bmp); //メモリDCにストレッチ描画 MemDC.SetStretchBltMode(HALFTONE); CDC* pImgDC = CDC::FromHandle(pBtnInfo->m_Image.GetDC()); HDC hImgDC = pImgDC->m_hDC; pBtnInfo->m_Image.StretchBlt(MemDC.m_hDC, 0, 0, nWidth, nHeight, SRCCOPY); pBtnInfo->m_Image.ReleaseDC(); (中略) //四角形を描画 CPen focusPen(PS_DOT, nPenWidth, RGB(nR, nG, nB)); CPen* OldPen = MemDC.SelectObject(&focusPen); MemDC.MoveTo(btnRect.left, btnRect.top); MemDC.LineTo(btnRect.left, btnRect.bottom); MemDC.LineTo(btnRect.right, btnRect.bottom); MemDC.LineTo(btnRect.right, btnRect.top); MemDC.LineTo(btnRect.left, btnRect.top); MemDC.SelectObject(OldPen); //メモリDCからウィンドウDCにビット転送 pDC->BitBlt(0, 0, nWidth, nHeight, &MemDC, 0 ,0, SRCCOPY); (後略)

みんなの回答

  • z64423
  • ベストアンサー率53% (26/49)
回答No.1

(Press Retry to debug the application) って書いてありますから、「再試行(R)」を押してデバッグしましょう。 ソースついてますから、デバッグし放題ですよ。 atlimage.h を読む限り、CImage::ReleaseDC() のアサーションは   hBitmap = HBITMAP( ::SelectObject( m_hDC, m_hOldBitmap ) );   ATLASSERT( hBitmap == m_hBitmap ); で、hBitmap と m_hBitmap が同じじゃなきょダメよ、と言っているので、 GetDC() で m_hDC、m_hOldBitmap がセットされた以降、ReleaseDC() されるまでの間に 値がどの時点で変わっているのかを追っかけていけば、問題の箇所が分かるのでは、と… 当方、DC まわりはサッパリ分からんので、あんまりヘルプできません。

関連するQ&A

  • 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();

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

    環境 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(); }

  • 画像操作について2

    どなたか助けてください。 下記ソースをチェックしていただけないでしょうか? ビットマップ画像処理を行うために、CreateDIBSection()で編集領域を 確保して、imageにコピーして画像操作を行いたいのですが、 Debug Assertion Failedというエラーがでます。 知識不足ということもあり、ソース自体に問題がある可能性の方が高いのですが、 根本的に画像操作に対する考え方が間違っているのでしょうか? ご教授よろしくお願い致します。 環境はVC++6.0 MFC ダイアログベースです BOOL C***Dlg::*******() { HBITMAP hBmp; BITMAPINFOHEADER bi; unsigned *bmbuf; image , MemDC, MemDC2はPublicです。 bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = 16; bi.biHeight = -40; //top-down bi.biPlanes = 1; bi.biBitCount = 32; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; hBmp=CreateDIBSection(NULL, (LPBITMAPINFO)&bi, DIB_RGB_COLORS, (void **)(&bmbuf), NULL, 0); CDC* pDC = this->GetDC(); MemDC.CreateCompatibleDC(pDC); SelectObject(MemDC.m_hDC,hBmp); MemDC2.CreateCompatibleDC(pDC); HBITMAP h_BMP = (HBITMAP)LoadImage(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDB_******), IMAGE_BITMAP, 16, 40, LR_CREATEDIBSECTION); HBITMAP h_OLD_BMP = (HBITMAP)::SelectObject(MemDC2.m_hDC,h_BMP); m_pbg1dc->BitBlt(42,16,100,100,&MemDC2,0,0,SRCCOPY); memcpy(image, bmbuf, 16 * 40 * 4); ::SelectObject(MemDC2.m_hDC,h_OLD_BMP); MemDC2.DeleteDC(); DeleteObject(hBmp); return TRUE; }

  • ピクチャとHBITMAP

    はじめまして。 VC.net winXPでプログラムの勉強をしてるんですが、 裏画面(メモリDC?)の処理がうまくできません。 ピクチャのプロパティをビットマップにしてOnInitDialogで HBITMAPにLoadimageで読み込み 関連しているCstaticにsetbitmapをしてビットマップの表示をしています。 さらにその上にMoveToやらLineToやらで線を引いているんですが、 ウィンドウが隠れた後等の再描画時に引いた線が消えてしまいます。 それを回避する為に裏画面のHBITMAPに描画し、 それをBitBlt等を使ってピクチャに転送すれば良いような事はわかったのですが、 うまくそれを実現する事ができません。 ソースの一部は以下の通りです。 void CtestpictDlg::OnBnClickedDraw()//コマンドボタンを押した時に処理 { //m_StaticPictureにはOnInitDialogでSetBitmap(m_hBmp)として //ビットマップのセットがしてあり、ダイアログを見るとちゃんと表示されている。 CDC dc; CString str; CWnd *h = GetDlgItem(IDC_STATICPICTURE); CDC *hdc = h->GetDC();//ピクチャのDCを取得 dc.CreateCompatibleDC(hdc); HBITMAP test=CreateCompatibleBitmap(hdc->m_hDC,256,256); //ピクチャからビットマップを初期化 HBITMAP* oldbmp = (HBITMAP*)dc.SelectObject(&test); //dcにビットマップを割り当て CPen p(PS_SOLID,1,RGB(0,255,0)); CPen* oldp = (CPen*)dc.SelectObject(&p); dc.MoveTo(10,10); dc.LineTo(100,100);//とりあえず斜めに線を引けるように。 //m_StaticPicture.SetBitmap(test);//ここでtestを見てみると真っ黒な256*256の画像 BitBlt(hdc->m_hDC,0,0,256,256,dc.m_hDC,0,0,SRCCOPY); //UpdateData(FALSE);必要かどうかわからない… //以下に開放処理等 } まだ勉強し始めて日が浅いので、 ちぐはぐな事をしているかもしれませんがよろしくお願いします。

  • PictureControlのハンドルをCImageで取得

    お世話になっております。 VC2005を使用しております。 PictureControlで編集した画像を、CImageを使用してjpgファイルに保存することを行っております。 CDC *pDC = m_Pic.GetDC();でPictureControlのCDC取得 CImage SaveImage;で本体を宣言し、 CDC *SaveImageDC;でCDCを宣言します。 SaveImageDC->BitBlt(0,0,image.GetWidth(),image.GetHeight(),pdc,0,0,SRCCOPY);でコピー を行っておりますが、SaveImageとSaveImageDCを連動させる事ができません。 どのようにすればよいか教えてください。 よろしくお願いします。

  • ビットマップに描画をしてピクチャーコントロールに貼り付けるためには?

    ビットマップに描画をしてピクチャーコントロールに貼り付けるためには どうすればよいでしょうか? ネットで検索しましたそして、 下のようなコードを書きましたがうまくゆきません。 void CXXXView::OnButton() { CStatic m_ctlImage; // ピクチャーボックスに関連付けした変数 CBitmap m_bmpImage; // ピクチャーボックスに貼り付けるイメージ CDC m_dcImage; // Bitmap描画用のDC CDC* pDC = m_ctlImage.GetDC(); m_dcImage.CreateCompatibleDC(pDC); CRect Cltsz; picture1.GetClientRect(&Cltsz); m_bmpImage.CreateCompatibleBitmap(pDC,Cltsz.Width(),Cltsz.Height()); CBitmap* pOld=m_dcImage.SelectObject(&m_bmpImage); CPen myPEN(PS_SOLID,5,RGB(0,0,255)); CPen* oldPEN=m_dcImage.SelectObject(&myPEN); m_dcImage.MoveTo(10,10); m_dcImage.LineTo(100,100); m_dcImage.SelectObject(oldPEN); m_dcImage.SelectObject(pOld); m_ctlImage.SetBitmap(m_bmpImage); } この様にしましたが、ピクチャーコントロールには 何も描画されません、 何故でしょうか? VS2005で、ボタンをクリックした イベントで描画する場合です、 直線とかは、問題なく描画できました。 ビットマップに描画して貼り付けたいのです、 よろしくお願いします

  • 呼び出し時のパラメータが足りない

    自作関数windowcaputureを作成して、 他のmain関数でその関数を呼び出すと "呼び出し時のパラメータが足りない"とエラーがでます。 この自作関数のみでコンパイルすると (windowcaputure → main関数と名前を変更し) きちんと動作することは確認しています。 以下、ソースを載せています。 原因がわかる方、アドバイスお願いします。 void SaveBitmap(HWND hWnd, LPCTSTR sFileName) { HANDLE hFile; HDC hDc, hDcBuf; LPBITMAPFILEHEADER lpHead; LPBITMAPINFOHEADER lpInfo; LPBYTE lpBuf, lpPixel; RECT cRect; HBITMAP hBmp, hOldBmp; DWORD nWriteSize, nFileSize, nWidth, nHeight, nLength; GetClientRect(hWnd, &cRect); // 画面サイズの取得 /* クライアント領域取得 */ nWidth = cRect.right; //幅 nHeight = cRect.bottom; //高さ if( ( nWidth * 3 ) % 4 == 0 ) // ライン長を計算 { nLength = nWidth * 3; } else{ nLength = nWidth * 3 + ( 4 - ( nWidth * 3 ) % 4 ); } nWidth=518; nHeight=610; // ファイルサイズの計算 nFileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + nLength * nHeight; // 一時メモリの確保と各種情報のセット lpBuf = (LPBYTE)GlobalAlloc(GPTR, nFileSize); // バッファの確保 lpHead = (LPBITMAPFILEHEADER)lpBuf; // ファイルヘッダ情報 lpInfo = (LPBITMAPINFOHEADER)(lpBuf + sizeof(BITMAPFILEHEADER));//その他情報 lpPixel = lpBuf + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//ピクセルの取得 // ビットマップ情報のセット lpHead->bfType = 'M' * 256 + 'B'; lpHead->bfSize = nFileSize; lpHead->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); lpInfo->biSize = sizeof(BITMAPINFOHEADER); lpInfo->biHeight = nHeight; lpInfo->biWidth = nWidth; lpInfo->biBitCount = 24; lpInfo->biPlanes = 1; // DCの取得とBMP情報のセット hDc = GetDC(hWnd); // DCの取得 hBmp = CreateCompatibleBitmap(hDc, nWidth, nHeight); // ウインドウのデバイスコンテキスト互換のBITMAP作成 */ hDcBuf = CreateCompatibleDC( hDc ); // DC互換のDCバッファを作成 // BMPのコピー hOldBmp = (HBITMAP)SelectObject( hDcBuf, hBmp ); // 旧BMPの待避 BitBlt( hDcBuf, 0, 0, nWidth=518, nHeight=620, hDc,16,32, SRCCOPY ); // ビットマップのコピー SelectObject( hDcBuf, hOldBmp ); // 旧BMPの復元 GetDIBits( hDc, hBmp, 0, nHeight, lpPixel, (LPBITMAPINFO)lpInfo, DIB_RGB_COLORS ); hFile = CreateFile( sFileName, GENERIC_WRITE, 0, NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL ); if( hFile != INVALID_HANDLE_VALUE ) { WriteFile( hFile, lpBuf, nFileSize, &nWriteSize, NULL ); // ファイルへの書き込み CloseHandle( hFile ); } ReleaseDC( hWnd, hDc ); // DCの解放 DeleteObject( hBmp ); DeleteObject( hDcBuf ); GlobalFree( lpBuf ); } BOOL CALLBACK EnumWndProc(HWND hWnd, LPARAM lParam) { WINDOWINFO wi; char szWindowName[ 128 ]; double caputuretime; wi.cbSize = sizeof(WINDOWINFO); GetWindowInfo(hWnd, &wi); if (wi.dwStyle & WS_VISIBLE) { GetClassName( hWnd, szWindowName, sizeof(szWindowName) ); if(strcmp(szWindowName,"ThunderRT6FormDC")==0){ //ウィンドウを前面にして書き直させる SetForegroundWindow(hWnd); Sleep(100); caputuretime = time(NULL); itoa(caputuretime , yy, 10);/* 10 は十進数変換 */ //キャプチャ習得時間をファイル名に strcat(yy, ".bmp"); SaveBitmap(hWnd,yy); } } return TRUE; } int windowcaputure(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR lpCmdLine,int nCmdShow) { EnumWindows(EnumWndProc, 0);/*画面上のすべてのトップレベルウィンドウを列挙*/ return 0; }

  • VC++のOnDraw()関数で、ボールを動かす

    下記のように、VC++のOnDraw()関数において、ウィンドウ上でボールを上下に 動かせたいのですが、動きません。VC++のバージョンは9.0です。(Visual Studio 2008) どういうふうに書けば動きますか? ------------------------------------------------------------------------- void CControllGameView::OnDraw(CDC* pDC) { Bitmap2.LoadBitmap(IDB_BITMAP2); // ボール pOldBitmap = MemDC.SelectObject(&Bitmap2); // 転送前のビットマップ領域を退避 GetClientRect(&rect); // ウィンドウのサイズをrectに記憶 pDC->BitBlt((rect.right-42)/2, rect.top+50, 42, 41, &MemDC, 0, 0, SRCCOPY); // ビット単位でビットマップ画像を転送 int z = rect.bottom + 50; // ボールのy座標の初期値 while(z < rect.top){ pDC->MoveTo((rect.right-42)/2, z+=1); } MemDC.SelectObject(pOldBitmap); // 元に戻す ReleaseDC(pDC); }

  • VC++でのアイコン背景透過について

    VC++2013 MFC環境です。 プログラムで○や×などの記号のアイコンを描画し、PNG,GIF,JPEGの形式でファイルに保存したいです。その時、アイコンの背景を透過したいのですがうまくいきません。 CDCクラスとCImageクラスを使用しアイコンの出力をしています。 背景透過について調べていくつか使えそうな関数があり試したのが、TransparentBltという関数で、デバイスコンテキストを二つ用意して、片方に記号を描画し、透過したい色を指定してもう片方にコピーすると指定した色が透過になる?と解釈しプログラム組みましたが結果は真っ黒の画像でした。 ここで完全に手が止まってしまい、質問させていただきます。 以下ソース CImage Image, image2; Image.Create( 50, 50, 24 ); image2.Create( 50, 50, 24 ); CDC* pDC = CDC::FromHandle( Image.GetDC( ) ); CDC* pdc2 = CDC::FromHandle( image2.GetDC( ) ); CRect rect( 0, 0, 50, 50 ); CPen BlackPen( PS_SOLID, 3, RGB( 0, 0, 0 ) ); CBrush WhitBrush( RGB( 255, 255, 255 ) ); CBrush BlackBrush( RGB( 0, 0, 0 ) ); pDC->FillRect( &rect, &WhitBrush ); pDC->SelectObject( &BlackPen ); pDC->SelectObject( &WhitBrush ); pDC->Ellipse( 5, 5, 45, 45 ); COLORREF col = Image.GetPixel( 0, 0 ); pdc2->TransparentBlt( 0, 0, 50, 50, pDC, 0, 0, 50, 50, col ); Image.SetTransparentColor( col ); image2.Save( L"c:\\icon\\maru.png" ); Image.ReleaseDC( ); image2.ReleaseDC( ); 他にも実装例があれば教えてください。 C++や画像生成に関しては経験がありません。

  • メモリーリークの原因

    お世話になっております。 VC2005を使用しております。 現在作成したいプログラムは、 (1)picture controlにて画像を編集する。(Pic1) (2)それをjpgファイルで保存する。 という事なのですが、下記プログラムにて、このルーチンを抜けた後に メモリーリークが発生してしまいます。saveの部分をコメントアウトすると発生しないため、ここが原因だと思いますが、どうして発生するかわかりません。 CImage SaveImage; RECT rect; CDC *pDC = m_Pic1.GetDC(); // ピクチャボックスのDC CDC *SaveImageDC;         //保存用のDC m_Pic1.GetClientRect(&rect); SaveImage.Create(rect.right,rect.bottom,24,0); SaveImageDC=CDC::FromHandle(SaveImage.GetDC()); SaveImageDC->BitBlt(0,0,rect.right,rect.bottom,pDC,0,0,SRCCOPY); SaveImage.Save("PP.jpg"); ReleaseDC(pDC); ReleaseDC(SaveImageDC); 何が悪いのか、どうすればよいか教えていただけないでしょうか? よろしくお願いします。

専門家に質問してみよう