• ベストアンサー

MFCのメモリ開放が必要なメソッド

現在、MFCを使ってドローツールを作成しています。 今まで、DCの取得にGetDC()を多用していたのですが、 今日初めて、GetDC()とReleaseDC()は必ずセットで使う事を知りました。 恥ずかしい話ですが、まだまだMFCには詳しくありません。 このように、WindowsのC言語開発でメモリ開放がセットになっている関数で 初心者がよく失敗しがちなものが他にもありましたら教えて下さい。 どうぞ宜しくお願い致します。

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

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8536/19406)
回答No.1

>このように、WindowsのC言語開発でメモリ開放がセットになっている関数で >初心者がよく失敗しがちなものが他にもありましたら教えて下さい。 ほとんどすべてがそうです。 ある程度は「プログラムが終了する際に自動的に開放」されますが、プログラムが終了してもシステムに残る(リークする)のが普通です。 特に「ハンドルを返すもの」は、ハンドルのクローズが必須です。 ハンドルは「ハンドルをオープンしたプロセスが、別プロセスにハンドルを渡して、自分は居なくなる」って言う使い方をする事があるので、オープンしたプログラムが終了してもオープンされたまま残ります。 ですので「オープンしたハンドルは、誰かが必ずクローズする」が鉄則。 あと、良くミスるのが、FindFirstFileをやって、FindNextFileして、最後にFindCloseFileを忘れる、っていうミス。 FindFile系は「検索時に内部リソースを使う」ので、FindCloseFileをしないと、リソースがリークします。

ken2r
質問者

お礼

