2 * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 Change History (most recent first):
25 $Log: SecondPage.cpp,v $
26 Revision 1.13 2005/02/15 07:50:10 shersche
27 <rdar://problem/4007151> Update name
29 Revision 1.12 2005/02/10 22:35:11 cheshire
30 <rdar://problem/3727944> Update name
32 Revision 1.11 2005/01/31 23:54:30 shersche
33 <rdar://problem/3947508> Start browsing when printer wizard starts. Move browsing logic from CSecondPage object to CPrinterSetupWizardSheet object.
35 Revision 1.10 2005/01/20 19:54:38 shersche
36 Fix parse error when text record is NULL
38 Revision 1.9 2005/01/06 08:13:50 shersche
39 Don't use moreComing flag to determine number of text record, disregard queue name if qtotal isn't defined, don't disregard queue name if "rp" is the only key specified
41 Revision 1.8 2005/01/04 21:09:14 shersche
42 Fix problems in parsing text records. Fix problems in remove event handling. Ensure that the same service can't be resolved more than once.
44 Revision 1.7 2004/12/31 07:25:27 shersche
45 Tidy up printer management, and fix memory leaks when hitting 'Cancel'
47 Revision 1.6 2004/12/30 01:24:02 shersche
48 <rdar://problem/3906182> Remove references to description key
51 Revision 1.5 2004/12/30 01:02:47 shersche
52 <rdar://problem/3734478> Add Printer information box that displays description and location information when printer name is selected
55 Revision 1.4 2004/12/29 18:53:38 shersche
56 <rdar://problem/3725106>
57 <rdar://problem/3737413> Added support for LPR and IPP protocols as well as support for obtaining multiple text records. Reorganized and simplified codebase.
58 Bug #: 3725106, 3737413
60 Revision 1.3 2004/09/13 21:26:15 shersche
61 <rdar://problem/3796483> Use the moreComing flag to determine whether drawing should take place in OnAddPrinter and OnRemovePrinter callbacks
64 Revision 1.2 2004/06/26 03:19:57 shersche
65 clean up warning messages
67 Submitted by: herscher
69 Revision 1.1 2004/06/18 04:36:57 rpantos
76 #include "PrinterSetupWizardApp.h"
77 #include "PrinterSetupWizardSheet.h"
78 #include "SecondPage.h"
79 #include "DebugServices.h"
80 #include "WinServices.h"
83 // local variable is initialize but not referenced
84 #pragma warning(disable:4189)
88 IMPLEMENT_DYNAMIC(CSecondPage
, CPropertyPage
)
89 CSecondPage::CSecondPage()
90 : CPropertyPage(CSecondPage::IDD
)
92 m_psp
.dwFlags
&= ~(PSP_HASHELP
);
93 m_psp
.dwFlags
|= PSP_DEFAULT
|PSP_USEHEADERTITLE
|PSP_USEHEADERSUBTITLE
;
95 m_psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_BROWSE_TITLE
);
96 m_psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_BROWSE_SUBTITLE
);
98 m_emptyListItem
= NULL
;
99 m_initialized
= false;
104 CSecondPage::~CSecondPage()
110 CSecondPage::InitBrowseList()
112 CPrinterSetupWizardSheet
* psheet
;
115 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
116 require_quiet( psheet
, exit
);
119 // load the no printers message until something shows up in the browse list
121 text
.LoadString(IDS_NO_PRINTERS
);
123 LoadTextAndDisableWindow( text
);
126 // disable the next button until there's a printer to select
128 psheet
->SetWizardButtons(PSWIZB_BACK
);
131 // disable the printer information box
133 SetPrinterInformationState( FALSE
);
141 void CSecondPage::DoDataExchange(CDataExchange
* pDX
)
143 CPropertyPage::DoDataExchange(pDX
);
144 DDX_Control(pDX
, IDC_BROWSE_LIST
, m_browseList
);
145 DDX_Control(pDX
, IDC_PRINTER_INFORMATION
, m_printerInformation
);
147 DDX_Control(pDX
, IDC_DESCRIPTION_LABEL
, m_descriptionLabel
);
149 DDX_Control(pDX
, IDC_DESCRIPTION_FIELD
, m_descriptionField
);
151 DDX_Control(pDX
, IDC_LOCATION_LABEL
, m_locationLabel
);
153 DDX_Control(pDX
, IDC_LOCATION_FIELD
, m_locationField
);
159 CSecondPage::OnSetCursor(CWnd
* pWnd
, UINT nHitTest
, UINT message
)
162 DEBUG_UNUSED(nHitTest
);
163 DEBUG_UNUSED(message
);
165 CPrinterSetupWizardSheet
* psheet
;
167 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
168 require_quiet( psheet
, exit
);
170 SetCursor(psheet
->GetCursor());
179 CSecondPage::OnSetActive()
181 CPrinterSetupWizardSheet
* psheet
;
183 Printers::iterator it
;
184 OSStatus err
= kNoErr
;
186 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
187 require_action( psheet
, exit
, err
= kUnknownErr
);
189 // initialize the browse list...this will remove everything currently
190 // in it, and add the no printers item
194 // And populate the list with any printers that we currently know about
196 for ( it
= psheet
->m_printers
.begin(); it
!= psheet
->m_printers
.end(); it
++ )
198 OnAddPrinter( *it
, false );
201 printer
= psheet
->GetSelectedPrinter();
203 if ( printer
!= NULL
)
205 m_browseList
.Select( printer
->item
, TVGN_FIRSTVISIBLE
);
210 return CPropertyPage::OnSetActive();
215 CSecondPage::OnKillActive()
217 return CPropertyPage::OnKillActive();
221 BEGIN_MESSAGE_MAP(CSecondPage
, CPropertyPage
)
222 ON_NOTIFY(TVN_SELCHANGED
, IDC_BROWSE_LIST
, OnTvnSelchangedBrowseList
)
227 // Printer::EventHandler implementation
229 CSecondPage::OnAddPrinter(
233 CPrinterSetupWizardSheet
* psheet
;
234 OSStatus err
= kNoErr
;
236 check( IsWindow( m_hWnd
) );
238 m_browseList
.SetRedraw(FALSE
);
240 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
241 require_quiet( psheet
, exit
);
243 printer
->item
= m_browseList
.InsertItem(printer
->displayName
);
245 m_browseList
.SetItemData( printer
->item
, (DWORD_PTR
) printer
);
247 m_browseList
.SortChildren(TVI_ROOT
);
249 if ( printer
->name
== m_selectedName
)
251 m_browseList
.SelectItem( printer
->item
);
255 // if the searching item is still in the list
258 // note that order is important here. Insert the printer
259 // item before removing the placeholder so we always have
260 // an item in the list to avoid experiencing the bug
261 // in Microsoft's implementation of CTreeCtrl
263 if (m_emptyListItem
!= NULL
)
265 m_browseList
.DeleteItem(m_emptyListItem
);
266 m_emptyListItem
= NULL
;
267 m_browseList
.EnableWindow(TRUE
);
274 m_browseList
.SetRedraw(TRUE
);
275 m_browseList
.Invalidate();
283 CSecondPage::OnRemovePrinter(
287 CPrinterSetupWizardSheet
* psheet
;
288 OSStatus err
= kNoErr
;
290 check( IsWindow( m_hWnd
) );
293 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
294 require_quiet( psheet
, exit
);
296 m_browseList
.SetRedraw(FALSE
);
299 // check to make sure if we're the only item in the control...i.e.
300 // the list size is 1.
302 if (m_browseList
.GetCount() > 1)
305 // if we're not the only thing in the list, then
306 // simply remove it from the list
308 m_browseList
.DeleteItem( printer
->item
);
313 // if we're the only thing in the list, then redisplay
314 // it with the no printers message
323 m_browseList
.SetRedraw(TRUE
);
324 m_browseList
.Invalidate();
332 CSecondPage::OnResolveService( Service
* service
)
334 CPrinterSetupWizardSheet
* psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
335 require_quiet( psheet
, exit
);
340 // and set it to selected
343 m_selectedName
= service
->printer
->name
;
346 // and update the printer information box
348 SetPrinterInformationState( TRUE
);
350 m_descriptionField
.SetWindowText( service
->description
);
351 m_locationField
.SetWindowText( service
->location
);
357 SetCursor(psheet
->m_active
);
365 void CSecondPage::OnTvnSelchangedBrowseList(NMHDR
*pNMHDR
, LRESULT
*pResult
)
367 LPNMTREEVIEW pNMTreeView
= reinterpret_cast<LPNMTREEVIEW
>(pNMHDR
);
368 CPrinterSetupWizardSheet
* psheet
;
371 HTREEITEM item
= m_browseList
.GetSelectedItem();
372 require_quiet( item
, exit
);
374 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
375 require_action( psheet
, exit
, err
= kUnknownErr
);
379 printer
= reinterpret_cast<Printer
*>(m_browseList
.GetItemData( item
) );
380 require_quiet( printer
, exit
);
383 // this call will trigger a resolve. When the resolve is complete,
384 // our OnResolve will be called.
386 err
= psheet
->StartResolve( printer
);
387 require_noerr( err
, exit
);
390 // And clear out the printer information box
392 SetPrinterInformationState( FALSE
);
393 m_descriptionField
.SetWindowText(L
"");
394 m_locationField
.SetWindowText(L
"");
403 text
.LoadString(IDS_ERROR_SELECTING_PRINTER_TEXT
);
404 caption
.LoadString(IDS_ERROR_SELECTING_PRINTER_CAPTION
);
406 MessageBox(text
, caption
, MB_OK
|MB_ICONEXCLAMATION
);
414 CSecondPage::LoadTextAndDisableWindow( CString
& text
)
416 m_emptyListItem
= m_browseList
.InsertItem( text
, 0, 0, NULL
, TVI_FIRST
);
417 m_browseList
.SelectItem( NULL
);
420 // this will remove everything else in the list...we might be navigating
421 // back to this window, and the browse list might have changed since
422 // we last displayed it.
424 if ( m_emptyListItem
)
426 HTREEITEM item
= m_browseList
.GetNextVisibleItem( m_emptyListItem
);
430 m_browseList
.DeleteItem( item
);
431 item
= m_browseList
.GetNextVisibleItem( m_emptyListItem
);
435 m_browseList
.EnableWindow( FALSE
);
440 CSecondPage::SetPrinterInformationState( BOOL state
)
442 m_printerInformation
.EnableWindow( state
);
444 m_descriptionLabel
.EnableWindow( state
);
446 m_descriptionField
.EnableWindow( state
);
448 m_locationLabel
.EnableWindow( state
);
450 m_locationField
.EnableWindow( state
);