#include "stdafx.h"
#include "PrinterSetupWizardApp.h"
#include "PrinterSetupWizardSheet.h"
#include "ThirdPage.h"
#include "tcpxcv.h"
#include <dns_sd.h>
#include <winspool.h>
#include <setupapi.h>
#pragma warning(disable:4189)
#define kNTPrintFile L"inf\\ntprint.inf"
#define kVistaPrintFiles L"inf\\prn*.inf"
#define kGenericManufacturer L"Generic"
#define kGenericText L"Generic / Text Only"
#define kGenericPostscript L"Generic / Postscript"
#define kGenericPCL L"Generic / PCL"
#define kPDLPostscriptKey L"application/postscript"
#define kPDLPCLKey L"application/vnd.hp-pcl"
#define kGenericPSColorDriver L"HP Color LaserJet 4550 PS"
#define kGenericPSDriver L"HP LaserJet 4050 Series PS"
#define kGenericPCLColorDriver L"HP Color LaserJet 4550 PCL"
#define kGenericPCLDriver L"HP LaserJet 4050 Series PCL"
IMPLEMENT_DYNAMIC(CThirdPage, CPropertyPage)
CThirdPage::CThirdPage()
: CPropertyPage(CThirdPage::IDD),
m_manufacturerSelected( NULL ),
m_modelSelected( NULL ),
m_genericPostscript( NULL ),
m_genericPCL( NULL ),
m_initialized(false),
m_printerImage( NULL )
{
static const int bufferSize = 32768;
TCHAR windowsDirectory[bufferSize];
CString header;
WIN32_FIND_DATA findFileData;
HANDLE findHandle;
CString prnFiles;
CString ntPrint;
OSStatus err;
BOOL ok;
m_psp.dwFlags &= ~(PSP_HASHELP);
m_psp.dwFlags |= PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE;
m_psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_INSTALL_TITLE);
m_psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_INSTALL_SUBTITLE);
ok = GetWindowsDirectory( windowsDirectory, bufferSize );
err = translate_errno( ok, errno_compat(), kUnknownErr );
require_noerr( err, exit );
prnFiles.Format( L"%s\\%s", windowsDirectory, kVistaPrintFiles );
findHandle = FindFirstFile( prnFiles, &findFileData );
if ( findHandle != INVALID_HANDLE_VALUE )
{
CString absolute;
absolute.Format( L"%s\\inf\\%s", windowsDirectory, findFileData.cFileName );
err = LoadPrintDriverDefsFromFile( m_manufacturers, absolute, false );
require_noerr( err, exit );
while ( FindNextFile( findHandle, &findFileData ) )
{
absolute.Format( L"%s\\inf\\%s", windowsDirectory, findFileData.cFileName );
err = LoadPrintDriverDefsFromFile( m_manufacturers, absolute, false );
require_noerr( err, exit );
}
FindClose( findHandle );
}
else
{
ntPrint.Format(L"%s\\%s", windowsDirectory, kNTPrintFile);
err = LoadPrintDriverDefsFromFile( m_manufacturers, ntPrint, false );
require_noerr(err, exit);
}
err = LoadPrintDriverDefs( m_manufacturers );
require_noerr(err, exit);
err = LoadGenericPrintDriverDefs( m_manufacturers );
require_noerr( err, exit );
exit:
return;
}
void
CThirdPage::FreeManufacturers( Manufacturers & manufacturers )
{
for ( Manufacturers::iterator it = manufacturers.begin(); it != manufacturers.end(); it++ )
{
for ( Models::iterator it2 = it->second->models.begin(); it2 != it->second->models.end(); it2++ )
{
delete *it2;
}
delete it->second;
}
}
CThirdPage::~CThirdPage()
{
FreeManufacturers( m_manufacturers );
}
void
CThirdPage::SelectMatch(Printer * printer, Service * service, Manufacturer * manufacturer, Model * model)
{
LVFINDINFO info;
int nIndex;
check( printer != NULL );
check( manufacturer != NULL );
check( model != NULL );
info.flags = LVFI_STRING;
info.psz = manufacturer->name;
nIndex = m_manufacturerListCtrl.FindItem(&info);
if (nIndex != -1)
{
m_manufacturerListCtrl.SetItemState(nIndex, LVIS_SELECTED, LVIS_SELECTED);
AutoScroll(m_manufacturerListCtrl, nIndex);
}
info.flags = LVFI_STRING;
info.psz = model->displayName;
nIndex = m_modelListCtrl.FindItem(&info);
if (nIndex != -1)
{
m_modelListCtrl.SetItemState(nIndex, LVIS_SELECTED, LVIS_SELECTED);
AutoScroll( m_modelListCtrl, nIndex );
m_modelListCtrl.SetFocus();
}
CopyPrinterSettings( printer, service, manufacturer, model );
}
void
CThirdPage::SelectMatch(Manufacturers & manufacturers, Printer * printer, Service * service, Manufacturer * manufacturer, Model * model)
{
PopulateUI( manufacturers );
SelectMatch( printer, service, manufacturer, model );
}
void
CThirdPage::CopyPrinterSettings( Printer * printer, Service * service, Manufacturer * manufacturer, Model * model )
{
DWORD portNameLen;
printer->manufacturer = manufacturer->name;
printer->displayModelName = model->displayName;
printer->modelName = model->name;
printer->driverInstalled = model->driverInstalled;
printer->infFileName = model->infFileName;
if ( service->type == kPDLServiceType )
{
printer->portName.Format(L"IP_%s.%d", static_cast<LPCTSTR>(service->hostname), service->portNumber);
service->protocol = L"Raw";
}
else if ( service->type == kLPRServiceType )
{
Queue * q = service->queues.front();
check( q );
if ( q->name.GetLength() > 0 )
{
printer->portName.Format(L"LPR_%s.%d.%s", static_cast<LPCTSTR>(service->hostname), service->portNumber, static_cast<LPCTSTR>(q->name) );
}
else
{
printer->portName.Format(L"LPR_%s.%d", static_cast<LPCTSTR>(service->hostname), service->portNumber);
}
service->protocol = L"LPR";
}
else if ( service->type == kIPPServiceType )
{
Queue * q = service->queues.front();
check( q );
if ( q->name.GetLength() > 0 )
{
printer->portName.Format(L"http://%s:%d/%s", static_cast<LPCTSTR>(service->hostname), service->portNumber, static_cast<LPCTSTR>(q->name) );
}
else
{
printer->portName.Format(L"http://%s:%d/", static_cast<LPCTSTR>(service->hostname), service->portNumber );
}
service->protocol = L"IPP";
}
if ( service->type != kIPPServiceType )
{
portNameLen = printer->portName.GetLength() + 1;
if ( portNameLen > MAX_PORTNAME_LEN )
{
printer->portName.Delete( MAX_PORTNAME_LEN - 1, ( portNameLen - MAX_PORTNAME_LEN ) );
}
}
}
BOOL
CThirdPage::DefaultPrinterExists()
{
CPrintDialog dlg(FALSE);
dlg.m_pd.Flags |= PD_RETURNDEFAULT;
return dlg.GetDefaults();
}
void
CThirdPage::AutoScroll( CListCtrl & list, int nIndex )
{
int top;
int count;
list.EnsureVisible( nIndex, FALSE );
top = list.GetTopIndex();
count = list.GetCountPerPage();
if ( ( nIndex == top ) || ( ( nIndex + 1 ) == ( top + count ) ) )
{
CRect rect;
int rows;
rows = ( count / 2 );
if ( nIndex == top )
{
list.GetItemRect(0, rect, LVIR_BOUNDS);
list.Scroll( CPoint( 0, rows * rect.Height() * -1 ) );
}
else
{
list.GetItemRect(0, rect, LVIR_BOUNDS);
list.Scroll( CPoint( 0, rows * rect.Height() ) );
}
}
}
OSStatus
CThirdPage::LoadPrintDriverDefsFromFile(Manufacturers & manufacturers, const CString & filename, bool checkForDuplicateModels )
{
HINF handle = INVALID_HANDLE_VALUE;
const TCHAR * section = TEXT( "Manufacturer" );
LONG sectionCount;
TCHAR line[ 1000 ];
CString klass;
INFCONTEXT manufacturerContext;
BOOL ok;
OSStatus err = 0;
handle = SetupOpenInfFile( filename, NULL, INF_STYLE_WIN4, NULL );
translate_errno( handle != INVALID_HANDLE_VALUE, GetLastError(), kUnknownErr );
require_noerr( err, exit );
ok = SetupGetLineText( NULL, handle, TEXT( "Version" ), TEXT( "Class" ), line, sizeof( line ), NULL );
translate_errno( ok, GetLastError(), kUnknownErr );
require_noerr( err, exit );
klass = line;
require_action( klass == TEXT( "Printer" ), exit, err = kUnknownErr );
sectionCount = SetupGetLineCount( handle, section );
translate_errno( sectionCount != -1, GetLastError(), kUnknownErr );
require_noerr( err, exit );
memset( &manufacturerContext, 0, sizeof( manufacturerContext ) );
for ( LONG i = 0; i < sectionCount; i++ )
{
Manufacturers::iterator iter;
Manufacturer * manufacturer;
CString manufacturerName;
CString temp;
CStringList modelSectionNameDecl;
CString modelSectionName;
CString baseModelName;
CString model;
INFCONTEXT modelContext;
LONG modelCount;
POSITION p;
if ( i == 0 )
{
ok = SetupFindFirstLine( handle, section, NULL, &manufacturerContext );
err = translate_errno( ok, GetLastError(), kUnknownErr );
require_noerr( err, exit );
}
else
{
ok = SetupFindNextLine( &manufacturerContext, &manufacturerContext );
err = translate_errno( ok, GetLastError(), kUnknownErr );
require_noerr( err, exit );
}
ok = SetupGetStringField( &manufacturerContext, 0, line, sizeof( line ), NULL );
err = translate_errno( ok, GetLastError(), kUnknownErr );
require_noerr( err, exit );
manufacturerName = line;
ok = SetupGetLineText( &manufacturerContext, handle, NULL, NULL, line, sizeof( line ), NULL );
err = translate_errno( ok, GetLastError(), kUnknownErr );
require_noerr( err, exit );
Split( line, ',', modelSectionNameDecl );
p = modelSectionNameDecl.GetHeadPosition();
modelSectionName = modelSectionNameDecl.GetNext( p );
modelCount = SetupGetLineCount( handle, modelSectionName );
baseModelName = modelSectionName;
while ( modelCount <= 0 && p )
{
CString targetOSVersion;
targetOSVersion = modelSectionNameDecl.GetNext( p );
modelSectionName = baseModelName + TEXT( "." ) + targetOSVersion;
modelCount = SetupGetLineCount( handle, modelSectionName );
}
if ( modelCount > 0 )
{
manufacturerName = NormalizeManufacturerName( manufacturerName );
iter = manufacturers.find( manufacturerName );
if ( iter != manufacturers.end() )
{
manufacturer = iter->second;
require_action( manufacturer, exit, err = kUnknownErr );
}
else
{
try
{
manufacturer = new Manufacturer;
}
catch (...)
{
manufacturer = NULL;
}
require_action( manufacturer, exit, err = kNoMemoryErr );
manufacturer->name = manufacturerName;
manufacturers[ manufacturerName ] = manufacturer;
}
memset( &modelContext, 0, sizeof( modelContext ) );
for ( LONG j = 0; j < modelCount; j++ )
{
CString modelName;
Model * model;
if ( j == 0 )
{
ok = SetupFindFirstLine( handle, modelSectionName, NULL, &modelContext );
err = translate_errno( ok, GetLastError(), kUnknownErr );
require_noerr( err, exit );
}
else
{
SetupFindNextLine( &modelContext, &modelContext );
err = translate_errno( ok, GetLastError(), kUnknownErr );
require_noerr( err, exit );
}
ok = SetupGetStringField( &modelContext, 0, line, sizeof( line ), NULL );
err = translate_errno( ok, GetLastError(), kUnknownErr );
require_noerr( err, exit );
modelName = line;
if (checkForDuplicateModels == true)
{
if ( MatchModel( manufacturer, ConvertToModelName( modelName ) ) != NULL )
{
continue;
}
}
if ( modelName.Find( TEXT( "{" ), 0 ) != -1 )
{
continue;
}
try
{
model = new Model;
}
catch (...)
{
model = NULL;
}
require_action( model, exit, err = kNoMemoryErr );
model->infFileName = filename;
model->displayName = modelName;
model->name = modelName;
model->driverInstalled = false;
manufacturer->models.push_back(model);
}
}
}
exit:
if ( handle != INVALID_HANDLE_VALUE )
{
SetupCloseInfFile( handle );
handle = NULL;
}
return err;
}
OSStatus
CThirdPage::LoadPrintDriverDefs( Manufacturers & manufacturers )
{
BYTE * buffer = NULL;
DWORD bytesReceived = 0;
DWORD numPrinters = 0;
OSStatus err = 0;
BOOL ok;
EnumPrinterDrivers(NULL, L"all", 6, NULL, 0, &bytesReceived, &numPrinters);
if (bytesReceived > 0)
{
try
{
buffer = new BYTE[bytesReceived];
}
catch (...)
{
buffer = NULL;
}
require_action( buffer, exit, err = kNoMemoryErr );
ok = EnumPrinterDrivers(NULL, L"all", 6, buffer, bytesReceived, &bytesReceived, &numPrinters);
err = translate_errno( ok, errno_compat(), kUnknownErr );
require_noerr( err, exit );
DRIVER_INFO_6 * info = (DRIVER_INFO_6*) buffer;
for (DWORD i = 0; i < numPrinters; i++)
{
Manufacturer * manufacturer;
Model * model;
CString name;
if (info[i].pszMfgName == NULL)
{
continue;
}
Manufacturers::iterator iter;
name = NormalizeManufacturerName( info[i].pszMfgName );
iter = manufacturers.find(name);
if (iter != manufacturers.end())
{
manufacturer = iter->second;
}
else
{
try
{
manufacturer = new Manufacturer;
}
catch (...)
{
manufacturer = NULL;
}
require_action( manufacturer, exit, err = kNoMemoryErr );
manufacturer->name = name;
manufacturers[name] = manufacturer;
}
if ( MatchModel( manufacturer, ConvertToModelName( info[i].pName ) ) == NULL )
{
try
{
model = new Model;
}
catch (...)
{
model = NULL;
}
require_action( model, exit, err = kNoMemoryErr );
model->displayName = info[i].pName;
model->name = info[i].pName;
model->driverInstalled = true;
manufacturer->models.push_back(model);
}
}
}
exit:
if (buffer != NULL)
{
delete [] buffer;
}
return err;
}
OSStatus
CThirdPage::LoadGenericPrintDriverDefs( Manufacturers & manufacturers )
{
Manufacturer * manufacturer;
Model * model;
Manufacturers::iterator iter;
CString psDriverName;
CString pclDriverName;
OSStatus err = 0;
iter = m_manufacturers.find(L"HP");
require_action( iter != m_manufacturers.end(), exit, err = kUnknownErr );
manufacturer = iter->second;
model = manufacturer->find( kGenericPSColorDriver );
if ( !model )
{
model = manufacturer->find( kGenericPSDriver );
}
if ( model )
{
psDriverName = model->name;
}
model = manufacturer->find( kGenericPCLColorDriver );
if ( !model )
{
model = manufacturer->find( kGenericPCLDriver );
}
if ( model )
{
pclDriverName = model->name;
}
if ( psDriverName.GetLength() || pclDriverName.GetLength() )
{
iter = manufacturers.find(L"Generic");
if (iter != manufacturers.end())
{
manufacturer = iter->second;
}
else
{
try
{
manufacturer = new Manufacturer;
}
catch (...)
{
manufacturer = NULL;
}
require_action( manufacturer, exit, err = kNoMemoryErr );
manufacturer->name = "Generic";
manufacturers[manufacturer->name] = manufacturer;
}
if ( psDriverName.GetLength() > 0 )
{
try
{
m_genericPostscript = new Model;
}
catch (...)
{
m_genericPostscript = NULL;
}
require_action( m_genericPostscript, exit, err = kNoMemoryErr );
m_genericPostscript->displayName = kGenericPostscript;
m_genericPostscript->name = psDriverName;
m_genericPostscript->driverInstalled = false;
manufacturer->models.push_back( m_genericPostscript );
}
if ( pclDriverName.GetLength() > 0 )
{
try
{
m_genericPCL = new Model;
}
catch (...)
{
m_genericPCL = NULL;
}
require_action( m_genericPCL, exit, err = kNoMemoryErr );
m_genericPCL->displayName = kGenericPCL;
m_genericPCL->name = pclDriverName;
m_genericPCL->driverInstalled = false;
manufacturer->models.push_back( m_genericPCL );
}
}
exit:
return err;
}
CString
CThirdPage::ConvertToManufacturerName( const CString & name )
{
CString lower = name;
lower.MakeLower();
if ( lower == L"hewlett-packard")
{
lower = "hp";
}
else if ( lower.Find( L"phaser", 0 ) != -1 )
{
lower = "xerox";
}
return lower;
}
CString
CThirdPage::ConvertToModelName( const CString & name )
{
CString lower = name;
lower.MakeLower();
return lower;
}
CString
CThirdPage::NormalizeManufacturerName( const CString & name )
{
CString normalized = name;
if ( normalized == L"Hewlett-Packard")
{
normalized = "HP";
}
return normalized;
}
OSStatus CThirdPage::MatchPrinter(Manufacturers & manufacturers, Printer * printer, Service * service, bool useCUPSWorkaround)
{
CString normalizedProductName;
Manufacturer * manufacturer = NULL;
Manufacturer * genericManufacturer = NULL;
Model * model = NULL;
Model * genericModel = NULL;
bool found = false;
CString text;
OSStatus err = kNoErr;
check( printer );
check( service );
Queue * q = service->SelectedQueue();
check( q );
if ( q->usb_MFG.GetLength() > 0)
{
manufacturer = MatchManufacturer( manufacturers, ConvertToManufacturerName ( q->usb_MFG ) );
}
if ( manufacturer == NULL )
{
q->product.Remove('(');
q->product.Remove(')');
manufacturer = MatchManufacturer( manufacturers, ConvertToManufacturerName ( q->product ) );
}
if ( manufacturer != NULL )
{
if ( q->usb_MDL.GetLength() > 0 )
{
model = MatchModel ( manufacturer, ConvertToModelName ( q->usb_MDL ) );
}
if ( ( model == NULL ) && ( q->product.GetLength() > 0 ) )
{
q->product.Remove('(');
q->product.Remove(')');
model = MatchModel ( manufacturer, ConvertToModelName ( q->product ) );
}
if ( model != NULL )
{
bool hasGenericDriver = false;
if ( MatchGeneric( manufacturers, printer, service, &genericManufacturer, &genericModel ) )
{
hasGenericDriver = true;
}
if ( q->pdl.Find( L"application/octet-stream" ) != -1 )
{
useCUPSWorkaround = false;
}
if ( useCUPSWorkaround && printer->isCUPSPrinter && hasGenericDriver )
{
Manufacturers genericManufacturers;
LoadGenericPrintDriverDefs( genericManufacturers );
SelectMatch( genericManufacturers, printer, service, genericManufacturer, genericModel );
FreeManufacturers( genericManufacturers );
}
else
{
SelectMatch(manufacturers, printer, service, manufacturer, model);
}
found = true;
}
}
if (found)
{
text.LoadString(IDS_PRINTER_MATCH_GOOD);
err = kNoErr;
}
else if ( MatchGeneric( manufacturers, printer, service, &genericManufacturer, &genericModel ) )
{
if ( printer->isCUPSPrinter )
{
Manufacturers genericManufacturers;
LoadGenericPrintDriverDefs( genericManufacturers );
SelectMatch( genericManufacturers, printer, service, genericManufacturer, genericModel );
text.LoadString(IDS_PRINTER_MATCH_GOOD);
FreeManufacturers( genericManufacturers );
}
else
{
SelectMatch( manufacturers, printer, service, genericManufacturer, genericModel );
text.LoadString(IDS_PRINTER_MATCH_MAYBE);
}
err = kNoErr;
}
else
{
text.LoadString(IDS_PRINTER_MATCH_BAD);
m_modelListCtrl.DeleteAllItems();
if (manufacturer != NULL)
{
LVFINDINFO info;
int nIndex;
info.flags = LVFI_STRING;
info.psz = manufacturer->name;
nIndex = m_manufacturerListCtrl.FindItem(&info);
if (nIndex != -1)
{
m_manufacturerListCtrl.SetItemState(nIndex, LVIS_SELECTED, LVIS_SELECTED);
AutoScroll(m_manufacturerListCtrl, nIndex);
}
}
err = kUnknownErr;
}
m_printerSelectionText.SetWindowText(text);
return err;
}
Manufacturer*
CThirdPage::MatchManufacturer( Manufacturers & manufacturers, const CString & name)
{
Manufacturers::iterator iter;
for (iter = manufacturers.begin(); iter != manufacturers.end(); iter++)
{
CString lower = iter->second->name;
lower.MakeLower();
if (name.Find(lower) != -1)
{
return iter->second;
}
}
return NULL;
}
Model*
CThirdPage::MatchModel(Manufacturer * manufacturer, const CString & name)
{
Models::iterator iter;
iter = manufacturer->models.begin();
for (iter = manufacturer->models.begin(); iter != manufacturer->models.end(); iter++)
{
Model * model = *iter;
CString lowered = model->name;
lowered.MakeLower();
if (lowered.Find( name ) != -1)
{
return model;
}
if ( name.Find(' ') != -1 )
{
CString altered = name;
altered.Delete( 0, altered.Find(' ') + 1 );
if ( lowered.Find( altered ) != -1 )
{
return model;
}
}
}
return NULL;
}
BOOL
CThirdPage::MatchGeneric( Manufacturers & manufacturers, Printer * printer, Service * service, Manufacturer ** manufacturer, Model ** model )
{
CString pdl;
BOOL ok = FALSE;
DEBUG_UNUSED( printer );
check( service );
Queue * q = service->SelectedQueue();
check( q );
Manufacturers::iterator iter = manufacturers.find( kGenericManufacturer );
require_action_quiet( iter != manufacturers.end(), exit, ok = FALSE );
*manufacturer = iter->second;
pdl = q->pdl;
pdl.MakeLower();
if ( m_genericPCL && ( pdl.Find( kPDLPCLKey ) != -1 ) )
{
*model = m_genericPCL;
ok = TRUE;
}
else if ( m_genericPostscript && ( pdl.Find( kPDLPostscriptKey ) != -1 ) )
{
*model = m_genericPostscript;
ok = TRUE;
}
exit:
return ok;
}
OSStatus CThirdPage::OnInitPage()
{
CString header;
CString ntPrint;
OSStatus err = kNoErr;
check( m_printerImage == NULL );
m_printerImage = (CStatic*) GetDlgItem( 1 ); check( m_printerImage );
if ( m_printerImage != NULL )
{
m_printerImage->SetIcon( LoadIcon( GetNonLocalizedResources(), MAKEINTRESOURCE( IDI_PRINTER ) ) );
}
header.LoadString(IDS_MANUFACTURER_HEADING);
m_manufacturerListCtrl.InsertColumn(0, header, LVCFMT_LEFT, -1 );
m_manufacturerSelected = NULL;
header.LoadString(IDS_MODEL_HEADING);
m_modelListCtrl.InsertColumn(0, header, LVCFMT_LEFT, -1 );
m_modelSelected = NULL;
return (err);
}
void CThirdPage::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
DDX_Control(pDX, IDC_PRINTER_MANUFACTURER, m_manufacturerListCtrl);
DDX_Control(pDX, IDC_PRINTER_MODEL, m_modelListCtrl);
DDX_Control(pDX, IDC_PRINTER_NAME, m_printerName);
DDX_Control(pDX, IDC_DEFAULT_PRINTER, m_defaultPrinterCtrl);
DDX_Control(pDX, IDC_PRINTER_SELECTION_TEXT, m_printerSelectionText);
}
BOOL
CThirdPage::OnSetActive()
{
CPrinterSetupWizardSheet * psheet;
Printer * printer;
Service * service;
psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
require_quiet( psheet, exit );
psheet->SetWizardButtons( PSWIZB_BACK );
printer = psheet->GetSelectedPrinter();
require_quiet( printer, exit );
service = printer->services.front();
require_quiet( service, exit );
if (!m_initialized)
{
OnInitPage();
m_initialized = true;
}
if ( DefaultPrinterExists() )
{
m_defaultPrinterCtrl.SetCheck( BST_UNCHECKED );
printer->deflt = false;
}
else
{
m_defaultPrinterCtrl.SetCheck( BST_CHECKED );
printer->deflt = true;
}
m_printerName.SetWindowText(printer->displayName);
PopulateUI( m_manufacturers );
if ( psheet->GetLastPage() == psheet->GetPage(0) )
{
MatchPrinter( m_manufacturers, printer, service, true );
if ( ( m_manufacturerSelected != NULL ) && ( m_modelSelected != NULL ) )
{
GetParent()->PostMessage(PSM_SETCURSEL, 2 );
}
}
else
{
SelectMatch(printer, service, m_manufacturerSelected, m_modelSelected);
}
exit:
return CPropertyPage::OnSetActive();
}
BOOL
CThirdPage::OnKillActive()
{
CPrinterSetupWizardSheet * psheet;
psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
require_quiet( psheet, exit );
psheet->SetLastPage(this);
exit:
return CPropertyPage::OnKillActive();
}
OSStatus
CThirdPage::PopulateUI(Manufacturers & manufacturers)
{
Manufacturers::iterator iter;
m_manufacturerListCtrl.DeleteAllItems();
for (iter = manufacturers.begin(); iter != manufacturers.end(); iter++)
{
int nIndex;
Manufacturer * manufacturer = iter->second;
nIndex = m_manufacturerListCtrl.InsertItem(0, manufacturer->name);
m_manufacturerListCtrl.SetItemData(nIndex, (DWORD_PTR) manufacturer);
m_manufacturerListCtrl.SetColumnWidth( 0, LVSCW_AUTOSIZE_USEHEADER );
}
return 0;
}
BEGIN_MESSAGE_MAP(CThirdPage, CPropertyPage)
ON_NOTIFY(LVN_ITEMCHANGED, IDC_PRINTER_MANUFACTURER, OnLvnItemchangedManufacturer)
ON_NOTIFY(LVN_ITEMCHANGED, IDC_PRINTER_MODEL, OnLvnItemchangedPrinterModel)
ON_BN_CLICKED(IDC_DEFAULT_PRINTER, OnBnClickedDefaultPrinter)
ON_BN_CLICKED(IDC_HAVE_DISK, OnBnClickedHaveDisk)
END_MESSAGE_MAP()
void CThirdPage::OnLvnItemchangedManufacturer(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
POSITION p = m_manufacturerListCtrl.GetFirstSelectedItemPosition();
int nSelected = m_manufacturerListCtrl.GetNextSelectedItem(p);
if (nSelected != -1)
{
m_manufacturerSelected = (Manufacturer*) m_manufacturerListCtrl.GetItemData(nSelected);
m_modelListCtrl.SetRedraw(FALSE);
m_modelListCtrl.DeleteAllItems();
m_modelSelected = NULL;
Models::iterator iter;
for (iter = m_manufacturerSelected->models.begin(); iter != m_manufacturerSelected->models.end(); iter++)
{
Model * model = *iter;
int nItem = m_modelListCtrl.InsertItem( 0, model->displayName );
m_modelListCtrl.SetItemData(nItem, (DWORD_PTR) model);
m_modelListCtrl.SetColumnWidth( 0, LVSCW_AUTOSIZE_USEHEADER );
}
m_modelListCtrl.SetRedraw(TRUE);
}
*pResult = 0;
}
void CThirdPage::OnLvnItemchangedPrinterModel(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
CPrinterSetupWizardSheet * psheet;
Printer * printer;
Service * service;
psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
require_quiet( psheet, exit );
printer = psheet->GetSelectedPrinter();
require_quiet( printer, exit );
service = printer->services.front();
require_quiet( service, exit );
check ( m_manufacturerSelected );
POSITION p = m_modelListCtrl.GetFirstSelectedItemPosition();
int nSelected = m_modelListCtrl.GetNextSelectedItem(p);
if (nSelected != -1)
{
m_modelSelected = (Model*) m_modelListCtrl.GetItemData(nSelected);
CopyPrinterSettings( printer, service, m_manufacturerSelected, m_modelSelected );
psheet->SetWizardButtons(PSWIZB_BACK|PSWIZB_NEXT);
}
else
{
psheet->SetWizardButtons(PSWIZB_BACK);
}
exit:
*pResult = 0;
}
void CThirdPage::OnBnClickedDefaultPrinter()
{
CPrinterSetupWizardSheet * psheet;
Printer * printer;
psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
require_quiet( psheet, exit );
printer = psheet->GetSelectedPrinter();
require_quiet( printer, exit );
printer->deflt = ( m_defaultPrinterCtrl.GetCheck() == BST_CHECKED ) ? true : false;
exit:
return;
}
void CThirdPage::OnBnClickedHaveDisk()
{
CPrinterSetupWizardSheet * psheet;
Printer * printer;
Service * service;
Manufacturers manufacturers;
CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY|OFN_FILEMUSTEXIST, L"Setup Information (*.inf)|*.inf||", this);
psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
require_quiet( psheet, exit );
printer = psheet->GetSelectedPrinter();
require_quiet( printer, exit );
service = printer->services.front();
require_quiet( service, exit );
for ( ;; )
{
if ( dlg.DoModal() == IDOK )
{
CString filename = dlg.GetPathName();
LoadPrintDriverDefsFromFile( manufacturers, filename, true );
if ( manufacturers.size() > 0 )
{
PopulateUI( manufacturers );
if ( MatchPrinter( manufacturers, printer, service, false ) != kNoErr )
{
CString errorMessage;
CString errorCaption;
errorMessage.LoadString( IDS_NO_MATCH_INF_FILE );
errorCaption.LoadString( IDS_NO_MATCH_INF_FILE_CAPTION );
MessageBox( errorMessage, errorCaption, MB_OK );
}
break;
}
else
{
CString errorMessage;
CString errorCaption;
errorMessage.LoadString( IDS_BAD_INF_FILE );
errorCaption.LoadString( IDS_BAD_INF_FILE_CAPTION );
MessageBox( errorMessage, errorCaption, MB_OK );
}
}
else
{
break;
}
}
exit:
FreeManufacturers( manufacturers );
return;
}
void
CThirdPage::Split( const CString & string, TCHAR ch, CStringList & components )
{
CString temp;
int n;
temp = string;
while ( ( n = temp.Find( ch ) ) != -1 )
{
components.AddTail( temp.Left( n ) );
temp = temp.Right( temp.GetLength() - ( n + 1 ) );
}
components.AddTail( temp );
}