これからは、教えていただいたようにクローズ処理を 常に気にしながらプログラムしたいと思います。 ご返信有難うございました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • MFC VC++ 6.0 使用 

    class patchmodel{ double a; double b; private: void Draw(); } void patchmodel::Draw(){ CDC DC; CDC* dc = GetDC(); dc->TextOut((int)a,(int)b,"HELLO"); ReleaseDC( dc ); } と 実行してみたところ エラーがでます。 error C2660: 'GetDC' : 関数が不正な 0 個の実引数をともなって呼び出されました。 error C2660: 'ReleaseDC' : 関数が不正な 1 個の実引数をともなって呼び出されました。 CModel::OnDraw(CDC* pDC) を あえて使わずに 実行したいので このように 簡単なもので 試して見たのですが、うまくいきません。 GetDC の使い方を まちがえているのでしょうか? お返事ください。

  • メモリの使用状況を解析するツール

    現在、MFCを使ってドローツールを作成しています。 C言語で開発しているため、リソースの開放は必需なのです。 そこで質問なのですが、開発中のプログラムがリソースを食いつぶしていないか チェックするツールのようなものは在るのでしょうか? (自分の書いたソースのリーク場合は検出できます) 有償無償は問いませんので、便利なツールをご存知の方がいましたら 教えて下さい。どうぞ宜しくお願い致します。

  • MFC デバイスコンテキストについて

    MFCのデバイスコンテキストを取得して、DirectXなどで描画を行っています。 環境は、 VS2008 DirextX 9.0 MDIなんですがOnInitDialogでDirectXのデバイスを取得しています。 次にOnDrawで描画を行っています。 GetDcでコンテキストを取得し、円の描画を行っています。 MDIですので、5以上のファイルを作成すると、描画が行われなくなります。 共通デバイスコンテキストは、5以上持てないということは検索して分かったのですが、5以上のファイルに描画を成功させるためには、どうすればいいのでしょうか? ・単純に新規ファイルを作ったときに、以前に作ったファイルのデバイスコンテキストを開放また、Directxのデバイスを開放すればいい? ・DirectXのデバイスをファイルごとに作成するのではなく、共通してもてば解決できる?? ・そもそも解放したりしても無理?? と考えているのですが、どうでしょうか? 助言をお願いします。

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

  • Accessで、メモリを開放するタイミング

    すみませんが、教えてください。 次のコードように、SQL命令を2回以上行う場合、メモリの開放は、最後だけでよいのでしょうか? これでも、一応動くのですが、メモリを余計に消費していないのかどうか、よく分かりません。 SUB SAMPLE() Dim CN As ADODB.Connection Dim RS As ADODB.Recordset Dim SQL As String '接続 Set CN = CurrentProject.Connection 'レコードセットを取得(1) Set RS = New ADODB.Recordset SQL = "SELECT COUNT(*) AS CNT FROM 生徒名簿 WHERE クラス = 'TS'" RS.Open SQL, CN, adOpenKeyset, adLockOptimistic Msgbox(CNT) 'レコードセットを取得(2) Set RS = New ADODB.Recordset SQL = "SELECT COUNT(*) AS CNT FROM 生徒名簿 WHERE クラス = 'WS'" RS.Open SQL, CN, adOpenKeyset, adLockOptimistic Msgbox(CNT) '終了 RS.Close: Set RS = Nothing CN.Close: Set CN = Nothing End Sub

  • GetDC()とCreateCompatibleDC()

    お世話になっています。 GetDC(NULL)とCreateCompatibleDC(NULL)で得られるhdcの違いがよくわかりません。 以下のプログラムA,Bで得られるのhDCw1,hDCw2に違いはありますか? A: hDCw1 = CreateCompatibleDC(NULL); //現在の画面と互換性のあるメモリデバイスコンテキスト hDCw2 = CreateCompatibleDC(NULL); <<hDCw1,hDCw2を使用>> DeleteDC(hDCw1); DeleteDC(hDCw2); B: hdc = GetDC( NULL ); // 画面全体を表すデバイスコンテキスト hDCw1 = CreateCompatibleDC(hdc); hDCw2 = CreateCompatibleDC(hdc); <<hDCw1,hDCw2を使用>> ReleaseDC( NULL, hdc ); // 取得した HDCの開放 DeleteDC(hDCw1); DeleteDC(hDCw2);

  • VC++6.0 MFC GetCommandLine()で取得したコマンドラインをすでに起動しているプログラムに渡す。

    お世話になります。 VC++6.0 MFC で開発しております。 プログラムAでGetCommandLine()で取得したコマンドラインをすでに起動しているプログラムBに渡すにはどのような関数を使えばよいのでしょうか? お手数ですが、何卒よろしくお願いします。

  • デスクトップイメージをメモリに取り込むには

    今、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には、ちゃんとデスクトップサイズが入っています。 なにが悪いのでしょうか。

  • MFC SDIアプリで開いているファイルを再度開く方法

    お世話になります。 VC++6.0 MFCを使ってSDIアプリを開発していますが、ウィザードが生成したスケルトンのシリアライズ関数についての質問です。 このシリアライズ関数は、「ファイル」メニューの「開く」コマンドで既に開いているファイルを指定すると、呼ばれないようです。 MSDNではDeleteContents関数で開いているドキュメントを捨てれば良いように書いてありますが、サンプルコードはアロケートメモリの解放位で、どうすればシリアライズ関数を呼び出してくれるのか判りません。 ご存じな方は教えて下さい。

  • MFCプロジェクト

     はじめまして。 realと申します。  早速で申し訳ございません。  MFCで、Cドライブ直下にtxtを吐き出す簡単なexeを作成し、 そのexeのフォルダを共有フォルダ設定したフォルダに置き、 同ネットワーク階層にいる別のパソコンからそのexeを起動すると、 exeを起動したパソコンのCドライブ直下にtxtファイルを吐き出すようになります。  これを、exeを起動したパソコンではなく、exeが存在するパソコンのCドライブにtxtを吐き出せるようにしたいのです。  しかし、方法が見つかりません。 どなたか、よい案をおもちであれば、 ご教授よろしくお願いいたします。  私は、MFCとJavaなら微力ながら開発可能です・・・。 OS:Windows XP Professional SP3 CPU:Pentium 4 3.4GHz メモリ:1G 言語:MFC