| /* -*- 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 <winspool.h> |
| |
| // 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<CPrinterSetupWizardSheet*>(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<CPrinterSetupWizardSheet*>(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<CPrinterSetupWizardSheet*>(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<CPrinterSetupWizardSheet*>(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<CPrinterSetupWizardSheet*>(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<CPrinterSetupWizardSheet*>(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<CPrinterSetupWizardSheet*>(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<LPNMTREEVIEW>(pNMHDR); |
| CPrinterSetupWizardSheet * psheet; |
| Printer * printer; |
| int err = 0; |
| |
| psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(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<Printer*>(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 ); |
| |
| } |
| |
| |
| |