Edit

CPrintDialog::OnInitDialog isn't called when using V4 printer drivers

This article helps work around a problem where CPrintDialog::OnInitDialog isn't called when using a printer with a V4 printer driver.

Symptoms

Functions specified in the message map of a CPrintDialog-derived class, including OnInitDialog, aren't called when using DoModal to display the Print dialog box. This behavior occurs when using a printer with a V4 printer driver, such as Microsoft Print to PDF.

Cause

The CPrintDialog class wraps the PrintDlg function. CPrintDialog::DoModal sets a WH_CBT window hook on the calling thread to obtain the window handle of the dialog box created by the PrintDlg function and attaches the handle to the CPrintDialog object.

Before the PrintDlg function creates the dialog box, it calls the DocumentProperties function on the selected printer to obtain a DEVMODE structure from the printer driver, which is then used to initialize the dialog. A hidden window, using the window class name URL Moniker Notification Window, is created when DocumentProperties is called on a printer using a V4 printer driver.

The WH_CBT window hook procedure incorrectly attaches the CPrintDialog object to the window handle of the URL Moniker Notification Window Window instead of the dialog box. The result is that the functions in the CPrintDialog object's message map aren't invoked for the dialog box.

Workaround

To work around the problem, use printer-driver isolation. It improves an application's reliability by running printer drivers in a separate process instead of the process calling the print spooler functions. This isolation prevents applications calling the print spooler functions from crashing if a printer driver has an error.

In this scenario, the reason for using printer-driver isolation is that the URL Moniker Notification Window window is created in a separate process.

To enable printer-driver isolation for an application, use one of the following methods:

More information