677 lines
14 KiB
C
677 lines
14 KiB
C
/*++
|
||
|
||
Copyright (c) 1996 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
docprop.c
|
||
|
||
Abstract:
|
||
|
||
Implemetation of DDI entry points:
|
||
DrvDocumentPropertySheets
|
||
DrvDocumentProperties
|
||
DrvAdvancedDocumentProperties
|
||
DrvConvertDevMode
|
||
|
||
Environment:
|
||
|
||
Fax driver user interface
|
||
|
||
Revision History:
|
||
|
||
01/09/96 -davidx-
|
||
Created it.
|
||
|
||
mm/dd/yy -author-
|
||
description
|
||
|
||
--*/
|
||
|
||
#include "faxui.h"
|
||
#include "forms.h"
|
||
#include "libproto.h"
|
||
#include "faxhelp.h"
|
||
|
||
|
||
INT_PTR FaxOptionsProc(HWND, UINT, WPARAM, LPARAM);
|
||
LONG SimpleDocumentProperties(PDOCUMENTPROPERTYHEADER);
|
||
BOOL GenerateFormsList(PUIDATA);
|
||
BOOL AddDocPropPages(PUIDATA, LPTSTR);
|
||
LPTSTR GetHelpFilename(PUIDATA);
|
||
|
||
|
||
|
||
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;
|
||
PUIDATA pUiData;
|
||
|
||
//
|
||
// 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);
|
||
|
||
Verbose(("DrvDocumentPropertySheets: %d\n", pPSUIInfo->Reason));
|
||
|
||
//
|
||
// 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:
|
||
|
||
pUiData->hasPermission = ((pDPHdr->fMode & DM_NOPERMISSION) == 0);
|
||
pUiData->pfnComPropSheet = pPSUIInfo->pfnComPropSheet;
|
||
pUiData->hComPropSheet = pPSUIInfo->hComPropSheet;
|
||
|
||
if (pDPHdr->fMode & DM_USER_DEFAULT)
|
||
pUiData->configDefault = TRUE;
|
||
|
||
//
|
||
// Find online help filename
|
||
//
|
||
|
||
GetHelpFilename(pUiData);
|
||
|
||
//
|
||
// Add our pages to the property sheet
|
||
//
|
||
|
||
if (GenerateFormsList(pUiData) && AddDocPropPages(pUiData, pDPHdr->pszPrinterName)) {
|
||
|
||
pPSUIInfo->UserData = (DWORD_PTR) pUiData;
|
||
pPSUIInfo->Result = CPSUI_CANCEL;
|
||
return 1;
|
||
}
|
||
|
||
//
|
||
// Clean up properly in case of an error
|
||
//
|
||
|
||
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_PRINTER2;
|
||
}
|
||
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;
|
||
|
||
Verbose(("Set result: %d\n", pSRInfo->Result));
|
||
|
||
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:
|
||
|
||
//
|
||
// Cleanup properly before exiting
|
||
//
|
||
|
||
HeapDestroy(pUiData->hheap);
|
||
return 1;
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
|
||
|
||
LONG
|
||
DoDocumentProperties(
|
||
HWND hwnd,
|
||
HANDLE hPrinter,
|
||
LPTSTR 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
|
||
DrvDocumentProperties(
|
||
HWND hwnd,
|
||
HANDLE hPrinter,
|
||
LPTSTR 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;
|
||
|
||
Verbose(("Entering DrvDocumentProperties: fMode = %x...\n", fMode));
|
||
|
||
//
|
||
// Check if caller is asking querying for size
|
||
//
|
||
|
||
if (fMode == 0 || pdmOutput == NULL)
|
||
return sizeof(DRVDEVMODE);
|
||
|
||
//
|
||
// Call the common routine shared with DrvAdvancedDocumentProperties
|
||
//
|
||
|
||
result = DoDocumentProperties(hwnd, hPrinter, pPrinterName, pdmOutput, pdmInput, fMode);
|
||
|
||
return (result > 0) ? IDOK : (result == 0) ? IDCANCEL : result;
|
||
}
|
||
|
||
|
||
|
||
LONG
|
||
DrvAdvancedDocumentProperties(
|
||
HWND hwnd,
|
||
HANDLE hPrinter,
|
||
LPTSTR 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.
|
||
|
||
--*/
|
||
|
||
{
|
||
Verbose(("Entering DrvAdvancedDocumentProperties...\n"));
|
||
|
||
//
|
||
// Return the number of bytes required if pdmOutput is NULL
|
||
//
|
||
|
||
if (pdmOutput == NULL)
|
||
return sizeof(DRVDEVMODE);
|
||
|
||
//
|
||
// Otherwise, call the common routine shared with DrvDocumentProperties
|
||
//
|
||
|
||
return DoDocumentProperties(hwnd,
|
||
hPrinter,
|
||
pPrinterName,
|
||
pdmOutput,
|
||
pdmInput,
|
||
DM_COPY|DM_PROMPT|DM_ADVANCED) > 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 versionInfo = {
|
||
|
||
// Current driver version number and private devmode size
|
||
|
||
DRIVER_VERSION, sizeof(DMPRIVATE),
|
||
|
||
// 3.51 driver version number and private devmode size
|
||
// NOTE: We don't have a 3.51 driver - use current version number and devmode size.
|
||
|
||
DRIVER_VERSION, sizeof(DMPRIVATE)
|
||
};
|
||
|
||
INT result;
|
||
HANDLE hPrinter;
|
||
|
||
Verbose(("Entering DrvConvertDevMode: %x...\n", fMode));
|
||
|
||
//
|
||
// Call a library routine to handle the common cases
|
||
//
|
||
|
||
result = CommonDrvConvertDevmode(pPrinterName, pdmIn, pdmOut, pcbNeeded, fMode, &versionInfo);
|
||
|
||
//
|
||
// 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) {
|
||
|
||
//
|
||
// Return driver default devmode
|
||
//
|
||
|
||
if (OpenPrinter(pPrinterName, &hPrinter, NULL)) {
|
||
|
||
PDRVDEVMODE pdmDefault = (PDRVDEVMODE) pdmOut;
|
||
|
||
DriverDefaultDevmode(pdmDefault, pPrinterName, hPrinter);
|
||
pdmDefault->dmPrivate.flags |= FAXDM_DRIVER_DEFAULT;
|
||
|
||
result = CDM_RESULT_TRUE;
|
||
ClosePrinter(hPrinter);
|
||
|
||
} else
|
||
Error(("OpenPrinter failed: %d\n", GetLastError()));
|
||
}
|
||
|
||
return (result == CDM_RESULT_TRUE);
|
||
}
|
||
|
||
|
||
|
||
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(DRVDEVMODE);
|
||
|
||
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);
|
||
|
||
HeapDestroy(pUiData->hheap);
|
||
return 1;
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
AddDocPropPages(
|
||
PUIDATA pUiData,
|
||
LPTSTR pPrinterName
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Add our "Document Properties" pages to the property sheet
|
||
|
||
Arguments:
|
||
|
||
pUiData - Points to our UIDATA structure
|
||
pPrinterName - Specifies the printer name
|
||
|
||
Return Value:
|
||
|
||
TRUE if successful, FALSE otherwise
|
||
|
||
--*/
|
||
|
||
{
|
||
PROPSHEETPAGE psp;
|
||
|
||
//
|
||
// "Document Properties" dialog only has one tab - "Fax Options"
|
||
//
|
||
|
||
memset(&psp, 0, sizeof(psp));
|
||
psp.dwSize = sizeof(PROPSHEETPAGE);
|
||
psp.dwFlags = 0;
|
||
psp.hInstance = ghInstance;
|
||
|
||
if (pUiData->configDefault) {
|
||
|
||
psp.lParam = 0;
|
||
psp.pszTemplate = MAKEINTRESOURCE(IDD_USER_INFO);
|
||
psp.pfnDlgProc = UserInfoDlgProc;
|
||
|
||
} else {
|
||
|
||
psp.lParam = (LPARAM) pUiData;
|
||
psp.pszTemplate = MAKEINTRESOURCE(IDD_DOCPROP);
|
||
psp.pfnDlgProc = FaxOptionsProc;
|
||
}
|
||
|
||
pUiData->hFaxOptsPage = (HANDLE)
|
||
pUiData->pfnComPropSheet(pUiData->hComPropSheet,
|
||
CPSFUNC_ADD_PROPSHEETPAGE,
|
||
(LPARAM) &psp,
|
||
0);
|
||
|
||
return (pUiData->hFaxOptsPage != NULL);
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
GenerateFormsList(
|
||
PUIDATA pUiData
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Generate the list of forms supported by the fax driver
|
||
|
||
Arguments:
|
||
|
||
pUiData - Points to our UIDATA structure
|
||
|
||
Return Value:
|
||
|
||
TRUE if successful, FALSE if there is an error
|
||
|
||
--*/
|
||
|
||
{
|
||
PFORM_INFO_1 pFormsDB;
|
||
DWORD cForms, count;
|
||
|
||
//
|
||
// Get a list of forms in the forms database
|
||
//
|
||
|
||
pFormsDB = GetFormsDatabase(pUiData->hPrinter, &cForms);
|
||
|
||
if (pFormsDB == NULL || cForms == 0) {
|
||
|
||
Error(("Couldn't get system forms\n"));
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// Enumerate the list of supported forms
|
||
//
|
||
|
||
pUiData->cForms = count = EnumPaperSizes(NULL, pFormsDB, cForms, DC_PAPERS);
|
||
Assert(count != GDI_ERROR);
|
||
|
||
pUiData->pFormNames = HeapAlloc(pUiData->hheap, 0, sizeof(TCHAR) * count * CCHPAPERNAME);
|
||
pUiData->pPapers = HeapAlloc(pUiData->hheap, 0, sizeof(WORD) * count);
|
||
|
||
if (!pUiData->pFormNames || !pUiData->pPapers) {
|
||
|
||
MemFree(pFormsDB);
|
||
return FALSE;
|
||
}
|
||
|
||
EnumPaperSizes(pUiData->pFormNames, pFormsDB, cForms, DC_PAPERNAMES);
|
||
EnumPaperSizes(pUiData->pPapers, pFormsDB, cForms, DC_PAPERS);
|
||
|
||
MemFree(pFormsDB);
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
|
||
LPTSTR
|
||
GetHelpFilename(
|
||
PUIDATA pUiData
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Return the driver's help filename string
|
||
|
||
Arguments:
|
||
|
||
pUiData - Points to our UIDATA structure
|
||
|
||
Return Value:
|
||
|
||
Pointer to the driver help filename, NULL if error
|
||
|
||
--*/
|
||
|
||
{
|
||
PDRIVER_INFO_3 pDriverInfo3 = NULL;
|
||
PVOID pHelpFile = NULL;
|
||
|
||
//
|
||
// Attempt to get help file name using the new DRIVER_INFO_3
|
||
//
|
||
|
||
if (pDriverInfo3 = MyGetPrinterDriver(pUiData->hPrinter, 3)) {
|
||
|
||
if ((pDriverInfo3->pHelpFile != NULL) &&
|
||
(pHelpFile = HeapAlloc(pUiData->hheap, 0, SizeOfString(pDriverInfo3->pHelpFile))))
|
||
{
|
||
_tcscpy(pHelpFile, pDriverInfo3->pHelpFile);
|
||
}
|
||
|
||
MemFree(pDriverInfo3);
|
||
}
|
||
|
||
//
|
||
// If DRIVER_INFO_3 isn't supported, get help file name the old fashion way
|
||
//
|
||
|
||
if (pHelpFile == NULL) {
|
||
if (!(pHelpFile = HeapAlloc(pUiData->hheap, 0, SizeOfString(FAXCFG_HELP_FILENAME))) )
|
||
{
|
||
pHelpFile = NULL;
|
||
|
||
} else {
|
||
|
||
_tcscpy(pHelpFile, FAXCFG_HELP_FILENAME);
|
||
}
|
||
}
|
||
|
||
Verbose(("Driver help filename: %ws\n", pHelpFile));
|
||
return (pUiData->pHelpFile = pHelpFile);
|
||
}
|
||
|