OLE パッケージ オブジェクトを含むドキュメントを開くと GDI オブジェクトが増加する

こんにちは、Visual Studio サポート チームです。 今回は、OLE パッケージ オブジェクトをプログラムから利用した場合に発生する問題についてご案内します。   現象 アプリケーションから OLE パッケージ オブジェクト (*1) を含むドキュメントを開いて閉じる操作を繰り返すと、アプリケーションの GDI オブジェクトの使用量が増加します。 増加量は僅かであるため、ほとんどのアプリケーションではこの問題が影響することはありませんが、パッケージ オブジェクトを含むドキュメントを、開いて閉じる動作を繰り返すようなアプリケーションでは、GDI オブジェクトの総量がプロセスごとに割り当てられた上限 (既定で 10,000) に達し、それ以降の GDI オブジェクトの生成に失敗して描画処理に問題が生じる場合があります。   (*1) パッケージ オブジェクトは、他のファイルやプログラムなどを OLE オブジェクトとしてドキュメントに挿入できるようにするためのオブジェクトです。   パッケージ オブジェクトの挿入 原因 本現象は、OLE パッケージ オブジェクトを管理する Windows OS のパッケージ管理コンポーネント (packager.dll) の不具合に起因するものです。 本コンポーネントでは、パッケージ オブジェクトごとにタイトルを表示するためのフォント オブジェクトを生成しますが、ドキュメントを閉じてもこのフォント オブジェクトが解放されないため、ドキュメントを開いて閉じる操作を繰り返すとフォント オブジェクト (GDI オブジェクト) が増加し続ける結果となります。   対応状況 マイクロソフトでは米国本社の開発部門でも本不具合を確認していますが、現時点では修正プログラムなどは提供されておらず、提供の予定はありません。 パッケージ…


CDatabase クラスで発生するメモリ リークの問題について

こんにちは、Visual Studio サポート チームです。 今回は、MFC の CDatabase クラスを特定の方法で使用した場合に発生するメモリ リークの問題についてご案内します。この現象は、Visual Studio 2012 以降のバージョンに含まれる MFC で発生します。   現象 CDatabase クラスの同一のオブジェクトに対して OpenEx メソッドと Close メソッドを使用するとメモリ リークが発生し、メモリ使用量が増加し続けます。   原因 この現象は Visual Studio 2012 で追加された、CDatabase クラスの接続文字列の暗号化を行う処理に起因しています。 OpenEx メソッドで接続文字列を暗号化するためのメモリが割り当てられますが、再度 OpenEx メソッドが呼び出された際にメモリを解放せず、新たに割り当てを行っていました。 なお、弊社ではこの問題を MFC の不具合と認識しており、Visual Studio の将来のバージョンで修正を検討しています。 弊社製品の不具合によりご迷惑をおかけし、大変申し訳ございません。   対処方法 以下のいずれかの方法により、メモリ リークの問題に対処することが可能です。 同一のオブジェクトに対して OpenEx メソッドを複数呼び出さないようにする。(OpenEx メソッドで割り当てたメモリはデストラクタで解放されます。) CDatabase クラスを継承し、OpenEx メソッドを修正する。 上記 2. の具体的な実装例を以下にご案内いたします。…


Visual C ++ で公開されているソース コードについて

こんにちは、Visual Studio サポート チームです。 今回は Visual C++ で公開しているソース コードについてお伝えします。 マイクロソフト製品のソースコードは公開されていないというイメージを持たれることが多いかと思いますが、Visual C++ の C Runtime (CRT) ライブラリ、MFC、および ATL に関しては、Visual Studio の製品版に付属しており、Visual Studio と一緒にソース コード ファイルもインストールされています。 インストール時に既定のフォルダー設定を変更しなければ、Visual Studio 2013 関連のファイルは以下のフォルダーに配置されます。  64 ビット OS の場合: C:\Program Files (x86)\Microsoft Visual Studio 12.0  32 ビット OS の場合: C:\Program Files\Microsoft Visual Studio 12.0 上記フォルダー内で、CRT / MFC / ATL の関連ファイルに関しては、それぞれ以下のように配置されています。   アプリケーションの開発中に…


Windows8 上で CMFCColorDialog を使用して、カラーダイアログを表示すると内部のタブの情報が正常に表示されない

  こんにちは。Visual Studio サポート チームです。 Windows8 上で CMFCColorDialog を使用して、カラーダイアログを表示すると以下のように内部のタブの下の部分の情報が正常に表示されないことがあります。         *カスタムタブでは、[明るさ(L)]、[青(B)] が表示されません。   原因について 本現象は、Windows 8 のフォントにおける仕様変更の影響で発生しています。 Windows 8 ではフォント自体のデザインなどの変更により、ダイアログの縦横比、および文字列のサイズが Windows 7 以前のバージョンと異なる場合があります。 Windows 8 および Windows Server 2012 では、システム フォントがメイリオ UI に変更されているため、CPropertySheet クラスなどの MFC で用意されているプロパティ シートのように、OS のダイアログ リソースを使用している場合には、使用されていたフォントも、従来の OS のフォントからメイリオ UI へ変更されることとなり、表示の差異の原因となります。 CMFCColorDialog では、ダイアログ内で表示されるタブ ウィンドウを作成する際には、CMFCColorPropertySheet というクラスを使用しており、このクラスは CPropertySheet を継承しているため、CMFCColorDialog を表示した際にはタブ ウィンドウ内の表示が OS…


MFC のダイアログでメモリリークが発生する

  Visual C++ でMFC のダイアログ形式のアプリケーションを長時間動作させている場合、メモリ使用量が増え続ける可能性があります。   なぜダイアログ形式の場合にメモリ使用量が増えるのか   このメモリ使用量の増加は、MFC がウィンドウなどの管理のために内部で生成している一時オブジェクトに紐づいています。 MFCアプリケーションの形式のうち、SDI および MDI アプリケーションでは、メッセージ ループの空き時間に、CWinApp::OnIdle() 関数が呼び出されて、一時的なオブジェクトを自動的に削除しています。 <SDI および MDI アプリケーションの場合 > AfxWinMain() CWinApp::InitInstance()   CWinApp::Run() ===>  この 実行によりメッセージ ループの処理に入り、メッセージ ループの空き時間に一時的なオブジェクトを削除します 一方、MFC のダイアログ形式のアプリケーションでは上記 SDI ないし MDI アプリケーションのように、Run() 関数やその中で呼び出される OnIdle() 関数が呼び出されることなくダイアログが終了します。そのため、一時オブジェクトが破棄されずに残ります。 <ダイアログ形式のアプリケーションの場合> AfxWinMain()   CWinApp::InitInstance()   メイン ダイアログの生成 ===> Run() 呼び出しのように OnIdle() 関数を呼び出す処理がありません  子ダイアログなどの生成 (あわせて一時オブジェクトが生成されます)   子ダイアログが破棄されると処理はメイン…