void CKDTree::SearchTree(KD_Node *parent, Point &p, float radius, ivector &vec_r)
{
	if (parent==NULL || parent->IsSearched)
		return;
	parent->IsSearched=true;
	//is a child node
	if(parent->m_left==NULL && parent->m_right==NULL)
	{
		int nSize=parent->m_vecIn.size();
		for (int i=0; i<nSize; ++i)
			if(m_regionArray[parent->m_vecIn[i]].IsSeen(p, radius))
				vec_r.push_back(parent->m_vecIn[i]);
	}
	//not a child node
	else
	{
		if(parent->m_left!=NULL && !parent->m_left->IsSearched && 
			(parent->m_left->m_regOverlap.IsSeen(p, radius)))
			SearchTree(parent->m_left, p, radius, vec_r);
		if (parent->m_right!=NULL && !parent->m_right->IsSearched &&
			(parent->m_right->m_regOverlap.IsSeen(p, radius)))
			SearchTree(parent->m_right, p, radius, vec_r);
	}
	//back trace : search parent
	SearchTree(parent->m_parent, p, radius, vec_r);
}
Ejemplo n.º 2
0
void CCJShellTree::TunnelTree(CString strFindPath)
{
	HTREEITEM subNode = GetRootItem();
	CString szPathHop;
	char drive[_MAX_DRIVE];
	char dir[_MAX_DIR];
	char fname[_MAX_FNAME];
	char ext[_MAX_EXT];
	char delimiter[]="\\";

	m_bRefresh = false;
	
	if(!m_shell.Exist(strFindPath))
	{
		if (strFindPath.GetLength() == 3)
		{
		}

		else
		{
			MessageBox(strFindPath,_T("Folder not found"),MB_ICONERROR);
			return;
		}
	}
	
	if(strFindPath.ReverseFind(_T('\\')) != strFindPath.GetLength()-1)
	{
		strFindPath += _T("\\");
	}
	
	m_shell.SplitPath(strFindPath,drive,dir,fname,ext);
	
	//search the drive first
	szPathHop=drive;
	subNode=GetChildItem(subNode);

	if(subNode)
	{
		if(SearchTree(subNode,szPathHop, CCJShellTree::type_drive))
		{
			SetRedraw(FALSE);
			//break down subfolders and search
			char *p=strtok(dir,delimiter);
			while(p)
			{
				subNode = GetSelectedItem();
				Expand(subNode, TVE_EXPAND);
				subNode = GetChildItem(subNode);

				if(SearchTree(subNode,p,CCJShellTree::type_folder))
					p=strtok(NULL,delimiter);
				else
					p=NULL;
			}
			SetRedraw();
		}
	}
}
Ejemplo n.º 3
0
NodeTree* SearchTree(NodeTree* ApT, key k) {

    if(ApT == NULL) {
        return NULL;
    }
    else if (ApT->info == k) {
        return ApT;
    }
    else if (ApT->info > k) {
        return SearchTree(ApT->left, k);
    }
    else {
        return SearchTree(ApT->right, k);
    }
}
//search the tree
void CKDTree::SearchTree(Point &p, float radius, ivector &vec_r)
{
	ResetTree(m_root);
	KD_Node *n=m_pRecentRoot;
	if (n==NULL)
	{
		n=m_root;
	}
	else
	{
		n=m_pRecentRoot;
		while(n!=m_root && !n->m_regOverlap.IsIn(p))
			n=n->m_parent;
	}
	while(n!=NULL && (n->m_left!=NULL || n->m_right!=NULL))
	{
		if (n->IsSplitX)
		{
			if(p.m_x<n->m_nMedian)
				n=n->m_left;
			else
				n=n->m_right;
		}
		else
		{
			if(p.m_y<n->m_nMedian)
				n=n->m_left;
			else
				n=n->m_right;
		}
	}
	m_pRecentRoot=n;
	SearchTree(n, p, radius, vec_r);
}
Ejemplo n.º 5
0
/* #FN#
   Pushes down and selects an item one level at a time until either we
   can't find anymore parts of the path, or we've finished searching

   Doesn't work on network (UNC) paths (Could search NETHOOD when
   prefix is \\) */
