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.
746 lines
17 KiB
746 lines
17 KiB
/*++
|
|
|
|
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);
|
|
BOOL SaveUserInfo(PDRVDEVMODE);
|
|
|
|
BOOL
|
|
SaveUserInfo(PDRVDEVMODE pDM) {
|
|
HKEY hKey;
|
|
|
|
if ((hKey = GetUserInfoRegKey(REGKEY_FAX_USERINFO,FALSE))) {
|
|
SetRegistryString( hKey, REGVAL_BILLING_CODE, pDM->dmPrivate.billingCode );
|
|
SetRegistryString( hKey, REGVAL_MAILBOX , pDM->dmPrivate.emailAddress );
|
|
|
|
RegCloseKey(hKey);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
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;
|
|
int iRet = -1;
|
|
|
|
//
|
|
// Do not execute any code before this initialization
|
|
//
|
|
if(!InitializeDll())
|
|
{
|
|
return iRet;
|
|
}
|
|
|
|
//
|
|
// 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))
|
|
{
|
|
goto exit;
|
|
}
|
|
//
|
|
// 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;
|
|
iRet = 1;
|
|
goto exit;
|
|
}
|
|
//
|
|
// 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 = g_hResource;
|
|
pPSUIHdr->IconID = IDI_CPSUI_PRINTER2;
|
|
}
|
|
iRet = 1;
|
|
goto exit;
|
|
|
|
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)))
|
|
{
|
|
if (!ConvertDevmodeOut(
|
|
(PDEVMODE) &pUiData->devmode,
|
|
pDPHdr->pdmIn,
|
|
pDPHdr->pdmOut,
|
|
pDPHdr->cbOut))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
SaveUserInfo(&pUiData->devmode);
|
|
}
|
|
|
|
pPSUIInfo->Result = pSRInfo->Result;
|
|
}
|
|
iRet = 1;
|
|
goto exit;
|
|
|
|
case PROPSHEETUI_REASON_DESTROY:
|
|
//
|
|
// Cleanup properly before exiting
|
|
//
|
|
HeapDestroy(pUiData->hheap);
|
|
iRet = 1;
|
|
goto exit;
|
|
}
|
|
|
|
exit:
|
|
return iRet;
|
|
} // DrvDocumentPropertySheets
|
|
|
|
|
|
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));
|
|
|
|
//
|
|
// Do not execute any code before this initialization
|
|
//
|
|
if(!InitializeDll())
|
|
{
|
|
return IDCANCEL;
|
|
}
|
|
|
|
//
|
|
// 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"));
|
|
|
|
//
|
|
// Do not execute any code before this initialization
|
|
//
|
|
if(!InitializeDll())
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
//
|
|
// 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));
|
|
|
|
//
|
|
// Do not execute any code before this initialization
|
|
//
|
|
if(!InitializeDll())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
int iRet = -1;
|
|
|
|
//
|
|
// 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 iRet;
|
|
}
|
|
|
|
//
|
|
// 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))
|
|
{
|
|
if (ConvertDevmodeOut((PDEVMODE) &pUiData->devmode, pDPHdr->pdmIn, pDPHdr->pdmOut, pDPHdr->cbOut))
|
|
{
|
|
iRet = 1;
|
|
}
|
|
}
|
|
|
|
HeapDestroy(pUiData->hheap);
|
|
return iRet;
|
|
}
|
|
|
|
|
|
|
|
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 = {0};
|
|
HANDLE hActCtx;
|
|
//
|
|
// "Document Properties" dialog only has one tab - "Fax Options"
|
|
//
|
|
psp.dwSize = sizeof(PROPSHEETPAGE);
|
|
psp.dwFlags = 0;
|
|
psp.hInstance = g_hResource;
|
|
|
|
psp.lParam = (LPARAM) pUiData;
|
|
psp.pszTemplate = MAKEINTRESOURCE(IDD_DOCPROP);
|
|
psp.pfnDlgProc = FaxOptionsProc;
|
|
//
|
|
// Need to add a Activation Context so that Compstui will create the property page using
|
|
// ComCtl v6 (i.e. so it will / can be Themed).
|
|
//
|
|
hActCtx = GetFaxActivationContext();
|
|
if (INVALID_HANDLE_VALUE != hActCtx)
|
|
{
|
|
pUiData->pfnComPropSheet(pUiData->hComPropSheet,
|
|
CPSFUNC_SET_FUSION_CONTEXT,
|
|
(LPARAM)hActCtx,
|
|
0);
|
|
}
|
|
|
|
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)
|
|
{
|
|
if(pUiData->pFormNames)
|
|
{
|
|
HeapFree(pUiData->hheap, 0, pUiData->pFormNames);
|
|
}
|
|
|
|
if(pUiData->pPapers)
|
|
{
|
|
HeapFree(pUiData->hheap, 0, 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);
|
|
}
|
|
|