1576 lines
36 KiB
C++
1576 lines
36 KiB
C++
/*++
|
|
|
|
Copyright (C) Microsoft Corporation, 1995 - 1999
|
|
All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
docprop.cxx
|
|
|
|
Abstract:
|
|
|
|
Job Properties
|
|
|
|
Author:
|
|
|
|
Steve Kiraly (SteveKi) 10/19/95
|
|
|
|
Revision History:
|
|
|
|
Lazar Ivanov (LazarI) - added DocumentPropertiesWrap (Nov-03-2000)
|
|
|
|
--*/
|
|
#include "precomp.hxx"
|
|
#pragma hdrstop
|
|
|
|
#include "time.hxx"
|
|
#include "docdata.hxx"
|
|
#include "propmgr.hxx"
|
|
#include "docprop.hxx"
|
|
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
vDocPropSelections
|
|
|
|
Routine Description:
|
|
|
|
Displays Document property sheets for multiple selections.
|
|
|
|
Arguments:
|
|
|
|
TSelection - pointer to a list of document selections.
|
|
|
|
Return Value:
|
|
|
|
Nothing.
|
|
|
|
--*/
|
|
|
|
VOID
|
|
vDocumentPropSelections(
|
|
IN HWND hWnd,
|
|
IN LPCTSTR pszPrinterName,
|
|
IN TSelection *pSelection
|
|
)
|
|
{
|
|
|
|
//
|
|
// Get the selection information. We are in a loop to
|
|
// handle the selection of multiple jobs.
|
|
//
|
|
for( UINT i = 0; i < pSelection->_cSelected; ++i ){
|
|
//
|
|
// Display the document property pages.
|
|
//
|
|
vDocumentPropPages(
|
|
hWnd,
|
|
pszPrinterName,
|
|
pSelection->_pid[i],
|
|
SW_SHOWNORMAL,
|
|
0 );
|
|
}
|
|
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function opens the property sheet of specified document.
|
|
|
|
We can't guarentee that this propset will perform all lengthy
|
|
operations in a worker thread (we synchronously call things like
|
|
ConfigurePort). Therefore, we spawn off a separate thread to
|
|
handle document properties.
|
|
|
|
Arguments:
|
|
|
|
hWnd - Specifies the parent window (optional).
|
|
pszPrinter - Specifies the printer name
|
|
nCmdShow - Initial show state
|
|
lParam - May spcify a sheet specifc index to directly open.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
VOID
|
|
vDocumentPropPages(
|
|
IN HWND hWnd,
|
|
IN LPCTSTR pszPrinterName,
|
|
IN IDENT JobId,
|
|
IN INT iCmdShow,
|
|
IN LPARAM lParam
|
|
)
|
|
|
|
{
|
|
HANDLE hThread;
|
|
|
|
//
|
|
// Create the document specific data
|
|
//
|
|
TDocumentData* pDocumentData = new TDocumentData( pszPrinterName,
|
|
JobId,
|
|
iCmdShow,
|
|
lParam );
|
|
//
|
|
// If errors were encountered creating document data.
|
|
//
|
|
if( !VALID_PTR( pDocumentData )){
|
|
goto Fail;
|
|
}
|
|
|
|
//
|
|
// Create the thread which handles the UI. vPrinterPropPages adopts
|
|
// pPrinterData, therefore only on thread creation failure do we
|
|
// releae the document data back to the heap.
|
|
//
|
|
DWORD dwIgnore;
|
|
hThread = TSafeThread::Create( NULL,
|
|
0,
|
|
(LPTHREAD_START_ROUTINE)iDocumentPropPagesProc,
|
|
pDocumentData,
|
|
0,
|
|
&dwIgnore );
|
|
|
|
//
|
|
// Check thread creation.
|
|
//
|
|
if( !hThread ){
|
|
|
|
//
|
|
// Display error message, and release document data.
|
|
//
|
|
vShowResourceError( hWnd );
|
|
delete pDocumentData;
|
|
|
|
} else {
|
|
|
|
CloseHandle( hThread );
|
|
}
|
|
|
|
return;
|
|
|
|
Fail:
|
|
|
|
//
|
|
// Display the error message.
|
|
//
|
|
iMessage( hWnd,
|
|
IDS_ERR_DOC_JOB_PROPERTY_TITLE,
|
|
IDS_ERR_DOC_JOB_PROPERTY_JOB_NA,
|
|
MB_OK|MB_ICONSTOP,
|
|
kMsgGetLastError,
|
|
NULL );
|
|
|
|
delete pDocumentData;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
iDocumentPropPagesProc
|
|
|
|
Routine Description:
|
|
|
|
This is the routine called by the create thread call to display the
|
|
document property sheets.
|
|
|
|
Arguments:
|
|
|
|
pDocumentData - Pointer to the document data needed for all property sheets.
|
|
|
|
Return Value:
|
|
|
|
TRUE - if the property sheets were displayed.
|
|
FALSE - error creating and displaying property sheets.
|
|
|
|
--*/
|
|
|
|
INT
|
|
iDocumentPropPagesProc(
|
|
IN TDocumentData *pDocumentData ADOPT
|
|
)
|
|
{
|
|
DBGMSG( DBG_TRACE, ( "iDocumentPropPagesProc\n") );
|
|
|
|
BOOL bStatus;
|
|
bStatus = pDocumentData->bRegisterWindow( PRINTER_PIDL_TYPE_JOBID |
|
|
pDocumentData->JobId( ));
|
|
if( bStatus ){
|
|
|
|
//
|
|
// Check if the window is already present. If it is, then
|
|
// exit immediately.
|
|
//
|
|
if( !pDocumentData->hwnd( )){
|
|
delete pDocumentData;
|
|
return 0;
|
|
}
|
|
|
|
bStatus = pDocumentData->bLoad();
|
|
}
|
|
|
|
if( !bStatus ){
|
|
|
|
iMessage( pDocumentData->hwnd(),
|
|
IDS_ERR_DOC_JOB_PROPERTY_TITLE,
|
|
IDS_ERR_DOC_JOB_PROPERTY_JOB_NA,
|
|
MB_OK|MB_ICONSTOP|MB_SETFOREGROUND,
|
|
kMsgGetLastError,
|
|
NULL );
|
|
|
|
delete pDocumentData;
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// Create the ducument property sheet windows.
|
|
//
|
|
TDocumentWindows DocumentWindows( pDocumentData );
|
|
|
|
//
|
|
// Were the document windows create
|
|
//
|
|
if( !VALID_OBJ( DocumentWindows ) ){
|
|
vShowResourceError( pDocumentData->hwnd() );
|
|
bStatus = FALSE;
|
|
}
|
|
|
|
//
|
|
// Display the property pages.
|
|
//
|
|
if( bStatus ){
|
|
if( !DocumentWindows.bDisplayPages( pDocumentData->hwnd() ) ){
|
|
vShowResourceError( pDocumentData->hwnd() );
|
|
bStatus = FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Ensure we release the document data.
|
|
// We have adopted pPrinterData, so we must free it.
|
|
//
|
|
delete pDocumentData;
|
|
return bStatus;
|
|
|
|
}
|
|
|
|
/********************************************************************
|
|
|
|
Document Prop Base Class
|
|
|
|
********************************************************************/
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
TDocumentProp
|
|
|
|
Routine Description:
|
|
|
|
Initialized the document property sheet base class
|
|
|
|
Arguments:
|
|
|
|
pDocumentData - Pointer to the document data needed for all property sheets.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
TDocumentProp::
|
|
TDocumentProp(
|
|
TDocumentData* pDocumentData
|
|
) : _pDocumentData( pDocumentData ),
|
|
_bApplyData( FALSE )
|
|
{
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
~TDocumentProp
|
|
|
|
Routine Description:
|
|
|
|
Base class desctuctor.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Nothing.
|
|
|
|
--*/
|
|
TDocumentProp::
|
|
~TDocumentProp(
|
|
)
|
|
{
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
bHandleMessage
|
|
|
|
Routine Description:
|
|
|
|
Base class message handler. This routine is called by
|
|
derived classes who do not want to handle the message.
|
|
|
|
|
|
Arguments:
|
|
|
|
uMsg - Windows message
|
|
wParam - Word parameter
|
|
lParam - Long parameter
|
|
|
|
|
|
Return Value:
|
|
|
|
TRUE if message was handled, FALSE if message not handled.
|
|
|
|
--*/
|
|
BOOL
|
|
TDocumentProp::
|
|
bHandleMessage(
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam
|
|
)
|
|
{
|
|
BOOL bStatus = TRUE;
|
|
|
|
switch( uMsg ){
|
|
|
|
//
|
|
// Set the values on the UI.
|
|
//
|
|
case WM_INITDIALOG:
|
|
bStatus = bSetUI();
|
|
break;
|
|
|
|
//
|
|
// Handle help and context help.
|
|
//
|
|
case WM_HELP:
|
|
case WM_CONTEXTMENU:
|
|
bStatus = PrintUIHelp( uMsg, _hDlg, wParam, lParam );
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch( ((LPNMHDR)lParam)->code )
|
|
{
|
|
//
|
|
// User switched to the next page.
|
|
//
|
|
case PSN_KILLACTIVE:
|
|
bStatus = bReadUI();
|
|
vSetDlgMsgResult( !bStatus ? TRUE : FALSE );
|
|
break;
|
|
|
|
//
|
|
// User chiose the apply button.
|
|
//
|
|
case PSN_APPLY:
|
|
_bApplyData = TRUE;
|
|
bStatus = ( _bApplyData ) ? bSaveUI() : FALSE;
|
|
if( !bStatus )
|
|
{
|
|
//
|
|
// Switch to page with the error.
|
|
//
|
|
PropSheet_SetCurSelByID( GetParent( _hDlg ), DLG_DOC_JOB_GENERAL );
|
|
}
|
|
vSetDlgMsgResult( !bStatus ? PSNRET_INVALID_NOCHANGEPAGE : PSNRET_NOERROR );
|
|
break;
|
|
|
|
//
|
|
// Indicate the use canceled the dialog.
|
|
//
|
|
case PSN_QUERYCANCEL:
|
|
_bApplyData = FALSE;
|
|
break;
|
|
|
|
default:
|
|
bStatus = FALSE;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
bStatus = FALSE;
|
|
break;
|
|
}
|
|
|
|
if( !bStatus )
|
|
{
|
|
//
|
|
// Allow the derived classes to handle the message.
|
|
//
|
|
bStatus = _bHandleMessage( uMsg, wParam, lParam );
|
|
}
|
|
|
|
//
|
|
// If the message was handled check if the
|
|
// apply button should be enabled.
|
|
//
|
|
if( bStatus )
|
|
{
|
|
if( _pDocumentData->bCheckForChange() )
|
|
{
|
|
PropSheet_Changed( GetParent( _hDlg ), _hDlg );
|
|
}
|
|
else
|
|
{
|
|
PropSheet_UnChanged( GetParent( _hDlg), _hDlg );
|
|
}
|
|
}
|
|
|
|
return bStatus;
|
|
}
|
|
|
|
|
|
/********************************************************************
|
|
|
|
General Document Property Sheet.
|
|
|
|
********************************************************************/
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
TDocumentGeneral
|
|
|
|
Routine Description:
|
|
|
|
Document property sheet derived class.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Nothing.
|
|
|
|
--*/
|
|
TDocumentGeneral::
|
|
TDocumentGeneral(
|
|
IN TDocumentData* pDocumentData
|
|
) : TDocumentProp( pDocumentData ),
|
|
_bSetUIDone( FALSE )
|
|
{
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
~TDocumentGeneral
|
|
|
|
Routine Description:
|
|
|
|
Document derived class destructor.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Nothing.
|
|
|
|
--*/
|
|
|
|
TDocumentGeneral::
|
|
~TDocumentGeneral(
|
|
)
|
|
{
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
bValid
|
|
|
|
Routine Description:
|
|
|
|
Document property sheet derived class valid object indicator.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Returns the status of the base class.
|
|
|
|
--*/
|
|
BOOL
|
|
TDocumentGeneral::
|
|
bValid(
|
|
VOID
|
|
)
|
|
{
|
|
return TDocumentProp::bValid();
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
bSetStartAndUntilTime
|
|
|
|
Routine Description:
|
|
|
|
Initialized the start and until time.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
TRUE time controls initialized, FALSE error occured.
|
|
|
|
--*/
|
|
BOOL
|
|
TDocumentGeneral::
|
|
bSetStartAndUntilTime(
|
|
VOID
|
|
)
|
|
{
|
|
TString strFormatString;
|
|
TStatusB bStatus;
|
|
|
|
//
|
|
// Get the time format string without seconds.
|
|
//
|
|
bStatus DBGCHK = bGetTimeFormatString( strFormatString );
|
|
|
|
//
|
|
// If we have retrived a valid time format string then use it,
|
|
// else use the default format string implemented by common control.
|
|
//
|
|
if( bStatus )
|
|
{
|
|
DateTime_SetFormat(GetDlgItem( _hDlg, IDC_DOC_JOB_START_TIME ), static_cast<LPCTSTR>( strFormatString ) );
|
|
DateTime_SetFormat(GetDlgItem( _hDlg, IDC_DOC_JOB_UNTIL_TIME ), static_cast<LPCTSTR>( strFormatString ) );
|
|
}
|
|
|
|
//
|
|
// If the printer is always available.
|
|
//
|
|
BOOL bAlways = ( _pDocumentData->pJobInfo()->StartTime == _pDocumentData->pJobInfo()->UntilTime );
|
|
|
|
//
|
|
// Set the start time.
|
|
//
|
|
SYSTEMTIME StartTime = { 0 };
|
|
DWORD dwLocalStartTime = 0;
|
|
|
|
GetLocalTime( &StartTime );
|
|
|
|
dwLocalStartTime = ( !bAlways ) ? SystemTimeToLocalTime( _pDocumentData->pJobInfo()->StartTime ) : 0;
|
|
|
|
StartTime.wHour = static_cast<WORD>( dwLocalStartTime / 60 );
|
|
StartTime.wMinute = static_cast<WORD>( dwLocalStartTime % 60 );
|
|
|
|
DateTime_SetSystemtime(GetDlgItem( _hDlg, IDC_DOC_JOB_START_TIME ), GDT_VALID, &StartTime );
|
|
|
|
//
|
|
// Set the until time.
|
|
//
|
|
SYSTEMTIME UntilTime = { 0 };
|
|
DWORD dwLocalUntilTime = 0;
|
|
|
|
GetLocalTime( &UntilTime );
|
|
|
|
dwLocalUntilTime = ( !bAlways ) ? SystemTimeToLocalTime( _pDocumentData->pJobInfo()->UntilTime ) : 0;
|
|
|
|
UntilTime.wHour = static_cast<WORD>( dwLocalUntilTime / 60 );
|
|
UntilTime.wMinute = static_cast<WORD>( dwLocalUntilTime % 60 );
|
|
|
|
DateTime_SetSystemtime(GetDlgItem( _hDlg, IDC_DOC_JOB_UNTIL_TIME ), GDT_VALID, &UntilTime );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
bSetUI
|
|
|
|
Routine Description:
|
|
|
|
Loads the property sheet dialog with the document data
|
|
information.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
TRUE if data loaded successfully, FALSE if error occurred.
|
|
|
|
--*/
|
|
BOOL
|
|
TDocumentGeneral::
|
|
bSetUI(
|
|
VOID
|
|
)
|
|
|
|
{
|
|
//
|
|
// Get the flag if always availble.
|
|
//
|
|
BOOL bAlways = ( _pDocumentData->pJobInfo()->StartTime ==
|
|
_pDocumentData->pJobInfo()->UntilTime );
|
|
|
|
//
|
|
// Initialize the stat and until time controls.
|
|
//
|
|
if( !bSetStartAndUntilTime() )
|
|
{
|
|
DBGMSG( DBG_TRACE, ( "TDocumentGeneral::bSetStartAndUntilTime failed %d\n", GetLastError( )));
|
|
}
|
|
|
|
//
|
|
// Read the job size format string.
|
|
//
|
|
TString strFormat;
|
|
if( strFormat.bLoadString( ghInst, IDS_JOB_SIZE ) ){
|
|
|
|
//
|
|
// Set the size in byes of the job.
|
|
//
|
|
bSetEditTextFormat( _hDlg,
|
|
IDC_DOC_JOB_SIZE,
|
|
strFormat,
|
|
_pDocumentData->pJobInfo()->Size );
|
|
}
|
|
|
|
//
|
|
// Set the Number of pages in the job.
|
|
//
|
|
bSetEditTextFormat( _hDlg,
|
|
IDC_DOC_JOB_PAGES,
|
|
TEXT( "%d" ),
|
|
_pDocumentData->pJobInfo()->TotalPages );
|
|
|
|
//
|
|
// Set the document text.
|
|
//
|
|
bSetEditText( _hDlg, IDC_DOC_JOB_TITLE, _pDocumentData->pJobInfo()->pDocument );
|
|
bSetEditText( _hDlg, IDC_DOC_JOB_DATATYPE, _pDocumentData->pJobInfo()->pDatatype );
|
|
bSetEditText( _hDlg, IDC_DOC_JOB_PROCCESSOR, _pDocumentData->pJobInfo()->pPrintProcessor );
|
|
bSetEditText( _hDlg, IDC_DOC_JOB_OWNER, _pDocumentData->pJobInfo()->pUserName );
|
|
bSetEditText( _hDlg, IDC_DOC_JOB_NOTIFY, _pDocumentData->pJobInfo()->pNotifyName );
|
|
|
|
//
|
|
// Set the Priority indicator.
|
|
//
|
|
bSetEditTextFormat( _hDlg,
|
|
IDC_DOC_JOB_PRIORITY,
|
|
TEXT( "%d" ),
|
|
_pDocumentData->pJobInfo()->Priority );
|
|
|
|
SendDlgItemMessage( _hDlg,
|
|
IDC_DOC_JOB_PRIORITY_CONTROL,
|
|
TBM_SETRANGE,
|
|
FALSE,
|
|
MAKELONG( TDocumentData::kPriorityLowerBound, TDocumentData::kPriorityUpperBound ));
|
|
|
|
SendDlgItemMessage( _hDlg,
|
|
IDC_DOC_JOB_PRIORITY_CONTROL,
|
|
TBM_SETPOS,
|
|
TRUE,
|
|
_pDocumentData->pJobInfo()->Priority );
|
|
|
|
//
|
|
// Format the submitted time field.
|
|
//
|
|
TStatusB bStatus = FALSE;
|
|
TCHAR szBuff[kStrMax] = {0};
|
|
SYSTEMTIME LocalTime;
|
|
|
|
//
|
|
// Convert to local time.
|
|
//
|
|
bStatus DBGCHK = SystemTimeToTzSpecificLocalTime(
|
|
NULL,
|
|
&_pDocumentData->pJobInfo()->Submitted,
|
|
&LocalTime );
|
|
if( !bStatus ){
|
|
DBGMSG( DBG_MIN, ( "SysTimeToTzSpecLocalTime failed %d\n", GetLastError( )));
|
|
}
|
|
|
|
if( bStatus ){
|
|
|
|
//
|
|
// Convert using local format information.
|
|
//
|
|
bStatus DBGCHK = GetTimeFormat( LOCALE_USER_DEFAULT,
|
|
0,
|
|
&LocalTime,
|
|
NULL,
|
|
szBuff,
|
|
COUNTOF( szBuff ));
|
|
if( !bStatus ){
|
|
DBGMSG( DBG_MIN, ( "No Time %d, ", GetLastError( )));
|
|
}
|
|
}
|
|
|
|
if( bStatus ){
|
|
|
|
//
|
|
// Tack on space between time and date.
|
|
//
|
|
lstrcat( szBuff, TEXT(" ") );
|
|
|
|
//
|
|
// Get data format.
|
|
//
|
|
bStatus DBGCHK = GetDateFormat( LOCALE_USER_DEFAULT,
|
|
0,
|
|
&LocalTime,
|
|
NULL,
|
|
szBuff + lstrlen( szBuff ),
|
|
COUNTOF( szBuff ) - lstrlen( szBuff ) );
|
|
|
|
if( !bStatus ){
|
|
DBGMSG( DBG_MIN, ( "No Date %d\n", GetLastError( )));
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set the submitted field
|
|
//
|
|
bStatus DBGCHK = bSetEditText( _hDlg, IDC_DOC_JOB_AT, szBuff );
|
|
|
|
//
|
|
// Set schedule radio buttons.
|
|
//
|
|
CheckRadioButton( _hDlg, IDC_DOC_JOB_START, IDC_DOC_JOB_ALWAYS,
|
|
bAlways ? IDC_DOC_JOB_ALWAYS : IDC_DOC_JOB_START );
|
|
|
|
vEnableAvailable( !bAlways );
|
|
|
|
//
|
|
// Disable all the controls if not an administrator.
|
|
//
|
|
if( !_pDocumentData->bAdministrator( )){
|
|
|
|
//
|
|
// Disable the time controls.
|
|
//
|
|
vEnableAvailable( FALSE );
|
|
|
|
//
|
|
// Disable things if not administrator.
|
|
//
|
|
static UINT auAvailable[] = {
|
|
IDC_DOC_JOB_NOTIFY,
|
|
IDC_DOC_JOB_PRIORITY_CONTROL,
|
|
IDC_DOC_JOB_ALWAYS,
|
|
IDC_DOC_JOB_START,
|
|
};
|
|
|
|
COUNT i;
|
|
for( i = 0; i < COUNTOF( auAvailable ); ++i ){
|
|
vEnableCtl( _hDlg, auAvailable[i], FALSE );
|
|
}
|
|
}
|
|
|
|
_bSetUIDone = TRUE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
bReadUI
|
|
|
|
Routine Description:
|
|
|
|
Stores the property information to the print server.
|
|
|
|
Arguments:
|
|
|
|
Nothing data is contained with in the class.
|
|
|
|
Return Value:
|
|
|
|
TRUE if data is stores successfully, FALSE if error occurred.
|
|
|
|
--*/
|
|
BOOL
|
|
TDocumentGeneral::
|
|
bReadUI(
|
|
VOID
|
|
)
|
|
{
|
|
DBGMSG( DBG_TRACE, ( "TDocumentGeneral::bReadUI\n") );
|
|
|
|
//
|
|
// Attempt to validate any UI changeable data.
|
|
// Currently not much can be validated, since all the
|
|
// controls have set constraints.
|
|
//
|
|
|
|
//
|
|
// Extract the UI and save it into the Document Data.
|
|
//
|
|
_pDocumentData->pJobInfo()->Priority = (DWORD)SendDlgItemMessage( _hDlg,
|
|
IDC_DOC_JOB_PRIORITY_CONTROL,
|
|
TBM_GETPOS,
|
|
0,
|
|
0 );
|
|
//
|
|
// Get the notify name.
|
|
//
|
|
bGetEditText( _hDlg, IDC_DOC_JOB_NOTIFY, _pDocumentData->strNotifyName() );
|
|
_pDocumentData->pJobInfo()->pNotifyName = (LPTSTR)(LPCTSTR)_pDocumentData->strNotifyName();
|
|
|
|
//
|
|
// If the Job always is set then indicate
|
|
// not time restriction in the start time and until time.
|
|
//
|
|
if( bGetCheck( _hDlg, IDC_DOC_JOB_ALWAYS ) ){
|
|
|
|
_pDocumentData->pJobInfo()->StartTime = 0;
|
|
_pDocumentData->pJobInfo()->UntilTime = 0;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Get the Start time.
|
|
//
|
|
SYSTEMTIME StartTime;
|
|
DateTime_GetSystemtime( GetDlgItem( _hDlg, IDC_DOC_JOB_START_TIME ), &StartTime );
|
|
_pDocumentData->pJobInfo()->StartTime = LocalTimeToSystemTime( StartTime.wHour * 60 + StartTime.wMinute );
|
|
|
|
//
|
|
// Get the Until time.
|
|
//
|
|
SYSTEMTIME UntilTime;
|
|
DateTime_GetSystemtime( GetDlgItem( _hDlg, IDC_DOC_JOB_UNTIL_TIME ), &UntilTime );
|
|
_pDocumentData->pJobInfo()->UntilTime = LocalTimeToSystemTime( UntilTime.wHour * 60 + UntilTime.wMinute );
|
|
|
|
//
|
|
// If the printer start and until time are the same this is
|
|
// exactly the same as always available.
|
|
//
|
|
if( _pDocumentData->pJobInfo()->StartTime == _pDocumentData->pJobInfo()->UntilTime )
|
|
{
|
|
_pDocumentData->pJobInfo()->StartTime = 0;
|
|
_pDocumentData->pJobInfo()->UntilTime = 0;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set the job position to unspecified it may
|
|
// have changed while this dialog was up.
|
|
//
|
|
_pDocumentData->pJobInfo()->Position = JOB_POSITION_UNSPECIFIED;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
bSaveUI
|
|
|
|
Routine Description:
|
|
|
|
Saves the UI data to some API call or print server.
|
|
|
|
Arguments:
|
|
|
|
Nothing data is contained with in the class.
|
|
|
|
Return Value:
|
|
|
|
TRUE if data is stores successfully, FALSE if error occurred.
|
|
|
|
--*/
|
|
BOOL
|
|
TDocumentGeneral::
|
|
bSaveUI(
|
|
VOID
|
|
)
|
|
{
|
|
DBGMSG( DBG_TRACE, ( "TDocumentGeneral::bSaveUI\n") );
|
|
|
|
//
|
|
// Clear the error saving flag.
|
|
//
|
|
_pDocumentData->bErrorSaving() = TRUE;
|
|
|
|
//
|
|
// Save the document data.
|
|
//
|
|
if( !_pDocumentData->bStore() ){
|
|
|
|
DWORD dwLastError = GetLastError ();
|
|
|
|
if( dwLastError == ERROR_INVALID_TIME ){
|
|
_pDocumentData->iErrorMsgId() = IDS_ERR_DOC_JOB_PROPERTY_TIME;
|
|
} else {
|
|
_pDocumentData->iErrorMsgId() = IDS_ERR_DOC_JOB_PROPERTY_MODIFY;
|
|
}
|
|
_pDocumentData->bErrorSaving() = FALSE;
|
|
}
|
|
|
|
//
|
|
// If there was an error saving the document data.
|
|
//
|
|
if( !_pDocumentData->bErrorSaving() ){
|
|
|
|
//
|
|
// Display the error message.
|
|
//
|
|
iMessage( _hDlg,
|
|
IDS_ERR_DOC_JOB_PROPERTY_TITLE,
|
|
_pDocumentData->iErrorMsgId(),
|
|
MB_OK|MB_ICONSTOP|MB_SETFOREGROUND,
|
|
kMsgNone,
|
|
NULL );
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
vEanbleAvailablity
|
|
|
|
Routine Description:
|
|
|
|
Enables the time availabilty of the job
|
|
|
|
Arguments:
|
|
|
|
TRUE enable the availablity, FALSE disable time availablity.
|
|
|
|
Return Value:
|
|
|
|
Nothing.
|
|
|
|
--*/
|
|
VOID
|
|
TDocumentGeneral::
|
|
vEnableAvailable(
|
|
IN BOOL bEnable
|
|
)
|
|
{
|
|
vEnableCtl( _hDlg, IDC_DOC_JOB_START_TIME, bEnable );
|
|
vEnableCtl( _hDlg, IDC_DOC_JOB_UNTIL_TIME, bEnable );
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
bReadUI
|
|
|
|
Routine Description:
|
|
|
|
Stores the property information to the print server.
|
|
|
|
Arguments:
|
|
|
|
Nothing data is contained with in the class.
|
|
|
|
Return Value:
|
|
|
|
TRUE if data is stores successfully, FALSE if error occurred.
|
|
|
|
--*/
|
|
VOID
|
|
TDocumentGeneral::
|
|
vSetActive(
|
|
VOID
|
|
)
|
|
{
|
|
DBGMSG( DBG_TRACE, ( "TDocumentGeneral::vSetActive\n") );
|
|
(VOID)bSetStartAndUntilTime();
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
bHandleMessage
|
|
|
|
Routine Description:
|
|
|
|
Document property sheet message handler. This handler only
|
|
handles events it wants and the base class handle will do the
|
|
standard message handling.
|
|
|
|
Arguments:
|
|
|
|
uMsg - Windows message
|
|
wParam - Word parameter
|
|
lParam - Long parameter
|
|
|
|
|
|
Return Value:
|
|
|
|
TRUE if message was handled, FALSE if message not handled.
|
|
|
|
--*/
|
|
|
|
BOOL
|
|
TDocumentGeneral::
|
|
_bHandleMessage(
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam
|
|
)
|
|
{
|
|
BOOL bStatus = TRUE;
|
|
|
|
switch( uMsg )
|
|
{
|
|
case WM_HSCROLL:
|
|
|
|
//
|
|
// Check for slider notification.
|
|
//
|
|
if( GET_WM_HSCROLL_HWND( wParam, lParam ) == GetDlgItem(_hDlg, IDC_DOC_JOB_PRIORITY_CONTROL ) ){
|
|
bSetEditTextFormat( _hDlg,
|
|
IDC_DOC_JOB_PRIORITY,
|
|
TEXT("%d"),
|
|
SendDlgItemMessage( _hDlg,
|
|
IDC_DOC_JOB_PRIORITY_CONTROL,
|
|
TBM_GETPOS,
|
|
0,
|
|
0 ) );
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch( GET_WM_COMMAND_ID( wParam, lParam ))
|
|
{
|
|
case IDC_DOC_JOB_ALWAYS:
|
|
vEnableAvailable( FALSE );
|
|
PropSheet_Changed( GetParent( _hDlg ), _hDlg );
|
|
break;
|
|
|
|
case IDC_DOC_JOB_START:
|
|
vEnableAvailable( TRUE );
|
|
PropSheet_Changed( GetParent( _hDlg ), _hDlg );
|
|
break;
|
|
|
|
case IDC_DOC_JOB_NOTIFY:
|
|
bStatus = GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE;
|
|
break;
|
|
|
|
default:
|
|
bStatus = FALSE;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_WININICHANGE:
|
|
vSetActive();
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
{
|
|
LPNMHDR pnmh = (LPNMHDR)lParam;
|
|
|
|
switch( wParam )
|
|
{
|
|
case 0:
|
|
{
|
|
switch( pnmh->code )
|
|
{
|
|
case PSN_SETACTIVE:
|
|
vSetActive();
|
|
break;
|
|
|
|
default:
|
|
bStatus = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDC_DOC_JOB_START_TIME:
|
|
case IDC_DOC_JOB_UNTIL_TIME:
|
|
{
|
|
switch( pnmh->code )
|
|
{
|
|
case DTN_DATETIMECHANGE:
|
|
break;
|
|
|
|
default:
|
|
bStatus = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
bStatus = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
bStatus = FALSE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// If message handled look for change.
|
|
//
|
|
if( bStatus && _bSetUIDone )
|
|
{
|
|
(VOID)bReadUI();
|
|
}
|
|
|
|
return bStatus;
|
|
}
|
|
|
|
/********************************************************************
|
|
|
|
Document property windows.
|
|
|
|
********************************************************************/
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Document property windows.
|
|
|
|
Arguments:
|
|
|
|
pDocumentData - Document data to display.
|
|
|
|
Return Value:
|
|
|
|
TRUE - Success, FALSE - failure.
|
|
|
|
--*/
|
|
|
|
TDocumentWindows::
|
|
TDocumentWindows(
|
|
TDocumentData* pDocumentData
|
|
) : _pDocumentData( pDocumentData ),
|
|
_General( pDocumentData )
|
|
{
|
|
DBGMSG( DBG_TRACE, ( "TDocumentWindows ctor\n") );
|
|
}
|
|
|
|
TDocumentWindows::
|
|
~TDocumentWindows(
|
|
)
|
|
{
|
|
DBGMSG( DBG_TRACE, ( "TDocumentWindows dtor\n") );
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
bBuildPages
|
|
|
|
Routine Description:
|
|
|
|
Builds the document property windows.
|
|
|
|
Arguments:
|
|
|
|
None - class specific.
|
|
|
|
Return Value:
|
|
|
|
TRUE pages built ok, FALSE failure building pages.
|
|
|
|
--*/
|
|
|
|
BOOL
|
|
TDocumentWindows::
|
|
bBuildPages(
|
|
IN PPROPSHEETUI_INFO pCPSUIInfo
|
|
)
|
|
{
|
|
TStatusB bStatus;
|
|
DBGMSG( DBG_TRACE, ( "TDocumentWindows bBuildPages\n") );
|
|
|
|
//
|
|
// Set the default activation context to be V6 prior calling into
|
|
// compstui to create the pages. This will force V6 context unless
|
|
// the callbacks which create the compstui pages specify otherwise
|
|
// on a per page basis.
|
|
//
|
|
bStatus DBGCHK = (BOOL)pCPSUIInfo->pfnComPropSheet(
|
|
pCPSUIInfo->hComPropSheet,
|
|
CPSFUNC_SET_FUSION_CONTEXT,
|
|
reinterpret_cast<LPARAM>(g_hActCtx),
|
|
static_cast<LPARAM>(0));
|
|
|
|
if (bStatus)
|
|
{
|
|
PROPSHEETPAGE psp;
|
|
ZeroMemory( &psp, sizeof( psp ) );
|
|
|
|
psp.dwSize = sizeof( psp );
|
|
psp.dwFlags = PSP_DEFAULT;
|
|
psp.hInstance = ghInst;
|
|
psp.pfnDlgProc = MGenericProp::SetupDlgProc;
|
|
psp.pszTemplate = MAKEINTRESOURCE( DLG_DOC_JOB_GENERAL );
|
|
psp.lParam = (LPARAM)(MGenericProp*)&_General;
|
|
|
|
if( pCPSUIInfo->pfnComPropSheet( pCPSUIInfo->hComPropSheet,
|
|
CPSFUNC_ADD_PROPSHEETPAGE,
|
|
(LPARAM)&psp,
|
|
NULL ) <= 0 )
|
|
{
|
|
DBGMSG( DBG_TRACE, ( "CPSFUNC_ADD_PROPSHEETPAGE failed.\n") );
|
|
bStatus DBGCHK = FALSE;
|
|
}
|
|
|
|
if (bStatus)
|
|
{
|
|
//
|
|
// If the dev mode is null don't display the
|
|
// device property sheets.
|
|
//
|
|
if( _pDocumentData->pJobInfo()->pDevMode )
|
|
{
|
|
ZeroMemory( &_dph, sizeof( _dph ) );
|
|
|
|
_dph.cbSize = sizeof( _dph );
|
|
_dph.hPrinter = _pDocumentData->hPrinter();
|
|
_dph.pszPrinterName = (LPTSTR)(LPCTSTR)_pDocumentData->strPrinterName();
|
|
_dph.pdmOut = _pDocumentData->pJobInfo()->pDevMode;
|
|
_dph.pdmIn = _pDocumentData->pJobInfo()->pDevMode;
|
|
_dph.fMode = DM_IN_BUFFER | DM_PROMPT | DM_NOPERMISSION;
|
|
|
|
if( pCPSUIInfo->pfnComPropSheet( pCPSUIInfo->hComPropSheet,
|
|
CPSFUNC_ADD_PFNPROPSHEETUI,
|
|
(LPARAM)DocumentPropertySheets,
|
|
(LPARAM)&_dph ) <= 0 )
|
|
{
|
|
DBGMSG( DBG_TRACE, ( "CPSFUNC_ADD_PFNPROPSHEETUI failed.\n") );
|
|
bStatus DBGCHK = FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return bStatus;
|
|
}
|
|
|
|
|
|
BOOL
|
|
TDocumentWindows::
|
|
bSetHeader(
|
|
IN PPROPSHEETUI_INFO pCPSUIInfo,
|
|
IN PPROPSHEETUI_INFO_HEADER pPSUIInfoHdr
|
|
)
|
|
{
|
|
DBGMSG( DBG_TRACE, ( "TDocumentWindows bSetHeader\n") );
|
|
|
|
UNREFERENCED_PARAMETER( pCPSUIInfo );
|
|
|
|
pPSUIInfoHdr->pTitle = _pDocumentData->pJobInfo()->pDocument;
|
|
pPSUIInfoHdr->Flags = PSUIHDRF_PROPTITLE;
|
|
pPSUIInfoHdr->hWndParent = _pDocumentData->hwnd();
|
|
pPSUIInfoHdr->hInst = ghInst;
|
|
pPSUIInfoHdr->IconID = IDI_DOCUMENT;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
TDocumentWindows::
|
|
bValid(
|
|
VOID
|
|
)
|
|
{
|
|
return _General.bValid();
|
|
}
|
|
|
|
/********************************************************************
|
|
|
|
Document properties UI (driver UI)
|
|
|
|
********************************************************************/
|
|
|
|
TDocumentProperties::
|
|
TDocumentProperties(
|
|
IN HWND hwnd,
|
|
IN HANDLE hPrinter,
|
|
IN LPCTSTR pszPrinter,
|
|
IN PDEVMODE pDevModeIn,
|
|
OUT PDEVMODE pDevModeOut,
|
|
IN DWORD dwHideBits,
|
|
IN DWORD dwFlags
|
|
):
|
|
_hwnd(hwnd),
|
|
_hPrinter(hPrinter),
|
|
_pszPrinter(pszPrinter),
|
|
_pDevModeIn(pDevModeIn),
|
|
_pDevModeOut(pDevModeOut),
|
|
_dwHideBits(dwHideBits),
|
|
_dwFlags(dwFlags),
|
|
_lResult(-1)
|
|
{
|
|
// nothing
|
|
}
|
|
|
|
LONG
|
|
TDocumentProperties::
|
|
lGetResult(
|
|
VOID
|
|
) const
|
|
{
|
|
return _lResult;
|
|
}
|
|
|
|
BOOL
|
|
TDocumentProperties::
|
|
bBuildPages(
|
|
IN PPROPSHEETUI_INFO pCPSUIInfo
|
|
)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
|
|
if( bValid() )
|
|
{
|
|
//
|
|
// Set the default activation context to be V6 prior calling into
|
|
// compstui to create the pages. This will force V6 context unless
|
|
// the callbacks which create the compstui pages specify otherwise
|
|
// on a per page basis.
|
|
//
|
|
bRet = (BOOL)pCPSUIInfo->pfnComPropSheet(
|
|
pCPSUIInfo->hComPropSheet,
|
|
CPSFUNC_SET_FUSION_CONTEXT,
|
|
reinterpret_cast<LPARAM>(g_hActCtx),
|
|
static_cast<LPARAM>(0));
|
|
|
|
if( bRet )
|
|
{
|
|
ZeroMemory(&_dph, sizeof(_dph));
|
|
|
|
_dph.cbSize = sizeof(_dph);
|
|
_dph.hPrinter = _hPrinter;
|
|
_dph.pszPrinterName = const_cast<LPTSTR>(_pszPrinter);
|
|
_dph.pdmIn = _pDevModeIn;
|
|
_dph.pdmOut = _pDevModeOut;
|
|
_dph.fMode = _dwFlags;
|
|
|
|
if( _dwHideBits )
|
|
{
|
|
_lResult = pCPSUIInfo->pfnComPropSheet(pCPSUIInfo->hComPropSheet,
|
|
CPSFUNC_SET_DMPUB_HIDEBITS, static_cast<LPARAM>(_dwHideBits), 0);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// If no bit is hided, The result value should be valid.
|
|
//
|
|
_lResult = 1;
|
|
}
|
|
|
|
if( _lResult > 0 )
|
|
{
|
|
_lResult = pCPSUIInfo->pfnComPropSheet(pCPSUIInfo->hComPropSheet,
|
|
CPSFUNC_ADD_PFNPROPSHEETUI, reinterpret_cast<LPARAM>(DocumentPropertySheets),
|
|
reinterpret_cast<LPARAM>(&_dph));
|
|
}
|
|
}
|
|
}
|
|
|
|
return (_lResult > 0);
|
|
}
|
|
|
|
BOOL
|
|
TDocumentProperties::
|
|
bSetHeader(
|
|
IN PPROPSHEETUI_INFO pCPSUIInfo,
|
|
IN PPROPSHEETUI_INFO_HEADER pPSUInfoHeader
|
|
)
|
|
{
|
|
// construct the title & setup the header
|
|
UNREFERENCED_PARAMETER(pCPSUIInfo);
|
|
|
|
if( 0 == _strTitle.uLen() )
|
|
{
|
|
_strTitle.bLoadString(ghInst, IDS_PRINTER_PREFERENCES);
|
|
}
|
|
|
|
pPSUInfoHeader->pTitle = const_cast<LPTSTR>(static_cast<LPCTSTR>(_strTitle));
|
|
pPSUInfoHeader->Flags = PSUIHDRF_EXACT_PTITLE | PSUIHDRF_NOAPPLYNOW;
|
|
pPSUInfoHeader->hWndParent = _hwnd;
|
|
pPSUInfoHeader->hInst = ghInst;
|
|
pPSUInfoHeader->IconID = IDI_PRINTER;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// table to remap the devmode field selections to DMPUB_* ids.
|
|
static DWORD arrDmFlagMap[] =
|
|
{
|
|
DM_ORIENTATION, MAKE_DMPUB_HIDEBIT( DMPUB_ORIENTATION ),
|
|
DM_PAPERSIZE , MAKE_DMPUB_HIDEBIT( 0 ),
|
|
DM_PAPERLENGTH, MAKE_DMPUB_HIDEBIT( 0 ),
|
|
DM_PAPERWIDTH , MAKE_DMPUB_HIDEBIT( 0 ),
|
|
DM_SCALE , MAKE_DMPUB_HIDEBIT( DMPUB_SCALE ),
|
|
DM_COPIES , MAKE_DMPUB_HIDEBIT( DMPUB_COPIES_COLLATE ),
|
|
DM_DEFAULTSOURCE, MAKE_DMPUB_HIDEBIT( DMPUB_DEFSOURCE ),
|
|
DM_PRINTQUALITY, MAKE_DMPUB_HIDEBIT( DMPUB_PRINTQUALITY ),
|
|
DM_COLOR , MAKE_DMPUB_HIDEBIT( DMPUB_COLOR ),
|
|
DM_DUPLEX , MAKE_DMPUB_HIDEBIT( DMPUB_DUPLEX ),
|
|
DM_YRESOLUTION, MAKE_DMPUB_HIDEBIT( 0 ),
|
|
DM_TTOPTION , MAKE_DMPUB_HIDEBIT( DMPUB_TTOPTION ),
|
|
DM_COLLATE , MAKE_DMPUB_HIDEBIT( DMPUB_COPIES_COLLATE ),
|
|
DM_FORMNAME , MAKE_DMPUB_HIDEBIT( DMPUB_FORMNAME ),
|
|
DM_LOGPIXELS , MAKE_DMPUB_HIDEBIT( 0 ),
|
|
DM_BITSPERPEL , MAKE_DMPUB_HIDEBIT( 0 ),
|
|
DM_PELSWIDTH , MAKE_DMPUB_HIDEBIT( 0 ),
|
|
DM_PELSHEIGHT , MAKE_DMPUB_HIDEBIT( 0 ),
|
|
DM_DISPLAYFLAGS, MAKE_DMPUB_HIDEBIT( 0 ),
|
|
DM_DISPLAYFREQUENCY, MAKE_DMPUB_HIDEBIT( 0 ),
|
|
DM_ICMMETHOD , MAKE_DMPUB_HIDEBIT( DMPUB_ICMMETHOD ),
|
|
DM_ICMINTENT , MAKE_DMPUB_HIDEBIT( DMPUB_ICMINTENT ),
|
|
DM_MEDIATYPE , MAKE_DMPUB_HIDEBIT( DMPUB_MEDIATYPE ),
|
|
DM_DITHERTYPE , MAKE_DMPUB_HIDEBIT( DMPUB_DITHERTYPE ),
|
|
DM_PANNINGWIDTH, MAKE_DMPUB_HIDEBIT( 0 ),
|
|
DM_PANNINGHEIGHT, MAKE_DMPUB_HIDEBIT( 0 )
|
|
};
|
|
|
|
static DWORD
|
|
RemapExclusionFlags(DWORD fExclusionFlags)
|
|
{
|
|
// walk through to collect the exclusion bits from the table above.
|
|
DWORD dwFlags = 0;
|
|
for( UINT i = 0; i < ARRAYSIZE(arrDmFlagMap); i += 2 )
|
|
{
|
|
if( fExclusionFlags & arrDmFlagMap[i] )
|
|
{
|
|
dwFlags |= arrDmFlagMap[i+1];
|
|
}
|
|
}
|
|
return dwFlags;
|
|
}
|
|
|
|
LONG
|
|
DocumentPropertiesWrapNative(
|
|
HWND hwnd, // handle to parent window
|
|
HANDLE hPrinter, // handle to printer object
|
|
LPTSTR pDeviceName, // device name
|
|
PDEVMODE pDevModeOutput, // modified device mode
|
|
PDEVMODE pDevModeInput, // original device mode
|
|
DWORD fMode, // mode options
|
|
DWORD fExclusionFlags // exclusion flags
|
|
)
|
|
{
|
|
// lResult <= 0 means error, for more information see
|
|
// the description of DocumentProperties in SDK.
|
|
LONG lResult = (-1);
|
|
|
|
if( hPrinter && pDeviceName && pDevModeOutput && pDevModeInput )
|
|
{
|
|
if (fMode & DM_PROMPT)
|
|
{
|
|
// invoke compstui to show up the driver UI
|
|
TDocumentProperties props(hwnd, hPrinter, pDeviceName, pDevModeInput, pDevModeOutput,
|
|
RemapExclusionFlags(fExclusionFlags), fMode);
|
|
|
|
if( props.bDisplayPages(hwnd, &lResult) )
|
|
{
|
|
// convert the result to IDOK/IDCANCEL
|
|
lResult = (lResult == CPSUI_OK) ? IDOK : IDCANCEL;
|
|
}
|
|
else
|
|
{
|
|
// error occured.
|
|
lResult = (-1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// this is no UI call - just invoke DocumentProperties.
|
|
lResult = DocumentProperties(hwnd, hPrinter, pDeviceName, pDevModeOutput, pDevModeInput, fMode);
|
|
}
|
|
}
|
|
|
|
return lResult;
|
|
}
|
|
|
|
LONG
|
|
DocumentPropertiesWrapWOW64(
|
|
HWND hwnd, // handle to parent window
|
|
HANDLE hPrinter, // handle to printer object
|
|
LPTSTR pDeviceName, // device name
|
|
PDEVMODE pDevModeOutput, // modified device mode
|
|
PDEVMODE pDevModeInput, // original device mode
|
|
DWORD fMode, // mode options
|
|
DWORD fExclusionFlags // exclusion flags
|
|
)
|
|
{
|
|
CDllLoader dll(TEXT("winspool.drv"));
|
|
ptr_PrintUIDocumentPropertiesWrap pfnPrintUIDocumentPropertiesWrap =
|
|
(ptr_PrintUIDocumentPropertiesWrap )dll.GetProcAddress(ord_PrintUIDocumentPropertiesWrap);
|
|
|
|
LONG lResult = (-1);
|
|
if( pfnPrintUIDocumentPropertiesWrap )
|
|
{
|
|
lResult = pfnPrintUIDocumentPropertiesWrap(hwnd, hPrinter, pDeviceName, pDevModeOutput, pDevModeInput, fMode, fExclusionFlags);
|
|
}
|
|
return lResult;
|
|
}
|
|
|
|
LONG
|
|
DocumentPropertiesWrap(
|
|
HWND hwnd, // handle to parent window
|
|
HANDLE hPrinter, // handle to printer object
|
|
LPTSTR pDeviceName, // device name
|
|
PDEVMODE pDevModeOutput, // modified device mode
|
|
PDEVMODE pDevModeInput, // original device mode
|
|
DWORD fMode, // mode options
|
|
DWORD fExclusionFlags // exclusion flags
|
|
)
|
|
{
|
|
// if running in WOW64 environment we need to call winspool.drv to remote the
|
|
// call into the surrogate 64bit process where the driver UI can be displayed.
|
|
LONG lResult = IsRunningWOW64() ?
|
|
DocumentPropertiesWrapWOW64(hwnd, hPrinter, pDeviceName, pDevModeOutput, pDevModeInput, fMode, fExclusionFlags) :
|
|
DocumentPropertiesWrapNative(hwnd, hPrinter, pDeviceName, pDevModeOutput, pDevModeInput, fMode, fExclusionFlags);
|
|
|
|
return lResult;
|
|
}
|
|
|