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.
3267 lines
72 KiB
3267 lines
72 KiB
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
Prop.cxx
|
|
|
|
Abstract:
|
|
|
|
Holds Printer properties.
|
|
|
|
Author:
|
|
|
|
Albert Ting (AlbertT) 15-Aug-1995
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "precomp.hxx"
|
|
#pragma hdrstop
|
|
|
|
#include <setupapi.h>
|
|
#include "lmerr.h"
|
|
#include "time.hxx"
|
|
#include "splsetup.h"
|
|
#include "psetup.hxx"
|
|
#include "instarch.hxx"
|
|
#include "portdlg.hxx"
|
|
#include "sepdlg.hxx"
|
|
#include "procdlg.hxx"
|
|
#include "portslv.hxx"
|
|
#include "prtprop.hxx"
|
|
#include "propmgr.hxx"
|
|
#include "prtprops.hxx"
|
|
#include "psetup.hxx"
|
|
#include "setup.hxx"
|
|
#include "tstpage.hxx"
|
|
#include "prtshare.hxx"
|
|
|
|
MSG_ERRMAP gaMsgErrMapSetPrinter[] = {
|
|
ERROR_INVALID_PRINTER_STATE, IDS_ERR_INVALID_PRINTER_STATE,
|
|
NERR_DuplicateShare, IDS_ERR_DUPLICATE_SHARE,
|
|
ERROR_INVALID_SHARENAME, IDS_ERR_INVALID_SHARENAME,
|
|
0, 0
|
|
};
|
|
|
|
MSG_ERRMAP gaMsgErrMapMakeConnection[] = {
|
|
{ ERROR_UNKNOWN_PRINTER_DRIVER, IDS_ERR_MAKE_CONNECTION },
|
|
{ 0, 0 }
|
|
};
|
|
|
|
/********************************************************************
|
|
|
|
Public interface.
|
|
|
|
********************************************************************/
|
|
|
|
VOID
|
|
vPrinterPropPages(
|
|
IN HWND hwnd,
|
|
IN LPCTSTR pszPrinterName,
|
|
IN INT nCmdShow,
|
|
IN LPARAM lParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function opens the property sheet of specified printer.
|
|
|
|
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 printer properties.
|
|
|
|
Arguments:
|
|
|
|
hWnd - Specifies the parent window for errors on creation.
|
|
|
|
pszPrinter - Specifies the printer name (e.g., "My HP LaserJet IIISi").
|
|
|
|
nCmdShow -
|
|
|
|
lParam - May specify a sheet number to open to.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
TPrinterData* pPrinterData = new TPrinterData( pszPrinterName,
|
|
nCmdShow,
|
|
lParam );
|
|
if( !VALID_PTR( pPrinterData )){
|
|
goto Fail;
|
|
}
|
|
|
|
//
|
|
// Create the thread which handles the UI. vPrinterPropPages adopts
|
|
// pPrinterData.
|
|
//
|
|
DWORD dwIgnore;
|
|
HANDLE hThread;
|
|
|
|
hThread = CreateThread( NULL,
|
|
0,
|
|
(LPTHREAD_START_ROUTINE)TPrinterProp::iPrinterPropPagesProc,
|
|
pPrinterData,
|
|
0,
|
|
&dwIgnore );
|
|
|
|
if( !hThread ){
|
|
goto Fail;
|
|
}
|
|
|
|
CloseHandle( hThread );
|
|
return;
|
|
|
|
Fail:
|
|
|
|
if( !pPrinterData ){
|
|
vShowResourceError( hwnd );
|
|
} else {
|
|
iMessage( hwnd,
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
IDS_ERR_PRINTER_PROP,
|
|
MB_OK|MB_ICONSTOP,
|
|
kMsgGetLastError,
|
|
NULL );
|
|
}
|
|
|
|
delete pPrinterData;
|
|
}
|
|
|
|
|
|
/********************************************************************
|
|
|
|
Worker thread that handles printer properties.
|
|
|
|
********************************************************************/
|
|
|
|
INT
|
|
TPrinterProp::
|
|
iPrinterPropPagesProc(
|
|
IN TPrinterData* pPrinterData ADOPT
|
|
)
|
|
{
|
|
BOOL bStatus;
|
|
|
|
bStatus = pPrinterData->bRegisterWindow( PRINTER_PIDL_TYPE_PROPERTIES );
|
|
if( bStatus ){
|
|
|
|
//
|
|
// Check if the window is already present. If it is, then
|
|
// exit immediately.
|
|
//
|
|
if( !pPrinterData->hwnd( )){
|
|
delete pPrinterData;
|
|
return 0;
|
|
}
|
|
|
|
bStatus = pPrinterData->bLoad();
|
|
}
|
|
|
|
if( !bStatus ){
|
|
|
|
iMessage( pPrinterData->hwnd(),
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
IDS_ERR_PRINTER_PROP,
|
|
MB_OK|MB_ICONSTOP|MB_SETFOREGROUND,
|
|
kMsgGetLastError,
|
|
NULL );
|
|
|
|
delete pPrinterData;
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// Instantiate the printer sheets and check if valid.
|
|
//
|
|
TPrinterPropertySheetManager PrinterSheets( pPrinterData );
|
|
INT iResult = ERROR_SUCCESS;
|
|
|
|
if( !VALID_OBJ( PrinterSheets )){
|
|
vShowUnexpectedError( pPrinterData->hwnd(), IDS_ERR_PRINTER_PROP_TITLE );
|
|
bStatus = FALSE;
|
|
}
|
|
|
|
//
|
|
// Save a back pointer to the property sheet manager.
|
|
//
|
|
pPrinterData->pPrinterPropertySheetManager() = &PrinterSheets;
|
|
|
|
//
|
|
// Display the property sheet pages.
|
|
//
|
|
if( bStatus ){
|
|
if( !PrinterSheets.bDisplayPages( pPrinterData->hwnd() )){
|
|
vShowUnexpectedError( pPrinterData->hwnd(), IDS_ERR_PRINTER_PROP_TITLE );
|
|
bStatus = FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// If sheets were displayed ok.
|
|
//
|
|
if( bStatus ){
|
|
|
|
//
|
|
// Total HACK until common ui is online.
|
|
//
|
|
if( pPrinterData->_bValid == 2 ){
|
|
|
|
//
|
|
// Need to save the information changed in pPrinterData
|
|
// since the user clicked OK.
|
|
//
|
|
if( pPrinterData->bAdministrator( )){
|
|
|
|
TStatusB bStatus;
|
|
bStatus DBGCHK = pPrinterData->bSave();
|
|
|
|
if( !bStatus ){
|
|
|
|
iMessage( pPrinterData->hwnd(),
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
IDS_ERR_SAVE_PRINTER,
|
|
MB_OK|MB_ICONSTOP,
|
|
kMsgGetLastError,
|
|
gaMsgErrMapSetPrinter );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
DBGMSG( DBG_WARN, ( "vPrinterPropPages: changes requested, yet not admin.\n" ));
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Remove the back pointer to the property sheet manager.
|
|
//
|
|
pPrinterData->pPrinterPropertySheetManager() = NULL;
|
|
|
|
//
|
|
// We have adopted pPrinterData, so we must free it.
|
|
//
|
|
delete pPrinterData;
|
|
|
|
return iResult;
|
|
}
|
|
|
|
/********************************************************************
|
|
|
|
TPrinterData.
|
|
|
|
********************************************************************/
|
|
|
|
TPrinterData::
|
|
TPrinterData(
|
|
IN LPCTSTR pszPrinterName,
|
|
IN INT nCmdShow,
|
|
IN LPARAM lParam
|
|
) : MSingletonWin( pszPrinterName )
|
|
{
|
|
_hIcon = NULL;
|
|
_hDefaultIcon = NULL;
|
|
_hDefaultSmallIcon = NULL;
|
|
_pDevMode = NULL;
|
|
_bNoAccess = FALSE;
|
|
_bValid = FALSE;
|
|
_bErrorSaving = FALSE;
|
|
_iStartPage = (INT)lParam;
|
|
_pszServerName = NULL;
|
|
_pPrinterPropertySheetManager = NULL;
|
|
_bRefreshArch = FALSE;
|
|
_bRefreshBidi = TRUE;
|
|
_hPrinter = NULL;
|
|
|
|
_bValid = MSingletonWin::bValid();
|
|
|
|
UNREFERENCED_PARAMETER( nCmdShow );
|
|
}
|
|
|
|
TPrinterData::
|
|
~TPrinterData(
|
|
VOID
|
|
)
|
|
{
|
|
//
|
|
// Unload the printer data.
|
|
//
|
|
vUnload();
|
|
}
|
|
|
|
BOOL
|
|
TPrinterData::
|
|
bAdministrator(
|
|
VOID
|
|
)
|
|
{
|
|
return _dwAccess == PRINTER_ALL_ACCESS;
|
|
}
|
|
|
|
BOOL
|
|
TPrinterData::
|
|
bLoad(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Load printer information. This call can fail because of access
|
|
denied, in which case only the security page should be added
|
|
to the propset.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// Retrieve icons.
|
|
//
|
|
Printer_LoadIcons( _strPrinterName,
|
|
&_hDefaultIcon,
|
|
&_hDefaultSmallIcon );
|
|
|
|
SPLASSERT( _hDefaultIcon );
|
|
SPLASSERT( _hDefaultSmallIcon );
|
|
|
|
//
|
|
// Start out using the default icon.
|
|
//
|
|
_hIcon = _hDefaultIcon;
|
|
|
|
//
|
|
// Open the printer.
|
|
//
|
|
TStatusB bStatus( DBG_WARN, ERROR_ACCESS_DENIED );
|
|
bStatus DBGNOCHK = FALSE;
|
|
|
|
PPRINTER_INFO_2 pInfo2 = NULL;
|
|
DWORD cbInfo2 = 0;
|
|
|
|
TStatus Status( DBG_WARN );
|
|
_dwAccess = 0;
|
|
|
|
Status DBGCHK = TPrinter::sOpenPrinter( _strPrinterName,
|
|
&_dwAccess,
|
|
&_hPrinter );
|
|
|
|
if( Status ){
|
|
_hPrinter = NULL;
|
|
goto Fail;
|
|
}
|
|
|
|
//
|
|
// Gather the information.
|
|
//
|
|
bStatus DBGCHK = VDataRefresh::bGetPrinter( _hPrinter,
|
|
2,
|
|
(PVOID*)&pInfo2,
|
|
&cbInfo2 );
|
|
|
|
if( !bStatus ){
|
|
goto Fail;
|
|
}
|
|
|
|
if( pInfo2->pDevMode ){
|
|
COUNTB cbDevMode = pInfo2->pDevMode->dmSize +
|
|
pInfo2->pDevMode->dmDriverExtra;
|
|
|
|
_pDevMode = (PDEVMODE)AllocMem( cbDevMode );
|
|
|
|
if( !_pDevMode ){
|
|
DBGMSG( DBG_WARN, ( "PrinterData.bLoad: failed to alloc dm %d: %d\n",
|
|
cbDevMode, GetLastError( )));
|
|
|
|
bStatus DBGNOCHK = FALSE;
|
|
goto Fail;
|
|
}
|
|
CopyMemory( _pDevMode,
|
|
pInfo2->pDevMode,
|
|
cbDevMode );
|
|
}
|
|
|
|
_dwAttributes = pInfo2->Attributes;
|
|
_dwPriority = pInfo2->Priority;
|
|
_dwStartTime = pInfo2->StartTime;
|
|
_dwUntilTime = pInfo2->UntilTime;
|
|
_dwStatus = pInfo2->Status;
|
|
|
|
//
|
|
// Run through printer_info_2.
|
|
// Check strings for allocation.
|
|
//
|
|
if( !_strPrinterName.bUpdate( pInfo2->pPrinterName ) ||
|
|
!_strServerName.bUpdate( pInfo2->pServerName ) ||
|
|
!_strShareName.bUpdate( pInfo2->pShareName ) ||
|
|
!_strDriverName.bUpdate( pInfo2->pDriverName ) ||
|
|
!_strComment.bUpdate( pInfo2->pComment ) ||
|
|
!_strLocation.bUpdate( pInfo2->pLocation ) ||
|
|
|
|
!_strPortName.bUpdate( pInfo2->pPortName ) ||
|
|
!_strSepFile.bUpdate( pInfo2->pSepFile ) ||
|
|
!_strPrintProcessor.bUpdate( pInfo2->pPrintProcessor ) ||
|
|
!_strDatatype.bUpdate( pInfo2->pDatatype )){
|
|
|
|
DBGMSG( DBG_WARN,
|
|
( "PrinterProp.bLoad: String update failed %x %d\n",
|
|
this, GetLastError( )));
|
|
|
|
bStatus DBGNOCHK = FALSE;
|
|
}
|
|
|
|
//
|
|
// Make a pointer to the server name. A Null pointer
|
|
// indicates the local machine.
|
|
//
|
|
if( _strServerName.bEmpty() )
|
|
_pszServerName = NULL;
|
|
else
|
|
_pszServerName = (LPCTSTR)_strServerName;
|
|
|
|
Fail:
|
|
FreeMem( pInfo2 );
|
|
|
|
//
|
|
// If we've failed because access was denied, then return
|
|
// success but set the bNoAccess flag. This allows the
|
|
// user to see the security tab.
|
|
//
|
|
if( !bStatus && ERROR_ACCESS_DENIED == GetLastError( )){
|
|
_bNoAccess = TRUE;
|
|
return TRUE;
|
|
}
|
|
return bStatus;
|
|
}
|
|
|
|
VOID
|
|
TPrinterData::
|
|
vUnload(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Free associated data in this, so that this can be freed or
|
|
loaded again.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// Release the deve mode.
|
|
//
|
|
FreeMem( _pDevMode );
|
|
_pDevMode = NULL;
|
|
|
|
//
|
|
// Close the printer
|
|
//
|
|
if( _hPrinter ){
|
|
ClosePrinter( _hPrinter );
|
|
_hPrinter = NULL;
|
|
}
|
|
|
|
//
|
|
// Release the printer icon.
|
|
//
|
|
if( _hIcon &&
|
|
_hIcon != _hDefaultIcon ){
|
|
DestroyIcon( _hIcon );
|
|
_hIcon = NULL;
|
|
}
|
|
|
|
//
|
|
// Release our default icon
|
|
//
|
|
if( _hDefaultIcon ){
|
|
DestroyIcon( _hDefaultIcon );
|
|
_hDefaultIcon = NULL;
|
|
}
|
|
|
|
//
|
|
// Release our default icon
|
|
//
|
|
if( _hDefaultSmallIcon ){
|
|
DestroyIcon( _hDefaultSmallIcon );
|
|
_hDefaultSmallIcon = NULL;
|
|
}
|
|
|
|
}
|
|
|
|
BOOL
|
|
TPrinterData::
|
|
bSave(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Save the data store in this.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// If bErrorSaving is set, then somewhere we had an error reading
|
|
// from the dialogs. This should be very rare.
|
|
//
|
|
if( bErrorSaving( )){
|
|
|
|
//
|
|
// Tell the user that we can't save the dialogs.
|
|
// Then just exit?
|
|
//
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// We must be an admin to save. It's an error to call us
|
|
// if we aren't.
|
|
//
|
|
SPLASSERT( bAdministrator( ));
|
|
|
|
//
|
|
// Setup the INFO_2 structure. First read it, modify it, then
|
|
// free it.
|
|
//
|
|
TStatusB bStatus;
|
|
|
|
PPRINTER_INFO_2 pInfo2 = NULL;
|
|
DWORD cbInfo2 = 0;
|
|
|
|
bStatus DBGCHK = VDataRefresh::bGetPrinter( _hPrinter,
|
|
2,
|
|
(PVOID*)&pInfo2,
|
|
&cbInfo2 );
|
|
|
|
if( !bStatus ){
|
|
goto Fail;
|
|
}
|
|
|
|
//
|
|
// Transfer pPrinterData to pInfo2.
|
|
//
|
|
|
|
pInfo2->pPrinterName = (LPTSTR)(LPCTSTR)_strPrinterName;
|
|
pInfo2->pShareName = (LPTSTR)(LPCTSTR)_strShareName;
|
|
pInfo2->pDriverName = (LPTSTR)(LPCTSTR)_strDriverName;
|
|
pInfo2->pComment = (LPTSTR)(LPCTSTR)_strComment;
|
|
pInfo2->pLocation = (LPTSTR)(LPCTSTR)_strLocation;
|
|
pInfo2->pPortName = (LPTSTR)(LPCTSTR)_strPortName;
|
|
pInfo2->pSepFile = (LPTSTR)(LPCTSTR)_strSepFile;
|
|
pInfo2->pPrintProcessor = (LPTSTR)(LPCTSTR)_strPrintProcessor;
|
|
pInfo2->pDatatype = (LPTSTR)(LPCTSTR)_strDatatype;
|
|
|
|
pInfo2->pDevMode = _pDevMode;
|
|
|
|
pInfo2->Attributes = _dwAttributes;
|
|
pInfo2->Priority = _dwPriority;
|
|
pInfo2->StartTime = _dwStartTime;
|
|
pInfo2->UntilTime = _dwUntilTime;
|
|
|
|
//
|
|
// Another piece of trivia: the security descriptor must be set
|
|
// to NULL since it might not be the owner.
|
|
//
|
|
pInfo2->pSecurityDescriptor = NULL;
|
|
|
|
bStatus DBGCHK = SetPrinter( _hPrinter,
|
|
2,
|
|
(PBYTE)pInfo2,
|
|
0 );
|
|
|
|
Fail:
|
|
|
|
FreeMem( pInfo2 );
|
|
return bStatus;
|
|
}
|
|
|
|
BOOL
|
|
TPrinterData::
|
|
bChangeDriver(
|
|
IN HWND hDlg,
|
|
IN LPCTSTR pszDriverName,
|
|
IN LPCTSTR pszPrinterName
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Update driver type.
|
|
|
|
Arguments:
|
|
|
|
hDlg - This is a hack: the callee must pass in the property sheet
|
|
that is changing the driver. PrinterPropertySheetManager should
|
|
already know which dialog it needs to update, but it can't
|
|
get the hwnd, so we end up passing it in here.
|
|
|
|
pszDriverName - New driver.
|
|
|
|
pszPrinterName - New updated printer name.
|
|
|
|
Return Value:
|
|
|
|
TRUE success, FALSE failure.
|
|
|
|
--*/
|
|
{
|
|
BOOL bStatus = FALSE;
|
|
TString strTempDriverName;
|
|
TString strTempPrinterName;
|
|
|
|
|
|
//
|
|
// Make a copy of the original driver name.
|
|
//
|
|
if( strTempDriverName.bUpdate( _strDriverName ) &&
|
|
strTempPrinterName.bUpdate( _strPrinterName ) ){
|
|
|
|
//
|
|
// This should never be null.
|
|
//
|
|
SPLASSERT( _pPrinterPropertySheetManager );
|
|
|
|
//
|
|
// Update the driver name printer name and save the printer data
|
|
// then refresh the driver pages.
|
|
//
|
|
if( _strDriverName.bUpdate( pszDriverName ) &&
|
|
_strPrinterName.bUpdate( pszPrinterName ) &&
|
|
bSave() &&
|
|
_pPrinterPropertySheetManager->bRefreshDriverPages() ){
|
|
|
|
bStatus = TRUE;
|
|
|
|
//
|
|
// Turn on BIDI since the spooler enables this if a
|
|
// language monitor is present. If it isn't it will
|
|
// be ignored by the spooler.
|
|
//
|
|
_dwAttributes |= PRINTER_ATTRIBUTE_ENABLE_BIDI;
|
|
|
|
} else {
|
|
|
|
DBGMSG( DBG_WARN, ( "Update driver failed restoring original driver.\n" ) );
|
|
|
|
//
|
|
// Restore the old driver name.
|
|
//
|
|
if( !_strDriverName.bUpdate( strTempDriverName ) ||
|
|
!_strPrinterName.bUpdate( strTempPrinterName ) ||
|
|
!bSave() ||
|
|
!_pPrinterPropertySheetManager->bRefreshDriverPages() ){
|
|
|
|
DBGMSG( DBG_WARN, ( "Restore driver and printer name failed with %d.\n", GetLastError() ) );
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
DBGMSG( DBG_WARN, ( "Copy driver name failed with %d.\n", GetLastError() ) );
|
|
|
|
}
|
|
|
|
if( bStatus ){
|
|
|
|
//
|
|
// Inform the architecture and ports page it needs to
|
|
// refresh itself during it's next activation.
|
|
//
|
|
_bRefreshArch = TRUE;
|
|
_bRefreshBidi = TRUE;
|
|
|
|
//
|
|
// Refresh the property sheet title.
|
|
//
|
|
_pPrinterPropertySheetManager->vRefreshTitle( hDlg );
|
|
}
|
|
|
|
return bStatus;
|
|
}
|
|
|
|
BOOL
|
|
TPrinterData::
|
|
bSupportBidi(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Check whether the current printer supports bidi. Assumes there
|
|
is a valid hPrinter available.
|
|
|
|
Note: this returns false if it can't make the determination.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
TRUE - Bidi supported.
|
|
FALSE - Failed or bidi not supported.
|
|
|
|
--*/
|
|
|
|
{
|
|
BOOL bSupport = FALSE;
|
|
|
|
PDRIVER_INFO_3 pInfo3 = NULL;
|
|
DWORD dwInfo3 = 0;
|
|
|
|
//
|
|
// !! BUGBUG !!
|
|
//
|
|
// We should really use the server environment, since if the
|
|
// local environment isn't installed on the server, this fails.
|
|
//
|
|
if( VDataRefresh::bGetPrinterDriver( _hPrinter,
|
|
NULL,
|
|
3,
|
|
(PVOID*)&pInfo3,
|
|
&dwInfo3 )){
|
|
|
|
bSupport = pInfo3->pMonitorName && pInfo3->pMonitorName[0];
|
|
FreeMem( pInfo3 );
|
|
}
|
|
|
|
return bSupport;
|
|
}
|
|
|
|
/********************************************************************
|
|
|
|
Printer property base class for generic services to
|
|
all property pages.
|
|
|
|
********************************************************************/
|
|
|
|
TPrinterProp::
|
|
TPrinterProp(
|
|
TPrinterData* pPrinterData
|
|
) : _pPrinterData( pPrinterData )
|
|
{
|
|
//
|
|
// PRINTER_SHARING_PAGE defined in win\inc\winprtp.h must
|
|
// match kPropSharing. Shell32.dll passes this value.
|
|
//
|
|
SPLASSERT( PRINTER_SHARING_PAGE == kPropSharing );
|
|
}
|
|
|
|
VOID
|
|
TPrinterProp::
|
|
vSetIconName(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets the printer icon to the custom one.
|
|
|
|
Arguments:
|
|
|
|
hDlg - Modifies this dialog.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// Set the correct icon; destroy the previous one.
|
|
//
|
|
HICON hIcon = (HICON)SendDlgItemMessage( _hDlg,
|
|
IDC_PRINTER_ICON,
|
|
STM_SETICON,
|
|
(WPARAM)_pPrinterData->hIcon(),
|
|
0 );
|
|
//
|
|
// Insure we destroy the icon, however, do not destroy
|
|
// the icon we get from the printers folder or the icon
|
|
// we get from the printer driver.
|
|
//
|
|
if( hIcon &&
|
|
hIcon != _pPrinterData->hIcon() &&
|
|
hIcon != _pPrinterData->hDefaultIcon() ){
|
|
|
|
DestroyIcon( hIcon );
|
|
|
|
}
|
|
|
|
LPCTSTR pszServer;
|
|
LPCTSTR pszPrinter;
|
|
TCHAR szScratch[kPrinterBufMax];
|
|
|
|
//
|
|
// Split the printer name into its components.
|
|
//
|
|
vPrinterSplitFullName( szScratch,
|
|
_pPrinterData->strPrinterName( ),
|
|
&pszServer,
|
|
&pszPrinter );
|
|
//
|
|
// Set the printer name.
|
|
//
|
|
bSetEditText( _hDlg, IDC_NAME, pszPrinter );
|
|
|
|
}
|
|
|
|
VOID
|
|
TPrinterProp::
|
|
vFreeIcon(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets the printer icon to the custom one.
|
|
|
|
Arguments:
|
|
|
|
hDlg - Modifies this dialog.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// Remove our icon.
|
|
//
|
|
if( _pPrinterData->hIcon( )){
|
|
|
|
SendDlgItemMessage( _hDlg,
|
|
IDC_PRINTER_ICON,
|
|
STM_SETICON,
|
|
(WPARAM)NULL,
|
|
0 );
|
|
}
|
|
}
|
|
|
|
VOID
|
|
TPrinterProp::
|
|
vReloadPages(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Something changed (driver or security etc.) so we need to completely
|
|
refresh all printer pages.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Nothing
|
|
|
|
Comments:
|
|
|
|
This is currently not implemented.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
}
|
|
|
|
/********************************************************************
|
|
|
|
General.
|
|
|
|
********************************************************************/
|
|
|
|
TPrinterGeneral::
|
|
TPrinterGeneral(
|
|
TPrinterData* pPrinterData
|
|
) : TPrinterProp( pPrinterData ),
|
|
_bDropDownState( FALSE )
|
|
{
|
|
}
|
|
|
|
TPrinterGeneral::
|
|
~TPrinterGeneral(
|
|
VOID
|
|
)
|
|
{
|
|
}
|
|
|
|
BOOL
|
|
TPrinterGeneral::
|
|
bValid(
|
|
VOID
|
|
)
|
|
{
|
|
return TPrinterProp::bValid();
|
|
}
|
|
|
|
BOOL
|
|
TPrinterGeneral::
|
|
bSetUI(
|
|
VOID
|
|
)
|
|
|
|
{
|
|
vSetIconName();
|
|
|
|
//
|
|
// Update the fields.
|
|
//
|
|
bSetEditText( _hDlg, IDC_COMMENT, _pPrinterData->strComment( ));
|
|
bSetEditText( _hDlg, IDC_LOCATION, _pPrinterData->strLocation( ));
|
|
|
|
vEnableCtl( _hDlg, IDC_COMMENT, _pPrinterData->bAdministrator( ));
|
|
vEnableCtl( _hDlg, IDC_LOCATION, _pPrinterData->bAdministrator( ));
|
|
vEnableCtl( _hDlg, IDC_DRIVER_NAME, _pPrinterData->bAdministrator( ));
|
|
vEnableCtl( _hDlg, IDC_DRIVER_NEW, _pPrinterData->bAdministrator( ));
|
|
|
|
vEnableCtl( _hDlg, IDC_TEXT_COMMENT, _pPrinterData->bAdministrator( ));
|
|
vEnableCtl( _hDlg, IDC_TEXT_LOCATION, _pPrinterData->bAdministrator( ));
|
|
vEnableCtl( _hDlg, IDC_TEXT_DRIVER, _pPrinterData->bAdministrator( ));
|
|
|
|
//
|
|
// Fill in drivers.
|
|
//
|
|
return bFillAndSelectDrivers();
|
|
}
|
|
|
|
BOOL
|
|
TPrinterGeneral::
|
|
bFillAndSelectDrivers(
|
|
VOID
|
|
)
|
|
{
|
|
PDRIVER_INFO_2 pDriverInfo2 = NULL;
|
|
DWORD cDrivers;
|
|
DWORD cbDriverInfo2 = kInitialDriverHint;
|
|
TStatusB bStatus( DBG_WARN, ERROR_INSUFFICIENT_BUFFER );
|
|
|
|
Retry:
|
|
|
|
pDriverInfo2 = (PDRIVER_INFO_2)AllocMem( cbDriverInfo2 );
|
|
|
|
if( !pDriverInfo2 ){
|
|
DBGMSG( DBG_WARN,
|
|
( "PrinterGeneral.bFillAndSelectDrivers: can't alloc %d %d\n",
|
|
cbDriverInfo2, GetLastError( )));
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
bStatus DBGCHK = EnumPrinterDrivers(
|
|
(LPTSTR)_pPrinterData->pszServerName(),
|
|
NULL,
|
|
2,
|
|
(PBYTE)pDriverInfo2,
|
|
cbDriverInfo2,
|
|
&cbDriverInfo2,
|
|
&cDrivers );
|
|
if( !bStatus ){
|
|
|
|
FreeMem( pDriverInfo2 );
|
|
|
|
if( GetLastError() == ERROR_INSUFFICIENT_BUFFER ){
|
|
goto Retry;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Fill in the driver information.
|
|
//
|
|
HWND hCtlDrivers = GetDlgItem( _hDlg, IDC_DRIVER_NAME );
|
|
SPLASSERT( hCtlDrivers );
|
|
|
|
ComboBox_ResetContent( hCtlDrivers );
|
|
|
|
DWORD i;
|
|
for( i = 0; i < cDrivers; ++i ){
|
|
|
|
//
|
|
// Add only the right version.
|
|
//
|
|
if( pDriverInfo2[i].cVersion == kCurrentDriverVersion ){
|
|
ComboBox_AddString( hCtlDrivers, pDriverInfo2[i].pName );
|
|
}
|
|
}
|
|
|
|
FreeMem( pDriverInfo2 );
|
|
|
|
INT iStatus = ComboBox_SelectString( hCtlDrivers,
|
|
-1,
|
|
_pPrinterData->strDriverName( ));
|
|
|
|
//
|
|
// The problem here is that the server many not have the driver
|
|
// for the client enviroment, so we need to jam in the extra driver
|
|
// name if iStatus is -1 (failure case).
|
|
//
|
|
if( iStatus == -1 ){
|
|
|
|
DBGMSG( DBG_INFO,
|
|
( "PrinterGeneral.bFillAndSelectDrivers: driver "TSTR" not on server\n",
|
|
DBGSTR( (LPCTSTR)_pPrinterData->strDriverName( ))));
|
|
|
|
ComboBox_AddString( hCtlDrivers,
|
|
_pPrinterData->strDriverName( ));
|
|
|
|
INT iSelectResult = ComboBox_SelectString(
|
|
hCtlDrivers,
|
|
-1,
|
|
_pPrinterData->strDriverName( ));
|
|
|
|
if( iSelectResult < 0 ){
|
|
DBGMSG( DBG_WARN,
|
|
( "PrinterGeneral.bFillAndSelectDrivers: driver "TSTR" select failed %d\n",
|
|
DBGSTR( (LPCTSTR)_pPrinterData->strDriverName( )),
|
|
iSelectResult ));
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
TPrinterGeneral::
|
|
vReadUI(
|
|
VOID
|
|
)
|
|
{
|
|
if( !bGetEditText( _hDlg, IDC_COMMENT, _pPrinterData->strComment( )) ||
|
|
!bGetEditText( _hDlg, IDC_LOCATION, _pPrinterData->strLocation( )) ||
|
|
!bGetEditText( _hDlg, IDC_DRIVER_NAME, _pPrinterData->strDriverName( ))){
|
|
|
|
_pPrinterData->_bErrorSaving = FALSE;
|
|
|
|
//
|
|
// Unable to read the text.
|
|
//
|
|
vShowResourceError( _hDlg );
|
|
}
|
|
}
|
|
|
|
VOID
|
|
TPrinterGeneral::
|
|
vSeparatorPage(
|
|
VOID
|
|
)
|
|
{
|
|
//
|
|
// Create separator page dialog.
|
|
//
|
|
TSeparatorPage SeparatorPage( _hDlg,
|
|
_pPrinterData->strSepFile(),
|
|
_pPrinterData->bAdministrator(),
|
|
_pPrinterData->strServerName().bEmpty() );
|
|
//
|
|
// Check if separator page dialog created ok.
|
|
//
|
|
if( !VALID_OBJ( SeparatorPage )){
|
|
|
|
iMessage( _hDlg,
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
TSeparatorPage::kErrorMessage,
|
|
MB_OK|MB_ICONHAND,
|
|
kMsgNone,
|
|
NULL );
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Interact with the separator page.
|
|
//
|
|
if( SeparatorPage.bDoModal() ){
|
|
|
|
//
|
|
// Assign back the separator page.
|
|
//
|
|
if( !_pPrinterData->strSepFile().bUpdate( SeparatorPage.strSeparatorPage() ) ){
|
|
vShowResourceError( _hDlg );
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID
|
|
TPrinterGeneral::
|
|
vPrintProcessor(
|
|
VOID
|
|
)
|
|
{
|
|
//
|
|
// Create print processor dialog.
|
|
//
|
|
TPrintProcessor PrintProcessor( _hDlg,
|
|
_pPrinterData->strServerName(),
|
|
_pPrinterData->strPrintProcessor(),
|
|
_pPrinterData->strDatatype(),
|
|
_pPrinterData->bAdministrator(),
|
|
_pPrinterData->dwAttributes() & PRINTER_ATTRIBUTE_RAW_ONLY );
|
|
//
|
|
// Check if print processor dialog was created ok.
|
|
//
|
|
if( !VALID_OBJ( PrintProcessor )){
|
|
|
|
iMessage( _hDlg,
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
TPrintProcessor::kErrorMessage,
|
|
MB_OK|MB_ICONHAND,
|
|
kMsgNone,
|
|
NULL );
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Interact with the print processor page.
|
|
//
|
|
if( PrintProcessor.bDoModal() ){
|
|
|
|
//
|
|
// Assign back the spool raw attribute.
|
|
//
|
|
if( PrintProcessor.bSpoolRaw() ){
|
|
_pPrinterData->dwAttributes() |= PRINTER_ATTRIBUTE_RAW_ONLY;
|
|
} else {
|
|
_pPrinterData->dwAttributes() &= ~PRINTER_ATTRIBUTE_RAW_ONLY;
|
|
}
|
|
|
|
//
|
|
// Assign back the print proccesor and data type.
|
|
//
|
|
if( !_pPrinterData->strPrintProcessor().bUpdate( PrintProcessor.strPrintProcessor() ) ||
|
|
!_pPrinterData->strDatatype().bUpdate( PrintProcessor.strDatatype() ) ){
|
|
|
|
vShowResourceError( _hDlg );
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
BOOL
|
|
TPrinterGeneral::
|
|
bHandleMessage(
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam
|
|
)
|
|
{
|
|
TStatusB bStatus;
|
|
|
|
bStatus DBGNOCHK = TRUE;
|
|
|
|
switch( uMsg ){
|
|
case WM_INITDIALOG:
|
|
|
|
bStatus DBGCHK = bSetUI();
|
|
break;
|
|
|
|
case WM_HELP:
|
|
case WM_CONTEXTMENU:
|
|
|
|
bStatus DBGCHK = PrintUIHelp( uMsg, _hDlg, wParam, lParam );
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
|
|
//
|
|
// Multiline edit controls send WM_CLOSE to dismiss the dialog.
|
|
// Convert it to a property-page friendly message.
|
|
//
|
|
PropSheet_PressButton( GetParent( _hDlg ), PSBTN_CANCEL );
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
|
|
vFreeIcon();
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
|
|
switch( GET_WM_COMMAND_ID( wParam, lParam )){
|
|
case IDC_SEPARATOR:
|
|
|
|
vSeparatorPage();
|
|
break;
|
|
|
|
case IDC_PRINT_PROC:
|
|
|
|
vPrintProcessor();
|
|
break;
|
|
|
|
case IDC_TEST:
|
|
|
|
bPrintTestPage( _hDlg, _pPrinterData->strPrinterName() );
|
|
break;
|
|
|
|
case IDC_DRIVER_NEW:
|
|
|
|
vChangeDriver( FALSE );
|
|
break;
|
|
|
|
case IDC_DRIVER_NAME:
|
|
|
|
vHandleDriverSelectionChange( wParam, lParam );
|
|
break;
|
|
|
|
default:
|
|
|
|
bStatus DBGNOCHK = FALSE;
|
|
break;
|
|
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
{
|
|
if( wParam ){
|
|
break;
|
|
}
|
|
|
|
LPNMHDR pnmh = (LPNMHDR)lParam;
|
|
|
|
switch( pnmh->code ){
|
|
case PSN_SETACTIVE:
|
|
|
|
vSetIconName();
|
|
break;
|
|
|
|
case PSN_KILLACTIVE:
|
|
|
|
vReadUI();
|
|
break;
|
|
|
|
//
|
|
// Total hack until common ui is online.
|
|
//
|
|
case PSN_APPLY:
|
|
_pPrinterData->_bValid = 2;
|
|
break;
|
|
|
|
default:
|
|
bStatus DBGNOCHK = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
bStatus DBGNOCHK = FALSE;
|
|
break;
|
|
|
|
}
|
|
|
|
return bStatus;
|
|
}
|
|
|
|
|
|
VOID
|
|
TPrinterGeneral::
|
|
vHandleDriverSelectionChange(
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Handle the driver selection change. This routine handles
|
|
changing of the driver from the keyboard. If the dropdown
|
|
combo box is droped, allow the up down arrow keys to move the
|
|
selection. When the drop down changes from the dropped state
|
|
to the up state indicate a selection change.
|
|
|
|
Arguments:
|
|
|
|
wParam - Parameter passed to by dialog proc.
|
|
lParam - Parameter passed to by dialog proc.
|
|
|
|
Return Value:
|
|
|
|
Nothing.
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// If a drop down state occurred, save droped down state.
|
|
//
|
|
if( GET_WM_COMMAND_CMD( wParam, lParam ) == CBN_DROPDOWN ){
|
|
_bDropDownState = TRUE;
|
|
|
|
//
|
|
// If the droped down state is now closed, change state and
|
|
// force a selection change.
|
|
//
|
|
} else if( GET_WM_COMMAND_CMD( wParam, lParam ) == CBN_CLOSEUP ){
|
|
|
|
_bDropDownState = FALSE;
|
|
vChangeDriver( TRUE );
|
|
|
|
//
|
|
// If not droped down look for a selection change.
|
|
//
|
|
} else if( !_bDropDownState ){
|
|
|
|
//
|
|
// If a selection chagned up date the driver.
|
|
//
|
|
if( GET_WM_COMMAND_CMD( wParam, lParam ) == CBN_SELCHANGE ){
|
|
vChangeDriver( TRUE );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
TPrinterGeneral::
|
|
vChangeDriver(
|
|
IN BOOL bUseSelection
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Change the selected driver (prompting the user with the device
|
|
selection dialog if necessary), then dismiss the current dialog
|
|
and bring up the new one.
|
|
|
|
Arguments:
|
|
|
|
bUseSelection - If TRUE, indicates the user has selected a new
|
|
driver in the combobox. If FALSE, indicates that we should
|
|
prompt using the device selection dialog.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
TString strDriverName;
|
|
TString strPrinterName;
|
|
|
|
//
|
|
// If user has selected a new driver from the combobox.
|
|
//
|
|
if( bUseSelection ){
|
|
|
|
//
|
|
// Check if the new driver name matches the current driver name.
|
|
//
|
|
if( !bGetEditText( _hDlg, IDC_DRIVER_NAME, strDriverName ) ){
|
|
|
|
vShowResourceError( _hDlg );
|
|
return;
|
|
|
|
} else if( _pPrinterData->strDriverName() == strDriverName ) {
|
|
|
|
return;
|
|
|
|
}
|
|
}
|
|
|
|
//
|
|
// Propmt user indicating that the setting will change the
|
|
// property sheets thus adding or removing pages.
|
|
//
|
|
if( IDYES != iMessage( _hDlg,
|
|
IDS_PRINTER,
|
|
IDS_DRIVER_CHANGE,
|
|
MB_YESNO|MB_ICONEXCLAMATION,
|
|
kMsgNone,
|
|
NULL )){
|
|
|
|
//
|
|
// Set the previous driver if use answers no.
|
|
//
|
|
ComboBox_SelectString( GetDlgItem( _hDlg, IDC_DRIVER_NAME ),
|
|
-1,
|
|
(LPCTSTR)_pPrinterData->strDriverName() );
|
|
return;
|
|
}
|
|
|
|
//
|
|
// New driver installation selected.
|
|
//
|
|
if( !bUseSelection ){
|
|
|
|
TCHAR szDriverName[kPrinterBufMax];
|
|
|
|
//
|
|
// Setup a new driver.
|
|
//
|
|
INT iStatus;
|
|
iStatus = iSetupNewDriver( _hDlg,
|
|
_pPrinterData->pszServerName( ),
|
|
FALSE,
|
|
szDriverName );
|
|
//
|
|
// If new driver installed ok update the combo box.
|
|
//
|
|
if( iStatus == kSetupNewDriverSuccess ){
|
|
|
|
//
|
|
// If a new driver was added, check if it already exists in the
|
|
// the list of drivers.
|
|
//
|
|
if( SendDlgItemMessage( _hDlg,
|
|
IDC_DRIVER_NAME,
|
|
CB_FINDSTRINGEXACT,
|
|
(WPARAM)-1,
|
|
(LPARAM)szDriverName ) == CB_ERR ){
|
|
//
|
|
// Add the the new driver to the combo box.
|
|
//
|
|
ComboBox_AddString( GetDlgItem( _hDlg, IDC_DRIVER_NAME ), szDriverName );
|
|
}
|
|
|
|
//
|
|
// Set flag to change driver selection.
|
|
//
|
|
bUseSelection = TRUE;
|
|
|
|
//
|
|
// Update the driver name.
|
|
//
|
|
if( !strDriverName.bUpdate( szDriverName ) ){
|
|
vShowResourceError( _hDlg );
|
|
return;
|
|
}
|
|
|
|
} else {
|
|
|
|
//
|
|
// Driver load failed display error message to user.
|
|
//
|
|
if( iStatus == kSetupNewDriverError ){
|
|
|
|
iMessage( _hDlg,
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
IDS_ERR_CHANGE_DRIVER,
|
|
MB_OK|MB_ICONSTOP,
|
|
kMsgNone,
|
|
NULL );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Driver selection changed.
|
|
//
|
|
if( bUseSelection ){
|
|
|
|
TCHAR szNewName[kPrinterBufMax];
|
|
|
|
//
|
|
// Check if the printer name should change. We change the printer name if
|
|
// the driver name is a sub string of the current printer name, and it is
|
|
// not a remote printer connection. There is not an explicit check if it
|
|
// is a remote printer connection since a remote printer connection will have
|
|
// the \\machine\printer name and therefore will never match
|
|
// the with the driver name.
|
|
//
|
|
if( !_tcsnicmp( _pPrinterData->strPrinterName(),
|
|
_pPrinterData->strDriverName(),
|
|
_tcslen( _pPrinterData->strDriverName() ) ) ){
|
|
|
|
//
|
|
// If a new friendly name was created then update the
|
|
// printer name.
|
|
//
|
|
if( NewFriendlyName( _pPrinterData->pszServerName(),
|
|
(LPTSTR)(LPCTSTR)strDriverName,
|
|
szNewName ) ){
|
|
//
|
|
// Update the new unique name.
|
|
//
|
|
if( !strPrinterName.bUpdate( szNewName ) ){
|
|
vShowResourceError( _hDlg );
|
|
return;
|
|
}
|
|
|
|
} else {
|
|
|
|
//
|
|
// The original new name will do.
|
|
//
|
|
if( !strPrinterName.bUpdate( strDriverName ) ){
|
|
vShowResourceError( _hDlg );
|
|
return;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
//
|
|
// Printer will not be changed use the existing name.
|
|
//
|
|
if( !strPrinterName.bUpdate( _pPrinterData->_strPrinterName ) ){
|
|
vShowResourceError( _hDlg );
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Driver selection changed, we will remove the driver
|
|
// property pages and then recreate them.
|
|
//
|
|
if( !_pPrinterData->bChangeDriver( _hDlg,
|
|
strDriverName,
|
|
strPrinterName ) ){
|
|
//
|
|
// Driver load failed display error message to user, indicating
|
|
// the driver could not be changed.
|
|
//
|
|
iMessage( _hDlg,
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
IDS_ERR_CHANGE_DRIVER,
|
|
MB_OK|MB_ICONSTOP,
|
|
kMsgNone,
|
|
NULL );
|
|
}
|
|
|
|
//
|
|
// Update the icon and name they may have changed,.
|
|
//
|
|
vSetIconName();
|
|
}
|
|
|
|
//
|
|
// Set the driver name this may be the old or the new driver name.
|
|
//
|
|
ComboBox_SelectString( GetDlgItem( _hDlg, IDC_DRIVER_NAME ),
|
|
-1,
|
|
(LPCTSTR)_pPrinterData->strDriverName() );
|
|
|
|
}
|
|
|
|
|
|
/********************************************************************
|
|
|
|
Printer Ports.
|
|
|
|
********************************************************************/
|
|
|
|
TPrinterPorts::
|
|
TPrinterPorts(
|
|
TPrinterData* pPrinterData
|
|
) : TPrinterProp( pPrinterData )
|
|
{
|
|
}
|
|
|
|
TPrinterPorts::
|
|
~TPrinterPorts(
|
|
VOID
|
|
)
|
|
{
|
|
}
|
|
|
|
BOOL
|
|
TPrinterPorts::
|
|
bValid(
|
|
VOID
|
|
)
|
|
{
|
|
return TPrinterProp::bValid() && _PortsLV.bValid();
|
|
}
|
|
|
|
BOOL
|
|
TPrinterPorts::
|
|
bSetUI(
|
|
VOID
|
|
)
|
|
{
|
|
//
|
|
// Update the name and icon.
|
|
//
|
|
vSetIconName();
|
|
|
|
HWND hwndLV = GetDlgItem( _hDlg, IDC_PORTS );
|
|
SPLASSERT( hwndLV );
|
|
|
|
if( !_PortsLV.bSetUI( hwndLV )){
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Load the machine's ports into the listview.
|
|
//
|
|
if( !_PortsLV.bReloadPorts( _pPrinterData->pszServerName( ) ) ){
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Select the current printer's ports.
|
|
//
|
|
_PortsLV.vCheckPorts((LPTSTR)(LPCTSTR)_pPrinterData->strPortName( ));
|
|
|
|
//
|
|
// Check if there are multiple ports selected.
|
|
//
|
|
BOOL bPooledPrinting = ( _PortsLV.cSelectedPorts() > 1 );
|
|
|
|
//
|
|
// Set the ports list view to single selection mode.
|
|
//
|
|
_PortsLV.vSetSingleSelection( !bPooledPrinting );
|
|
|
|
//
|
|
// Set the pooled printing mode on the UI.
|
|
//
|
|
vSetCheck( _hDlg, IDC_POOLED_PRINTING, bPooledPrinting );
|
|
|
|
//
|
|
// Adding / deleting / configuring ports is
|
|
// currently not supported remotely.
|
|
//
|
|
if( !_pPrinterData->bAdministrator( ) ||
|
|
_pPrinterData->pszServerName( ) ){
|
|
|
|
//
|
|
// Disable things if not administrator.
|
|
//
|
|
static UINT auAvailable[] = {
|
|
IDC_PORT_CREATE,
|
|
IDC_PORT_DELETE,
|
|
IDC_PROPERTIES,
|
|
0
|
|
};
|
|
|
|
COUNT i;
|
|
for( i=0; auAvailable[i]; ++i ){
|
|
vEnableCtl( _hDlg, auAvailable[i], FALSE );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Disable bidi selection if not an administrator.
|
|
// Disable printer pooling if not an administrator.
|
|
//
|
|
vEnableCtl( _hDlg, IDC_ENABLE_BIDI, _pPrinterData->bAdministrator( ) );
|
|
vEnableCtl( _hDlg, IDC_POOLED_PRINTING, _pPrinterData->bAdministrator( ) );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
VOID
|
|
TPrinterPorts::
|
|
vReadUI(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Gets the ports from the listview and create the string.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// Read bidi options.
|
|
//
|
|
DWORD dwAttributes = _pPrinterData->dwAttributes();
|
|
|
|
if( BST_CHECKED == IsDlgButtonChecked( _hDlg, IDC_ENABLE_BIDI )){
|
|
dwAttributes |= PRINTER_ATTRIBUTE_ENABLE_BIDI;
|
|
} else {
|
|
dwAttributes &= ~PRINTER_ATTRIBUTE_ENABLE_BIDI;
|
|
}
|
|
|
|
_pPrinterData->_dwAttributes = dwAttributes;
|
|
|
|
//
|
|
// Build the ports string.
|
|
//
|
|
if( !_PortsLV.bReadUI( &_pPrinterData->_strPortName )){
|
|
|
|
_pPrinterData->_bErrorSaving = TRUE;
|
|
vShowResourceError( _hDlg );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
VOID
|
|
TPrinterPorts::
|
|
vSetActive(
|
|
VOID
|
|
)
|
|
{
|
|
vSetIconName();
|
|
|
|
if( _pPrinterData->bRefreshBidi( )){
|
|
|
|
BOOL bEnable = FALSE;
|
|
BOOL bCheck = FALSE;
|
|
|
|
//
|
|
// If the call fails or the monitor name is NULL/szNULL,
|
|
// then disable bidi.
|
|
//
|
|
if( _pPrinterData->bSupportBidi( )){
|
|
|
|
bEnable = TRUE;
|
|
|
|
//
|
|
// Only set the checkbox if a language monitor is present.
|
|
// (When we change drivers, we always set this attribute
|
|
// bit, even if bidi isn't supported. The spooler and UI
|
|
// ignore it in this case.)
|
|
//
|
|
bCheck = _pPrinterData->dwAttributes() &
|
|
PRINTER_ATTRIBUTE_ENABLE_BIDI;
|
|
}
|
|
|
|
//
|
|
// Set bidi options.
|
|
//
|
|
vSetCheck( _hDlg, IDC_ENABLE_BIDI, bCheck );
|
|
|
|
//
|
|
// If we are an administrator and this is the local
|
|
// machine, we can enable the bidi control.
|
|
//
|
|
if( _pPrinterData->bAdministrator( ) ){
|
|
vEnableCtl( _hDlg, IDC_ENABLE_BIDI, bEnable );
|
|
}
|
|
|
|
_pPrinterData->bRefreshBidi() = FALSE;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
BOOL
|
|
TPrinterPorts::
|
|
bKillActive(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Validate that the printer page is in a consistent state.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
TRUE - Ok to kill active, FALSE = can't kill active, UI displayed.
|
|
|
|
--*/
|
|
|
|
{
|
|
BOOL bSuccess = FALSE;
|
|
|
|
//
|
|
// Validate that at least 1 port is selected.
|
|
//
|
|
if( _PortsLV.cSelectedPorts() == 0 ){
|
|
|
|
//
|
|
// Put up error explaining that at least one port must be
|
|
// selected.
|
|
//
|
|
iMessage( _hDlg,
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
IDS_ERR_NO_PORTS,
|
|
MB_OK|MB_ICONSTOP,
|
|
kMsgNone,
|
|
NULL );
|
|
|
|
_PortsLV.vSetFocus();
|
|
|
|
} else {
|
|
|
|
bSuccess = TRUE;
|
|
}
|
|
|
|
return bSuccess;
|
|
}
|
|
|
|
BOOL
|
|
TPrinterPorts::
|
|
bHandleMessage(
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Handle message.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
TStatusB bStatus;
|
|
|
|
bStatus DBGNOCHK = TRUE;
|
|
|
|
switch( uMsg ){
|
|
case WM_INITDIALOG:
|
|
|
|
bStatus DBGCHK = bSetUI();
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
|
|
vFreeIcon();
|
|
break;
|
|
|
|
case WM_HELP:
|
|
case WM_CONTEXTMENU:
|
|
|
|
PrintUIHelp( uMsg, _hDlg, wParam, lParam );
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
|
|
switch( GET_WM_COMMAND_ID( wParam, lParam )){
|
|
|
|
case IDC_PORT_DELETE:
|
|
|
|
_PortsLV.vDeletePort( _hDlg, _pPrinterData->pszServerName( ));
|
|
SetFocus( GetDlgItem( _hDlg, IDC_PORT_DELETE ) );
|
|
|
|
break;
|
|
|
|
case IDC_PROPERTIES:
|
|
|
|
//
|
|
// Get selected port. Nothing may be selected if there
|
|
// are no ports!
|
|
//
|
|
TCHAR szPortName[TPortsLV::kPortNameMax];
|
|
|
|
if( _PortsLV.bGetSelectedPort( szPortName, COUNTOF( szPortName ))){
|
|
|
|
TStatusB bStatus;
|
|
|
|
//
|
|
// Call Configure Port.
|
|
//
|
|
bStatus DBGCHK = ConfigurePort(
|
|
(LPTSTR)_pPrinterData->pszServerName(),
|
|
_hDlg,
|
|
szPortName );
|
|
//
|
|
// Change the focus to this button The configure
|
|
// port call is not returning the focus.
|
|
//
|
|
SetFocus( GetDlgItem( _hDlg, IDC_PROPERTIES ) );
|
|
|
|
if( !bStatus ){
|
|
|
|
iMessage( _hDlg,
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
IDS_ERR_CONFIG_PORT,
|
|
MB_OK|MB_ICONSTOP,
|
|
kMsgGetLastError,
|
|
NULL );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDC_PORT_CREATE:
|
|
{
|
|
//
|
|
// Create add ports class.
|
|
//
|
|
TAddPort AddPort( _hDlg,
|
|
_pPrinterData->pszServerName(),
|
|
_pPrinterData->bAdministrator() );
|
|
|
|
//
|
|
// Insure the add port was created successfully.
|
|
//
|
|
if( !VALID_OBJ( AddPort ) ){
|
|
|
|
vShowUnexpectedError( _hDlg, TAddPort::kErrorMessage );
|
|
bStatus DBGNOCHK = FALSE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Interact with the Add Ports dialog.
|
|
//
|
|
if( AddPort.bDoModal() ){
|
|
|
|
//
|
|
// Refresh machine's ports into the listview.
|
|
//
|
|
if( !_PortsLV.bReloadPorts( _pPrinterData->pszServerName( ), TRUE )){
|
|
bStatus DBGNOCHK = FALSE;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDC_POOLED_PRINTING:
|
|
{
|
|
//
|
|
// Get the current selection state.
|
|
//
|
|
BOOL bSingleSelection = _PortsLV.bGetSingleSelection();
|
|
|
|
//
|
|
// If we are going from pooled printing to non-pooled printing
|
|
// and the printer is currently being used by multiple ports, inform
|
|
// the user all the port selection will be lost.
|
|
//
|
|
if( !bSingleSelection &&
|
|
_PortsLV.cSelectedPorts() > 1 ){
|
|
|
|
INT iStatus = iMessage( _hDlg,
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
IDS_ERR_PORT_SEL_CHANGE,
|
|
MB_YESNO|MB_ICONEXCLAMATION,
|
|
kMsgNone,
|
|
NULL );
|
|
//
|
|
// If user does not want to do this.
|
|
//
|
|
if( iStatus != IDYES ){
|
|
vSetCheck( _hDlg, IDC_POOLED_PRINTING, !bSingleSelection );
|
|
bSingleSelection = !bSingleSelection;
|
|
//
|
|
// Remove all the port selections.
|
|
//
|
|
} else {
|
|
_PortsLV.vRemoveAllChecks();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set the new selection state.
|
|
//
|
|
_PortsLV.vSetSingleSelection( !bSingleSelection );
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
bStatus DBGNOCHK = FALSE;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
|
|
//
|
|
// Handle clicking of check boxes in ports listview.
|
|
//
|
|
switch( wParam ){
|
|
case IDC_PORTS:
|
|
|
|
//
|
|
// If not an admin, don't allow the user to change the state.
|
|
//
|
|
if( !_pPrinterData->bAdministrator( )){
|
|
break;
|
|
}
|
|
|
|
bStatus DBGNOCHK = _PortsLV.bHandleNotifyMessage( lParam );
|
|
break;
|
|
|
|
case 0:
|
|
{
|
|
LPNMHDR pnmh = (LPNMHDR)lParam;
|
|
|
|
switch( pnmh->code ){
|
|
case PSN_SETACTIVE:
|
|
|
|
vSetActive();
|
|
break;
|
|
|
|
case PSN_KILLACTIVE:
|
|
//
|
|
// Check if ok to loose the focus.
|
|
//
|
|
if( bKillActive( )){
|
|
|
|
vReadUI();
|
|
|
|
} else {
|
|
|
|
//
|
|
// Inform the propsheet whether it should not loose the focus.
|
|
//
|
|
vSetDlgMsgResult( TRUE );
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
bStatus DBGNOCHK = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
bStatus DBGNOCHK = FALSE;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
bStatus DBGNOCHK = FALSE;
|
|
break;
|
|
}
|
|
|
|
return bStatus;
|
|
}
|
|
|
|
|
|
/********************************************************************
|
|
|
|
JobScheduling.
|
|
|
|
********************************************************************/
|
|
|
|
TPrinterJobScheduling::
|
|
TPrinterJobScheduling(
|
|
TPrinterData* pPrinterData
|
|
) : TPrinterProp( pPrinterData )
|
|
{
|
|
}
|
|
|
|
TPrinterJobScheduling::
|
|
~TPrinterJobScheduling(
|
|
VOID
|
|
)
|
|
{
|
|
}
|
|
|
|
BOOL
|
|
TPrinterJobScheduling::
|
|
bValid(
|
|
VOID
|
|
)
|
|
{
|
|
return TPrinterProp::bValid() &&
|
|
_StartTime.bValid() &&
|
|
_UntilTime.bValid();
|
|
}
|
|
|
|
VOID
|
|
TPrinterJobScheduling::
|
|
vEnableAvailable(
|
|
IN BOOL bEnable
|
|
)
|
|
{
|
|
_StartTime.vEnable( bEnable );
|
|
_UntilTime.vEnable( bEnable );
|
|
}
|
|
|
|
|
|
VOID
|
|
TPrinterJobScheduling::
|
|
vUpdatePriorityNumber(
|
|
IN DWORD dwPriority
|
|
)
|
|
{
|
|
SPLASSERT( dwPriority >= kPriorityMin );
|
|
SPLASSERT( dwPriority <= kPriorityMax );
|
|
|
|
bSetEditTextFormat( _hDlg, IDC_PRIORITY_NUMBER, TEXT("%d"), dwPriority );
|
|
}
|
|
|
|
|
|
BOOL
|
|
TPrinterJobScheduling::
|
|
bSetUI(
|
|
VOID
|
|
)
|
|
{
|
|
//
|
|
// Set bAlways flag.
|
|
//
|
|
BOOL bAlways = ( _pPrinterData->dwStartTime() ==
|
|
_pPrinterData->dwUntilTime( ));
|
|
|
|
//
|
|
// Convert StartTime to SystemTime, init the dialogs.
|
|
//
|
|
if( !_StartTime.bLoad( _hDlg,
|
|
IDC_START_FRAME,
|
|
IDC_START_HOUR,
|
|
IDC_START_MIN,
|
|
IDC_NONE, // IDC_START_SEC,
|
|
IDC_START_SEP1,
|
|
IDC_NONE, // IDC_START_SEP2,
|
|
IDC_START_PREFIX,
|
|
IDC_START_SPIN,
|
|
_pPrinterData->bAdministrator( )) ||
|
|
|
|
!_UntilTime.bLoad( _hDlg,
|
|
IDC_UNTIL_FRAME,
|
|
IDC_UNTIL_HOUR,
|
|
IDC_UNTIL_MIN,
|
|
IDC_NONE, // IDC_UNTIL_SEC,
|
|
IDC_UNTIL_SEP1,
|
|
IDC_NONE, // IDC_UNTIL_SEP2,
|
|
IDC_UNTIL_PREFIX,
|
|
IDC_UNTIL_SPIN,
|
|
_pPrinterData->bAdministrator( ))){
|
|
|
|
DBGMSG( DBG_ERROR, ( "PrinterJobScheduling.bSetUI: Time initialization failed %d\n", GetLastError( )));
|
|
return FALSE;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Convert from minutes to system time.
|
|
//
|
|
SYSTEMTIME StartTime;
|
|
DWORD dwLocalStartTime;
|
|
ZeroMemory( &StartTime, sizeof( StartTime ));
|
|
if( !bAlways )
|
|
dwLocalStartTime = SystemTimeToLocalTime( _pPrinterData->_dwStartTime );
|
|
else
|
|
dwLocalStartTime = 0;
|
|
StartTime.wHour = (WORD)(dwLocalStartTime / 60);
|
|
StartTime.wMinute = (WORD)(dwLocalStartTime % 60);
|
|
|
|
//
|
|
// Convert from minutes to system time.
|
|
//
|
|
SYSTEMTIME UntilTime;
|
|
DWORD dwLocalUntilTime;
|
|
ZeroMemory( &UntilTime, sizeof( UntilTime ));
|
|
if( !bAlways )
|
|
dwLocalUntilTime = SystemTimeToLocalTime( _pPrinterData->_dwUntilTime );
|
|
else
|
|
dwLocalUntilTime = 0;
|
|
UntilTime.wHour = (WORD)(dwLocalUntilTime / 60);
|
|
UntilTime.wMinute = (WORD)(dwLocalUntilTime % 60);
|
|
|
|
//
|
|
// Set the start and until to the specified time.
|
|
//
|
|
if( !_StartTime.bSetTime( &StartTime ) ||
|
|
!_UntilTime.bSetTime( &UntilTime )){
|
|
|
|
DBGMSG( DBG_ERROR, ( "PrinterJobScheduling.bSetTime failed.\n" ) );
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set Availability radio buttons.
|
|
//
|
|
vSetCheck( _hDlg, bAlways ? IDC_ALWAYS : IDC_START, TRUE );
|
|
|
|
if( !_pPrinterData->bAdministrator( )){
|
|
vEnableAvailable( FALSE );
|
|
} else {
|
|
vEnableAvailable( !bAlways );
|
|
}
|
|
|
|
//
|
|
// Set the priority range.
|
|
//
|
|
SendMessage( _hwndSlider,
|
|
TBM_SETRANGE,
|
|
FALSE,
|
|
MAKELONG( kPriorityMin, kPriorityMax ));
|
|
|
|
//
|
|
// !! POLICY !!
|
|
//
|
|
// What do we do if dwPriority is out of bounds?
|
|
//
|
|
DWORD dwPriority = _pPrinterData->dwPriority();
|
|
|
|
if( dwPriority < kPriorityMin ){
|
|
|
|
DBGMSG( DBG_WARN,
|
|
( "PrinterJobScheduling.vLoadState: dwPriority %d < %d\n",
|
|
dwPriority, kPriorityMin ));
|
|
|
|
dwPriority = kPriorityMin;
|
|
}
|
|
|
|
if( dwPriority > kPriorityMax ){
|
|
|
|
DBGMSG( DBG_WARN,
|
|
( "PrinterJobScheduling.vLoadState: dwPriority %d > %d\n",
|
|
dwPriority, kPriorityMax ));
|
|
|
|
dwPriority = kPriorityMax;
|
|
}
|
|
|
|
SendMessage( _hwndSlider,
|
|
TBM_SETPOS,
|
|
TRUE,
|
|
dwPriority );
|
|
|
|
vUpdatePriorityNumber( dwPriority );
|
|
|
|
DWORD dwAttributes = _pPrinterData->dwAttributes();
|
|
|
|
vSetCheck( _hDlg,
|
|
IDC_DEVQUERYPRINT,
|
|
dwAttributes & PRINTER_ATTRIBUTE_ENABLE_DEVQ );
|
|
|
|
vSetCheck( _hDlg,
|
|
IDC_PRINT_SPOOLED_FIRST,
|
|
dwAttributes & PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST );
|
|
|
|
vSetCheck( _hDlg,
|
|
IDC_KEEP_PRINTED_JOBS,
|
|
dwAttributes & PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS );
|
|
|
|
//
|
|
// Set spool radio buttons.
|
|
// bQueued -> Spool entire document.
|
|
// both -> Spool entire document.
|
|
// neither -> Spool and print after first page.
|
|
// bDirect -> Direct.
|
|
//
|
|
BOOL bSpool = !( dwAttributes & PRINTER_ATTRIBUTE_DIRECT ) ||
|
|
( dwAttributes & PRINTER_ATTRIBUTE_QUEUED );
|
|
|
|
vSetCheck( _hDlg,
|
|
bSpool ?
|
|
IDC_SPOOL :
|
|
IDC_PRINT_DIRECT,
|
|
TRUE );
|
|
|
|
vSetCheck( _hDlg,
|
|
( dwAttributes & PRINTER_ATTRIBUTE_QUEUED ) ?
|
|
IDC_SPOOL_ALL :
|
|
IDC_SPOOL_PRINT_FASTER,
|
|
TRUE );
|
|
|
|
vEnableCtl( _hDlg, IDC_SPOOL_ALL, bSpool );
|
|
vEnableCtl( _hDlg, IDC_SPOOL_PRINT_FASTER, bSpool );
|
|
vEnableCtl( _hDlg, IDC_PRINT_SPOOLED_FIRST, bSpool );
|
|
vEnableCtl( _hDlg, IDC_DEVQUERYPRINT, bSpool );
|
|
vEnableCtl( _hDlg, IDC_KEEP_PRINTED_JOBS, bSpool );
|
|
|
|
//
|
|
// Enable appropriately.
|
|
//
|
|
static UINT auControl[] = {
|
|
IDC_ALWAYS,
|
|
IDC_START,
|
|
IDC_PRIORITY_SLIDER,
|
|
IDC_SPOOL,
|
|
IDC_SPOOL_ALL,
|
|
IDC_SPOOL_PRINT_FASTER,
|
|
IDC_PRINT_DIRECT,
|
|
IDC_DEVQUERYPRINT,
|
|
IDC_PRINT_SPOOLED_FIRST,
|
|
IDC_KEEP_PRINTED_JOBS,
|
|
0
|
|
};
|
|
|
|
COUNT i;
|
|
if( !_pPrinterData->bAdministrator( )){
|
|
for( i=0; auControl[i]; ++i ){
|
|
vEnableCtl( _hDlg, auControl[i], FALSE );
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
VOID
|
|
TPrinterJobScheduling::
|
|
vReadUI(
|
|
VOID
|
|
)
|
|
{
|
|
DWORD dwPriority = SendDlgItemMessage( _hDlg,
|
|
IDC_PRIORITY_SLIDER,
|
|
TBM_GETPOS,
|
|
0,
|
|
0 );
|
|
|
|
SPLASSERT( dwPriority >= kPriorityMin );
|
|
SPLASSERT( dwPriority <= kPriorityMax );
|
|
|
|
_pPrinterData->_dwPriority = dwPriority;
|
|
|
|
DWORD dwAttributes = _pPrinterData->dwAttributes();
|
|
|
|
//
|
|
// Mask out attributes we are going to read back.
|
|
//
|
|
dwAttributes &= ~( PRINTER_ATTRIBUTE_ENABLE_DEVQ |
|
|
PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST |
|
|
PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS |
|
|
PRINTER_ATTRIBUTE_QUEUED |
|
|
PRINTER_ATTRIBUTE_DIRECT );
|
|
|
|
if( BST_CHECKED == IsDlgButtonChecked( _hDlg, IDC_DEVQUERYPRINT )){
|
|
dwAttributes |= PRINTER_ATTRIBUTE_ENABLE_DEVQ;
|
|
}
|
|
|
|
if( BST_CHECKED == IsDlgButtonChecked( _hDlg, IDC_PRINT_SPOOLED_FIRST )){
|
|
dwAttributes |= PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST;
|
|
}
|
|
|
|
if( BST_CHECKED == IsDlgButtonChecked( _hDlg, IDC_KEEP_PRINTED_JOBS )){
|
|
dwAttributes |= PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS;
|
|
}
|
|
|
|
//
|
|
// Get radio buttons. If direct is selected, then ignore
|
|
// all the other spool fields.
|
|
//
|
|
if( BST_CHECKED == IsDlgButtonChecked( _hDlg, IDC_PRINT_DIRECT )){
|
|
|
|
//
|
|
// Direct, no spooling options selected.
|
|
//
|
|
dwAttributes |= PRINTER_ATTRIBUTE_DIRECT;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Spool, print after last page -> QUEUED.
|
|
// Spool, print after first page -> neither.
|
|
//
|
|
if( BST_CHECKED == IsDlgButtonChecked( _hDlg, IDC_SPOOL_ALL )){
|
|
dwAttributes |= PRINTER_ATTRIBUTE_QUEUED;
|
|
}
|
|
}
|
|
|
|
_pPrinterData->_dwAttributes = dwAttributes;
|
|
|
|
//
|
|
// Get availability time if the printer is always
|
|
// available then set the time to no time restriction.
|
|
//
|
|
if( bGetCheck( _hDlg, IDC_ALWAYS ) ){
|
|
|
|
_pPrinterData->_dwStartTime = 0;
|
|
_pPrinterData->_dwUntilTime = 0;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Get the Start time.
|
|
//
|
|
SYSTEMTIME StartTime;
|
|
_StartTime.bGetTime( &StartTime );
|
|
_pPrinterData->_dwStartTime = LocalTimeToSystemTime( StartTime.wHour * 60 + StartTime.wMinute );
|
|
|
|
//
|
|
// Get the Until time.
|
|
//
|
|
SYSTEMTIME UntilTime;
|
|
_UntilTime.bGetTime( &UntilTime );
|
|
_pPrinterData->_dwUntilTime = LocalTimeToSystemTime( UntilTime.wHour * 60 + UntilTime.wMinute );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BOOL
|
|
TPrinterJobScheduling::
|
|
bHandleMessage(
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam
|
|
)
|
|
{
|
|
TStatusB bStatus;
|
|
bStatus DBGNOCHK = TRUE;
|
|
|
|
switch( uMsg ){
|
|
case WM_INITDIALOG:
|
|
|
|
_hwndSlider = GetDlgItem( _hDlg, IDC_PRIORITY_SLIDER );
|
|
SPLASSERT( _hwndSlider );
|
|
|
|
bStatus DBGCHK = bSetUI();
|
|
|
|
break;
|
|
|
|
case WM_HSCROLL:
|
|
|
|
//
|
|
// Check for slider notification.
|
|
//
|
|
if( GET_WM_HSCROLL_HWND( wParam, lParam ) == _hwndSlider ){
|
|
vUpdatePriorityNumber( SendMessage( _hwndSlider,
|
|
TBM_GETPOS,
|
|
0,
|
|
0 ));
|
|
}
|
|
break;
|
|
|
|
case WM_HELP:
|
|
case WM_CONTEXTMENU:
|
|
|
|
PrintUIHelp( uMsg, _hDlg, wParam, lParam );
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
|
|
switch( GET_WM_COMMAND_ID( wParam, lParam )){
|
|
case IDC_SPOOL:
|
|
|
|
vEnableCtl( _hDlg, IDC_SPOOL_ALL, TRUE );
|
|
vEnableCtl( _hDlg, IDC_SPOOL_PRINT_FASTER, TRUE );
|
|
vEnableCtl( _hDlg, IDC_PRINT_SPOOLED_FIRST, TRUE );
|
|
vEnableCtl( _hDlg, IDC_DEVQUERYPRINT, TRUE );
|
|
vEnableCtl( _hDlg, IDC_KEEP_PRINTED_JOBS, TRUE );
|
|
break;
|
|
|
|
case IDC_PRINT_DIRECT:
|
|
|
|
vEnableCtl( _hDlg, IDC_SPOOL_ALL, FALSE );
|
|
vEnableCtl( _hDlg, IDC_SPOOL_PRINT_FASTER, FALSE );
|
|
vEnableCtl( _hDlg, IDC_PRINT_SPOOLED_FIRST, FALSE );
|
|
vEnableCtl( _hDlg, IDC_DEVQUERYPRINT, FALSE );
|
|
vEnableCtl( _hDlg, IDC_KEEP_PRINTED_JOBS, FALSE );
|
|
break;
|
|
|
|
case IDC_ALWAYS:
|
|
|
|
vEnableAvailable( FALSE );
|
|
break;
|
|
|
|
case IDC_START:
|
|
|
|
vEnableAvailable( TRUE );
|
|
break;
|
|
|
|
default:
|
|
|
|
bStatus DBGNOCHK = FALSE;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
if( wParam ){
|
|
bStatus DBGNOCHK = FALSE;
|
|
break;
|
|
}
|
|
|
|
{
|
|
LPNMHDR pnmh = (LPNMHDR)lParam;
|
|
|
|
switch( pnmh->code ){
|
|
case PSN_KILLACTIVE:
|
|
|
|
vReadUI();
|
|
break;
|
|
|
|
//
|
|
// Total hack until common ui is online.
|
|
//
|
|
case PSN_APPLY:
|
|
_pPrinterData->_bValid = 2;
|
|
break;
|
|
|
|
default:
|
|
|
|
bStatus DBGNOCHK = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
bStatus DBGNOCHK = FALSE;
|
|
break;
|
|
|
|
}
|
|
|
|
//
|
|
// If the message was handle just return.
|
|
//
|
|
if( bStatus != FALSE )
|
|
return bStatus;
|
|
|
|
//
|
|
// Must allow the time control object to get messages.
|
|
//
|
|
bStatus DBGNOCHK = _StartTime.bHandleMessage( uMsg, wParam, lParam );
|
|
if( bStatus != FALSE )
|
|
return bStatus;
|
|
|
|
//
|
|
// Must allow the time control object to get messages.
|
|
//
|
|
bStatus DBGNOCHK = _UntilTime.bHandleMessage( uMsg, wParam, lParam );
|
|
if( bStatus != FALSE )
|
|
return bStatus;
|
|
|
|
return bStatus;
|
|
}
|
|
|
|
/********************************************************************
|
|
|
|
Sharing.
|
|
|
|
********************************************************************/
|
|
|
|
TPrinterSharing::
|
|
TPrinterSharing(
|
|
TPrinterData* pPrinterData
|
|
) : TPrinterProp( pPrinterData ),
|
|
_pPrtShare( NULL )
|
|
{
|
|
}
|
|
|
|
TPrinterSharing::
|
|
~TPrinterSharing(
|
|
VOID
|
|
)
|
|
{
|
|
delete _pPrtShare;
|
|
}
|
|
|
|
BOOL
|
|
TPrinterSharing::
|
|
bValid(
|
|
VOID
|
|
)
|
|
{
|
|
return TPrinterProp::bValid() && _Architecture.bValid();
|
|
}
|
|
|
|
VOID
|
|
TPrinterSharing::
|
|
vSharePrinter(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
User clicked share radio button. Change the UI appropriately.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// Set radio button and possibly enable window.
|
|
//
|
|
CheckRadioButton( _hDlg, IDC_SHARED_OFF, IDC_SHARED, IDC_SHARED );
|
|
|
|
if( _pPrinterData->bAdministrator( )){
|
|
|
|
//
|
|
// Set the default share name.
|
|
//
|
|
vSetDefaultShareName();
|
|
|
|
HWND hCtl = GetDlgItem( _hDlg, IDC_SHARED_NAME );
|
|
|
|
vEnableCtl( _hDlg, IDC_SHARED_NAME, TRUE );
|
|
SetFocus( hCtl );
|
|
Edit_SetSel( hCtl, 0, -1 );
|
|
|
|
//
|
|
// Disable the install architecutre UI.
|
|
//
|
|
_Architecture.vEnable();
|
|
|
|
}
|
|
}
|
|
|
|
VOID
|
|
TPrinterSharing::
|
|
vUnsharePrinter(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
User clicked don't share radio button. Change the UI appropriately.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// Set radio button and disable window.
|
|
//
|
|
CheckRadioButton( _hDlg, IDC_SHARED_OFF, IDC_SHARED, IDC_SHARED_OFF );
|
|
vEnableCtl( _hDlg, IDC_SHARED_NAME, FALSE );
|
|
|
|
//
|
|
// Enable the architecture installation.
|
|
//
|
|
_Architecture.vDisable();
|
|
|
|
}
|
|
|
|
VOID
|
|
TPrinterSharing::
|
|
vSetDefaultShareName(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets the default share name if use has choosen to share
|
|
this printer. We will update the share name if
|
|
this is the first time setting the share name.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Nothing.
|
|
|
|
--*/
|
|
{
|
|
TStatusB bStatus;
|
|
TString strShareName;
|
|
|
|
//
|
|
// Read the current contents of the edit control.
|
|
//
|
|
bStatus DBGCHK = bGetEditText( _hDlg,
|
|
IDC_SHARED_NAME,
|
|
strShareName );
|
|
|
|
DBGMSG( DBG_TRACE, ( "strShareName " TSTR "\n", (LPCTSTR)strShareName ) );
|
|
|
|
//
|
|
// Create a share name if the current edit field is empty.
|
|
//
|
|
if( strShareName.bEmpty() ){
|
|
|
|
//
|
|
// If the share object has not be constructed, then
|
|
// construct it.
|
|
//
|
|
if( !_pPrtShare ){
|
|
_pPrtShare = new TPrtShare( _pPrinterData->pszServerName() );
|
|
}
|
|
|
|
//
|
|
// Ensure the share object is still valid.
|
|
//
|
|
if( VALID_PTR( _pPrtShare ) ){
|
|
|
|
//
|
|
// Get just the printer name.
|
|
//
|
|
LPCTSTR pszServer;
|
|
LPCTSTR pszPrinter;
|
|
TCHAR szScratch[kPrinterBufMax];
|
|
|
|
vPrinterSplitFullName( szScratch,
|
|
_pPrinterData->strPrinterName( ),
|
|
&pszServer,
|
|
&pszPrinter );
|
|
|
|
//
|
|
// Create valid unique share name.
|
|
//
|
|
bStatus DBGNOCHK = _pPrtShare->bNewShareName( strShareName,
|
|
pszPrinter );
|
|
//
|
|
// Set the default share name.
|
|
//
|
|
bStatus DBGCHK = bSetEditText( _hDlg,
|
|
IDC_SHARED_NAME,
|
|
strShareName );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
BOOL
|
|
TPrinterSharing::
|
|
bSetUI(
|
|
VOID
|
|
)
|
|
{
|
|
//
|
|
// Set the UI of the install architecture
|
|
//
|
|
if( !_Architecture.bSetUI( _hDlg,
|
|
IDC_DRIVER,
|
|
_pPrinterData->pszServerName(),
|
|
_pPrinterData->strDriverName(),
|
|
TRUE ) ){
|
|
//
|
|
// Install extra driver selection list failed.
|
|
//
|
|
iMessage( _hDlg,
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
IDS_ERR_SHARING_EXTRA_DRIVER_FAILED,
|
|
MB_OK|MB_ICONSTOP,
|
|
kMsgNone,
|
|
NULL );
|
|
}
|
|
|
|
//
|
|
// Set the icon and printer name.
|
|
//
|
|
vSetIconName();
|
|
|
|
//
|
|
// Set the printer share name limit. The limit in win9x is
|
|
// 8.3 == 12+1 chars (including NULL terminator). The Winnt limit
|
|
// is defined as NNLEN;
|
|
//
|
|
SendDlgItemMessage( _hDlg, IDC_SHARED_NAME,
|
|
EM_SETLIMITTEXT,
|
|
kPrinterShareNameMax,
|
|
0 );
|
|
|
|
//
|
|
// Update the fields.
|
|
//
|
|
bSetEditText( _hDlg, IDC_SHARED_NAME, _pPrinterData->strShareName( ));
|
|
|
|
//
|
|
// If not an administrator, disable the edit controls.
|
|
//
|
|
if( !_pPrinterData->bAdministrator( )){
|
|
|
|
static UINT auShared[] = {
|
|
IDC_SHARED_NAME,
|
|
IDC_SHARED_NAME_TEXT,
|
|
IDC_SHARED,
|
|
IDC_SHARED_OFF,
|
|
0
|
|
};
|
|
|
|
UINT i;
|
|
for( i=0; auShared[i]; ++i ){
|
|
vEnableCtl( _hDlg, auShared[i], FALSE );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Select correct radio button.
|
|
//
|
|
if( _pPrinterData->dwAttributes() & PRINTER_ATTRIBUTE_SHARED ){
|
|
vSharePrinter();
|
|
} else {
|
|
vUnsharePrinter();
|
|
}
|
|
|
|
//
|
|
// If not administrator disable the install architecture.
|
|
//
|
|
if( !_pPrinterData->bAdministrator( )){
|
|
_Architecture.vDisable();
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
TPrinterSharing::
|
|
vReadUI(
|
|
VOID
|
|
)
|
|
{
|
|
//
|
|
// Check if the printer has been shared.
|
|
//
|
|
if( BST_CHECKED == IsDlgButtonChecked( _hDlg, IDC_SHARED )){
|
|
|
|
//
|
|
// Indicate printer is shared.
|
|
//
|
|
_pPrinterData->dwAttributes() |= PRINTER_ATTRIBUTE_SHARED;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Indicate the printer is not share.
|
|
//
|
|
_pPrinterData->dwAttributes() &= ~PRINTER_ATTRIBUTE_SHARED;
|
|
|
|
}
|
|
|
|
//
|
|
// Get the share name form the edit control.
|
|
//
|
|
if( !bGetEditText( _hDlg, IDC_SHARED_NAME, _pPrinterData->strShareName( ))){
|
|
|
|
_pPrinterData->_bErrorSaving = TRUE;
|
|
vShowResourceError( _hDlg );
|
|
}
|
|
|
|
//
|
|
// Read the selected install architectures.
|
|
//
|
|
_Architecture.bReadUI();
|
|
|
|
}
|
|
|
|
BOOL
|
|
TPrinterSharing::
|
|
bKillActive(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Validate that the share page is in a consistent state.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
TRUE - Ok to kill active, FALSE = can't kill active, UI displayed.
|
|
|
|
--*/
|
|
|
|
{
|
|
TString strName;
|
|
INT iStatus;
|
|
BOOL bSuccess = TRUE;
|
|
|
|
//
|
|
// If not shared then just return success.
|
|
//
|
|
if( BST_CHECKED != IsDlgButtonChecked( _hDlg, IDC_SHARED ) ){
|
|
goto Done;
|
|
}
|
|
|
|
//
|
|
// Read the share name.
|
|
//
|
|
if( !bGetEditText( _hDlg, IDC_SHARED_NAME, strName ) ){
|
|
|
|
vShowResourceError( _hDlg );
|
|
bSuccess = FALSE;
|
|
goto Done;
|
|
}
|
|
|
|
//
|
|
// If the printer is currently shared and the
|
|
// share name in the edit control has not changed
|
|
// then just return success.
|
|
//
|
|
if( !_tcsicmp( strName, _pPrinterData->strShareName() ) &&
|
|
_pPrinterData->dwAttributes() & PRINTER_ATTRIBUTE_SHARED ){
|
|
|
|
DBGMSG( DBG_TRACE, ( "bKillActive - currently shared and the name has not changed.\n" ) );
|
|
goto Done;
|
|
}
|
|
|
|
//
|
|
// If the share name is empty.
|
|
//
|
|
if( strName.bEmpty() ){
|
|
|
|
iMessage( _hDlg,
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
IDS_ERR_NO_SHARE_NAME,
|
|
MB_OK|MB_ICONSTOP,
|
|
kMsgNone,
|
|
NULL );
|
|
|
|
bSuccess = FALSE;
|
|
goto Done;
|
|
}
|
|
|
|
//
|
|
// If the share object has not be constructed, then
|
|
// construct it.
|
|
//
|
|
if( !_pPrtShare ){
|
|
_pPrtShare = new TPrtShare( _pPrinterData->pszServerName() );
|
|
}
|
|
|
|
//
|
|
// Ensure we have a valid share object.
|
|
//
|
|
if( !VALID_PTR( _pPrtShare ) ){
|
|
goto Done;
|
|
}
|
|
|
|
//
|
|
// Check the share name if its valid.
|
|
//
|
|
iStatus = _pPrtShare->iIsValidNtShare( strName );
|
|
|
|
//
|
|
// If share name is not a valid NT share name, put error message.
|
|
//
|
|
if( iStatus != TPrtShare::kSuccess ){
|
|
|
|
iMessage( _hDlg,
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
IDS_ERR_INVALID_CHAR_SHARENAME,
|
|
MB_OK|MB_ICONSTOP,
|
|
kMsgNone,
|
|
NULL );
|
|
|
|
bSuccess = FALSE;
|
|
goto Done;
|
|
}
|
|
|
|
//
|
|
// Check if the share name is a valid DOS share.
|
|
//
|
|
iStatus = _pPrtShare->iIsValidDosShare( strName );
|
|
|
|
//
|
|
// If share name is not a valid DOS share name, warn the user.
|
|
//
|
|
if( iStatus != TPrtShare::kSuccess ){
|
|
|
|
iStatus = iMessage( _hDlg,
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
IDS_ERR_SHARE_NAME_NOT_DOS,
|
|
MB_YESNO|MB_ICONEXCLAMATION,
|
|
kMsgNone,
|
|
NULL );
|
|
|
|
if( iStatus != IDYES ){
|
|
bSuccess = FALSE;
|
|
goto Done;
|
|
}
|
|
}
|
|
|
|
//
|
|
// If the share name confilcts with an existing name.
|
|
// If the previous name was ours and we were shared,
|
|
// do not display the error message.
|
|
//
|
|
if( !_pPrtShare->bIsValidShareNameForThisPrinter(
|
|
strName,
|
|
_pPrinterData->strPrinterName() ) ){
|
|
|
|
if( !_tcsicmp( strName, _pPrinterData->strShareName() ) &&
|
|
_pPrinterData->dwAttributes() & PRINTER_ATTRIBUTE_SHARED ){
|
|
|
|
DBGMSG( DBG_TRACE, ( "Name is not unique, currently ours.\n" ));
|
|
|
|
} else {
|
|
|
|
iMessage( _hDlg,
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
IDS_ERR_DUPLICATE_SHARE,
|
|
MB_OK|MB_ICONSTOP,
|
|
kMsgNone,
|
|
NULL );
|
|
|
|
bSuccess = FALSE;
|
|
goto Done;
|
|
}
|
|
}
|
|
|
|
//
|
|
// If success then read share name and read the
|
|
// install architecture.
|
|
//
|
|
Done:
|
|
|
|
if( !bSuccess ){
|
|
|
|
//
|
|
// Set the focus to the shared as text.
|
|
//
|
|
SetFocus( GetDlgItem( _hDlg, IDC_SHARED_NAME ));
|
|
|
|
}
|
|
|
|
return bSuccess;
|
|
}
|
|
|
|
VOID
|
|
TPrinterSharing::
|
|
vSetActive(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Routine called when the pages is set active. This routine
|
|
will check if the installation archictectue has to refreshed and
|
|
and a new icon and name will be displayed.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Nothing.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// The icon and name.
|
|
//
|
|
vSetIconName();
|
|
|
|
//
|
|
// Check if we should refresh the install architecture UI.
|
|
//
|
|
if( _pPrinterData->bRefreshArch() ){
|
|
|
|
_pPrinterData->bRefreshArch() = FALSE;
|
|
|
|
if( !_Architecture.bRefreshUI( _pPrinterData->strDriverName() ) ){
|
|
|
|
//
|
|
// Install extra driver selection list failed.
|
|
//
|
|
iMessage( _hDlg,
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
IDS_ERR_SHARING_EXTRA_DRIVER_FAILED,
|
|
MB_OK|MB_ICONSTOP,
|
|
kMsgNone,
|
|
NULL );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
BOOL
|
|
TPrinterSharing::
|
|
bApply(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Routine called when the apply message is seend by this property
|
|
sheet.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
TRUE Printer data should be applied. FALSE if error.
|
|
|
|
--*/
|
|
{
|
|
BOOL bStatus = TRUE;
|
|
|
|
if( _pPrinterData->bAdministrator( ) ){
|
|
|
|
//
|
|
// Read the share name.
|
|
//
|
|
vReadUI();
|
|
|
|
if( !_Architecture.bInstall() ){
|
|
|
|
//
|
|
// Install extra driver selection list failed.
|
|
//
|
|
iMessage( _hDlg,
|
|
IDS_ERR_PRINTER_PROP_TITLE,
|
|
IDS_ERR_INSTALLING_EXTRA_DRIVERS,
|
|
MB_OK|MB_ICONSTOP,
|
|
kMsgGetLastError,
|
|
NULL );
|
|
|
|
_pPrinterData->_bErrorSaving = FALSE;
|
|
|
|
bStatus = FALSE;
|
|
|
|
}
|
|
}
|
|
|
|
return bStatus;
|
|
}
|
|
|
|
|
|
BOOL
|
|
TPrinterSharing::
|
|
bHandleMessage(
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam
|
|
)
|
|
{
|
|
TStatusB bStatus;
|
|
bStatus DBGNOCHK = TRUE;
|
|
|
|
switch( uMsg ){
|
|
case WM_INITDIALOG:
|
|
|
|
bSetUI();
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
|
|
vFreeIcon();
|
|
break;
|
|
|
|
case WM_HELP:
|
|
case WM_CONTEXTMENU:
|
|
|
|
PrintUIHelp( uMsg, _hDlg, wParam, lParam );
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
|
|
switch( GET_WM_COMMAND_ID( wParam, lParam )){
|
|
|
|
case IDC_SHARED_OFF:
|
|
|
|
vUnsharePrinter();
|
|
break;
|
|
|
|
case IDC_SHARED:
|
|
|
|
vSharePrinter();
|
|
break;
|
|
|
|
default:
|
|
|
|
bStatus DBGNOCHK = FALSE;
|
|
break;
|
|
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
{
|
|
//
|
|
// wParam is 0 on PSN_* notifications.
|
|
//
|
|
if( wParam ){
|
|
bStatus DBGNOCHK = FALSE;
|
|
break;
|
|
}
|
|
|
|
LPNMHDR pnmh = (LPNMHDR)lParam;
|
|
|
|
switch( pnmh->code ){
|
|
|
|
case PSN_SETACTIVE:
|
|
|
|
vSetActive();
|
|
break;
|
|
|
|
case PSN_KILLACTIVE:
|
|
|
|
//
|
|
// Check if it is ok to loose the focus.
|
|
//
|
|
if( !bKillActive( )){
|
|
|
|
//
|
|
// Inform the property sheet not to loose focus.
|
|
//
|
|
vSetDlgMsgResult( TRUE );
|
|
}
|
|
break;
|
|
|
|
//
|
|
// Total hack until common ui is online.
|
|
//
|
|
case PSN_APPLY:
|
|
|
|
if( bApply() ){
|
|
_pPrinterData->_bValid = 2;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
bStatus DBGNOCHK = FALSE;
|
|
break;
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
bStatus DBGNOCHK = FALSE;
|
|
break;
|
|
}
|
|
|
|
return bStatus;
|
|
}
|
|
|