void
/* #AS#
   Nothing */
CShellTree::
TunnelTree(
	LPCSTR lpszPath /* #IN# */
)
{
	char szSearchPath[ MAX_PATH + 1 ];
	BOOL bFound = FALSE;
	int  i = 0;

	HTREEITEM hTopLevelItem;
	HTREEITEM hItem;

	if( (hTopLevelItem = GetRootItem()) )
	{
		do /* Enumerate the top level items */
		{
			if( Expand( hTopLevelItem, TVE_EXPAND ) )
			{
				hItem = GetChildItem( hTopLevelItem );

				while( hItem )
				{
					for( ; i < (int)strlen( lpszPath ) && lpszPath[ i ] != '\\'; i++ )
						szSearchPath[ i ] = lpszPath[ i ];

					szSearchPath[ i++ ] = '\0';
					/* Add ending backslash to drive name */
					if( strlen( szSearchPath ) == 2 && szSearchPath[ 1 ] == ':' )
						strcat( szSearchPath, "\\" );

					if( SearchTree( hItem, szSearchPath ) )
					{
						hItem = GetSelectedItem();
						if( Expand( hItem, TVE_EXPAND ) )
						{
							/* Get first leaf of the new bunch */
							hItem = GetChildItem( hItem );
						}
						bFound = TRUE;
					}
					else
						break;
					/* Append a folder delimiter */
					szSearchPath[ i - 1 ] = '\\';
				}
				/* The path has not been found, reset the searching "engine" */
				if( !bFound )
				{
					Expand( hTopLevelItem, TVE_COLLAPSE );
					i = 0;
				}
			}
		}
		while( !bFound && (hTopLevelItem = GetNextSiblingItem( hTopLevelItem )) );
	}
} /* #OF# CShellTree::TunnelTree */
Ejemplo n.º 6
0
Archivo: ugenv.c Proyecto: rolk/ug
ENVITEM * NS_PREFIX SearchEnv (const char *name, const char *where, INT type, INT dirtype)
{
  /* check if search directory is changed */
  if (strcmp(where,".")!=0)
    if (ChangeEnvDir(where)==NULL) return(NULL);

  /* recursive search */
  return(SearchTree(name,type,dirtype));
}
Ejemplo n.º 7
0
ND* SearchTree(const ND* node, char* searchString)
{
	ND* found = NULL;

	if (node == NULL) {
		return (ND*)found;
	}

	if (strcmp(node->text, searchString) == 0) {
		return (ND*)node;
	}
	if ((found = SearchTree(node->next, searchString)) != NULL) {
		return found;
	}
	if ((found = SearchTree(node->children, searchString)) != NULL) {
		return found;
	}
	return found;
}
Ejemplo n.º 8
0
D3DXVECTOR3 QuadTree::PlaceATower(D3D10_VIEWPORT vp, POINT mouse)
{
	D3DXVECTOR3 vPickRayDir;
	D3DXVECTOR3 vPickRayOrig;
	GenerateMouse3DPos(vp, mouse, vPickRayDir, vPickRayOrig);

	SearchTree(vPickRayDir, vPickRayOrig, getBLS());

	D3DXVECTOR3 ret = newTowerPos;
	newTowerPos = D3DXVECTOR3(-99,-99,-99);
	return ret;
}
Ejemplo n.º 9
0
bool SearchTree(TreeNode *root,int key, int &ret)
{
    if (root) {
        if (root->Key > key)
        {
            //std::cout << root->Key << std::endl;
            SearchTree (root->Left,key, ret);
        } else if (root->Key < key)
        {
            //std::cout << root->Key << std::endl;
            SearchTree(root->Right,key, ret);
        } else if (root->Key == key)
        {
            //std::cout << root->Key << std::endl;
            ret = true;
            return true;
        }
    }
  //  std::cout << root << std::endl;
    return false;
}
Ejemplo n.º 10
0
void QuadTree::SearchTree(D3DXVECTOR3 vPickRayDir, D3DXVECTOR3 vPickRayOrig, BoxNode box)
{
	bool result = false;

	result = Pick(vPickRayDir, vPickRayOrig, box);

	if (!result)
		return;

	if (!box.ChildNode.empty())
	{	
		for (int i=0; i<4; ++i)
			SearchTree(vPickRayDir, vPickRayOrig, box.ChildNode.at(i));
		return;
	}

	newTowerPos.x = (box.minB.x+box.maxB.x)/2;
	newTowerPos.z = (box.minB.z+box.maxB.z)/2;
	newTowerPos.y =  pLand->getHeight(newTowerPos.x, newTowerPos.z)+1;
	return;
}
Ejemplo n.º 11
0
Archivo: ugenv.c Proyecto: rolk/ug
static ENVITEM *SearchTree (const char *name, INT type, INT dirtype)
{
  ENVDIR *currentDir;
  ENVITEM *theItem,*result;

  currentDir = path[pathIndex];

  /* first loop in current directory */
  theItem = currentDir->down;
  while (theItem!=NULL)
  {
    if (theItem->v.type == type)
      if (strcmp(theItem->v.name,name)==0)
        return(theItem);
    theItem = theItem->v.next;
  }

  /* try recursive search */
  theItem = currentDir->down;
  while (theItem!=NULL)
  {
    if (theItem->v.type%2 == 1)
    {
      /* this is a directory */
      if ((theItem->d.type==dirtype)||(dirtype==SEARCHALL))
      {
        path[++pathIndex] = (ENVDIR *) theItem;
        if ((result=SearchTree(name,type,dirtype))!=NULL)
          return(result);
        pathIndex--;
      }
    }
    theItem = theItem->v.next;
  }

  /* return not found */
  return(NULL);
}
Ejemplo n.º 12
0
// Function which deletes subscriber from the tree
void DeleteSubscriber(SUBSCRIBER **tree, LONG_MAC mac) {

	SUBSCRIBER *parent, *tmp, *tmpsucc;

	// Return if tree is empty
	if ((*tree) == NULL) return;

	// If the subscriber doesn't exist, return from function
	if (FindSubscriberMAC(tree, mac) == NULL) return;

	// Otherwise find parent of element
	parent = tmp = NULL;
	SearchTree(tree, mac, &parent, &tmp);

	// If the node to be deleted has two children
	if ( (tmp->left != NULL) && (tmp->right != NULL) )
	{
		parent = tmp;
		tmpsucc = tmp->right;

		while (tmpsucc->left != NULL)
		{
			parent = tmpsucc;
			tmpsucc = tmpsucc->left;
		}

		tmp->mac = tmpsucc->mac;
		tmp->ip = tmpsucc->ip;
		tmp->session_id = tmpsucc->session_id;
		tmp = tmpsucc;
	}

	// If the node to be deleted has no children
	if ( (tmp->left == NULL) && (tmp->right == NULL) )
	{
		if (parent == NULL) (*tree) = NULL;
		else if (parent->right == tmp) parent->right = NULL;
		else parent->left = NULL;

		free (tmp);
		return;
	}

	// If the node to be deleted has only rightchild
	if ( (tmp->left == NULL) && (tmp->right != NULL) )
	{
		if (parent == NULL) (*tree) = tmp->right;
		else if (parent->left == tmp) parent->left = tmp->right;
		else parent->right = tmp->right;

		free (tmp);
		return;
	}

	// If the node to be deleted has only left child
	if ( (tmp->left != NULL) && (tmp->right == NULL) )
	{
		if (parent == NULL) (*tree) = tmp->left;
		else if (parent->left == tmp) parent->left = tmp->left;
		else parent->right = tmp->left;

		free (tmp);
		return;
	}
}
Ejemplo n.º 13
0
/** fast NFFT-based summation */
void fastsum_trafo(fastsum_plan *ths)
{
  int j,k,t;
  ticks t0, t1;

  ths->MEASURE_TIME_t[4] = 0.0; 
  ths->MEASURE_TIME_t[5] = 0.0;
  ths->MEASURE_TIME_t[6] = 0.0;
  ths->MEASURE_TIME_t[7] = 0.0;

#ifdef MEASURE_TIME
  t0 = getticks();
#endif
  /** first step of algorithm */
  nfft_adjoint(&(ths->mv1));
#ifdef MEASURE_TIME
  t1 = getticks();
  ths->MEASURE_TIME_t[4] += nfft_elapsed_seconds(t1,t0);
#endif


#ifdef MEASURE_TIME
  t0 = getticks();
#endif
  /** second step of algorithm */
  #pragma omp parallel for default(shared) private(k)
  for (k=0; k<ths->mv2.N_total; k++)
    ths->mv2.f_hat[k] = ths->b[k] * ths->mv1.f_hat[k];
#ifdef MEASURE_TIME
  t1 = getticks();
  ths->MEASURE_TIME_t[5] += nfft_elapsed_seconds(t1,t0);
#endif


#ifdef MEASURE_TIME
  t0 = getticks();
#endif
  /** third step of algorithm */
  nfft_trafo(&(ths->mv2));
#ifdef MEASURE_TIME
  t1 = getticks();
  ths->MEASURE_TIME_t[6] += nfft_elapsed_seconds(t1,t0);
#endif


#ifdef MEASURE_TIME
  t0 = getticks();
#endif
  /** add near field */
  #pragma omp parallel for default(shared) private(j,k,t)
  for (j=0; j<ths->M_total; j++)
  {
    double ymin[ths->d], ymax[ths->d]; /** limits for d-dimensional near field box */

    if (ths->flags & NEARFIELD_BOXES)
    {
      ths->f[j] = ths->mv2.f[j] + SearchBox(ths->y + ths->d*j, ths);
    }
    else
    {
      for (t=0; t<ths->d; t++)
      {
        ymin[t] = ths->y[ths->d*j+t] - ths->eps_I;
        ymax[t] = ths->y[ths->d*j+t] + ths->eps_I;
      }
      ths->f[j] = ths->mv2.f[j] + SearchTree(ths->d,0, ths->x, ths->alpha, ymin, ymax, ths->N_total, ths->k, ths->kernel_param, ths->Ad, ths->Add, ths->p, ths->flags);
    }
    /* ths->f[j] = ths->mv2.f[j]; */
    /* ths->f[j] = SearchTree(ths->d,0, ths->x, ths->alpha, ymin, ymax, ths->N_total, ths->k, ths->kernel_param, ths->Ad, ths->Add, ths->p, ths->flags); */
  }

#ifdef MEASURE_TIME
  t1 = getticks();
  ths->MEASURE_TIME_t[7] += nfft_elapsed_seconds(t1,t0);
#endif
}
Ejemplo n.º 14
0
/** fast search in tree of source knots for near field computation*/
double _Complex SearchTree(const int d, const int t, const double *x,
  const double _Complex *alpha, const double *xmin, const double *xmax,
  const int N, const kernel k, const double *param, const int Ad,
  const double _Complex *Add, const int p, const unsigned flags)
{
  int m=N/2;
  double Min=xmin[t], Max=xmax[t], Median=x[m*d+t];
  double a=fabs(Max-Min)/2;
  int l;
  int E=0;
  double r;

  if (N==0)
    return 0.0;
  if (Min>Median)
    return SearchTree(d,(t+1)%d,x+(m+1)*d,alpha+(m+1),xmin,xmax,N-m-1,k,param,Ad,Add,p,flags);
  else if (Max<Median)
    return SearchTree(d,(t+1)%d,x,alpha,xmin,xmax,m,k,param,Ad,Add,p,flags);
  else
  {
    double _Complex result = 0.0;
    E=0;

    for (l=0; l<d; l++)
    {
      if ( x[m*d+l]>xmin[l] && x[m*d+l]<xmax[l] )
        E++;
    }

    if (E==d)
    {
      if (d==1)
      {
        r = xmin[0]+a-x[m];  /* remember: xmin+a = y */
      }
      else
      {
        r=0.0;
        for (l=0; l<d; l++)
          r+=(xmin[l]+a-x[m*d+l])*(xmin[l]+a-x[m*d+l]);  /* remember: xmin+a = y */
        r=sqrt(r);
      }
      if (fabs(r)<a)
      {
        result += alpha[m]*k(r,0,param);                         /* alpha*(kern-regkern) */
        if (d==1)
        {
          if (flags & EXACT_NEARFIELD)
            result -= alpha[m]*regkern1(k,r,p,param,a,1.0/16.0); /* exact value (in 1D)  */
          else
            result -= alpha[m]*kubintkern1(r,Add,Ad,a);               /* spline approximation */
        }
        else
        {
          if (flags & EXACT_NEARFIELD)
            result -= alpha[m]*regkern(k,r,p,param,a,1.0/16.0);  /* exact value (in dD)  */
          else
#if defined(NF_KUB)
            result -= alpha[m]*kubintkern(r,Add,Ad,a);                /* spline approximation */
#elif defined(NF_QUADR)
            result -= alpha[m]*quadrintkern(r,Add,Ad,a);                /* spline approximation */
#elif defined(NF_LIN)
            result -= alpha[m]*linintkern(r,Add,Ad,a);                /* spline approximation */
#else
  #error define interpolation method
#endif
        }
      }
    }
    result += SearchTree(d,(t+1)%d,x+(m+1)*d,alpha+(m+1),xmin,xmax,N-m-1,k,param,Ad,Add,p,flags)
      + SearchTree(d,(t+1)%d,x,alpha,xmin,xmax,m,k,param,Ad,Add,p,flags);
    return result;
  }
}
Ejemplo n.º 15
0
//----------------------------------------------------------------------------
//
// build kd tree (prototype)
//
// pts: point locations to be indexed in kd-tree (for now)
// loc_num_pats: local number of points
// glo_num_pats: global number of points
// num_levels: number of tree levels, counting root
// num_bins: number of histogram bins at all levels
//
void Blocking::BuildTree(float *pts, int loc_num_pts, int glo_num_pts,
			 int num_levels, int num_bins) {

  int num_hists; // number of historgrams in this level
  int median = glo_num_pts / 2; // desired median
  int parent = 0; // curent parent tree node
  int tot_num_bins; // total number of bins in all histograms for a block

  // headers for each block
  int **hdrs = new int*[nb];
  for (int i = 0; i < nb; i++)
    hdrs[i] = new int[1];

  // todo: only the right number of bins for global range
  // yet to implement local ranges, especially for later levels

  // allocate histograms, hists[i] allocated and freed during each level
  int **hists;
  hists = new int*[nb];

  // initialize kd-tree with level 0
  kd_node_t node;
  for (int i = 0; i < dim; i++) {
    node.bounds.min[i] = data_min[i];
    node.bounds.max[i] = data_max[i];
  }
  node.proc = 0; // default
  node.l_child = -1; // empty, to be filled in later
  node.r_child = -1; // ditto
  node.parent = -1; // will remain empty for root
  kd_tree.push_back(node);

  for (int level = 1; level < num_levels; level++) { // tree levels

    int dir = (level - 1) % dim;
    num_hists = ((level - 1) ? num_hists * 2 : 1);
    // toto: reduce histogram size with level (after one full cycle of all dirs)
    // turned off for now
//     if (level - 1)
//       num_bins = (num_bins >= 2 * min_num_bins ? num_bins / 2 : min_num_bins);
    tot_num_bins = num_hists * num_bins;

    for (int b = 0; b < nb; b++)
      hists[b] = new int[tot_num_bins];

    // init histograms
    for (int b = 0; b < nb; b++) {
      for (int i = 0; i < tot_num_bins; i++)
	hists[b][i] = 0;
    }

    for (int b = 0; b < nb; b++) { // local blocks

      // scan and bin objects
      // todo: is data_max and data_min set correctly? I doubt it for particles
      float bin_width = (data_max[dir] - data_min[dir]) / num_bins;
      for (int i = 0; i < loc_num_pts; i++) {

	// search for particle in tree
	// todo: don't have to start at root each time
	int pt_node = SearchTree(&pts[3 * i], 0);
	// pos of node in level
	int temp = (int)(pow(2, level - 1));
	int node_level_pos = pt_node + 1 - temp;

	// debug
// 	fprintf(stderr, "pt: %.1f %.1f %.1f in node %d: node_level_pos %d\n",
// 		pts[3 * i], pts[3 * i + 1], pts[3 * i + 2],
// 		pt_node, node_level_pos);

	int bin = pts[3 * i + dir] / bin_width;
	if (bin >= num_bins)
	  bin = num_bins - 1;
	bin += num_bins * node_level_pos; // move to correct histogram
	hists[b][bin]++;

      } // objects

      hdrs[b][0] = tot_num_bins;

    } // local blocks

    // debug: print the histograms
//     for (int b = 0; b < nb; b++) {
//       for (int i = 0; i < num_bins; i++)
// 	fprintf(stderr, "hists[%d][%d] = %d\n", b, i, hists[b][i]);
//     }

    // merge the histograms
    // todo: change merge and swap API to take a target k and figure out
    // rounds and kvalues itself
    int rounds = log2f((float)tot_b); // todo: assumes power of 2 blocks
    int kvalues[rounds];
    for (int i = 0; i < rounds; i++)
      kvalues[i] = 2;
    int nb_merged; // number of output merged blocks

    DIY_Merge_blocks(did, (char**)hists, hdrs, rounds, kvalues, 
		     &KdTree_MergeHistogram, &KdTree_CreateHistogram, 
		     &KdTree_DestroyHistogram, 
		     &KdTree_CreateHistogramType, &nb_merged);

    // find median split points in histograms
    int split_index[num_hists]; // split indices in cumulative mass function
    if (rank == groupsize - 1) {

      assert(nb_merged == 1); // sanity

      // debug: print the merged histogram
//       for (int i = 0; i < num_bins; i++)
// 	fprintf(stderr, "hist[%d] = %d\n", i, hists[0][i]);

      // convert histogram to cumulative mass function; prefix sum
      for (int i = 0; i < num_hists; i++) {
	int ofst = i * num_bins; // start of this histogram
	for (int j = 1; j < num_bins; j++)
	  hists[0][ofst + j] += hists[0][ofst + j - 1];
      }

      // debug: print the CMF
//       for (int i = 0; i < num_bins; i++)
// 	fprintf(stderr, "cmf[%d] = %d\n", i, hists[0][i]);

      // find split index of CMF
      for (int i = 0; i < num_hists; i++) {
	int ofst = i * num_bins; // start of this histogram
	split_index[i] = BinarySearch(ofst, num_bins, hists[0], median);
	// debug
	fprintf(stderr, "level = %d split_index[%d] = %d median = %d\n", 
		level, i, split_index[i], median);
      }

    }

    // broadcast the split points
    MPI_Bcast(split_index, num_hists, MPI_INT, groupsize - 1, comm);

    // add new level to kd-tree
    for (int i = 0; i < num_hists; i++) {
      int ofst = i * num_bins; // start of this histogram
      AddChildren(parent + i, dir, ((float)split_index[i] - ofst)/ num_bins);
    }

    parent += num_hists;
    median /= 2;

    // cleanup
    for (int b = 0; b < nb; b++)
      delete[] hists[b];

  // debug: print the kd tree
//   if (rank == 0) { // duplicated on all ranks, print only once
//     for (int i = 0; i < kd_tree.size(); i++)
//       fprintf(stderr, "kd tree node %d: proc %d min[%.1f %.1f %.1f] "
// 	      "max[%.1f %.1f %.1f] l_child %d r_child %d parent %d\n",
// 	      i, kd_tree[i].proc, kd_tree[i].bounds.min[0], 
// 	      kd_tree[i].bounds.min[1], kd_tree[i].bounds.min[2], 
// 	      kd_tree[i].bounds.max[0], kd_tree[i].bounds.max[1], 
// 	      kd_tree[i].bounds.max[2], kd_tree[i].l_child, kd_tree[i].r_child,
// 	      kd_tree[i].parent);
//   }

  } // tree levels

  // debug: print the kd tree
  if (rank == 0) { // duplicated on all ranks, print only once
    for (int i = 0; i < (int)kd_tree.size(); i++)
      fprintf(stderr, "kd tree node %d: proc %d min[%.1f %.1f %.1f] "
	      "max[%.1f %.1f %.1f] l_child %d r_child %d parent %d\n",
	      i, kd_tree[i].proc, kd_tree[i].bounds.min[0], 
	      kd_tree[i].bounds.min[1], kd_tree[i].bounds.min[2], 
	      kd_tree[i].bounds.max[0], kd_tree[i].bounds.max[1], 
	      kd_tree[i].bounds.max[2], kd_tree[i].l_child, kd_tree[i].r_child,
	      kd_tree[i].parent);
  }

  // cleanup
  delete[] hists;

}
Ejemplo n.º 16
0
bool BTree::Find(int key) const
{
    int ret=false;
    SearchTree(root, key,ret);
    return ret;
}
Ejemplo n.º 17
0
/****************************************************************************
*
*	FUNCTION:	TunnelTree(CString szFindPath)
*
*	PURPOSE:	Too crude to explain, just use it
*
*	WARNING:	Only works if you use the default PopulateTree()
*				Not guaranteed to work on any future or existing
*				version of windows. Use with caution. Pretty much
*				ok if you're using on local drives
*
****************************************************************************/
void CShellTreeCtrl::TunnelTree(CString szFindPath)
{
	HTREEITEM subNode = GetRootItem();
	CString szPathHop;
	char drive[_MAX_DRIVE];
	char dir[_MAX_DIR];
	char fname[_MAX_FNAME];
	char ext[_MAX_EXT];
	char delimiter[]="\\";
//	LPTVITEMDATA   lptvid;  //Long pointer to TreeView item data
//	HRESULT        hr;
	LPSHELLFOLDER  lpsf2=NULL;
	static char    szBuff[MAX_PATH];
//	TV_SORTCB      tvscb;

	CFileName checkPath(szFindPath);
	if(!checkPath.Exist())
	{
		MessageBox(szFindPath,"Folder not found",MB_ICONERROR);
		return;
	}
		
	if(szFindPath.ReverseFind('\\') != szFindPath.GetLength()-1)
	{
		szFindPath += "\\";
	}

	_splitpath(szFindPath,drive,dir,fname,ext);

	//search the drive first
	bool found = false;
	szPathHop=drive;
	subNode=GetChildItem(subNode);
	if(subNode)
	{
		found = SearchTree(subNode,szPathHop, CShellTreeCtrl::type_drive);
		if(!found)
		{
			subNode = GetRootItem();
			subNode = GetNextSiblingItem(subNode);
			Expand(subNode, TVE_EXPAND);
			subNode = GetChildItem(subNode);
			if(subNode)
				found = SearchTree(subNode,szPathHop, CShellTreeCtrl::type_drive);
		}
		if(found)
		{
			//break down subfolders and search
			char *p=strtok(dir,delimiter);
			while(p)
			{
				subNode = GetSelectedItem();

				//expand it
				Expand(subNode, TVE_EXPAND);


				subNode = GetChildItem(subNode);
				if(SearchTree(subNode,p,CShellTreeCtrl::type_folder))
					p=strtok(NULL,delimiter);
				else
					p=NULL;
			}

		}
	}
}