winhand.cppで発生する例外の原因とは?

このQ&Aのポイント
  • VC6.0で開発されたMFCプロジェクトをVS2015用に変換したプロジェクトで、OnPaint()にて描画処理を追加した際に例外が発生しています。
  • 例外の内容はDebug Assertion Failed!というメッセージであり、エラー解析の方法や原因の特定に苦労しています。
  • 同様の処理を空のVS2015 MFCプロジェクトで行った場合には問題なく動作するため、問題の原因を特定するための手段を模索しています。
回答を見る
  • ベストアンサー

winhand.cpp で発生する例外の原因

VC6.0で開発されたMFCプロジェクトをVS2015用に変換したプロジェクトを使用しています。 OnPaint()にて描画処理を追加したいのですが、ピクチャコントロールに対してGetDCを行っただけで例外が発生し、 下記の内容のログが出て中断してしまいます。 --------------------------------------- Debug Assertion Failed! Program: C:\WINDOWS\SYSTEM32\mfc140d.dll File: f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\winhand.cpp Line: 210 For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts. --------------------------------------- この例外をどのようにエラー解析していけばよいか、原因も見当がつかず困っています。 上記にパスが示されていますが、使用しているマシンにそのようなフォルダは見当たりません。 エラーの内容は常に同一です。 なお、VisualStudio2015で空のMFCプロジェクトを作成し、OnPaint()で同様の処理を行った場合には問題なく動作します。 本来であれば新しくVS2015で作り直して一から検証した方がいいと思うのですが、実装済みの機能が多いため、できれば最終手段としたいと思います…。 よろしくお願い致します。 OS:Win10 開発環境:VisualStudio2015 C++ ■以下OnPaint()中で呼び出している処理 引数にはピクチャコントロールへのアドレスを渡しています --------------------------------------- void CCtfCheckSTCDlg::TestOnPaint(CWnd* pcWnd) {     CDC* pDC = pcWnd->GetDC();     if(pDC != NULL)     {         BOOL blRet = pDC->DeleteDC();     } } ---------------------------------------

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

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

CWnd::GetDCでアサートチェックされるのは、ウィンドウハンドルが有効かどうかだけのはずです。 ・渡したポインタがCWnd(もしくはその派生クラス)のオブジェクトではない ・ピクチャーコントロールがまだ生成されていない ・ピクチャーコントロールがすでに破棄されている ・ピクチャーコントロールとコントロール変数がDDX等で結び付けられていない ・CWnd::fromHandleで生成された一時オブジェクトを変数に保存して、後で使いまわしている といった原因が考えられます。 オブジェクトのm_hWndの値を調べて、ピクチャーコントロールのハンドルと一致しているか調べてみましょう。

umiushi21
質問者

お礼

ご回答ありがとうございました。 ご指摘頂いたように、ピクチャコントロールのハンドルの流れを調べてみたところ、起動時にGetDC()して取得したデバイスコンテキストをメンバ変数で管理し、別関数では再度同一のピクチャコントロールに対して(ReleaseDC()前に)GetDC()していたのが原因のようでした。 このGetDC()の再呼び出しを回避したところエラーは出なくなりました。 大変助かりました、ありがとうございました

