Microsoft KB Archive/200913

{|
 * width="100%"|

INFO: CPSUI Behavior When Printing Through MS WORD

 * }

Q200913

-

The information in this article applies to:


 * Microsoft Win32 Device Driver Kit (DDK) for Windows NT

-

SUMMARY
This article explains the behavior of the CPSUI (Common Property Sheet User Interface) when printing in Microsoft Word.

MORE INFORMATION
Printer Settings are not saved in Microsoft Word when printing to a printer connected to a server.

Steps to Reproduce Behavior

 * 1) Select Print Menu and double-click Properties.
 * 2) Change settings and click OK.
 * 3) Select Print Menu and double-click Properties.

After the first step, DrvDocumentPropertySheets with PROPSHEETUI_REASON_INIT is called. DrvDocumentPropertySheets with PROPSHEETUI_REASON_SET_RESULT is called next. The UI updates pDPHdr->pdmOut with the user selections. Then, DrvDocumentPropertySheets with pPSUIInfo==NULL is called. The pdmIn contains the DEVMODE returned by the UI in step 6. The UI then updates pDPHdr->pdmOut based on pDPHdr->pdmIn. DrvDocumentPropertySheets with PROPSHEETUI_REASON_INIT is called and pdmIn contains the changes done in step 6. Finally, the UI dialog box shows the last selection made by the user.

Steps to Reproduce Behavior
Remote Printing In Word from the UI point of view (Administrator in both Client and printer server):


 * 1) Selects Print Menu in Word and click Properties.
 * 2) Changes the settings and click OK.
 * 3) Select Print Menu and click Properties again.

DrvDocumentPropertySheets with PROPSHEETUI_REASON_INIT is called and pdmIn contains the default DEVMODE. First, DrvDocumentPropertySheets with PROPSHEETUI_REASON_INIT is called. The UI displays a dialog box. Next, DrvDocumentPropertySheets with PROPSHEETUI_REASON_SET_RESULT is called. Then, The UI updates pDPHdr->pdmOut with the users selections. DrvDocumentPropertySheets with pPSUIInfo==NULL is called. After that, the pdmIn contains the DEVMODE returned by the UI in step 6. The UI is updated pDPHdr->pdmOut based on pDPHdr->pdmIn. DrvDocumentPropertySheets with pPSUIInfo==NULL is called. The pdmIn is also NULL. The UI updates pDPHdr->pdmOut using the printer default DEVMODE. Finally, the UI displays the dialog box showing default settings (not the last selections from user)! As a result, DrvDocumentPropertySheets with PROPSHEETUI_REASON_SET_RESULT is called. The new DEVMODE from pDPHdr->pdmOut gets flushed to the driver; that is, the new DEVMODE is written out, but the pCPSUIInfo==NULL and the printer default DEVMODE is also written from the pdmOut buffer.

One work around is to opt a third-party driver to bypass this problem and to store the current DEVMODE in the registry whenever PROPSHEETUI_REASON_SET_RESULT was called. This is done by creating a key in the registry as follows. Although, this is not the most effective solution. Following is a code snippet from this solution.

//Within DrvDocumentPropertySheets //...... case PROPSHEETUI_REASON_SET_RESULT: {  PSETRESULT_INFO pSRInfo = (PSETRESULT_INFO) lParam;

if (pSRInfo-&gt;Result == CPSUI_OK && (pDPHdr-&gt;fMode & (DM_COPY | DM_UPDATE)))  {

GetUIData(&theDevMode, lpUITrans-&gt;lpUIData);

ConvertDevmodeOut(&theDevMode, pDPHdr-&gt;pdmIn, pDPHdr-&gt;pdmOut);

SetCurrentDevMode(pDPHdr-&gt;hPrinter, &theDevMode); }  pPSUIInfo-&gt;Result = pSRInfo-&gt;Result; }

//SetCurrentDevMode---

static BOOL SetCurrentDevMode( HANDLE hPrinter, DRVDEVMODE* lpDevMode) {  //...   GetPrinter; //...  ret = GetPrinter; //....  ret = RegCreateKeyEx;

ret = RegSetValueEx;

RegCloseKey; //...  return( TRUE ); }  From Compstui.h, when pPSUIInfo is NULL, then it is not calling from COMPSTUI.DLL. It is up to the caller and called to agree on the lParam value passed.

From the DrvDocumentPropertySheets point of view, if pPSUIINfo in not NULL, then COMPSTUI is the caller. In this case, DrvDocumentPropertySheets should follow the guidelines laid out in PFNPROPSHEETUI and it is then ready for any of the PROPSHEETUI_REASON_Xxx case processing. However, if pPSUIInfo==NULL, then the call is from one of the two following cases.


 * 1) From other applications, it directly loads the driver DLL, and gets the proc address. It does not know what it is asking from the driver.
 * 2) From the printer UI (spooler component), the driver doesn't need to call the CPSUI because no user interface is required. The lParam is PDOCUMENTPROPERTYHEADER (in Winddiui.h) and the driver should do whatever the DM_Xxx flag in the fMode field of DOCUMENTPROPERTYHEADER structure advised. The driver should use the information passed through lParam.