Microsoft Print to PDF 選択時の CPrintDialog::OnInitDialog() 動作について

こんにちは、Platform SDK (Windows SDK) サポートチームです。

今回は、通常使うプリンターに Microsoft Print to PDF が選択されている場合の CPrintDialog 動作についてご案内します。

 

現象

MFC の CPringDialog クラスは、Windows のコモン ダイアログ ボックスである [印刷] ダイアログで提供されるサービスをカプセル化したクラスです。
このため、CPringDialog 派生クラス内で CPringDialog::OnInitDialog() をオーバーライドすると、アプリケーション独自に [印刷] ダイアログの外観をカスタマイズする等が可能です。

ところが、以下の条件に該当する場合は、CPringDialog 派生クラス内で CPrintDialog::OnInitDialog() が呼び出されません。
(同様に、CPrintDialog 派生クラス内で WindowProc() をオーバーライドしても、WM_INITDIALOG メッセージが受信されません)

  • Windows 10 上でプログラムを実行している
  • プログラムを 64-bit でビルドしている
  • 通常使うプリンターに Microsoft Print to PDF が選択されている

 

原因

前述した三つの条件に該当していない場合は、CPrintDialog クラス内部では DialogBoxIndirectParam() を呼び出して、[印刷] コモンダイアログを開きます。
このため、ダイアログ初期化時のイベント ハンドラーとして、CPrintDialog::OnInitDialog() が呼び出されます。
(同様に、CPrintDialog 派生クラス内で WindowProc() をオーバーライドすると、WM_INITDIALOG メッセージが受信されます)

これに対し、前述した三つの条件に全て該当していた場合は、CPrintDialog クラス内部では DocumentProperties() を呼び出して、プリンタ設定プロパティを開きます。
プリンター設定プロパティはダイアログではないため、CPrintDialog::OnInitDialog() が呼び出されません。
(同様に、CPrintDialog 派生クラス内で WindowProc() をオーバーライドしても、WM_INITDIALOG メッセージは受信されません)

DialogBoxIndirectParam function
https://msdn.microsoft.com/en-us/library/windows/desktop/ms645461.aspx

DocumentProperties
https://msdn.microsoft.com/ja-jp/library/cc428447.aspx

 

回避策

現在のプリンター名 (※) が Microsoft Print to PDF であった場合には、別途 32-bit でビルドしたプログラムから CPrintDialog をご利用ください。

※ 現在のプリンター名は下記 GetDefaultPrinter() で取得することが可能です。

GetDefaultPrinter function
https://msdn.microsoft.com/en-us/library/windows/desktop/dd144876.aspx

 

状況

マイクロソフトでは、この現象について調査しています。
進展があり次第、本ブログを更新予定です。