関連するQ&A

  • CStaticコントロールの静的イメージ描画

    はじめまして、質問させてください。 VC++ 2005 MFC で開発しております。 Picture Control(DDX CStasic型)に イメージ(外部ファイル JPG)を静的に描画させたいのですが 方法がわかりません。 お詳しい方がおられましたら、ご教授お願いいたします。 ちなみに CImageを使用して描画はできるのですが その場合、OnPaintをオーバーライドして 描画更新処理を書かないと一度だけ描画されて終わって しまうと思います。 CStaic変数にロードしたら 再度ロードされるまで ずっと描画させていたいです。 以上になります。 宜しくお願いいたします。

  • C++の例外(SEHの例外を有効にする)

    VisualStudio2005 でC++のコンパイルしていますが、 「cl : コマンド ライン warning D9025 : '/EHs' より '/EHa' が優先されます。」 っていう警告を出ないようにしたいんですが、どうしたらいいでしょうか? /EHaの例外を処理するようにしたいです。 MSDNみたけど、解決できませんでした。 http://msdn.microsoft.com/ja-jp/library/8k3f51f1(VS.80).aspx お互いに排他なオプションなんだから /EHsを外せばいいだけだと思うんだけど /EHs ってどこで定義されていますか?

  • VisualStudioでC関数の呼び出し

    VisualStudio2008のなんらかのプロジェクトから C関数の呼び出しを行いたいのですが、 現在、VC++とMFCでWindowsForm等を作成して そこからextern"C"でC言語の関数をcallしているのですが MFC自体、無くなりつつあり、VS2008EXPRESSではサポートされていません。できれば無料版のEXPRESSで実現したいのですが どういう方法があるでしょうか? ダイアログとボタン程度のWindowsFormは使用したいのですが。

  • メモリーリークの原因

    お世話になっております。 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); 何が悪いのか、どうすればよいか教えていただけないでしょうか? よろしくお願いします。

  • pictureBoxの例外処理

    VC++2010Expressを使用しています。 pictureBox1->ImageLocation = "○○.jpg"として、画像を表示しています。ただし、おそらく、この画像ファイルにやや損傷があるため、次の2つの事象のいずれかが発生しています。 1)画像は表示されるものの例外が発生する(VSの出力ウィンドウに表示される。) 2)例外が発生して、プログラムが落ちてします。 これらを回避する方法を教えてください。例外処理に詳しくないので具体的方法を宜しくお願い致します。

  • クライアント領域を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(); }

  • 画像処理したBitmapをピクチャボックスで表示すると、例外が発生して

    画像処理したBitmapをピクチャボックスで表示すると、例外が発生してしまいます。 使用言語はVC#、開発環境はVisual Stdio 200です。 コードは以下の通りです。 class MyClass { Bitmap bmp_result;  public MyClass() { bmp_result = new Bitmap(1024,768,PicelFormat.24bpprgb); } while (true) { ・スクリーンショット画像を撮影し、bmp_resultに格納 ・bmp_resultに対して画像処理  //結果をピクチャボックスに表示。 Invoke(new UpdateDelegate(UpdateUI)); } private void UpdateUI() { pictureBox1.Image = this.bmp_result; } } 実行すると、 bmp_resultに対する画像処理のところで 「オブジェクトは現在他の場所で使用されています。 」 という例外が発生してしまいます。 invokeをコメントアウトすると、例外は発生しなくなります。 よって、UpdateUI関数と、無限ループ内の画像処理とが衝突しているのではないかと 思っているのですが、どう直せば解決するのかわかりません。 どなたかアドバイスをください!

  • VisualC++6.0にてボタンにビットマップを表示させる方法

    VisualC++6.0のダイアログベースのアプリにおいて、 フォーム上に配置したボタン上にビットマップを表示 させたいと思ってます。OnPaint()の中で、以下のコード を書いたのですが、うまくいきません。  CWnd* myWnd = GetDlgItem(IDC_BUTTON1);  CDC* pDC = myWnd->GetDC();  CDC myDC;  CBitmap myBMP;  myBMP.LoadBitmap(IDB_BITMAP);  myDC.CreateCompatibleDC(pDC);  CBitmap* oldBMP = myDC.SelectObject(&myBMP);  pDC->BitBlt(0,0,100,100,&myDC,0,0,SRCCOPY);  myDC.SelectObject(oldBMP); ビットマップはちゃんと書かれてはいますが、その上にボタンが 描かれてしまうので、ビットマップが隠されてしまいます。 解決方法を教えてくださいますでしょうか。 よろしくお願いします。 % 絵をクリックするとアクションを起こすようにしたいので、 % ピクチャーボックスでも試してみました。これだとビット % マップはちゃんと表示されますが、BN_CLICKEDを書いて % ピクチャーボックスをクリックしてもOnPict()に処理が % 移りません。

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

    非クライアント領域に文字を書こうとしました。 以下の(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

  • 複数のプロジェクトがある場合のデバッグについて

    開発環境はVisualStudio2008 、C++にてSDK開発(非MFC)です。 同じような機能を使う通信プログラムを作っており、 クラスファイルを共通で使いたいので 1つのソリューションに2つのプロジェクトを作っています。 デバッグをしたいのですが、最初に作ったプロジェクトが必ずデバッグされてしまいます。 [F5]キーを押した時に、どのプロジェクトをデバッグするか指定する方法はどうすれば良いでしょうか?