home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 27 / IOPROG_27.ISO / SOFT / ADSDK.ZIP / Samples / General / ADQI / adscontainer.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-04-01  |  11.2 KB  |  540 lines

  1. //----------------------------------------------------------------------------
  2. //
  3. //  Microsoft Active Directory 2.5 Sample Code
  4. //
  5. //  Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. //  File:       ADsContainer.cpp
  8. //
  9. //  Contents:   IADsContainer usage
  10. //
  11. //
  12. //----------------------------------------------------------------------------
  13.  
  14. #include "stdafx.h"
  15. #include "ADQI.h"
  16. #include "ads.h"
  17. #include "ADsContainer.h"
  18.  
  19. #ifdef _DEBUG
  20. #undef THIS_FILE
  21. static char THIS_FILE[]=__FILE__;
  22. #define new DEBUG_NEW
  23. #endif
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30. /////////////////////////////////////////////////////////////////////////////
  31. // CDlgIADsContainer dialog
  32.  
  33.  
  34. CDlgIADsContainer::CDlgIADsContainer(LPUNKNOWN pUnk, CWnd* pParent /*=NULL*/)
  35.     : CDialog(CDlgIADsContainer::IDD, pParent)
  36. {
  37.     //{{AFX_DATA_INIT(CDlgIADsContainer)
  38.     m_sFilter = _T("");
  39.     //}}AFX_DATA_INIT
  40.  
  41.     ///////////////////////////////////////
  42.     // Get the IADsContainer pointer and save it as a member
  43.     /////////////////////////////////////
  44.     HRESULT hr;
  45.     m_pCont = NULL;
  46.     hr = pUnk->QueryInterface( IID_IADsContainer, (void **) &m_pCont );
  47.     if ( !SUCCEEDED(hr) )
  48.     {
  49.         AfxMessageBox(_T("Fatal Error! QI for IADs failed"));
  50.         return;
  51.     }
  52.     pUnk->Release();
  53.  
  54. }
  55.  
  56. CDlgIADsContainer::~CDlgIADsContainer()
  57. {
  58.     
  59.     if ( m_pCont )
  60.     {
  61.          m_pCont->Release();
  62.     }
  63. }
  64.  
  65.  
  66. void CDlgIADsContainer::DoDataExchange(CDataExchange* pDX)
  67. {
  68.     CDialog::DoDataExchange(pDX);
  69.     //{{AFX_DATA_MAP(CDlgIADsContainer)
  70.     DDX_Control(pDX, IDC_CHILDRENLIST, m_cChildList);
  71.     DDX_Text(pDX, IDC_FILTER, m_sFilter);
  72.     //}}AFX_DATA_MAP
  73. }
  74.  
  75.  
  76. BEGIN_MESSAGE_MAP(CDlgIADsContainer, CDialog)
  77.     //{{AFX_MSG_MAP(CDlgIADsContainer)
  78.     ON_BN_CLICKED(IDC_VIEW, OnView)
  79.     ON_LBN_DBLCLK(IDC_CHILDRENLIST, OnDblClkChildrenList)
  80.     ON_BN_CLICKED(IDC_DELETE, OnDelete)
  81.     ON_BN_CLICKED(IDC_RENAME, OnRename)
  82.     ON_BN_CLICKED(IDC_SET, OnSet)
  83.     ON_BN_CLICKED(IDC_MOVE, OnMove)
  84.     //}}AFX_MSG_MAP
  85. END_MESSAGE_MAP()
  86.  
  87. /////////////////////////////////////////////////////////////////////////////
  88. // CDlgIADsContainer message handlers
  89.  
  90. BOOL CDlgIADsContainer::OnInitDialog() 
  91. {
  92.     
  93.     CDialog::OnInitDialog();    
  94.     EnumerateChildren();
  95.     return TRUE;  // return TRUE unless you set the focus to a control
  96.                   // EXCEPTION: OCX Property Pages should return FALSE
  97. }
  98.  
  99. //////////////////////////////////////////////////////////
  100. // On View demonstrate the IADsContainer::GetObject()
  101. // This is when the user double click the list box or
  102. // when the user select an item in the list and click "View"
  103. /////////////////////////////////////////////////////////////
  104. void CDlgIADsContainer::OnView() 
  105. {
  106.     ASSERT( m_pCont );
  107.  
  108.     
  109.     
  110.     CString sName;
  111.     CString sClass;
  112.     HRESULT hr;
  113.  
  114.     
  115.     if ( !GetClassAndName( sClass, sName) )
  116.     {
  117.         return;
  118.     }
  119.  
  120.  
  121.     USES_CONVERSION;
  122.     IDispatch *pDisp;
  123.     IUnknown  *pUnk;
  124.     hr = m_pCont->GetObject(T2OLE(sClass), T2OLE(sName), &pDisp );
  125.     if ( !SUCCEEDED(hr) )
  126.     {
  127.         return;
  128.     }
  129.  
  130.     pDisp->QueryInterface( IID_IUnknown, (void**) &pUnk );
  131.     pDisp->Release();
  132.  
  133.  
  134.     /////////////////////////////////
  135.     // Bring up the dialog box
  136.     ////////////////////////////////////
  137.     pUnk->AddRef();
  138.     CDlgIADs dlg( pUnk );
  139.     dlg.DoModal();
  140.     pUnk->Release();
  141.     
  142. }
  143.  
  144. void CDlgIADsContainer::OnDblClkChildrenList() 
  145. {
  146.     OnView();    
  147. }
  148.  
  149. ////////////////////////////////
  150. // IADsContainer::Delete
  151. /////////////////////////////////
  152. void CDlgIADsContainer::OnDelete() 
  153. {
  154.     CString sName;
  155.     CString sClass;
  156.     HRESULT hr;
  157.  
  158.     
  159.     if ( !GetClassAndName( sClass, sName) )
  160.     {
  161.         return;
  162.     }
  163.  
  164.     ///////////////////////
  165.     // Delete Now
  166.     ////////////////////////
  167.     USES_CONVERSION;
  168.     ///////////////////////////////////////////////////////////////
  169.     // For example m_pCont->Delete(L"user", L"cn=jsmith");
  170.     ////////////////////////////////////////////////////////////////
  171.     hr = m_pCont->Delete( T2OLE( sClass ), T2OLE( sName ) );
  172.     if (!SUCCEEDED(hr) )
  173.     {
  174.         AfxMessageBox( GetErrorMessage(hr));
  175.         return;
  176.     }
  177.     EnumerateChildren();
  178. }
  179.  
  180.  
  181.  
  182. BOOL CDlgIADsContainer::GetClassAndName(CString & sClass, CString & sName)
  183. {
  184.     int idx;
  185.     POSITION pos;
  186.  
  187.  
  188.     idx = m_cChildList.GetCurSel();
  189.     if ( idx == LB_ERR )
  190.     {
  191.         return FALSE;
  192.     }
  193.  
  194.  
  195.     m_cChildList.GetText( idx, sName );
  196.     pos = m_sClassList.FindIndex( idx );
  197.     if ( pos == NULL )
  198.     {
  199.       return FALSE;
  200.     }
  201.  
  202.     sClass = m_sClassList.GetAt(pos);
  203.     return TRUE;
  204.  
  205. }
  206.  
  207.  
  208. //////////////////////////////////////////////////
  209. // EnumerateChildren Function
  210. // IADsContainer::get_Enum
  211. // ADsBuildEnumerator
  212. // ADsEnumerateNext
  213. // ADsFreeEnumerator
  214. //
  215. ///////////////////////////////////////////////
  216. HRESULT CDlgIADsContainer::EnumerateChildren()
  217. {
  218.     HRESULT hr=S_OK;
  219.     VARIANT var;
  220.     ULONG   lFetch;
  221.  
  222.     m_cChildList.ResetContent();
  223.     m_sClassList.RemoveAll();
  224.  
  225.     //////////////////////////////////////////////////////
  226.     // Use the ADSI Helper APIs to enumerate Children
  227.     ////////////////////////////////////////////////////
  228.     IEnumVARIANT *pEnum;
  229.     IDispatch     *pDisp;
  230.     IADs         *pADs;
  231.     BSTR          bstr;
  232.     CString       s;
  233.     
  234.     VariantInit(&var);
  235.     hr = ADsBuildEnumerator( m_pCont, &pEnum );
  236.     if ( !SUCCEEDED(hr) )
  237.     {
  238.         return S_FALSE;
  239.     }
  240.     
  241.     hr = ADsEnumerateNext( pEnum, 1, &var, &lFetch );
  242.     while( hr == S_OK )
  243.     {        
  244.         if ( lFetch == 1 )
  245.         {
  246.                pDisp = V_DISPATCH(&var);
  247.             ///////////////////////////
  248.             // Get the Child Name
  249.             /////////////////////////////
  250.             hr = pDisp->QueryInterface( IID_IADs, (void**)&pADs ); 
  251.             if ( SUCCEEDED(hr) )
  252.             {
  253.                 pADs->get_Name(&bstr);
  254.                 s = bstr;
  255.                 m_cChildList.AddString( s );
  256.                 SysFreeString(bstr);
  257.                 
  258.             
  259.               ///////////////////////////////////////////////
  260.               // While we're holding the child's object
  261.               // let's get the class info for later use. 
  262.               // The class info will be used for getting the actual object
  263.               // via IADsContainer::GetObject) when the user wants to view
  264.               // object in detail. 
  265.               // We could have stored the ADsPath as well. 
  266.               //////////////////////////////////////////////
  267.                 pADs->get_Class(&bstr);
  268.                 s = bstr;
  269.                 m_sClassList.AddTail( s );
  270.                 SysFreeString(bstr);
  271.  
  272.                 pADs->Release();
  273.             }
  274.  
  275.             VariantClear(&var);
  276.         }
  277.         hr = ADsEnumerateNext( pEnum, 1, &var, &lFetch );
  278.     };
  279.  
  280.     
  281.  
  282.  
  283.     // Free Enumerator
  284.     ADsFreeEnumerator( pEnum );
  285.     
  286.     return S_OK;
  287.  
  288.  
  289. }
  290.  
  291.  
  292.  
  293. /////////////////////////////////////////
  294. // OnRename
  295. // Demonstrate: 
  296. // IADsContainer::MoveHere
  297. // IADsContainer::GetObject
  298. //////////////////////////////////////////////
  299. void CDlgIADsContainer::OnRename() 
  300. {
  301.    CString sName;
  302.    CString sNewName;
  303.    CString sClass;
  304.  
  305.    if ( !GetClassAndName( sClass,  sName) )
  306.    {
  307.        return;
  308.    }
  309.    
  310.    CRenameDlg dlg( sName );
  311.  
  312.    if ( dlg.DoModal() == IDOK )
  313.    {
  314.       //////////////////////////////////////////////////////////////////
  315.       // To Rename we need:
  316.       //  1. A new name ( we'll get it from the rename dialog box )
  317.       //  2. ADsPath of the object to be renamed 
  318.       //  3. The container where the child lives.
  319.       /////////////////////////////////////////////////////////////////
  320.  
  321.       sNewName = dlg.GetName();
  322.  
  323.       //////////////////////////////////////////////////
  324.       // Get the child's ADsPath,
  325.       // First we can use IADsContainer::GetObject
  326.       /////////////////////////////////////////////////////
  327.       USES_CONVERSION;
  328.       IDispatch *pDisp;
  329.       IADs        *pADs;
  330.       BSTR        bstrPath;
  331.       CString    sADsPath;
  332.       HRESULT   hr;
  333.  
  334.       hr = m_pCont->GetObject(T2OLE(sClass), T2OLE(sName), &pDisp );
  335.       if ( !SUCCEEDED(hr) )
  336.       {
  337.           return;
  338.       }
  339.       
  340.       hr = pDisp->QueryInterface( IID_IADs, (void**) &pADs );
  341.       pDisp->Release();
  342.  
  343.       ////////////////////////////////
  344.       // Now get the child's ADsPath
  345.       //////////////////////////////////
  346.       if ( !SUCCEEDED(hr) )
  347.       {
  348.           return;
  349.       }
  350.  
  351.       pADs->get_ADsPath( &bstrPath );      
  352.       pADs->Release();
  353.     
  354.       ////////////////////////////////////////////////////
  355.       // We have all the information, time to rename    //
  356.       ////////////////////////////////////////////////////
  357.       hr = m_pCont->MoveHere( bstrPath, T2OLE(sNewName), &pDisp );
  358.       SysFreeString( bstrPath );
  359.      
  360.       if ( !SUCCEEDED(hr) )
  361.       {
  362.           AfxMessageBox(GetErrorMessage(hr));
  363.           return;
  364.       }
  365.       pDisp->Release();
  366.  
  367.       // Refresh the list
  368.       EnumerateChildren();
  369.       
  370.       
  371.    }
  372.     
  373. }
  374.  
  375. void CDlgIADsContainer::OnMove() 
  376. {
  377.     CMoveDlg dlg;
  378.     if ( dlg.DoModal() == IDOK )
  379.     {
  380.         CString sADsPath;
  381.         IDispatch *pDisp;
  382.         USES_CONVERSION;
  383.         HRESULT hr;
  384.  
  385.         sADsPath = dlg.GetObjectPath();
  386.         hr = m_pCont->MoveHere( T2OLE(sADsPath), NULL, &pDisp );
  387.         pDisp->Release();
  388.         RETURN_ON_FAILURE(hr);
  389.  
  390.         EnumerateChildren(); // Refresh the list
  391.  
  392.     }
  393.     
  394. }
  395.  
  396. void CDlgIADsContainer::OnOK() 
  397. {
  398.     m_sClassList.RemoveAll();
  399.     CDialog::OnOK();
  400. }
  401.  
  402. ///////////////////////////////
  403. // IADsContainer::put_Filter
  404. //
  405. void CDlgIADsContainer::OnSet() 
  406. {
  407.     CStringList sList;
  408.     VARIANT var;
  409.     HRESULT hr;
  410.     
  411.     
  412.     UpdateData(TRUE);
  413.     VariantInit(&var);
  414.  
  415.     // The user may enter many classes to filter 'user,group'
  416.     StringToStringList( m_sFilter, sList );
  417.     StringListToVariant(var, sList );
  418.  
  419.     hr = m_pCont->put_Filter( var );
  420.  
  421.     VariantClear(&var);
  422.  
  423.     if ( !SUCCEEDED(hr) )
  424.     {
  425.         AfxMessageBox(GetErrorMessage(hr));
  426.         return;
  427.     }
  428.  
  429.     EnumerateChildren();
  430.     
  431. }
  432.  
  433.  
  434.  
  435.  
  436.  
  437. /////////////////////////////////////////////////////////////////////////////
  438. // CRenameDlg dialog
  439.  
  440.  
  441. CRenameDlg::CRenameDlg(CString sOldName, CWnd* pParent /*=NULL*/)
  442.     : CDialog(CRenameDlg::IDD, pParent)
  443. {
  444.     //{{AFX_DATA_INIT(CRenameDlg)
  445.     m_sName = _T("");
  446.     //}}AFX_DATA_INIT
  447.     
  448.     m_sOldName = _T("Rename '");
  449.     m_sOldName += sOldName;
  450.     m_sOldName += _T("'");
  451.     m_sNewName = _T("");
  452.     
  453. }
  454.  
  455.  
  456. void CRenameDlg::DoDataExchange(CDataExchange* pDX)
  457. {
  458.     CDialog::DoDataExchange(pDX);
  459.     //{{AFX_DATA_MAP(CRenameDlg)
  460.     DDX_Text(pDX, IDC_NAME, m_sName);
  461.     //}}AFX_DATA_MAP
  462. }
  463.  
  464.  
  465. BEGIN_MESSAGE_MAP(CRenameDlg, CDialog)
  466.     //{{AFX_MSG_MAP(CRenameDlg)
  467.     //}}AFX_MSG_MAP
  468. END_MESSAGE_MAP()
  469.  
  470. /////////////////////////////////////////////////////////////////////////////
  471. // CRenameDlg message handlers
  472.  
  473. void CRenameDlg::OnOK() 
  474. {
  475.     UpdateData(TRUE);
  476.     m_sNewName = m_sName;
  477.     CDialog::OnOK();
  478. }
  479.  
  480.  
  481.  
  482. BOOL CRenameDlg::OnInitDialog() 
  483. {
  484.     CDialog::OnInitDialog();
  485.     
  486.     SetWindowText( m_sOldName );
  487.     return TRUE;  // return TRUE unless you set the focus to a control
  488.                   // EXCEPTION: OCX Property Pages should return FALSE
  489. }
  490.  
  491.  
  492.  
  493. /////////////////////////////////////////////////////////////////////////////
  494. // CMoveDlg dialog
  495.  
  496.  
  497. CMoveDlg::CMoveDlg(CWnd* pParent /*=NULL*/)
  498.     : CDialog(CMoveDlg::IDD, pParent)
  499. {
  500.     //{{AFX_DATA_INIT(CMoveDlg)
  501.     m_sADsPath = _T("");
  502.     //}}AFX_DATA_INIT
  503. }
  504.  
  505.  
  506. void CMoveDlg::DoDataExchange(CDataExchange* pDX)
  507. {
  508.     CDialog::DoDataExchange(pDX);
  509.     //{{AFX_DATA_MAP(CMoveDlg)
  510.     DDX_Text(pDX, IDC_ADSPATH, m_sADsPath);
  511.     //}}AFX_DATA_MAP
  512. }
  513.  
  514.  
  515. BEGIN_MESSAGE_MAP(CMoveDlg, CDialog)
  516.     //{{AFX_MSG_MAP(CMoveDlg)
  517.     ON_EN_CHANGE(IDC_ADSPATH, OnChangeADspath)
  518.     //}}AFX_MSG_MAP
  519. END_MESSAGE_MAP()
  520.  
  521. /////////////////////////////////////////////////////////////////////////////
  522. // CMoveDlg message handlers
  523.  
  524. void CMoveDlg::OnOK() 
  525. {
  526.     UpdateData(TRUE); //Retrieve
  527.     CDialog::OnOK();
  528. }
  529.  
  530.  
  531. void CMoveDlg::OnChangeADspath() 
  532. {
  533.     BOOL bEnabled;
  534.     bEnabled = GetDlgItem(IDC_ADSPATH)->GetWindowTextLength() > 0 ? TRUE : FALSE;
  535.  
  536.     GetDlgItem(IDOK)->EnableWindow( bEnabled );
  537.  
  538.     
  539. }
  540.