/* -*- Mode: C; tab-width: 4 -*- * * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "stdafx.h" #include "PrinterSetupWizardApp.h" #include "PrinterSetupWizardSheet.h" #include "SecondPage.h" #include "DebugServices.h" #include "WinServices.h" #include // local variable is initialize but not referenced #pragma warning(disable:4189) // CSecondPage dialog IMPLEMENT_DYNAMIC(CSecondPage, CPropertyPage) CSecondPage::CSecondPage() : CPropertyPage(CSecondPage::IDD) { m_psp.dwFlags &= ~(PSP_HASHELP); m_psp.dwFlags |= PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE; m_psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_BROWSE_TITLE); m_psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_BROWSE_SUBTITLE); m_emptyListItem = NULL; m_initialized = false; m_waiting = false; } CSecondPage::~CSecondPage() { } void CSecondPage::InitBrowseList() { CPrinterSetupWizardSheet * psheet; CString text; psheet = reinterpret_cast(GetParent()); require_quiet( psheet, exit ); // Initialize so that nothing is selected when we add to the list psheet->SetSelectedPrinter( NULL ); m_gotChoice = false; m_browseList.Select( NULL, TVGN_FIRSTVISIBLE ); // // load the no printers message until something shows up in the browse list // text.LoadString(IDS_NO_PRINTERS); LoadTextAndDisableWindow( text ); // // disable the next button until there's a printer to select // psheet->SetWizardButtons(PSWIZB_BACK); // // disable the printer information box // SetPrinterInformationState( FALSE ); m_descriptionField.SetWindowText( L"" ); m_locationField.SetWindowText( L"" ); exit: return; } void CSecondPage::DoDataExchange(CDataExchange* pDX) { CPropertyPage::DoDataExchange(pDX); DDX_Control(pDX, IDC_BROWSE_LIST, m_browseList); DDX_Control(pDX, IDC_PRINTER_INFORMATION, m_printerInformation); DDX_Control(pDX, IDC_DESCRIPTION_LABEL, m_descriptionLabel); DDX_Control(pDX, IDC_DESCRIPTION_FIELD, m_descriptionField); DDX_Control(pDX, IDC_LOCATION_LABEL, m_locationLabel); DDX_Control(pDX, IDC_LOCATION_FIELD, m_locationField); } afx_msg BOOL CSecondPage::OnSetCursor(CWnd * pWnd, UINT nHitTest, UINT message) { DEBUG_UNUSED(pWnd); DEBUG_UNUSED(nHitTest); DEBUG_UNUSED(message); CPrinterSetupWizardSheet * psheet; psheet = reinterpret_cast(GetParent()); require_quiet( psheet, exit ); SetCursor(psheet->GetCursor()); exit: return TRUE; } BOOL CSecondPage::OnSetActive() { CPrinterSetupWizardSheet * psheet; Printer * printer; CWnd * pWnd; Printers::iterator it; OSStatus err = kNoErr; BOOL b; b = CPropertyPage::OnSetActive(); psheet = reinterpret_cast(GetParent()); require_action( psheet, exit, err = kUnknownErr ); // Stash the selected printer if any printer = psheet->GetSelectedPrinter(); // initialize the browse list...this will remove everything currently // in it, and add the no printers item InitBrowseList(); // Populate the list with any printers that we currently know about for ( it = psheet->m_printers.begin(); it != psheet->m_printers.end(); it++ ) { OnAddPrinter( *it, false ); } if ( ( !printer && ( psheet->m_printers.size() > 0 ) ) || ( printer != psheet->GetSelectedPrinter() ) ) { if ( !printer ) { printer = psheet->m_printers.front(); } psheet->SetSelectedPrinter( printer ); } if ( printer ) { m_browseList.SelectItem( printer->item ); ::SetFocus( m_browseList ); } // Hide the back button pWnd = ((CPropertySheet*)GetParent())->GetDlgItem(ID_WIZBACK); if ( pWnd != NULL ) { pWnd->ShowWindow(SW_HIDE); } exit: return b; } BOOL CSecondPage::OnKillActive() { CPrinterSetupWizardSheet * psheet; CWnd * pWnd; psheet = reinterpret_cast(GetParent()); require_quiet( psheet, exit ); psheet->SetLastPage(this); // Show the back button pWnd = ((CPropertySheet*)GetParent())->GetDlgItem(ID_WIZBACK); if ( pWnd != NULL ) { pWnd->ShowWindow(SW_SHOW); } exit: return CPropertyPage::OnKillActive(); } BEGIN_MESSAGE_MAP(CSecondPage, CPropertyPage) ON_NOTIFY(TVN_SELCHANGED, IDC_BROWSE_LIST, OnTvnSelchangedBrowseList) ON_NOTIFY(NM_CLICK, IDC_BROWSE_LIST, OnNmClickBrowseList) ON_NOTIFY(TVN_KEYDOWN, IDC_BROWSE_LIST, OnTvnKeyDownBrowseList) ON_WM_SETCURSOR() END_MESSAGE_MAP() // Printer::EventHandler implementation OSStatus CSecondPage::OnAddPrinter( Printer * printer, bool moreComing ) { CPrinterSetupWizardSheet * psheet; Printer * selectedPrinter; OSStatus err = kNoErr; check( IsWindow( m_hWnd ) ); m_browseList.SetRedraw(FALSE); psheet = reinterpret_cast(GetParent()); require_quiet( psheet, exit ); if ( printer ) { selectedPrinter = psheet->GetSelectedPrinter(); printer->item = m_browseList.InsertItem(printer->displayName); m_browseList.SetItemData( printer->item, (DWORD_PTR) printer ); m_browseList.SortChildren(TVI_ROOT); // // if the searching item is still in the list // get rid of it // // note that order is important here. Insert the printer // item before removing the placeholder so we always have // an item in the list to avoid experiencing the bug // in Microsoft's implementation of CTreeCtrl // if (m_emptyListItem != NULL) { m_browseList.DeleteItem(m_emptyListItem); m_emptyListItem = NULL; m_browseList.EnableWindow(TRUE); } if ( !selectedPrinter ) { psheet->SetSelectedPrinter( printer ); m_browseList.SelectItem( printer->item ); ::SetFocus( m_browseList ); } } exit: if (!moreComing) { m_browseList.SetRedraw(TRUE); m_browseList.Invalidate(); } return err; } OSStatus CSecondPage::OnRemovePrinter( Printer * printer, bool moreComing) { CPrinterSetupWizardSheet * psheet; OSStatus err = kNoErr; check( IsWindow( m_hWnd ) ); check( printer ); psheet = reinterpret_cast(GetParent()); require_quiet( psheet, exit ); m_browseList.SetRedraw(FALSE); if ( printer ) { // // check to make sure if we're the only item in the control...i.e. // the list size is 1. // if (m_browseList.GetCount() > 1) { // // if we're not the only thing in the list, then // simply remove it from the list // m_browseList.DeleteItem( printer->item ); } else { // // if we're the only thing in the list, then redisplay // it with the no printers message // InitBrowseList(); } } exit: if ( !moreComing ) { m_browseList.SetRedraw(TRUE); m_browseList.Invalidate(); } return err; } void CSecondPage::OnResolveService( Service * service ) { CPrinterSetupWizardSheet * psheet = reinterpret_cast(GetParent()); require_quiet( psheet, exit ); check( service ); Queue * q = service->SelectedQueue(); check( q ); // // and set it to selected // m_selectedName = service->printer->name; // // and update the printer information box // SetPrinterInformationState( TRUE ); m_descriptionField.SetWindowText( q->description ); m_locationField.SetWindowText( q->location ); // // reset the cursor // SetCursor(psheet->m_active); exit: return; } void CSecondPage::OnTvnSelchangedBrowseList(NMHDR *pNMHDR, LRESULT *pResult) { LPNMTREEVIEW pNMTreeView = reinterpret_cast(pNMHDR); CPrinterSetupWizardSheet * psheet; Printer * printer; int err = 0; psheet = reinterpret_cast(GetParent()); require_action( psheet, exit, err = kUnknownErr ); // The strange code here is to workaround a bug in the CTreeCtrl, whereupon the item // we selected isn't passed through correctly to this callback routine. if ( !m_gotChoice ) { printer = psheet->GetSelectedPrinter(); // If we really haven't selected a printer, then re-select NULL and exit if ( !printer ) { m_browseList.SelectItem( NULL ); goto exit; } // If we already have selected a printer, fake like we've clicked on it, but only // if the CTreeCtrl hasn't already selected it else if ( printer->item != m_browseList.GetSelectedItem() ) { m_gotChoice = true; m_browseList.SelectItem( printer->item ); goto exit; } } HTREEITEM item = m_browseList.GetSelectedItem(); require_quiet( item, exit ); printer = reinterpret_cast(m_browseList.GetItemData( item ) ); require_quiet( printer, exit ); // // this call will trigger a resolve. When the resolve is complete, // our OnResolve will be called. // err = psheet->StartResolve( printer ); require_noerr( err, exit ); // // And clear out the printer information box // SetPrinterInformationState( FALSE ); m_descriptionField.SetWindowText(L""); m_locationField.SetWindowText(L""); exit: if (err != 0) { CString text; CString caption; text.LoadString(IDS_ERROR_SELECTING_PRINTER_TEXT); caption.LoadString(IDS_ERROR_SELECTING_PRINTER_CAPTION); MessageBox(text, caption, MB_OK|MB_ICONEXCLAMATION); } *pResult = 0; } void CSecondPage::OnNmClickBrowseList(NMHDR *pNMHDR, LRESULT *pResult) { DEBUG_UNUSED( pNMHDR ); m_gotChoice = true; *pResult = 0; } void CSecondPage::OnTvnKeyDownBrowseList( NMHDR * pNMHDR, LRESULT * pResult) { DEBUG_UNUSED( pNMHDR ); m_gotChoice = true; *pResult = 0; } void CSecondPage::LoadTextAndDisableWindow( CString & text ) { m_emptyListItem = m_browseList.InsertItem( text, 0, 0, NULL, TVI_FIRST ); m_browseList.SelectItem( NULL ); // // this will remove everything else in the list...we might be navigating // back to this window, and the browse list might have changed since // we last displayed it. // if ( m_emptyListItem ) { HTREEITEM item = m_browseList.GetNextVisibleItem( m_emptyListItem ); while ( item ) { m_browseList.DeleteItem( item ); item = m_browseList.GetNextVisibleItem( m_emptyListItem ); } } m_browseList.EnableWindow( FALSE ); } void CSecondPage::SetPrinterInformationState( BOOL state ) { m_printerInformation.EnableWindow( state ); m_descriptionLabel.EnableWindow( state ); m_descriptionField.EnableWindow( state ); m_locationLabel.EnableWindow( state ); m_locationField.EnableWindow( state ); }