// Printer::EventHandler implementation OSStatus CSecondPage::OnAddPrinter( uint32_t inInterfaceIndex, const char * inName, const char * inType, const char * inDomain, bool moreComing) { Printer * printer; Service * service; CPrinterSetupWizardSheet * psheet; DWORD printerNameCount; bool newPrinter = false; OSStatus err = kNoErr; check( IsWindow( m_hWnd ) ); m_browseList.SetRedraw(FALSE); psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent()); require_quiet( psheet, exit ); printer = Lookup( inName ); if (printer == NULL) { try { printer = new Printer; } catch (...) { printer = NULL; } require_action( printer, exit, err = E_OUTOFMEMORY ); printer->window = this; printer->name = inName; err = UTF8StringToStringObject(inName, printer->displayName); check_noerr( err ); printer->actualName = printer->displayName; printer->installed = false; printer->deflt = false; printer->resolving = 0; // // Compare this name against printers that are already installed // to avoid name clashes. Rename as necessary // to come up with a unique name. // printerNameCount = 2; for (;;) { PrinterNameMap::iterator it; it = m_printerNames.find(printer->actualName); if (it != m_printerNames.end()) { printer->actualName.Format(L"%s (%d)", printer->displayName, printerNameCount); } else { break; } printerNameCount++; } newPrinter = true; } check( printer ); service = printer->LookupService( inType ); if ( service != NULL ) { service->refs++; } else { try { service = new Service; } catch (...) { service = NULL; } require_action( service, exit, err = E_OUTOFMEMORY ); service->printer = printer; service->ifi = inInterfaceIndex; service->type = inType; service->domain = inDomain; service->qtotal = 1; service->refs = 1; service->serviceRef = NULL; printer->services.push_back( service ); // // if the printer is selected, then we'll want to start a // resolve on this guy // if ( m_selected == printer ) { StartResolve( service ); } } if ( newPrinter ) { printer->item = m_browseList.InsertItem(printer->displayName); m_browseList.SetItemData( printer->item, (DWORD_PTR) printer ); m_printers.push_back( printer ); m_browseList.SortChildren(TVI_ROOT); if ( printer->name == m_selectedName ) { m_browseList.SelectItem( printer->item ); } // // 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); } } exit: if (!moreComing) { m_browseList.SetRedraw(TRUE); m_browseList.Invalidate(); } return err; }
OSStatus CSecondPage::OnRemovePrinter( const char * inName, const char * inType, const char * inDomain, bool moreComing) { DEBUG_UNUSED( inDomain ); DEBUG_UNUSED( inType ); Printer * printer; OSStatus err = kNoErr; check( IsWindow( m_hWnd ) ); m_browseList.SetRedraw(FALSE); printer = Lookup( inName ); if ( printer ) { Service * service; service = printer->LookupService( inType ); if ( service && ( --service->refs == 0 ) ) { if ( service->serviceRef != NULL ) { err = StopResolve( service ); require_noerr( err, exit ); } printer->services.remove( service ); delete service; } if ( printer->services.size() == 0 ) { // // 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 rendezvous printers message // InitBrowseList(); } m_printers.remove( printer ); if ( m_selected == printer ) { m_selected = NULL; m_selectedName = ""; } delete printer; } } exit: if (!moreComing) { m_browseList.SetRedraw(TRUE); m_browseList.Invalidate(); } return err; }
void DNSSD_API CPrinterSetupWizardSheet::OnBrowse( DNSServiceRef inRef, DNSServiceFlags inFlags, uint32_t inInterfaceIndex, DNSServiceErrorType inErrorCode, const char * inName, const char * inType, const char * inDomain, void * inContext ) { DEBUG_UNUSED(inRef); CPrinterSetupWizardSheet * self; bool moreComing = (bool) (inFlags & kDNSServiceFlagsMoreComing); CPropertyPage * active; Printer * printer = NULL; Service * service = NULL; OSStatus err = kNoErr; require_noerr( inErrorCode, exit ); self = reinterpret_cast <CPrinterSetupWizardSheet*>( inContext ); require_quiet( self, exit ); active = self->GetActivePage(); require_quiet( active, exit ); // Have we seen this printer before? printer = self->Lookup( inName ); if ( printer ) { service = printer->LookupService( inType ); } if ( inFlags & kDNSServiceFlagsAdd ) { if (printer == NULL) { // If not, then create a new one printer = self->OnAddPrinter( inInterfaceIndex, inName, inType, inDomain, moreComing ); require_action( printer, exit, err = kUnknownErr ); } if ( !service ) { err = self->OnAddService( printer, inInterfaceIndex, inName, inType, inDomain ); require_noerr( err, exit ); } else { service->refs++; } } else if ( printer ) { check( service ); err = self->OnRemoveService( service ); require_noerr( err, exit ); if ( printer->services.size() == 0 ) { err = self->OnRemovePrinter( printer, moreComing ); require_noerr( err, exit ); } } exit: return; }