mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
328 lines
9.4 KiB
328 lines
9.4 KiB
// ContainerSelectionDlg.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "OUPicker.h"
|
|
#include "ContainerSelectionDlg.h"
|
|
#include "iads.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CContainerSelectionDlg dialog
|
|
|
|
const BSTR sQuery = L"(|(objectClass=organizationalUnit) (objectClass=container))";
|
|
HTREEITEM root;
|
|
|
|
CContainerSelectionDlg::CContainerSelectionDlg(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CContainerSelectionDlg::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CContainerSelectionDlg)
|
|
m_strCont = _T("");
|
|
//}}AFX_DATA_INIT
|
|
}
|
|
|
|
|
|
void CContainerSelectionDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CContainerSelectionDlg)
|
|
DDX_Control(pDX, IDOK, m_btnOK);
|
|
DDX_Control(pDX, IDC_TREE1, m_trOUTree);
|
|
DDX_Text(pDX, IDC_EDIT1, m_strCont);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CContainerSelectionDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CContainerSelectionDlg)
|
|
ON_BN_CLICKED(IDOK, OnOk)
|
|
ON_NOTIFY(TVN_SELCHANGED, IDC_TREE1, OnSelchangedTree1)
|
|
ON_NOTIFY(NM_DBLCLK, IDC_TREE1, OnDblclkTree1)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CContainerSelectionDlg message handlers
|
|
|
|
void CContainerSelectionDlg::OnOk()
|
|
{
|
|
CDialog::OnOK();
|
|
}
|
|
|
|
BOOL CContainerSelectionDlg::OnInitDialog()
|
|
{
|
|
CWaitCursor wait;
|
|
CDialog::OnInitDialog();
|
|
if ( m_strDomain.IsEmpty() )
|
|
return TRUE;
|
|
|
|
LoadImageList();
|
|
|
|
root = m_trOUTree.InsertItem(m_strDomain, 0, 1);
|
|
ExpandCompletely(root, L"");
|
|
FindContainer();
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
|
|
}
|
|
|
|
HRESULT CContainerSelectionDlg::PopulateContainer(
|
|
HTREEITEM tvItemParent, //in- Item to expand
|
|
BSTR sContName, //in- Name of the container.
|
|
INetObjEnumeratorPtr pQuery //in- Query Object
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
IEnumVARIANT * pEnum = NULL;
|
|
SAFEARRAY * psaCols = NULL;
|
|
SAFEARRAYBOUND bd = { 2, 0 };
|
|
LPWSTR pCols[] = { L"name", L"objectClass" };
|
|
BSTR HUGEP * pData;
|
|
_variant_t var;
|
|
DWORD dwFetch = 0;
|
|
BSTR domain = m_strDomain.AllocSysString();
|
|
SAFEARRAY * psaVals;
|
|
_bstr_t sValName;
|
|
_bstr_t sType;
|
|
_variant_t * pDataVar;
|
|
_variant_t varVal;
|
|
WCHAR sTempName[255];
|
|
int img = 0;
|
|
|
|
psaCols = SafeArrayCreate(VT_BSTR, 1, &bd);
|
|
if ( psaCols )
|
|
{
|
|
hr = SafeArrayAccessData(psaCols, (void HUGEP **)&pData);
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
pData[0] = SysAllocString(pCols[0]);
|
|
pData[1] = SysAllocString(pCols[1]);
|
|
}
|
|
SafeArrayUnaccessData(psaCols);
|
|
}
|
|
|
|
|
|
if ( SUCCEEDED(hr))
|
|
hr = pQuery->raw_SetQuery(sContName, domain, sQuery, ADS_SCOPE_ONELEVEL, FALSE);
|
|
|
|
if ( SUCCEEDED(hr) )
|
|
hr = pQuery->raw_SetColumns(psaCols);
|
|
|
|
if ( SUCCEEDED(hr))
|
|
hr = pQuery->raw_Execute(&pEnum);
|
|
|
|
if ( pEnum )
|
|
{
|
|
while ( pEnum->Next(1, &var, &dwFetch) == S_OK )
|
|
{
|
|
psaVals = V_ARRAY(&var);
|
|
hr = SafeArrayAccessData(psaVals, (void**)&pDataVar);
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
varVal = pDataVar[0];
|
|
if ( varVal.vt == VT_BSTR ) sValName = V_BSTR(&varVal);
|
|
varVal = pDataVar[1];
|
|
if ( varVal.vt == VT_BSTR ) sType = V_BSTR(&varVal);
|
|
SafeArrayUnaccessData(psaVals);
|
|
}
|
|
|
|
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
//
|
|
if ( wcsicmp(sType, L"organizationalUnit") == 0 )
|
|
{
|
|
wsprintf(sTempName, L"OU=%s", (WCHAR*)sValName);
|
|
img = 4;
|
|
}
|
|
else
|
|
{
|
|
wsprintf(sTempName, L"CN=%s", (WCHAR*)sValName);
|
|
img = 2;
|
|
}
|
|
if ( wcsicmp(sTempName, L"CN=System") != 0 )
|
|
m_trOUTree.InsertItem(sTempName, img, img+1, tvItemParent);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Clean up
|
|
::SysFreeString(domain);
|
|
if ( pEnum ) pEnum->Release();
|
|
VariantInit(&var);
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CContainerSelectionDlg::ExpandCompletely(HTREEITEM tvItem, BSTR parentCont)
|
|
{
|
|
HTREEITEM tvChild;
|
|
WCHAR currCont[255];
|
|
CString sContName;
|
|
HRESULT hr = S_OK;
|
|
INetObjEnumeratorPtr pQuery(__uuidof(NetObjEnumerator));
|
|
|
|
// First populate this container
|
|
hr = PopulateContainer( tvItem, parentCont, pQuery);
|
|
|
|
// Check if it has children. If it does then for each child call this function recursively
|
|
if ( m_trOUTree.ItemHasChildren(tvItem) )
|
|
{
|
|
tvChild = m_trOUTree.GetChildItem(tvItem);
|
|
while ( tvChild )
|
|
{
|
|
// Get the name of the
|
|
sContName = m_trOUTree.GetItemText(tvChild);
|
|
if ( wcslen(parentCont) > 0 )
|
|
wsprintf(currCont, L"%s,%s", sContName, (WCHAR*)parentCont);
|
|
else
|
|
wcscpy(currCont, sContName);
|
|
ExpandCompletely(tvChild, currCont);
|
|
tvChild = m_trOUTree.GetNextSiblingItem(tvChild);
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
BOOL CContainerSelectionDlg::LoadImageList()
|
|
{
|
|
// set up icon list for list box
|
|
// use bitmaps
|
|
CBitmap cont;
|
|
CBitmap ou;
|
|
CBitmap openCont;
|
|
CBitmap openOU;
|
|
CBitmap dir;
|
|
CBitmap dirOpen;
|
|
|
|
COLORREF cr = 0x000000;
|
|
if (
|
|
dir.LoadBitmap(IDB_DIR)
|
|
&& dirOpen.LoadBitmap(IDB_OPEN_DIR)
|
|
&& cont.LoadBitmap(IDB_CONT)
|
|
&& ou.LoadBitmap(IDB_OU)
|
|
&& openCont.LoadBitmap(IDB_OPEN_CONT)
|
|
&& openOU.LoadBitmap(IDB_OPEN_OU)
|
|
)
|
|
{
|
|
cr = GetFirstBitmapPixel(this,IDB_CONT);
|
|
ilist.Create(IDB_DIR, 16, 16, cr);
|
|
ilist.Add(&dirOpen, cr);
|
|
ilist.Add(&cont,cr);
|
|
ilist.Add(&openCont,cr);
|
|
ilist.Add(&ou,cr);
|
|
ilist.Add(&openOU,cr);
|
|
m_trOUTree.SetImageList(&ilist,TVSIL_NORMAL);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
COLORREF CContainerSelectionDlg::GetFirstBitmapPixel(CWnd * window,UINT idbBitmap)
|
|
{
|
|
CBitmap bmp;
|
|
COLORREF color = 0x00ffffff;
|
|
|
|
if ( bmp.LoadBitmap(idbBitmap) )
|
|
{
|
|
// Get Device context
|
|
CDC * windowDC = window->GetDC();
|
|
HDC hdcImage = ::CreateCompatibleDC(windowDC->m_hDC);
|
|
CBitmap * tempBmp = (CBitmap *)::SelectObject(hdcImage,(HBITMAP)bmp);
|
|
// now get the pixel
|
|
if ( windowDC && hdcImage && tempBmp )
|
|
{
|
|
color = GetPixel(hdcImage,0, 0);
|
|
}
|
|
if ( tempBmp )
|
|
::SelectObject(hdcImage,tempBmp);
|
|
if ( hdcImage )
|
|
::DeleteObject(hdcImage);
|
|
}
|
|
return color;
|
|
}
|
|
|
|
void CContainerSelectionDlg::OnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
m_strCont = L"";
|
|
HTREEITEM tvSelected, tvParent;
|
|
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
|
|
tvSelected = m_trOUTree.GetSelectedItem();
|
|
if ( tvSelected )
|
|
{
|
|
// We dont want to process the domain name in the Container name so go upto
|
|
// the point where we have a parent. i.e. Child of the domain node.
|
|
while( tvParent = m_trOUTree.GetParentItem(tvSelected) )
|
|
{
|
|
// Build the container list by walking up the tree.
|
|
if ( m_strCont.IsEmpty() )
|
|
m_strCont = m_trOUTree.GetItemText(tvSelected);
|
|
else
|
|
m_strCont = m_strCont + CString(L",") + m_trOUTree.GetItemText(tvSelected);
|
|
tvSelected = tvParent;
|
|
}
|
|
}
|
|
m_btnOK.EnableWindow(!m_strCont.IsEmpty());
|
|
UpdateData(FALSE);
|
|
*pResult = 0;
|
|
}
|
|
|
|
void CContainerSelectionDlg::OnDblclkTree1(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
UpdateData();
|
|
if ( !m_strCont.IsEmpty() )
|
|
OnOk();
|
|
*pResult = 0;
|
|
}
|
|
|
|
HRESULT CContainerSelectionDlg::FindContainer()
|
|
{
|
|
CString strName;
|
|
int ndx = 0, oldNdx = -1;
|
|
// We can find the container iff there is one specified.
|
|
if (!m_strCont.IsEmpty())
|
|
{
|
|
OpenContainer(m_strCont, root);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
HTREEITEM CContainerSelectionDlg::OpenContainer(CString strCont, HTREEITEM rootSub)
|
|
{
|
|
int ndx = -1;
|
|
CString strLeft, strRight;
|
|
HTREEITEM tvItem = NULL;
|
|
|
|
if ( !strCont.IsEmpty() && rootSub )
|
|
{
|
|
ndx = strCont.Find(L",", 0);
|
|
if ( ndx > -1 )
|
|
{
|
|
// Get the right side of the comma string and Call this again to open the parent container.
|
|
strLeft = strCont.Left(ndx);
|
|
strRight = strCont.Mid(ndx + 1);
|
|
tvItem = OpenContainer(strRight, rootSub);
|
|
tvItem = OpenContainer(strLeft, tvItem);
|
|
}
|
|
else
|
|
{
|
|
// We have a container name so lets find it below rootSub node.
|
|
tvItem = m_trOUTree.GetChildItem(rootSub);
|
|
while (tvItem)
|
|
{
|
|
if ( m_trOUTree.GetItemText(tvItem) == strCont )
|
|
{
|
|
//m_trOUTree.Expand(tvItem, 0);
|
|
m_trOUTree.Select(tvItem, TVGN_CARET);
|
|
break;
|
|
}
|
|
tvItem = m_trOUTree.GetNextSiblingItem(tvItem);
|
|
}
|
|
}
|
|
}
|
|
return tvItem;
|
|
}
|