mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1975 lines
51 KiB
1975 lines
51 KiB
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
docprop.c
|
|
|
|
Abstract:
|
|
|
|
Implemetation of DrvDocumentProperties and DrvAdvancedDocumentProperties
|
|
|
|
[Environment:]
|
|
|
|
Win32 subsystem, PostScript driver, user mode
|
|
|
|
Revision History:
|
|
|
|
06/23/95 -davidx-
|
|
Created it.
|
|
|
|
08/28/95 -davidx-
|
|
Use common UI library to display document property dialog
|
|
|
|
mm/dd/yy -author-
|
|
description
|
|
|
|
--*/
|
|
|
|
#include "psui.h"
|
|
#include "..\..\lib\libproto.h"
|
|
|
|
// Forward declaration of local functions
|
|
|
|
BOOL PackDocumentPropertyItems(PPACKINFO);
|
|
BOOL PackItemOrientation(PPACKINFO, PSDEVMODE*);
|
|
BOOL PackItemScale(PPACKINFO, PSDEVMODE*);
|
|
BOOL PackItemCopiesCollate(PPACKINFO, PSDEVMODE*);
|
|
BOOL PackItemInputSlot(PPACKINFO, PSDEVMODE*);
|
|
BOOL PackItemResolution(PPACKINFO, PSDEVMODE*);
|
|
BOOL PackItemColor(PPACKINFO, PSDEVMODE*);
|
|
BOOL PackItemDuplex(PPACKINFO, PSDEVMODE*);
|
|
BOOL PackItemFormName(PPACKINFO, PSDEVMODE*);
|
|
BOOL PackItemTTOptions(PPACKINFO, PSDEVMODE*);
|
|
BOOL PackItemMetafileOptions(PPACKINFO, PSDEVMODE*);
|
|
BOOL PackItemPostScriptOptions(PPACKINFO, PSDEVMODE*);
|
|
BOOL PackItemHalftoneAdjustment(PPACKINFO, PSDEVMODE*);
|
|
BOOL PackItemDeviceOptions(PPACKINFO, PSDEVMODE*);
|
|
|
|
CPSUICALLBACK DocumentPropertyCallback(PCPSUICBPARAM);
|
|
LONG PsDocumentProperties(HWND, HANDLE, PWSTR, PDEVMODE, PDEVMODE, DWORD);
|
|
INT CheckDocumentConstraints(PUIDATA, POPTITEM, WORD);
|
|
VOID DocPropShowConstraints(PUIDATA, POPTITEM, WORD);
|
|
LONG SimpleDocumentProperties(PDOCUMENTPROPERTYHEADER);
|
|
|
|
|
|
|
|
LONG
|
|
DrvDocumentPropertySheets(
|
|
PPROPSHEETUI_INFO pPSUIInfo,
|
|
LPARAM lParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Display "Document Properties" property sheets
|
|
|
|
Arguments:
|
|
|
|
pPSUIInfo - Pointer to a PROPSHEETUI_INFO structure
|
|
lParam - Pointer to a DOCUMENTPROPERTYHEADER structure
|
|
|
|
Return Value:
|
|
|
|
> 0 if successful, <= 0 if failed
|
|
|
|
[Note:]
|
|
|
|
Please refer to WinNT DDK/SDK documentation for more details.
|
|
|
|
--*/
|
|
|
|
{
|
|
PDOCUMENTPROPERTYHEADER pDPHdr;
|
|
PCOMPROPSHEETUI pCompstui;
|
|
PUIDATA pUiData;
|
|
PDLGPAGE pDlgPage;
|
|
LONG result;
|
|
|
|
//
|
|
// Validate input parameters
|
|
// pPSUIInfo = NULL is a special case: don't need to display the dialog
|
|
//
|
|
|
|
if (! (pDPHdr = (PDOCUMENTPROPERTYHEADER) (pPSUIInfo ? pPSUIInfo->lParamInit : lParam))) {
|
|
|
|
Assert(FALSE);
|
|
return -1;
|
|
}
|
|
|
|
if (pPSUIInfo == NULL)
|
|
return SimpleDocumentProperties(pDPHdr);
|
|
|
|
//
|
|
// Create a UIDATA structure if necessary
|
|
//
|
|
|
|
pUiData = (pPSUIInfo->Reason == PROPSHEETUI_REASON_INIT) ?
|
|
FillUiData(pDPHdr->hPrinter, pDPHdr->pdmIn) :
|
|
(PUIDATA) pPSUIInfo->UserData;
|
|
|
|
if (! ValidUiData(pUiData))
|
|
return -1;
|
|
|
|
//
|
|
// Handle various cases for which this function might be called
|
|
//
|
|
|
|
switch (pPSUIInfo->Reason) {
|
|
|
|
case PROPSHEETUI_REASON_INIT:
|
|
|
|
//
|
|
// Allocate memory and partially fill out various data
|
|
// structures required to call common UI routine.
|
|
//
|
|
|
|
pDlgPage = (pDPHdr->fMode & DM_ADVANCED) ?
|
|
CPSUI_PDLGPAGE_ADVDOCPROP :
|
|
CPSUI_PDLGPAGE_DOCPROP;
|
|
|
|
pUiData->bPermission = ((pDPHdr->fMode & DM_NOPERMISSION) == 0);
|
|
|
|
if (pCompstui = PrepareDataForCommonUi(pUiData, pDlgPage, PackDocumentPropertyItems)) {
|
|
|
|
pCompstui->pfnCallBack = DocumentPropertyCallback;
|
|
pUiData->pfnComPropSheet = pPSUIInfo->pfnComPropSheet;
|
|
pUiData->hComPropSheet = pPSUIInfo->hComPropSheet;
|
|
|
|
//
|
|
// Convert DEVMODE fields to printer feature selection
|
|
//
|
|
|
|
DevModeFieldsToOptions(&pUiData->devmode,
|
|
pUiData->devmode.dmPublic.dmFields,
|
|
pUiData->hppd);
|
|
|
|
//
|
|
// Indicate which items are constrained
|
|
//
|
|
|
|
DocPropShowConstraints(pUiData, pCompstui->pOptItem, pCompstui->cOptItem);
|
|
|
|
//
|
|
// Call common UI library to add our pages
|
|
//
|
|
|
|
if (pUiData->pfnComPropSheet(pUiData->hComPropSheet,
|
|
CPSFUNC_ADD_PCOMPROPSHEETUI,
|
|
(LPARAM) pCompstui,
|
|
(LPARAM) &result))
|
|
{
|
|
pPSUIInfo->UserData = (DWORD) pUiData;
|
|
pPSUIInfo->Result = CPSUI_CANCEL;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Clean up properly in case of an error
|
|
//
|
|
|
|
UnloadPpdFile(pUiData->hppd);
|
|
HEAPDESTROY(pUiData->hheap);
|
|
break;
|
|
|
|
case PROPSHEETUI_REASON_GET_INFO_HEADER:
|
|
|
|
{ PPROPSHEETUI_INFO_HEADER pPSUIHdr;
|
|
|
|
pPSUIHdr = (PPROPSHEETUI_INFO_HEADER) lParam;
|
|
pPSUIHdr->Flags = PSUIHDRF_PROPTITLE | PSUIHDRF_NOAPPLYNOW;
|
|
pPSUIHdr->pTitle = pDPHdr->pszPrinterName;
|
|
pPSUIHdr->hInst = ghInstance;
|
|
pPSUIHdr->IconID = IDI_CPSUI_POSTSCRIPT;
|
|
}
|
|
return 1;
|
|
|
|
case PROPSHEETUI_REASON_SET_RESULT:
|
|
|
|
//
|
|
// Copy the new devmode back into the output buffer provided by the caller
|
|
// Always return the smaller of current and input devmode
|
|
//
|
|
|
|
{ PSETRESULT_INFO pSRInfo = (PSETRESULT_INFO) lParam;
|
|
|
|
if (pSRInfo->Result == CPSUI_OK && (pDPHdr->fMode & (DM_COPY | DM_UPDATE)))
|
|
ConvertDevmodeOut((PDEVMODE) &pUiData->devmode, pDPHdr->pdmIn, pDPHdr->pdmOut);
|
|
|
|
pPSUIInfo->Result = pSRInfo->Result;
|
|
}
|
|
return 1;
|
|
|
|
case PROPSHEETUI_REASON_DESTROY:
|
|
|
|
UnloadPpdFile(pUiData->hppd);
|
|
HEAPDESTROY(pUiData->hheap);
|
|
return 1;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
LONG
|
|
DrvDocumentProperties(
|
|
HWND hwnd,
|
|
HANDLE hPrinter,
|
|
PWSTR pPrinterName,
|
|
PDEVMODE pdmOutput,
|
|
PDEVMODE pdmInput,
|
|
DWORD fMode
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Set the public members of a DEVMODE structure for a print document
|
|
|
|
[Note:]
|
|
|
|
Please refer to WinNT DDK/SDK documentation for more details.
|
|
|
|
This is the old entry point for the spooler. Even though
|
|
no one should be using this, do it for compatibility.
|
|
|
|
--*/
|
|
|
|
{
|
|
LONG result;
|
|
|
|
//
|
|
// Check if caller is asking querying for size
|
|
//
|
|
|
|
if (fMode == 0 || pdmOutput == NULL)
|
|
return sizeof(PSDEVMODE);
|
|
|
|
//
|
|
// Call the common routine shared with DrvAdvancedDocumentProperties
|
|
//
|
|
|
|
result = PsDocumentProperties(hwnd, hPrinter, pPrinterName, pdmOutput, pdmInput, fMode);
|
|
|
|
return (result > 0) ? IDOK : (result == 0) ? IDCANCEL : result;
|
|
}
|
|
|
|
|
|
|
|
LONG
|
|
DrvAdvancedDocumentProperties(
|
|
HWND hwnd,
|
|
HANDLE hPrinter,
|
|
PWSTR pPrinterName,
|
|
PDEVMODE pdmOutput,
|
|
PDEVMODE pdmInput
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Set the private members of a DEVMODE structure.
|
|
In this release, this function is almost identical to
|
|
DrvDocumentProperties above with a few minor exceptions
|
|
|
|
[Note:]
|
|
|
|
Please refer to WinNT DDK/SDK documentation for more details.
|
|
|
|
This is the old entry point for the spooler. Even though
|
|
no one should be using this, do it for compatibility.
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD fMode;
|
|
LONG result;
|
|
|
|
//
|
|
// Return the number of bytes required if pdmOutput is NULL
|
|
//
|
|
|
|
if (pdmOutput == NULL)
|
|
return sizeof(PSDEVMODE);
|
|
|
|
//
|
|
// Otherwise, call the common routine shared with DrvDocumentProperties
|
|
//
|
|
|
|
fMode = DM_COPY | DM_PROMPT | DM_ADVANCED;
|
|
result = PsDocumentProperties(hwnd, hPrinter, pPrinterName, pdmOutput, pdmInput, fMode);
|
|
|
|
return (result > 0);
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
DrvConvertDevMode(
|
|
LPTSTR pPrinterName,
|
|
PDEVMODE pdmIn,
|
|
PDEVMODE pdmOut,
|
|
PLONG pcbNeeded,
|
|
DWORD fMode
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Use by SetPrinter and GetPrinter to convert devmodes
|
|
|
|
Arguments:
|
|
|
|
pPrinterName - Points to printer name string
|
|
pdmIn - Points to the input devmode
|
|
pdmOut - Points to the output devmode buffer
|
|
pcbNeeded - Specifies the size of output buffer on input
|
|
On output, this is the size of output devmode
|
|
fMode - Specifies what function to perform
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful
|
|
FALSE otherwise and an error code is logged
|
|
|
|
--*/
|
|
|
|
{
|
|
static DRIVER_VERSION_INFO psDriverVersions = {
|
|
|
|
// Current driver version number and private devmode size
|
|
|
|
DRIVER_VERSION, sizeof(PRIVATEDEVMODE),
|
|
|
|
// 3.51 driver version number and private devmode size
|
|
|
|
DRIVER_VERSION_351, sizeof(PRIVATEDEVMODE351),
|
|
};
|
|
|
|
PDRIVER_INFO_2 pDriverInfo2;
|
|
HANDLE hPrinter;
|
|
HPPD hppd;
|
|
INT result;
|
|
|
|
//
|
|
// Call a library routine to handle the common cases
|
|
//
|
|
|
|
result = CommonDrvConvertDevmode(pPrinterName,
|
|
pdmIn,
|
|
pdmOut,
|
|
pcbNeeded,
|
|
fMode,
|
|
&psDriverVersions);
|
|
|
|
//
|
|
// If not handled by the library routine, we only need to worry
|
|
// about the case when fMode is CDM_DRIVER_DEFAULT
|
|
//
|
|
|
|
if (result == CDM_RESULT_NOT_HANDLED &&
|
|
fMode == CDM_DRIVER_DEFAULT &&
|
|
OpenPrinter(pPrinterName, &hPrinter, NULL))
|
|
{
|
|
if (pDriverInfo2 = MyGetPrinterDriver(hPrinter, 2)) {
|
|
|
|
//
|
|
// Load PPD file
|
|
//
|
|
|
|
if (hppd = PpdCreate(pDriverInfo2->pDataFile)) {
|
|
|
|
//
|
|
// Get driver default devmode
|
|
//
|
|
|
|
SetDefaultDevMode(pdmOut, pDriverInfo2->pName, hppd, IsMetricCountry());
|
|
PpdDelete(hppd);
|
|
result = CDM_RESULT_TRUE;
|
|
|
|
}
|
|
|
|
MEMFREE(pDriverInfo2);
|
|
}
|
|
|
|
ClosePrinter(hPrinter);
|
|
}
|
|
|
|
return (result == CDM_RESULT_TRUE);
|
|
}
|
|
|
|
|
|
|
|
LONG
|
|
PsDocumentProperties(
|
|
HWND hwnd,
|
|
HANDLE hPrinter,
|
|
PWSTR pPrinterName,
|
|
PDEVMODE pdmOutput,
|
|
PDEVMODE pdmInput,
|
|
DWORD fMode
|
|
)
|
|
|
|
/*++
|
|
|
|
Arguments:
|
|
|
|
hwnd - Handle to the parent window of the document properties dialog box.
|
|
|
|
hPrinter - Handle to a printer object.
|
|
|
|
pPrinterName - Points to a null-terminated string that specifies
|
|
the name of the device for which the document properties dialog
|
|
box should be displayed.
|
|
|
|
pdmOutput - Points to a DEVMODE structure that receives the document
|
|
properties data specified by the user.
|
|
|
|
pdmInput - Points to a DEVMODE structure that initializes the dialog
|
|
box controls. This parameter can be NULL.
|
|
|
|
fmode - Specifies a mask of flags that determine which operations
|
|
the function performs.
|
|
|
|
Return Value:
|
|
|
|
> 0 if successful
|
|
= 0 if canceled
|
|
< 0 if error
|
|
|
|
--*/
|
|
|
|
{
|
|
DOCUMENTPROPERTYHEADER docPropHdr;
|
|
DWORD result;
|
|
|
|
//
|
|
// Initialize a DOCUMENTPROPERTYHEADER structure
|
|
//
|
|
|
|
memset(&docPropHdr, 0, sizeof(docPropHdr));
|
|
docPropHdr.cbSize = sizeof(docPropHdr);
|
|
docPropHdr.hPrinter = hPrinter;
|
|
docPropHdr.pszPrinterName = pPrinterName;
|
|
docPropHdr.pdmIn = pdmInput;
|
|
docPropHdr.pdmOut = pdmOutput;
|
|
docPropHdr.fMode = fMode;
|
|
|
|
//
|
|
// Don't need to get compstui involved when the dialog is not displayed
|
|
//
|
|
|
|
if ((fMode & DM_PROMPT) == 0)
|
|
return SimpleDocumentProperties(&docPropHdr);
|
|
|
|
CallCompstui(hwnd, DrvDocumentPropertySheets, (LPARAM) &docPropHdr, &result);
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
LONG
|
|
SimpleDocumentProperties(
|
|
PDOCUMENTPROPERTYHEADER pDPHdr
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Handle simple "Document Properties" where we don't need to display
|
|
a dialog and therefore don't have to have common UI library involved
|
|
|
|
Arguments:
|
|
|
|
pDPHdr - Points to a DOCUMENTPROPERTYHEADER structure
|
|
|
|
Return Value:
|
|
|
|
> 0 if successful, <= 0 otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
PUIDATA pUiData;
|
|
|
|
//
|
|
// Check if the caller is interested in the size only
|
|
//
|
|
|
|
pDPHdr->cbOut = sizeof(PSDEVMODE);
|
|
|
|
if (pDPHdr->fMode == 0 || pDPHdr->pdmOut == NULL)
|
|
return pDPHdr->cbOut;
|
|
|
|
//
|
|
// Create a UIDATA structure
|
|
//
|
|
|
|
if (! (pUiData = FillUiData(pDPHdr->hPrinter, pDPHdr->pdmIn)))
|
|
return -1;
|
|
|
|
//
|
|
// Copy the devmode back into the output buffer provided by the caller
|
|
// Always return the smaller of current and input devmode
|
|
//
|
|
|
|
if (pDPHdr->fMode & (DM_COPY | DM_UPDATE))
|
|
ConvertDevmodeOut((PDEVMODE) &pUiData->devmode, pDPHdr->pdmIn, pDPHdr->pdmOut);
|
|
|
|
UnloadPpdFile(pUiData->hppd);
|
|
HEAPDESTROY(pUiData->hheap);
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
UndoDevModeOptions(
|
|
HPPD hppd,
|
|
PBYTE pOptions
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
If a feature is handled by a public devmode field, then there is
|
|
no need to store its selection in the private portion of devmode.
|
|
|
|
Arguments:
|
|
|
|
hppd - Handle to PPD object
|
|
pOptions - Pointer to an array of feature selections
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
|
|
--*/
|
|
|
|
{
|
|
WORD index;
|
|
|
|
if ((index = GetFeatureIndex(hppd->pCollate)) != OPTION_INDEX_NONE)
|
|
pOptions[index] = OPTION_INDEX_ANY;
|
|
|
|
if ((index = GetFeatureIndex(hppd->pDuplex)) != OPTION_INDEX_NONE)
|
|
pOptions[index] = OPTION_INDEX_ANY;
|
|
|
|
if ((index = GetFeatureIndex(hppd->pResOptions)) != OPTION_INDEX_NONE)
|
|
pOptions[index] = OPTION_INDEX_ANY;
|
|
|
|
if ((index = GetFeatureIndex(hppd->pPageSizes)) != OPTION_INDEX_NONE)
|
|
pOptions[index] = OPTION_INDEX_ANY;
|
|
|
|
if ((index = GetFeatureIndex(hppd->pInputSlots)) != OPTION_INDEX_NONE)
|
|
pOptions[index] = OPTION_INDEX_ANY;
|
|
}
|
|
|
|
|
|
|
|
WORD
|
|
DevModeFieldsToOptions(
|
|
PSDEVMODE *pDevMode,
|
|
DWORD dmFields,
|
|
HPPD hppd
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert DEVMODE fields to printer feature selections
|
|
|
|
Arguments:
|
|
|
|
pUiData - Pointer to our UIDATA structure
|
|
dmFields - Which DEVMODE fields are we interested in?
|
|
|
|
Return Value:
|
|
|
|
Print feature index corresponding to the devmode field
|
|
|
|
--*/
|
|
|
|
{
|
|
PDEVMODE pdm = & pDevMode->dmPublic;
|
|
PBYTE pOptions = pDevMode->dmPrivate.options;
|
|
WORD feature, selection;
|
|
|
|
if ((dmFields & DM_COLLATE) &&
|
|
(feature = GetFeatureIndex(hppd->pCollate)) != OPTION_INDEX_NONE)
|
|
{
|
|
if (! LISTOBJ_FindItemIndex(
|
|
(PLISTOBJ) hppd->pCollate->pUiOptions,
|
|
(pdm->dmCollate == DMCOLLATE_TRUE) ? "True" : "False",
|
|
&selection))
|
|
{
|
|
selection = OPTION_INDEX_ANY;
|
|
}
|
|
|
|
pOptions[feature] = (BYTE) selection;
|
|
}
|
|
|
|
if ((dmFields & DM_DUPLEX) &&
|
|
(feature = GetFeatureIndex(hppd->pDuplex)) != OPTION_INDEX_NONE)
|
|
{
|
|
if (! LISTOBJ_FindItemIndex(
|
|
(PLISTOBJ) hppd->pDuplex->pUiOptions,
|
|
MapDevModeDuplexOption(pdm->dmDuplex),
|
|
&selection))
|
|
{
|
|
selection = OPTION_INDEX_ANY;
|
|
}
|
|
|
|
pOptions[feature] = (BYTE) selection;
|
|
}
|
|
|
|
if ((dmFields & DM_PRINTQUALITY) &&
|
|
(feature = GetFeatureIndex(hppd->pResOptions)) != OPTION_INDEX_NONE)
|
|
{
|
|
PRESOPTION pResOption;
|
|
LONG resolution;
|
|
|
|
pOptions[feature] = OPTION_INDEX_ANY;
|
|
|
|
// Go throught the list of resolutions supported by the printer
|
|
|
|
pResOption = (PRESOPTION) UIGROUP_GetOptions(hppd->pResOptions);
|
|
|
|
for (selection=0; pResOption; pResOption = pResOption->pNext) {
|
|
|
|
if ((resolution = atol(pResOption->pName)) > 0) {
|
|
|
|
if (pdm->dmPrintQuality == resolution) {
|
|
|
|
pOptions[feature] = (BYTE) selection;
|
|
break;
|
|
}
|
|
|
|
selection++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((dmFields & DM_FORMNAME) &&
|
|
(feature = GetFeatureIndex(hppd->pPageSizes)) != OPTION_INDEX_NONE)
|
|
{
|
|
CHAR formname[CCHFORMNAME];
|
|
|
|
CopyUnicode2Str(formname, pdm->dmFormName, CCHFORMNAME);
|
|
|
|
if (! PpdFindUiOptionWithXlation(hppd->pPageSizes->pUiOptions, formname, &selection))
|
|
selection = OPTION_INDEX_ANY;
|
|
|
|
pOptions[feature] = (BYTE) selection;
|
|
}
|
|
|
|
if ((dmFields & DM_DEFAULTSOURCE) &&
|
|
(feature = GetFeatureIndex(hppd->pInputSlots)) != OPTION_INDEX_NONE)
|
|
{
|
|
if (pdm->dmDefaultSource >= DMBIN_USER)
|
|
selection = pdm->dmDefaultSource - DMBIN_USER;
|
|
else
|
|
selection = OPTION_INDEX_ANY;
|
|
|
|
pOptions[feature] = (BYTE) selection;
|
|
}
|
|
|
|
return feature;
|
|
}
|
|
|
|
|
|
|
|
WORD
|
|
UnpackDocumentPropertiesItems(
|
|
PUIDATA pUiData,
|
|
PSDEVMODE *pdm,
|
|
POPTITEM pOptItem,
|
|
WORD cOptItem
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Extract devmode information from an OPTITEM
|
|
|
|
Arguments:
|
|
|
|
pUiData - Pointer to our UIDATA structure
|
|
pdm - Pointer to PSDEVMODE structure
|
|
pOptItem - Pointer to an array of OPTITEMs
|
|
cOptItem - Number of OPTITEMs
|
|
|
|
Return Value:
|
|
|
|
Printer feature index corresponding to the last item unpacked
|
|
|
|
--*/
|
|
|
|
{
|
|
WORD feature = OPTION_INDEX_NONE;
|
|
DWORD dmFields = 0;
|
|
|
|
for ( ; cOptItem > 0; cOptItem--, pOptItem++) {
|
|
|
|
if (IsPrinterFeatureItem(pOptItem->UserData)) {
|
|
|
|
PUIGROUP pUiGroup;
|
|
|
|
pUiGroup = (PUIGROUP) pOptItem->UserData;
|
|
ASSERT(! pUiGroup->bInstallable);
|
|
|
|
feature = pUiGroup->featureIndex;
|
|
pdm->dmPrivate.options[feature] =
|
|
pOptItem->Sel ? (BYTE) (pOptItem->Sel - 1) : OPTION_INDEX_ANY;
|
|
|
|
} else switch (pOptItem->UserData) {
|
|
|
|
case ORIENTATION_ITEM:
|
|
if (pOptItem->Sel == 0)
|
|
pdm->dmPublic.dmOrientation = DMORIENT_PORTRAIT;
|
|
else {
|
|
|
|
pdm->dmPublic.dmOrientation = DMORIENT_LANDSCAPE;
|
|
if (pOptItem->Sel == 1)
|
|
pdm->dmPrivate.dwFlags &= ~PSDEVMODE_LSROTATE;
|
|
else
|
|
pdm->dmPrivate.dwFlags |= PSDEVMODE_LSROTATE;
|
|
}
|
|
break;
|
|
|
|
case SCALE_ITEM:
|
|
pdm->dmPublic.dmScale = (SHORT) pOptItem->Sel;
|
|
break;
|
|
|
|
case COPIES_COLLATE_ITEM:
|
|
pdm->dmPublic.dmCopies = (SHORT) pOptItem->Sel;
|
|
|
|
if (pOptItem->pExtChkBox) {
|
|
|
|
pdm->dmPublic.dmCollate =
|
|
(pOptItem->Flags & OPTIF_ECB_CHECKED) ?
|
|
DMCOLLATE_TRUE : DMCOLLATE_FALSE;
|
|
dmFields |= DM_COLLATE;
|
|
}
|
|
break;
|
|
|
|
case COLOR_ITEM:
|
|
|
|
if (pOptItem->Sel == 1) {
|
|
|
|
pdm->dmPublic.dmFields |= DM_COLOR;
|
|
pdm->dmPublic.dmColor = DMCOLOR_COLOR;
|
|
|
|
} else
|
|
pdm->dmPublic.dmColor = DMCOLOR_MONOCHROME;
|
|
|
|
break;
|
|
|
|
case DUPLEX_ITEM:
|
|
pdm->dmPublic.dmDuplex =
|
|
(pOptItem->Sel == 0) ? DMDUP_SIMPLEX :
|
|
(pOptItem->Sel == 1) ? DMDUP_HORIZONTAL : DMDUP_VERTICAL;
|
|
dmFields |= DM_DUPLEX;
|
|
break;
|
|
|
|
case TTOPTION_ITEM:
|
|
if (pOptItem->Sel == 0)
|
|
pdm->dmPrivate.dwFlags |= PSDEVMODE_FONTSUBST;
|
|
else
|
|
pdm->dmPrivate.dwFlags &= ~PSDEVMODE_FONTSUBST;
|
|
break;
|
|
|
|
case METASPOOL_ITEM:
|
|
if (pOptItem->Sel == 0)
|
|
pdm->dmPrivate.dwFlags |= PSDEVMODE_METAFILE_SPOOL;
|
|
else
|
|
pdm->dmPrivate.dwFlags &= ~PSDEVMODE_METAFILE_SPOOL;
|
|
break;
|
|
|
|
case MIRROR_ITEM:
|
|
if (pOptItem->Sel == 0)
|
|
pdm->dmPrivate.dwFlags |= PSDEVMODE_MIRROR;
|
|
else
|
|
pdm->dmPrivate.dwFlags &= ~PSDEVMODE_MIRROR;
|
|
break;
|
|
|
|
case NEGATIVE_ITEM:
|
|
if (pOptItem->Sel == 0)
|
|
pdm->dmPrivate.dwFlags |= PSDEVMODE_NEG;
|
|
else
|
|
pdm->dmPrivate.dwFlags &= ~PSDEVMODE_NEG;
|
|
break;
|
|
|
|
case PAGEINDEP_ITEM:
|
|
if (pOptItem->Sel == 0)
|
|
pdm->dmPrivate.dwFlags |= PSDEVMODE_INDEPENDENT;
|
|
else
|
|
pdm->dmPrivate.dwFlags &= ~PSDEVMODE_INDEPENDENT;
|
|
break;
|
|
|
|
case COMPRESSBMP_ITEM:
|
|
if (pOptItem->Sel == 0)
|
|
pdm->dmPrivate.dwFlags |= PSDEVMODE_COMPRESSBMP;
|
|
else
|
|
pdm->dmPrivate.dwFlags &= ~PSDEVMODE_COMPRESSBMP;
|
|
break;
|
|
|
|
case JOB_CONTROL_ITEM:
|
|
if (pOptItem->Sel == 1)
|
|
pdm->dmPrivate.dwFlags |= PSDEVMODE_NO_JOB_CONTROL;
|
|
else
|
|
pdm->dmPrivate.dwFlags &= ~PSDEVMODE_NO_JOB_CONTROL;
|
|
break;
|
|
|
|
case CTRLD_BEFORE_ITEM:
|
|
if (pOptItem->Sel == 0)
|
|
pdm->dmPrivate.dwFlags |= PSDEVMODE_CTRLD_BEFORE;
|
|
else
|
|
pdm->dmPrivate.dwFlags &= ~PSDEVMODE_CTRLD_BEFORE;
|
|
break;
|
|
|
|
case CTRLD_AFTER_ITEM:
|
|
if (pOptItem->Sel == 0)
|
|
pdm->dmPrivate.dwFlags |= PSDEVMODE_CTRLD_AFTER;
|
|
else
|
|
pdm->dmPrivate.dwFlags &= ~PSDEVMODE_CTRLD_AFTER;
|
|
break;
|
|
|
|
case RESOLUTION_ITEM:
|
|
pdm->dmPublic.dmPrintQuality = (SHORT)
|
|
pUiData->pResolutions[pOptItem->Sel * 2];
|
|
dmFields |= DM_PRINTQUALITY;
|
|
break;
|
|
|
|
case FORMNAME_ITEM:
|
|
pdm->dmPublic.dmFields &= ~(DM_PAPERLENGTH|DM_PAPERWIDTH);
|
|
pdm->dmPublic.dmFields |= (DM_FORMNAME|DM_PAPERSIZE);
|
|
|
|
pdm->dmPublic.dmPaperSize = pUiData->pPapers[pOptItem->Sel];
|
|
CopyStringW(pdm->dmPublic.dmFormName,
|
|
pOptItem->pOptType->pOptParam[pOptItem->Sel].pData,
|
|
CCHFORMNAME);
|
|
dmFields |= DM_FORMNAME;
|
|
break;
|
|
|
|
case INPUTSLOT_ITEM:
|
|
|
|
if ((feature = (WORD) pOptItem->Sel) == 0) {
|
|
|
|
pdm->dmPublic.dmDefaultSource = DMBIN_FORMSOURCE;
|
|
|
|
} else {
|
|
|
|
if (feature+1 == pOptItem->pOptType->Count &&
|
|
wcscmp(pOptItem->pOptType->pOptParam[feature].pData,
|
|
STDSTR_SLOT_MANUAL) == EQUAL_STRING)
|
|
{
|
|
pdm->dmPublic.dmDefaultSource = DMBIN_MANUAL;
|
|
} else
|
|
pdm->dmPublic.dmDefaultSource = feature - 1 + DMBIN_USER;
|
|
}
|
|
|
|
dmFields |= DM_DEFAULTSOURCE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Convert DEVMODE fields to printer feature selection
|
|
|
|
if (dmFields != 0) {
|
|
|
|
feature = DevModeFieldsToOptions(&pUiData->devmode, dmFields, pUiData->hppd);
|
|
}
|
|
|
|
return feature;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
RestoreDefaultFeatureSelection(
|
|
PUIDATA pUiData
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Restore the printer feature selections to their default state
|
|
|
|
Arguments:
|
|
|
|
pUiData - Points to our UIDATA structure
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
|
|
--*/
|
|
|
|
{
|
|
PUIGROUP pUiGroup;
|
|
POPTITEM pOptItem;
|
|
DWORD count, featureIndex;
|
|
PBYTE pOptions;
|
|
|
|
//
|
|
// Go through each printer feature item and check to see if
|
|
// its current selection matches the default value
|
|
//
|
|
|
|
pOptions = pUiData->devmode.dmPrivate.options;
|
|
pOptItem = pUiData->pFeatureItems;
|
|
count = pUiData->cFeatureItem;
|
|
|
|
while (count-- > 0) {
|
|
|
|
pUiGroup = (PUIGROUP) pOptItem->UserData;
|
|
featureIndex = pUiGroup->featureIndex;
|
|
|
|
//
|
|
// If the current selection doesn't match the default,
|
|
// restore it to the default value.
|
|
//
|
|
|
|
if (pOptions[featureIndex] != pUiGroup->dwDefault) {
|
|
|
|
pOptions[featureIndex] = (BYTE) pUiGroup->dwDefault;
|
|
pOptItem->Flags |= OPTIF_CHANGED;
|
|
pOptItem->Sel =
|
|
(pOptions[featureIndex] == OPTION_INDEX_ANY) ? 0 : (pOptions[featureIndex]+1);
|
|
}
|
|
|
|
pOptItem++;
|
|
}
|
|
|
|
//
|
|
// Update the display and indicate which items are constrained
|
|
//
|
|
|
|
DocPropShowConstraints(pUiData, pUiData->pFeatureItems, pUiData->cFeatureItem);
|
|
}
|
|
|
|
|
|
|
|
CPSUICALLBACK
|
|
DocumentPropertyCallback(
|
|
PCPSUICBPARAM pCallbackParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Callback function provided to common UI DLL for handling
|
|
document properties dialog.
|
|
|
|
Arguments:
|
|
|
|
pCallbackParam - Pointer to CPSUICBPARAM structure
|
|
|
|
Return Value:
|
|
|
|
CPSUICB_ACTION_NONE - no action needed
|
|
CPSUICB_ACTION_OPTIF_CHANGED - items changed and should be refreshed
|
|
|
|
--*/
|
|
|
|
{
|
|
PUIDATA pUiData;
|
|
POPTITEM pCurItem;
|
|
|
|
pUiData = (PUIDATA) pCallbackParam->UserData;
|
|
ASSERT(pUiData != NULL);
|
|
|
|
pUiData->hDlg = pCallbackParam->hDlg;
|
|
pCurItem = pCallbackParam->pCurItem;
|
|
|
|
// If user has no permission to change anything, then
|
|
// simply return without taking any action.
|
|
|
|
if (! HasPermission(pUiData))
|
|
return CPSUICB_ACTION_NONE;
|
|
|
|
switch (pCallbackParam->Reason) {
|
|
|
|
case CPSUICB_REASON_SEL_CHANGED:
|
|
case CPSUICB_REASON_ECB_CHANGED:
|
|
|
|
if (UnpackDocumentPropertiesItems(pUiData,
|
|
&pUiData->devmode,
|
|
pCurItem,
|
|
1) != OPTION_INDEX_NONE)
|
|
{
|
|
INT conflict = CONFLICT_NONE;
|
|
|
|
if (pCurItem->pOptType->Type == TVOT_LISTBOX)
|
|
conflict = CheckConstraintsDlg(pUiData, pCurItem, 1, FALSE);
|
|
|
|
switch (conflict) {
|
|
|
|
case CONFLICT_CANCEL:
|
|
|
|
// If there is a conflict and the user clicked
|
|
// CANCEL to restore the original selection.
|
|
|
|
pCurItem->Sel = pCallbackParam->OldSel;
|
|
pCurItem->Flags |= OPTIF_CHANGED;
|
|
|
|
UnpackDocumentPropertiesItems(pUiData, &pUiData->devmode, pCurItem, 1);
|
|
|
|
return CPSUICB_ACTION_OPTIF_CHANGED;
|
|
|
|
case CONFLICT_RESOLVE:
|
|
|
|
UnpackDocumentPropertiesItems(pUiData, &pUiData->devmode, pCurItem, 1);
|
|
|
|
default:
|
|
|
|
// Update the display and indicate which items are constrained
|
|
|
|
DocPropShowConstraints(pUiData,
|
|
pCallbackParam->pOptItem,
|
|
pCallbackParam->cOptItem);
|
|
|
|
return CPSUICB_ACTION_REINIT_ITEMS;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case CPSUICB_REASON_ITEMS_REVERTED:
|
|
|
|
// Unpack document properties treeview items
|
|
|
|
UnpackDocumentPropertiesItems(pUiData,
|
|
&pUiData->devmode,
|
|
pCallbackParam->pOptItem,
|
|
pCallbackParam->cOptItem);
|
|
|
|
// Update the display and indicate which items are constrained
|
|
|
|
DocPropShowConstraints(pUiData, pCallbackParam->pOptItem, pCallbackParam->cOptItem);
|
|
|
|
return CPSUICB_ACTION_OPTIF_CHANGED;
|
|
|
|
case CPSUICB_REASON_EXTPUSH:
|
|
|
|
if (pCurItem == pUiData->pFeatureHdrItem && pUiData->cFeatureItem > 0) {
|
|
|
|
RestoreDefaultFeatureSelection(pUiData);
|
|
return CPSUICB_ACTION_REINIT_ITEMS;
|
|
}
|
|
break;
|
|
|
|
case CPSUICB_REASON_APPLYNOW:
|
|
|
|
// Check if there are still any unresolved constraints left?
|
|
|
|
if (OptItemSelectionsChanged(pCallbackParam->pOptItem, pCallbackParam->cOptItem) &&
|
|
CheckDocumentConstraints(pUiData,
|
|
pCallbackParam->pOptItem,
|
|
pCallbackParam->cOptItem) == CONFLICT_CANCEL)
|
|
{
|
|
// Conflicts found and user clicked CANCEL to
|
|
// go back to the dialog without dismissing it.
|
|
|
|
return CPSUICB_ACTION_NO_APPLY_EXIT;
|
|
}
|
|
|
|
UndoDevModeOptions(pUiData->hppd, pUiData->devmode.dmPrivate.options);
|
|
|
|
pCallbackParam->Result = CPSUI_OK;
|
|
return CPSUICB_ACTION_ITEMS_APPLIED;
|
|
}
|
|
|
|
return CPSUICB_ACTION_NONE;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
PackDocumentPropertyItems(
|
|
PPACKINFO pPackInfo
|
|
)
|
|
|
|
{
|
|
PSDEVMODE *pdm = &pPackInfo->pUiData->devmode;
|
|
|
|
// Note: FormName item should be packed before InputSlot item.
|
|
|
|
return PackItemOrientation(pPackInfo, pdm) &&
|
|
PackItemScale(pPackInfo, pdm) &&
|
|
PackItemCopiesCollate(pPackInfo, pdm) &&
|
|
PackItemColor(pPackInfo, pdm) &&
|
|
PackItemDuplex(pPackInfo, pdm) &&
|
|
PackItemFormName(pPackInfo, pdm) &&
|
|
PackItemInputSlot(pPackInfo, pdm) &&
|
|
PackItemResolution(pPackInfo, pdm) &&
|
|
PackItemTTOptions(pPackInfo, pdm) &&
|
|
PackItemMetafileOptions(pPackInfo, pdm) &&
|
|
PackItemPostScriptOptions(pPackInfo, pdm) &&
|
|
PackItemHalftoneAdjustment(pPackInfo, pdm) &&
|
|
PackItemDeviceOptions(pPackInfo, pdm);
|
|
}
|
|
|
|
|
|
|
|
//======================================================================//
|
|
// Go through the tedious process to pack various pieces of document //
|
|
// property information to a format expected by common UI DLL. //
|
|
//======================================================================//
|
|
|
|
BOOL
|
|
PackItemOrientation(
|
|
PPACKINFO pPackInfo,
|
|
PSDEVMODE *pdm
|
|
)
|
|
|
|
{
|
|
static WORD ItemInfo[] = {
|
|
IDS_CPSUI_ORIENTATION, TVITEM_LEVEL1, DMPUB_ORIENTATION,
|
|
ORIENTATION_ITEM, HELP_INDEX_ORIENTATION,
|
|
3, TVOT_3STATES,
|
|
IDS_CPSUI_PORTRAIT, IDI_CPSUI_PORTRAIT,
|
|
IDS_CPSUI_LANDSCAPE, IDI_CPSUI_LANDSCAPE,
|
|
IDS_CPSUI_ROT_LAND, IDI_CPSUI_ROT_LAND,
|
|
ITEM_INFO_SIGNATURE
|
|
};
|
|
|
|
DWORD selection;
|
|
|
|
if ((pdm->dmPublic.dmFields & DM_ORIENTATION) &&
|
|
(pdm->dmPublic.dmOrientation == DMORIENT_LANDSCAPE))
|
|
{
|
|
selection = (pdm->dmPrivate.dwFlags & PSDEVMODE_LSROTATE) ? 2 : 1;
|
|
} else
|
|
selection = 0;
|
|
|
|
return PackOptItemTemplate(pPackInfo, ItemInfo, selection);
|
|
}
|
|
|
|
BOOL
|
|
PackItemScale(
|
|
PPACKINFO pPackInfo,
|
|
PSDEVMODE *pdm
|
|
)
|
|
|
|
{
|
|
static WORD ItemInfo[] = {
|
|
IDS_CPSUI_SCALING, TVITEM_LEVEL1, DMPUB_SCALE,
|
|
SCALE_ITEM, HELP_INDEX_SCALE,
|
|
2, TVOT_UDARROW,
|
|
IDS_CPSUI_PERCENT, IDI_CPSUI_SCALING,
|
|
0, MIN_SCALE,
|
|
ITEM_INFO_SIGNATURE
|
|
};
|
|
|
|
POPTTYPE pOptType = pPackInfo->pOptType;
|
|
|
|
if (! PackOptItemTemplate(pPackInfo, ItemInfo,
|
|
(pdm->dmPublic.dmFields & DM_SCALE) ? pdm->dmPublic.dmScale : 100))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (pOptType)
|
|
pOptType->pOptParam[1].lParam = MAX_SCALE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
PackItemCopiesCollate(
|
|
PPACKINFO pPackInfo,
|
|
PSDEVMODE *pdm
|
|
)
|
|
|
|
{
|
|
static WORD ItemInfo[] = {
|
|
IDS_CPSUI_COPIES, TVITEM_LEVEL1, DMPUB_COPIES_COLLATE,
|
|
COPIES_COLLATE_ITEM, HELP_INDEX_COPIES_COLLATE,
|
|
2, TVOT_UDARROW,
|
|
0, IDI_CPSUI_COPY,
|
|
0, MIN_COPIES,
|
|
ITEM_INFO_SIGNATURE
|
|
};
|
|
|
|
POPTITEM pOptItem = pPackInfo->pOptItem;
|
|
POPTTYPE pOptType = pPackInfo->pOptType;
|
|
PEXTCHKBOX pExtCheckbox;
|
|
|
|
if (! PackOptItemTemplate(pPackInfo, ItemInfo,
|
|
(pdm->dmPublic.dmFields & DM_COPIES) ? pdm->dmPublic.dmCopies : 1))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (pOptItem != NULL && PpdSupportCollation(pPackInfo->pUiData->hppd)) {
|
|
|
|
pExtCheckbox =
|
|
HEAPALLOC(pPackInfo->pUiData->hheap, sizeof(EXTCHKBOX));
|
|
|
|
if (pExtCheckbox == NULL) {
|
|
DBGERRMSG("HEAPALLOC");
|
|
return FALSE;
|
|
}
|
|
|
|
memset(pExtCheckbox, 0, sizeof(EXTCHKBOX));
|
|
|
|
pExtCheckbox->cbSize = sizeof(EXTCHKBOX);
|
|
pExtCheckbox->pTitle = (PWSTR) IDS_CPSUI_COLLATE;
|
|
pExtCheckbox->pCheckedName = (PWSTR) IDS_CPSUI_COLLATED;
|
|
pExtCheckbox->IconID = IDI_CPSUI_COLLATE;
|
|
|
|
pOptItem->pExtChkBox = pExtCheckbox;
|
|
if ((pdm->dmPublic.dmFields & DM_COLLATE) &&
|
|
(pdm->dmPublic.dmCollate == DMCOLLATE_TRUE))
|
|
{
|
|
pOptItem->Flags |= OPTIF_ECB_CHECKED;
|
|
}
|
|
}
|
|
|
|
if (pOptType)
|
|
pOptType->pOptParam[1].lParam = MAX_COPIES;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
PackItemColor(
|
|
PPACKINFO pPackInfo,
|
|
PSDEVMODE *pdm
|
|
)
|
|
|
|
{
|
|
static WORD ItemInfo[] = {
|
|
IDS_CPSUI_COLOR, TVITEM_LEVEL1, DMPUB_COLOR,
|
|
COLOR_ITEM, HELP_INDEX_COLOR,
|
|
2, TVOT_2STATES,
|
|
IDS_CPSUI_GRAYSCALE, IDI_CPSUI_MONO,
|
|
IDS_CPSUI_COLOR, IDI_CPSUI_COLOR,
|
|
ITEM_INFO_SIGNATURE
|
|
};
|
|
|
|
INT selection;
|
|
|
|
selection = ((pdm->dmPublic.dmFields & DM_COLOR) &&
|
|
(pdm->dmPublic.dmColor == DMCOLOR_COLOR)) ? 1 : 0;
|
|
|
|
return PackOptItemTemplate(pPackInfo, ItemInfo, selection);
|
|
}
|
|
|
|
BOOL
|
|
PackItemHalftoneAdjustment(
|
|
PPACKINFO pPackInfo,
|
|
PSDEVMODE *pdm
|
|
)
|
|
|
|
{
|
|
static WORD ItemInfo[] = {
|
|
IDS_CPSUI_HTCLRADJ, TVITEM_LEVEL1, DMPUB_NONE,
|
|
UNKNOWN_ITEM, HELP_INDEX_HALFTONE_COLORADJ,
|
|
1, TVOT_PUSHBUTTON,
|
|
0, IDI_CPSUI_HTCLRADJ,
|
|
ITEM_INFO_SIGNATURE
|
|
};
|
|
|
|
POPTTYPE pOptType = pPackInfo->pOptType;
|
|
|
|
if (! PackOptItemTemplate(pPackInfo, ItemInfo, 0))
|
|
return FALSE;
|
|
|
|
if (pOptType) {
|
|
|
|
pOptType->pOptParam[0].pData = (PWSTR)
|
|
&pPackInfo->pUiData->devmode.dmPrivate.coloradj;
|
|
pOptType->pOptParam[0].Style = PUSHBUTTON_TYPE_HTCLRADJ;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
PackItemDuplex(
|
|
PPACKINFO pPackInfo,
|
|
PSDEVMODE *pdm
|
|
)
|
|
|
|
{
|
|
static WORD ItemInfo[] = {
|
|
IDS_CPSUI_DUPLEX, TVITEM_LEVEL1, DMPUB_DUPLEX,
|
|
DUPLEX_ITEM, HELP_INDEX_DUPLEX,
|
|
3, TVOT_3STATES,
|
|
IDS_CPSUI_NONE, IDI_CPSUI_DUPLEX_NONE,
|
|
IDS_CPSUI_SHORT_SIDE, IDI_CPSUI_DUPLEX_HORZ,
|
|
IDS_CPSUI_LONG_SIDE, IDI_CPSUI_DUPLEX_VERT,
|
|
ITEM_INFO_SIGNATURE
|
|
};
|
|
|
|
INT selection = 0;
|
|
POPTTYPE pOptType;
|
|
HPPD hppd = pPackInfo->pUiData->hppd;
|
|
BOOL bDuplexVertical, bDuplexHorizontal;
|
|
|
|
if (! PpdSupportDuplex(hppd))
|
|
return TRUE;
|
|
|
|
pOptType = pPackInfo->pOptType;
|
|
|
|
bDuplexVertical = bDuplexHorizontal = FALSE;
|
|
if (PpdFindDuplexCode(hppd, MapDevModeDuplexOption(DMDUP_VERTICAL)))
|
|
bDuplexVertical = TRUE;
|
|
if (PpdFindDuplexCode(hppd, MapDevModeDuplexOption(DMDUP_HORIZONTAL)))
|
|
bDuplexHorizontal = TRUE;
|
|
|
|
if (pdm->dmPublic.dmFields & DM_DUPLEX) {
|
|
|
|
if (pdm->dmPublic.dmDuplex == DMDUP_VERTICAL && bDuplexVertical)
|
|
selection = 2;
|
|
else if (pdm->dmPublic.dmDuplex == DMDUP_HORIZONTAL && bDuplexHorizontal)
|
|
selection = 1;
|
|
}
|
|
|
|
if (! PackOptItemTemplate(pPackInfo, ItemInfo, selection))
|
|
return FALSE;
|
|
|
|
if (pOptType) {
|
|
|
|
if (! bDuplexVertical)
|
|
pOptType->pOptParam[1].Flags |= OPTPF_HIDE;
|
|
|
|
if (! bDuplexHorizontal)
|
|
pOptType->pOptParam[2].Flags |= OPTPF_HIDE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
PackItemResolution(
|
|
PPACKINFO pPackInfo,
|
|
PSDEVMODE *pdm
|
|
)
|
|
|
|
{
|
|
if (pPackInfo->pOptItem) {
|
|
|
|
WORD cResolutions;
|
|
PLONG pResolutions;
|
|
DWORD selection = 0;
|
|
CHAR buffer[MAX_INT_DIGITS];
|
|
POPTPARAM pParam;
|
|
|
|
// Get a list of resolutions supported by the printer
|
|
|
|
cResolutions = (WORD) pPackInfo->pUiData->cResolutions;
|
|
pResolutions = pPackInfo->pUiData->pResolutions;
|
|
|
|
// Figure out the current selection
|
|
|
|
if (pdm->dmPublic.dmFields & DM_PRINTQUALITY) {
|
|
|
|
for (selection=0;
|
|
selection < cResolutions &&
|
|
pdm->dmPublic.dmPrintQuality != pResolutions[selection*2];
|
|
selection++)
|
|
{
|
|
}
|
|
|
|
if (selection == cResolutions)
|
|
selection = 0;
|
|
}
|
|
|
|
// Fill out OPTITEM, OPTTYPE, and OPTPARAM structures
|
|
|
|
FILLOPTITEM(pPackInfo->pOptItem,
|
|
pPackInfo->pOptType,
|
|
IDS_CPSUI_RESOLUTION,
|
|
selection,
|
|
TVITEM_LEVEL1,
|
|
DMPUB_PRINTQUALITY,
|
|
RESOLUTION_ITEM,
|
|
HELP_INDEX_RESOLUTION);
|
|
|
|
pParam = FillOutOptType(pPackInfo->pOptType,
|
|
TVOT_LISTBOX,
|
|
cResolutions,
|
|
pPackInfo->pUiData->hheap);
|
|
|
|
if (pParam == NULL)
|
|
return FALSE;
|
|
|
|
while (cResolutions--) {
|
|
|
|
_ltoa(*pResolutions, buffer, 10);
|
|
|
|
pParam->cbSize = sizeof(OPTPARAM);
|
|
pParam->pData = GetStringFromAnsi(buffer, pPackInfo->pUiData->hheap);
|
|
pParam->IconID =
|
|
(*pResolutions <= 300) ? IDI_CPSUI_RES_LOW :
|
|
(*pResolutions <= 600) ? IDI_CPSUI_RES_MEDIUM :
|
|
(*pResolutions <= 1200) ? IDI_CPSUI_RES_HIGH : IDI_CPSUI_RES_PRESENTATION;
|
|
|
|
pResolutions += 2;
|
|
pParam++;
|
|
}
|
|
|
|
pPackInfo->pOptItem++;
|
|
pPackInfo->pOptType++;
|
|
}
|
|
|
|
pPackInfo->cOptItem++;
|
|
pPackInfo->cOptType++;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
PackItemInputSlot(
|
|
PPACKINFO pPackInfo,
|
|
PSDEVMODE *pdm
|
|
)
|
|
|
|
{
|
|
if (pPackInfo->pOptItem) {
|
|
|
|
WORD cBinNames, IconID;
|
|
PWSTR pBinNames;
|
|
DWORD selection;
|
|
POPTPARAM pParam;
|
|
|
|
// Get a list of resolutions supported by the printer
|
|
|
|
cBinNames = (WORD) pPackInfo->pUiData->cBinNames;
|
|
pBinNames = pPackInfo->pUiData->pBinNames;
|
|
|
|
// Figure out the current selection
|
|
|
|
if ((pdm->dmPublic.dmFields & DM_DEFAULTSOURCE) &&
|
|
(pdm->dmPublic.dmDefaultSource >= DMBIN_USER) &&
|
|
(pdm->dmPublic.dmDefaultSource < DMBIN_USER + cBinNames - 1))
|
|
{
|
|
selection = pdm->dmPublic.dmDefaultSource - DMBIN_USER + 1;
|
|
} else
|
|
selection = 0;
|
|
|
|
// Fill out OPTITEM, OPTTYPE, and OPTPARAM structures
|
|
|
|
FILLOPTITEM(pPackInfo->pOptItem,
|
|
pPackInfo->pOptType,
|
|
IDS_CPSUI_FORMSOURCE,
|
|
selection,
|
|
TVITEM_LEVEL1,
|
|
DMPUB_DEFSOURCE,
|
|
INPUTSLOT_ITEM,
|
|
HELP_INDEX_INPUT_SLOT);
|
|
|
|
pParam = FillOutOptType(pPackInfo->pOptType,
|
|
TVOT_LISTBOX,
|
|
cBinNames,
|
|
pPackInfo->pUiData->hheap);
|
|
|
|
if (pParam == NULL)
|
|
return FALSE;
|
|
|
|
IconID = IDI_CPSUI_PRINTER_FOLDER;
|
|
while (cBinNames--) {
|
|
|
|
pParam->cbSize = sizeof(OPTPARAM);
|
|
pParam->pData = pBinNames;
|
|
|
|
if ((pParam->IconID = IconID) == IDI_CPSUI_PRINTER_FOLDER) {
|
|
|
|
IconID = IDI_CPSUI_PAPER_TRAY;
|
|
pParam->pData = (PWSTR) IDS_CPSUI_PRINTFLDSETTING;
|
|
}
|
|
|
|
pParam++;
|
|
pBinNames += CCHBINNAME;
|
|
}
|
|
|
|
if ((pdm->dmPublic.dmFields & DM_DEFAULTSOURCE) &&
|
|
(pdm->dmPublic.dmDefaultSource == DMBIN_MANUAL ||
|
|
pdm->dmPublic.dmDefaultSource == DMBIN_ENVMANUAL) &&
|
|
wcscmp(pBinNames-CCHBINNAME, STDSTR_SLOT_MANUAL) == EQUAL_STRING)
|
|
{
|
|
pPackInfo->pOptItem->Sel = pPackInfo->pOptType->Count - 1;
|
|
}
|
|
|
|
pPackInfo->pOptItem++;
|
|
pPackInfo->pOptType++;
|
|
}
|
|
|
|
pPackInfo->cOptItem++;
|
|
pPackInfo->cOptType++;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
PackItemFormName(
|
|
PPACKINFO pPackInfo,
|
|
PSDEVMODE *pdm
|
|
)
|
|
|
|
{
|
|
if (pPackInfo->pOptItem) {
|
|
|
|
WORD cFormNames;
|
|
PWSTR pFormNames;
|
|
DWORD selection = 0;
|
|
POPTPARAM pParam;
|
|
FORM_INFO_1 FormInfo;
|
|
|
|
// Get a list of resolutions supported by the printer
|
|
|
|
cFormNames = (WORD) pPackInfo->pUiData->cFormNames;
|
|
pFormNames = pPackInfo->pUiData->pFormNames;
|
|
|
|
// Figure out the current selection.
|
|
// Due to the devmode validation process, DM_FORMNAME
|
|
// flag will always be set if a known form is specified,
|
|
|
|
if (pdm->dmPublic.dmFields & DM_FORMNAME) {
|
|
|
|
selection = FindFormNameIndex(pPackInfo->pUiData, pdm->dmPublic.dmFormName);
|
|
}
|
|
|
|
// Fill out OPTITEM, OPTTYPE, and OPTPARAM structures
|
|
|
|
FILLOPTITEM(pPackInfo->pOptItem,
|
|
pPackInfo->pOptType,
|
|
IDS_CPSUI_FORMNAME,
|
|
selection,
|
|
TVITEM_LEVEL1,
|
|
DMPUB_FORMNAME,
|
|
FORMNAME_ITEM,
|
|
HELP_INDEX_FORMNAME);
|
|
|
|
pPackInfo->pOptType->Style = OTS_LBCB_SORT;
|
|
|
|
pParam = FillOutOptType(pPackInfo->pOptType,
|
|
TVOT_LISTBOX,
|
|
cFormNames,
|
|
pPackInfo->pUiData->hheap);
|
|
|
|
if (pParam == NULL)
|
|
return FALSE;
|
|
|
|
while (cFormNames--) {
|
|
|
|
pParam->cbSize = sizeof(OPTPARAM);
|
|
pParam->pData = pFormNames;
|
|
pParam->IconID = GetFormIconID(pFormNames);
|
|
|
|
pParam++;
|
|
pFormNames += CCHPAPERNAME;
|
|
}
|
|
|
|
pPackInfo->pOptItem++;
|
|
pPackInfo->pOptType++;
|
|
}
|
|
|
|
pPackInfo->cOptItem++;
|
|
pPackInfo->cOptType++;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
PackItemTTOptions(
|
|
PPACKINFO pPackInfo,
|
|
PSDEVMODE *pdm
|
|
)
|
|
|
|
{
|
|
static WORD ItemInfo[] = {
|
|
IDS_CPSUI_TTOPTION, TVITEM_LEVEL1, DMPUB_TTOPTION,
|
|
TTOPTION_ITEM, HELP_INDEX_TTOPTION,
|
|
2, TVOT_2STATES,
|
|
IDS_CPSUI_TT_SUBDEV, IDI_CPSUI_TT_SUBDEV,
|
|
IDS_CPSUI_TT_DOWNLOADSOFT, IDI_CPSUI_TT_DOWNLOADSOFT,
|
|
ITEM_INFO_SIGNATURE
|
|
};
|
|
|
|
if (GetACP() != 1252) {
|
|
|
|
pdm->dmPrivate.dwFlags &= ~PSDEVMODE_FONTSUBST;
|
|
return TRUE;
|
|
}
|
|
|
|
return PackOptItemTemplate(pPackInfo,
|
|
ItemInfo,
|
|
(pdm->dmPrivate.dwFlags & PSDEVMODE_FONTSUBST) ? 0 : 1);
|
|
}
|
|
|
|
BOOL
|
|
PackItemMetafileOptions(
|
|
PPACKINFO pPackInfo,
|
|
PSDEVMODE *pdm
|
|
)
|
|
|
|
{
|
|
static WORD ItemInfo[] = {
|
|
IDS_METAFILE_SPOOLING, TVITEM_LEVEL1, DMPUB_NONE,
|
|
METASPOOL_ITEM, HELP_INDEX_METAFILE_SPOOLING,
|
|
2, TVOT_2STATES,
|
|
IDS_ENABLED, IDI_CPSUI_ON,
|
|
IDS_DISABLED, IDI_CPSUI_OFF,
|
|
ITEM_INFO_SIGNATURE
|
|
};
|
|
|
|
return PackOptItemTemplate(pPackInfo,
|
|
ItemInfo,
|
|
(pdm->dmPrivate.dwFlags & PSDEVMODE_METAFILE_SPOOL) ? 0 : 1);
|
|
}
|
|
|
|
BOOL
|
|
PackItemPostScriptOptions(
|
|
PPACKINFO pPackInfo,
|
|
PSDEVMODE *pdm
|
|
)
|
|
|
|
{
|
|
static WORD MirrorItemInfo[] = {
|
|
IDS_MIRROR, TVITEM_LEVEL2, DMPUB_NONE,
|
|
MIRROR_ITEM, HELP_INDEX_MIRROR,
|
|
2, TVOT_2STATES,
|
|
IDS_CPSUI_YES, IDI_CPSUI_ON,
|
|
IDS_CPSUI_NO, IDI_CPSUI_OFF,
|
|
ITEM_INFO_SIGNATURE
|
|
};
|
|
|
|
static WORD NegativeItemInfo[] = {
|
|
IDS_NEGATIVE_PRINT, TVITEM_LEVEL2, DMPUB_NONE,
|
|
NEGATIVE_ITEM, HELP_INDEX_NEGATIVE,
|
|
2, TVOT_2STATES,
|
|
IDS_CPSUI_YES, IDI_CPSUI_ON,
|
|
IDS_CPSUI_NO, IDI_CPSUI_OFF,
|
|
ITEM_INFO_SIGNATURE
|
|
};
|
|
|
|
static WORD PageIndepItemInfo[] = {
|
|
IDS_PAGEINDEP, TVITEM_LEVEL2, DMPUB_NONE,
|
|
PAGEINDEP_ITEM, HELP_INDEX_PAGEINDEP,
|
|
2, TVOT_2STATES,
|
|
IDS_CPSUI_YES, IDI_CPSUI_ON,
|
|
IDS_CPSUI_NO, IDI_CPSUI_OFF,
|
|
ITEM_INFO_SIGNATURE
|
|
};
|
|
|
|
static WORD CompressBmpItemInfo[] = {
|
|
IDS_COMPRESSBMP, TVITEM_LEVEL2, DMPUB_NONE,
|
|
COMPRESSBMP_ITEM, HELP_INDEX_COMPRESSBMP,
|
|
2, TVOT_2STATES,
|
|
IDS_CPSUI_YES, IDI_CPSUI_ON,
|
|
IDS_CPSUI_NO, IDI_CPSUI_OFF,
|
|
ITEM_INFO_SIGNATURE
|
|
};
|
|
|
|
static WORD JobControlItemInfo[] = {
|
|
IDS_JOB_CONTROL, TVITEM_LEVEL2, DMPUB_NONE,
|
|
JOB_CONTROL_ITEM, HELP_INDEX_JOB_CONTROL,
|
|
2, TVOT_2STATES,
|
|
IDS_CPSUI_YES, IDI_CPSUI_ON,
|
|
IDS_CPSUI_NO, IDI_CPSUI_OFF,
|
|
ITEM_INFO_SIGNATURE
|
|
};
|
|
|
|
static WORD CtrlDBeforeItemInfo[] = {
|
|
IDS_CTRLD_BEFORE, TVITEM_LEVEL2, DMPUB_NONE,
|
|
CTRLD_BEFORE_ITEM, HELP_INDEX_CTRLD_BEFORE,
|
|
2, TVOT_2STATES,
|
|
IDS_CPSUI_YES, IDI_CPSUI_ON,
|
|
IDS_CPSUI_NO, IDI_CPSUI_OFF,
|
|
ITEM_INFO_SIGNATURE
|
|
};
|
|
|
|
static WORD CtrlDAfterItemInfo[] = {
|
|
IDS_CTRLD_AFTER, TVITEM_LEVEL2, DMPUB_NONE,
|
|
CTRLD_AFTER_ITEM, HELP_INDEX_CTRLD_AFTER,
|
|
2, TVOT_2STATES,
|
|
IDS_CPSUI_YES, IDI_CPSUI_ON,
|
|
IDS_CPSUI_NO, IDI_CPSUI_OFF,
|
|
ITEM_INFO_SIGNATURE
|
|
};
|
|
|
|
// PostScript options
|
|
// Mirror
|
|
// Negative
|
|
// Page independence
|
|
// Compress bitmaps
|
|
// Send ^D before each job
|
|
// Send ^D after each job
|
|
|
|
POPTITEM pOptItem = pPackInfo->pOptItem;
|
|
DWORD dmFlags;
|
|
|
|
PackOptItemGroupHeader(pPackInfo,
|
|
IDS_PSOPTIONS,
|
|
IDI_CPSUI_POSTSCRIPT,
|
|
HELP_INDEX_PSOPTIONS);
|
|
|
|
if (pOptItem)
|
|
pOptItem->Flags |= OPTIF_COLLAPSE;
|
|
|
|
dmFlags = pdm->dmPrivate.dwFlags;
|
|
|
|
return PackOptItemTemplate(pPackInfo,
|
|
MirrorItemInfo,
|
|
(dmFlags & PSDEVMODE_MIRROR) ? 0 : 1) &&
|
|
PackOptItemTemplate(pPackInfo,
|
|
NegativeItemInfo,
|
|
(dmFlags & PSDEVMODE_NEG) ? 0 : 1) &&
|
|
PackOptItemTemplate(pPackInfo,
|
|
PageIndepItemInfo,
|
|
(dmFlags & PSDEVMODE_INDEPENDENT) ? 0 : 1) &&
|
|
(!Level2Device(pPackInfo->pUiData->hppd) ||
|
|
PackOptItemTemplate(pPackInfo,
|
|
CompressBmpItemInfo,
|
|
(dmFlags & PSDEVMODE_COMPRESSBMP) ? 0 : 1)) &&
|
|
PackOptItemTemplate(pPackInfo,
|
|
JobControlItemInfo,
|
|
(dmFlags & PSDEVMODE_NO_JOB_CONTROL) ? 1 : 0) &&
|
|
PackOptItemTemplate(pPackInfo,
|
|
CtrlDBeforeItemInfo,
|
|
(dmFlags & PSDEVMODE_CTRLD_BEFORE) ? 0 : 1) &&
|
|
PackOptItemTemplate(pPackInfo,
|
|
CtrlDAfterItemInfo,
|
|
(dmFlags & PSDEVMODE_CTRLD_AFTER) ? 0 : 1);
|
|
}
|
|
|
|
BOOL
|
|
PackItemDeviceOptions(
|
|
PPACKINFO pPackInfo,
|
|
PSDEVMODE *pdm
|
|
)
|
|
{
|
|
//
|
|
// Extended push button for restoring to default feature selections
|
|
//
|
|
|
|
static EXTPUSH extPush = {
|
|
|
|
sizeof(EXTPUSH),
|
|
EPF_NO_DOT_DOT_DOT,
|
|
(PWSTR) IDS_RESTORE_DEFAULTS,
|
|
NULL,
|
|
0,
|
|
0,
|
|
};
|
|
|
|
HPPD hppd = pPackInfo->pUiData->hppd;
|
|
WORD cFeatures;
|
|
POPTITEM pOptItem;
|
|
|
|
if ((cFeatures = hppd->cDocumentStickyFeatures) > 0) {
|
|
|
|
pOptItem = pPackInfo->pOptItem;
|
|
|
|
PackOptItemGroupHeader(pPackInfo,
|
|
IDS_PRINTER_FEATURES,
|
|
IDI_CPSUI_PRINTER_FEATURE,
|
|
HELP_INDEX_PRINTER_FEATURES);
|
|
|
|
if (pOptItem != NULL) {
|
|
|
|
//
|
|
// "Restore Defaults" button
|
|
//
|
|
|
|
pPackInfo->pUiData->pFeatureHdrItem = pOptItem;
|
|
pOptItem->Flags |= (OPTIF_EXT_IS_EXTPUSH|OPTIF_CALLBACK);
|
|
pOptItem->pExtPush = &extPush;
|
|
}
|
|
|
|
pOptItem = pPackInfo->pOptItem;
|
|
|
|
if (! PackPrinterFeatureItems(pPackInfo,
|
|
hppd->pUiGroups,
|
|
cFeatures,
|
|
pdm->dmPrivate.options,
|
|
FALSE,
|
|
pPackInfo->pUiData->hheap))
|
|
{
|
|
DBGERRMSG("PackPrinterFeatureItems");
|
|
return FALSE;
|
|
}
|
|
|
|
if (pOptItem != NULL) {
|
|
|
|
pPackInfo->pUiData->pFeatureItems = pOptItem;
|
|
pPackInfo->pUiData->cFeatureItem = (pPackInfo->pOptItem - pOptItem);
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
INT
|
|
CheckDocumentConstraints(
|
|
PUIDATA pUiData,
|
|
POPTITEM pOptItem,
|
|
WORD cOptItem
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Make sure there are no unresolved conflicts left when
|
|
the user clicks OK to exit the dialog.
|
|
|
|
Arguments:
|
|
|
|
pUiData - Pointer to our UIDATA structure
|
|
pOptItem - Pointer to an array of OPTITEMs
|
|
cOptItem - Number of items to be checked
|
|
|
|
Return Value:
|
|
|
|
CONFLICT_NONE - No conflicts found
|
|
CONFLICT_CANCEL - Clicked CANCEL to stay in the dialog
|
|
|
|
--*/
|
|
|
|
{
|
|
for ( ; cOptItem--; pOptItem++) {
|
|
|
|
if ((IsPrinterFeatureItem(pOptItem->UserData) ||
|
|
pOptItem->UserData == INPUTSLOT_ITEM ||
|
|
pOptItem->UserData == FORMNAME_ITEM) &&
|
|
CheckConstraintsDlg(pUiData, pOptItem, 1, TRUE) == CONFLICT_CANCEL)
|
|
{
|
|
return CONFLICT_CANCEL;
|
|
}
|
|
}
|
|
|
|
return CONFLICT_NONE;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
DocPropShowConstraints(
|
|
PUIDATA pUiData,
|
|
POPTITEM pOptItem,
|
|
WORD cOptItem
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Indicate which items are constrained
|
|
|
|
Arguments:
|
|
|
|
pUiData - Pointer to ur UIDATA structure
|
|
pCurItem - Pointer to an array of OPTITEMs
|
|
cOptItem - Number of OPTITEMs
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
|
|
--*/
|
|
|
|
{
|
|
WORD feature, selection, index;
|
|
|
|
for ( ; cOptItem--; pOptItem++) {
|
|
|
|
if (IsPrinterFeatureItem(pOptItem->UserData) || pOptItem->UserData == INPUTSLOT_ITEM) {
|
|
|
|
if (pOptItem->UserData == INPUTSLOT_ITEM) {
|
|
|
|
// Check input slot constraints
|
|
|
|
feature = GetFeatureIndex(pUiData->hppd->pInputSlots);
|
|
|
|
} else {
|
|
|
|
// Check document-sticky printer feature constraints
|
|
|
|
feature = ((PUIGROUP) pOptItem->UserData)->featureIndex;
|
|
}
|
|
|
|
for (selection = 1;
|
|
selection < pOptItem->pOptType->Count;
|
|
selection ++)
|
|
{
|
|
MarkSelectionConstrained(
|
|
pOptItem, selection,
|
|
PpdFeatureConstrained(pUiData->hppd,
|
|
pUiData->printerData.options,
|
|
pUiData->devmode.dmPrivate.options,
|
|
feature,
|
|
(WORD) (selection - 1)));
|
|
}
|
|
|
|
} else if (pOptItem->UserData == FORMNAME_ITEM) {
|
|
|
|
// Check paper size constraints
|
|
|
|
feature = GetFeatureIndex(pUiData->hppd->pPageSizes);
|
|
selection = OPTION_INDEX_ANY;
|
|
|
|
for (index=0; index < pOptItem->pOptType->Count; index++) {
|
|
|
|
if (feature != OPTION_INDEX_NONE &&
|
|
pUiData->pPaperFeatures[index] != OPTION_INDEX_ANY)
|
|
{
|
|
POPTPARAM pOptParam;
|
|
|
|
MarkSelectionConstrained(
|
|
pOptItem, index,
|
|
PpdFeatureConstrained(pUiData->hppd,
|
|
pUiData->printerData.options,
|
|
pUiData->devmode.dmPrivate.options,
|
|
feature,
|
|
pUiData->pPaperFeatures[index]));
|
|
|
|
// Hide the form selection if it's constrained
|
|
|
|
pOptParam = &pOptItem->pOptType->pOptParam[index];
|
|
|
|
if (pOptParam->Flags & CONSTRAINED_FLAG) {
|
|
|
|
pOptParam->Flags |= OPTPF_HIDE;
|
|
|
|
} else {
|
|
|
|
pOptParam->Flags &= ~OPTPF_HIDE;
|
|
|
|
if (selection == OPTION_INDEX_ANY)
|
|
selection = index;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If the current paper size selection is hidden
|
|
// pick the first selection that's not.
|
|
|
|
if (IS_CONSTRAINED(pOptItem, pOptItem->Sel) && selection != OPTION_INDEX_ANY) {
|
|
|
|
pOptItem->Sel = selection;
|
|
UnpackDocumentPropertiesItems(pUiData, &pUiData->devmode, pOptItem, 1);
|
|
pOptItem->Flags |= OPTIF_CHANGED;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|