package Win32::GuiTest::TreeView;

=head1 NAME 

Win32::GuiTest::TreeView - Help to work with SysTreeView32 Control, in addition to Win32::GuiTest::SelTreeViewItemPath() and Win32::GuiTest::GetTreeViewSelPath().

=head1 Synopsis

  use Win32::GuiTest::TreeView
  ...
  my $hwnd = Win32::GuiTest::TreeView::GetFirstChild_H();
  ...

=head1 Description

All functions from this module will help you to easily navigate around the SysTreeView32 control by using it's hwnd.

Most of the functions here maybe helpful in using with Win32::GuiTest::SelTreeViewItemPath() and Win32::GuiTest::GetTreeViewSelPath().

=head1 Installation

=over

=item 1

put the module under Win32::GuiTest packages as follow:

C:\<To_PERL_Path>\site\lib\Win32\guitest\treeview.pm

=item 2

Please goes to Functions and Example section for more details how to use this module

=back

=cut

use strict;
use Carp;
use Win32;
use Win32::GuiTest;

use strict;
require Exporter;
our @ISA       = qw(Exporter);
our @EXPORT_OK = qw(
  	GetSelItem_H
  	GetFirstChild_H
  	GetChildList_H
  	GetNextSibling_H
  	GetParent_H
  	GetRoot_H
  	SelItem
  	ExpandItem
  	IsVisible
  	GetItemText
  	GetItemRec
  	HasChildren
  	GetBuildTree_H
);

# no need to export these function since they're no good to other (__I think :)__)
our @EXPORT_FAIL = qw(
  BuildTree_H
  TV_FIRST TVM_GETITEMRECT TVM_GETNEXTITEM TVM_GETITEMSTATE
  TVM_SELECTITEM TVM_EXPAND TVM_GETITEM TVGN_ROOT TVGN_NEXT
  TVGN_PREVIOUS TVGN_PARENT TVGN_CHILD TVGN_NEXTVISIBLE TVGN_PREVIOUSVISIBLE TVGN_CARET
  TVIS_EXPANDED TVIF_CHILDREN TVIF_TEXT TVE_EXPAND
);

#************************* Def TV MSG Values *************************#
#TV Values;
sub TV_FIRST { 0x1100 }

#TVM Flags
sub TVM_GETITEMRECT   { 0x1100 + 4 }
sub TVM_GETNEXTITEM   { 0x1100 + 10 }
sub TVM_GETITEMSTATE  { TV_FIRST() + 39 }
sub TVM_SELECTITEM    { TV_FIRST() + 11 }
sub TVM_EXPAND        { TV_FIRST() + 2 }
sub TVM_GETITEM       { TV_FIRST() + 12 }
sub TVM_ENSUREVISIBLE { TV_FIRST() + 20 }

#TVM_GETNEXTITEM Message flag:
sub TVGN_ROOT            { 0x0000 }
sub TVGN_NEXT            { 0x0001 }
sub TVGN_PREVIOUS        { 0x0002 }
sub TVGN_PARENT          { 0x0003 }
sub TVGN_CHILD           { 0x0004 }
sub TVGN_NEXTVISIBLE     { 0x0006 }
sub TVGN_PREVIOUSVISIBLE { 0x0007 }
sub TVGN_CARET           { 0x0009 }

sub TVIS_EXPANDED { 0x0020 }
sub TVIF_CHILDREN { 0x0040 }
sub TVIF_TEXT     { 0x0001 }

sub TVE_EXPAND        { 0x0002 }

#************************* END OF Def TV MSG Values ************************#

=head1 Functions:

=head2 GetRoot_H()

GetRoot_H function retrieves the root node handle of the Win32 Tree View control.

=over

=item Syntax:

my $root_H = Win32::GuiTest::TreeView::GetRoot_H($Tree_hwnd);

=item Parameters:

I<$Tree_hwnd> - A Tree Control handle (this parameter is required)

=item Return Value:

The top root node handle of the Tree View.

=back

=cut

sub GetRoot_H {
	my $Tree_hwnd = shift;
	my $hItem     = 0;
	Carp::croak('usage: GetRoot_H($Tree_hwnd)') unless defined($Tree_hwnd);
	my $child_hItem = Win32::GuiTest::SendMessage( $Tree_hwnd, TVM_GETNEXTITEM(), TVGN_ROOT(), $hItem );

	return undef unless defined $child_hItem;
	return $child_hItem;
}

=head2 GetFirstChild_H()

GetFirstChild_H function retrieves the first child handle of any given node that has one or more children node.

=over

=item Syntax:

my $child_H = Win32::GuiTest::TreeView::GetFirstChild_H($Tree_hwnd,$hItem);

=item Parameters:

I<$Tree_hwnd> - A Tree Control handle (this parameter is required)

I<$hItem> - handle of any node that has one or more children on the Tree Control;

=item Return Value:

The first child handle of $hItem.

=item Remarks

If $hItem is undefined, this function will return first child of the root node.

=back

=cut

##============================================================
## my $hItem = GetFirstChild_H($Tree_hwnd,$hItem)
## This function will require $Tree_hwnd and/or $hitem
## if $hItem is not provided it will return first child of the root.
#============================================================
sub GetFirstChild_H {
	my $Tree_hwnd = shift;
	my $hItem     = shift || 0;

	Carp::croak('usage: GetFirstChild_H($Tree_hwnd,$hItem)')  unless defined($Tree_hwnd);
	
	my $child_hItem = Win32::GuiTest::SendMessage( $Tree_hwnd, TVM_GETNEXTITEM(), TVGN_CHILD(), $hItem );
	return $child_hItem;
}

=head2 GetNextSibling_H()

GetNextSibling_H retrieves the next node handle on the same level if exist.

=over

=item Syntax:

my $child_H = Win32::GuiTest::TreeView::GetNextSibling_H($Tree_hwnd,$hItem);

=item Parameters:

I<$Tree_hwnd> - A Tree Control handle (required)

I<$hItem> - handle of any node on the Tree Control (required);

=item Return Value:

Next sibling item handle of $hItem, 0 otherwise.

=back

=cut

##============================================================
## my $hItem = GetNextSibling_H($Tree_hwnd,$hItem)
## This function will require $Tree_hwnd and $hItem.
#============================================================
sub GetNextSibling_H {
	my $Tree_hwnd = shift;
	my $hItem     = shift;
	
	Carp::croak('usage: GetNextSibling_H($Tree_hwnd,$hItem)')
	  unless defined( $Tree_hwnd && $hItem );
	  
	my $child_hItem = Win32::GuiTest::SendMessage( $Tree_hwnd, TVM_GETNEXTITEM(), TVGN_NEXT(),$hItem );
	return undef unless defined $child_hItem;
	return $child_hItem;
}

=head2 SelItem()

SelItem - will select a given item based on item handle (not by Name), if it is visible.
		  if you want to select by name, please use Win32::GuiTest::SelTreeViewItemPath()

=over

=item Syntax:

my $result = Win32::GuiTest::TreeView::SelItem($Tree_hwnd,$hItem);

=item Parameters:

I<$Tree_hwnd> - A Tree Control handle (required)

I<$hItem> - handle of any node on the Tree Control (required);

=item Return Value:

1 if successfully select the item, 0 otherwise

=back

=cut

##============================================================
##	Selitem
##============================================================
sub SelItem {
	my $Tree_hwnd = shift;
	my $hItem     = shift;
	Carp::croak('usage: SelItem($Tree_hwnd,$hItem)')
	  unless defined( $Tree_hwnd && $hItem );
	my $result = Win32::GuiTest::SendMessage( $Tree_hwnd, TVM_SELECTITEM(), TVGN_CARET(), $hItem );
	return $result;
}

=head2 ExpandItem()

ExpandItem function will try to expand any given item, if it has one or more child node.

=over

=item Syntax:

my $result = Win32::GuiTest::TreeView::ExpandItem($Tree_hwnd,$hItem);

=item Parameters:

I<$Tree_hwnd> - A Tree Control handle (required)

I<$hItem> - handle of any node on the Tree Control that has one or more child;

=item Return Value:

1 if successfully expanded the item, 0 otherwise

=item Remarks

if $hItem parameter is not given, this function will try to expand the current selected node.

=back

=cut

##============================================================
## my $hItem = ExpandItem($Tree_hwnd,$hItem)
## This function will require $Tree_hwnd and $hItem.
#============================================================
sub ExpandItem {
	my $Tree_hwnd = shift;    #this is expecting.
	my $hItem = shift || GetSelItem_H($Tree_hwnd);  #give me the node to expand
	     											#or i'll expand the current selected item
	my $result = undef;    #Result of expanding a node;

	Carp::croak('usage: ExpandItem($Tree_hwnd,$hItem)')
	  unless defined($Tree_hwnd);

	if ( HasChildren( $Tree_hwnd, $hItem ) == 1 ) {

		#Expand only if there are chidren under hItem;
		my $result = Win32::GuiTest::SendMessage($Tree_hwnd, TVM_EXPAND(), TVE_EXPAND(), $hItem );

		#just give the tree control some time to
		#expand if I can't see the first child of the expanding node
		my $ct = 0;
		while ( GetFirstChild_H( $Tree_hwnd, $hItem ) == 0 && ( $ct != 100 ) ) {

			#sleep 10 milliseconds for 100 time
			#will return undef if still can't see the first child
			Win32::Sleep(10);
			$ct++;
		}
		$result = 0 if ( $ct == 100 );
	}

	return $result;
}

=head2 GetChildList_H()

GetChildList_H function retrieves all visible child of a node, if there are one or more child node

=over

=item Syntax:

my @child_H = Win32::GuiTest::TreeView::GetChildList_H($Tree_hwnd,$hItem);

=item Parameters:

I<$Tree_hwnd> - A Tree Control handle (required)

I<$hItem> - handle of any node on the Tree Control that has one or more child;

=item Return Value:

An array of children(s);

=item Remarks

if $hItem parameter is not given, this function will return an array of the Root's children(s)

=back

=cut

sub GetChildList_H {
	my $Tree_hwnd = shift;
	my $hItem     = shift || GetRoot_H($Tree_hwnd);

	my $curr_child;
	my @child_arr;
	my $child_Idx = 0;

	Carp::croak(
				 "usage: GetChildList_H($Tree_hwnd,$hItem)",
				 "$Tree_hwnd is required\n",
				 "$hItem Will be root if not provided."
	  )unless defined($Tree_hwnd);

	$curr_child = GetFirstChild_H( $Tree_hwnd, $hItem );
	$child_arr[$child_Idx] = $curr_child;
	if ( !$curr_child ) {
		return;    #return nothing since there are no child.
	}
	else {
		while ( GetNextSibling_H( $Tree_hwnd, $curr_child ) ) {
			$child_Idx = $child_Idx + 1;
			my $Next_child = GetNextSibling_H( $Tree_hwnd, $curr_child );
			$child_arr[$child_Idx] = $Next_child;
			$curr_child = $Next_child;
		}
		return @child_arr;
	}
}

=head2 GetSelItem_H()

GetSelItem_H function retrieves the currect selected item handle

=over

=item Syntax:

my $hItem = Win32::GuiTest::TreeView::GetSelItem_H($Tree_hwnd);

=item Parameters:

I<$Tree_hwnd> - A Tree Control handle (required)

=item Return Value:

Handle of the current selected item.

=back

=cut

#-==========================================================
## my $hItem = GetSelItem_H($Tree_hwnd)
## This function require the TreeView control hwnd.
## Return selected item of the tree_control
#============================================================
sub GetSelItem_H {
	my $Tree_hwnd = shift;
	Carp::croak('usage: GetSelItem_H($Tree_hwnd)') unless defined($Tree_hwnd);
	my $hItem = Win32::GuiTest::SendMessage( $Tree_hwnd, TVM_GETNEXTITEM(), TVGN_CARET(), 0 );
	return undef unless defined $hItem;
	return $hItem;
}

=head2 GetParent_H()

GetParent_H function retrieves the parent handle of a node;

=over

=item Syntax:

my $parent_H = Win32::GuiTest::TreeView::GetParent_H($Tree_hwnd,$hItem);

=item Parameters:

I<$Tree_hwnd> - A Tree Control handle (required)

I<$hItem> - handle of any node (required)

=item Return Value:

The Parent's handle if exist, 0 otherwise

=back

=cut

#-==========================================================
## my $hItem = GetParent_H($Tree_hwnd)
## $parent will be the return value. which is the parent's handle of the $hItem in the treeview
## This function require the TreeView control hwnd and $hItem.
#============================================================
sub GetParent_H {
	my $Tree_hwnd = shift;
	my $hItem     = shift;
	Carp::croak('usage: GetParent_H($Tree_hwnd,$hItem)')
	  unless defined( $Tree_hwnd && $hItem );
	my $parent = Win32::GuiTest::SendMessage( $Tree_hwnd, TVM_GETNEXTITEM(), TVGN_PARENT(),$hItem );
	
	return $parent;
}

=head2 GetItemText()

GetItemText function retrieves the text of any item's handle

=over

=item Syntax:

my $ItemText = Win32::GuiTest::TreeView::GetItemText($Tree_hwnd,$hItem);

=item Parameters:

I<$Tree_hwnd> - A Tree Control handle (required)

I<$hItem> - handle of any node;

=item Return Value:

Text of an item handle;

=item Remarks

If $hItem parameter is not given, this function will return the current selected item's text;

=back

=cut

##============================================================
## my $text = GetItemText($Tree_hwnd,$hItem)
## This function will require $Tree_hwnd;
## if $hItem is not provided, will return $text of the selected item.
#============================================================
sub GetItemText {
	my $Tree_hwnd = shift;
	my $hItem     = shift || GetSelItem_H($Tree_hwnd);

	Carp::croak('usage: GetItemText($Tree_hwnd)') unless defined($Tree_hwnd);

	my $tvitem   = Win32::GuiTest::AllocateVirtualBuffer( $Tree_hwnd, 128 );
	my $text_buf = Win32::GuiTest::AllocateVirtualBuffer( $Tree_hwnd, 128 );

	my $str_buf = pack(
						"L L L L L L L L L L",
						TVIF_TEXT(),             #UINT mask;
						$hItem,                  #HTREEITEM hItem;
						0,                       #UINT state;
						0,                       #UINT stateMask;
						$text_buf->{'ptr'},      #LPTSTR pszText;
						128,                     #int cchTextMax;
						0,                       #int iImage;
						0,                       #int iSelectedImage;
						0,                       #int cChildren;
						0,                       #LPARAM lParam;
	);

	Win32::GuiTest::WriteToVirtualBuffer( $tvitem, $str_buf );
	Win32::GuiTest::SendMessage( $Tree_hwnd, TVM_GETITEM(), 0, $tvitem->{'ptr'} );
	my $text = Win32::GuiTest::ReadFromVirtualBuffer( $text_buf, 128 );
	$text =~ s/\0//g;
	Win32::GuiTest::FreeVirtualBuffer($tvitem);
	Win32::GuiTest::FreeVirtualBuffer($text_buf);
	return undef unless defined $text;
	return $text;
}

=head2 HasChildren()

HasChildren function try to see if an item has any children

=over

=item Syntax:

my $result = Win32::GuiTest::TreeView::HasChildren($Tree_hwnd,$hItem);

=item Parameters:

I<$Tree_hwnd> - A Tree Control handle (required)

I<$hItem> - handle of any node;

=item Return Value:

1 if there are one or more children(s), 0 otherwise;

=item Remarks

If $hItem parameter is not given, this function will use the current selected item's hanlde;

=back

=cut

##============================================================
## my $hasChildren = HasChildren($Tree_hwnd,$hItem)
## This function will require $Tree_hwnd;
## if $hItem is not provided, will assuming that you're looking @ current selected Item.
#============================================================
sub HasChildren {
	my $Tree_hwnd = shift;
	my $hItem     = shift || GetSelItem_H($Tree_hwnd);

	Carp::croak('usage: GetItemText($Tree_hwnd)') unless defined($Tree_hwnd);

	my $tvitem = Win32::GuiTest::AllocateVirtualBuffer( $Tree_hwnd, 50 );
	my $str_buf = pack(
						"L L L L L L L L L L",
						TVIF_CHILDREN(),         #UINT mask;
						$hItem,                  #HTREEITEM hItem;
						0,                       #UINT state;
						0,                       #UINT stateMask;
						0,                       #LPTSTR pszText;
						0,                       #int cchTextMax;
						0,                       #int iImage;
						0,                       #int iSelectedImage;
						0,                       #int cChildren;
						0,                       #LPARAM lParam;
	);

	Win32::GuiTest::WriteToVirtualBuffer( $tvitem, $str_buf );
	Win32::GuiTest::SendMessage( $Tree_hwnd, TVM_GETITEM(), 0,
								 $tvitem->{'ptr'} );
	my $ResultString = Win32::GuiTest::ReadFromVirtualBuffer( $tvitem, 50 );
	Win32::GuiTest::FreeVirtualBuffer($tvitem);

	#my ($a,$b,$c,$d,$e,$f,$g,$h,$Result,$j) = unpack ("L10",$ResultString);
	my @Result = unpack( "L10", $ResultString );
	return $Result[8];
}

=head2 GetItemRec()

GetItemRec function retrives the dimensions of the bounding rectangle of a node. The (x,y) values are given in screen coordinates.  

=over

=item Syntax:

my ($lx,$ty,$rx,$by) = Win32::GuiTest::TreeView::GetItemRec($Tree_hwnd,$hItem);

=item Parameters:

I<$Tree_hwnd> - A Tree Control handle (required)

I<$hItem> - handle of any node;

=item Return Value:

Top left and bottom right coordinates of a node's rectangle relative to the screen

=item Remarks

If $hItem parameter is not given, this function will return the dimensions of the current selected item;

=back

=cut

##============================================================
## my ($lx,$ty,$rx,$by) = GetItemRec($Tree_hwnd)
## return ($lx,$ty,$rx,$by) will be the selected item OR $hItem
## This function will require $Tree_hwnd and/or $hItem.
## If $hItem is not givin, this function will assuming you're looking for the seleted item.
#============================================================
sub GetItemRec {
	my $Tree_hwnd = shift;
	my $hItem     = shift || GetSelItem_H($Tree_hwnd);

	Carp::croak('usage: GetItemRec($Tree_hwnd)') unless defined($Tree_hwnd);
	my $TreeViewGetRect =  Win32::GuiTest::AllocateVirtualBuffer( $Tree_hwnd, 50 );
	my $S_SearchBuffer = pack( "L4", $hItem, 0, 0, 0, );
	Win32::GuiTest::WriteToVirtualBuffer( $TreeViewGetRect, $S_SearchBuffer );
	Win32::GuiTest::SendMessage( $Tree_hwnd, TVM_GETITEMRECT, 1,$TreeViewGetRect->{'ptr'} );
	my $RectStruct = Win32::GuiTest::ReadFromVirtualBuffer( $TreeViewGetRect, 50 );
	Win32::GuiTest::FreeVirtualBuffer($TreeViewGetRect);

	my ( $lx, $ty, $rx, $by ) = unpack( "L4", $RectStruct );
	my ( $Tree_lx, $Tree_ty, $Tree_rx, $Tree_by ) =
	  Win32::GuiTest::GetWindowRect($Tree_hwnd);
	return ( $lx + $Tree_lx, $ty + $Tree_ty, $rx + $Tree_lx, $by + $Tree_ty );
}

=head2 GetBuildTreePath_H()

GetBuildTree_H function retrives Arrays of tree path i.e Root|parent|child|... 

	This functions will help to collect tree view path so can be easily use with 
	Win32::GuiTest::GetBuildTreePath_H() or Win32::GuiTest::GetTreeViewSelPath()   

=over

=item Syntax:

my $handles = Win32::GuiTest::TreeView::GetBuildTreePath_H($Tree_hwnd,$StartNode,$Limit);

=item Parameters:

I<$Tree_hwnd> - A Tree Control handle (required)

I<$StartRoot> - handle of any node (if undef, this function will assign Root handle);

I<$StartChild> - which child should start to collect reletive to $StartRoot node

	0 - ignore this parameter
	1 - Start from Child number 1
	2 - Start from child number 2...etc

I<$EndChild> - which child should end the collection reletive to $StartRoot node

	0 - ignore this parameter
	1 - End at child number 1
	2 - End at child number 2....etc

=item Return Value:

	Reference to an Array of reference arrays, because the path can get really big.

=back

=cut


##===========END of SAMPLE===========================
my @TreeArr;
##=================================================
## my $ArrRef = GetBuildTree_H()
##=================================================
sub GetBuildTreePath_H {
	my $Tree_hwnd = shift;    #Tree Control hwnd
	my $StartRoot = shift || GetRoot_H($Tree_hwnd);    #The root where to start from the tree (meaning that all child from this node will be collected)
	my $StartChild= shift;	   #Child to start from respect to $StartRoot (meanning collect all child start from this node.)
	my $LastChild =	shift;    #Limit of how many direct child should recursion goes through respect to startNode
	{ #ERROR BLOCK
		#Do this if one of the pramameter is missing.
		Carp::croak("Usage: GetBuildTree(\$TreeCtl_H,\$StartRoot,\$StartChild,\$Limit)\n",
				"\$TreeCtl_H is required\n",
				"\$StartRoot can be undef, if so it will be the top root of the Tree\n",
				"\$StartChild can be 0 or greater,assign 0 will start from the top child\n",
				"\$Limit can be 0 or greater, assign 0 will be no limit\n")
			if(!defined($Tree_hwnd) || !defined($StartRoot) || !defined($StartChild) || !defined($LastChild));
		#Do this if $StartChild is greater than $LastChild
		Carp::croak("\$StartChild cannot be greater than \$LastChild\n")
			if($StartChild>$LastChild);
	}
	{ #WORKING BLOCK
		#Start To get all Direct Children respect to $StartRoot to work with.
		my @children = GetChildList_H($Tree_hwnd,$StartRoot);
		#Deciding from the Given StartNode, 
		#which child to start and which child to stop
		#Collect all otherwise
		my ($ct, $child) = (0,undef);
		if($LastChild != 0 || $StartChild != 0){
			while(@children){
				if($ct>=$StartChild-1){
					BuildTree_H( $Tree_hwnd, $children[$ct]);
					#Stop if $LastChild has reach.
					last if($ct==$LastChild-1);
				}
				$ct++;
			}	
		}
		else{
			#Collect everything if there are no StartChild and LastChild defined.
			BuildTree_H( $Tree_hwnd, $StartChild);
		}
		#return the TreeArr Container by Ref. value.
		return \@TreeArr;
	}
}

#***** LOCAL not Exported ******
#***Only being use by GetBuildTree_H****
# BuildTree_H function will be call first to build the tree structure.
# Recursively goes through the tree if desire 
sub BuildTree_H {
	my $Tree_hwnd = shift;  #Tree Control hwnd
	my $StartRoot = shift;	#The root or where to start from the tree

	return unless defined ($StartRoot);	#so No more?
	
	ExpandItem( $Tree_hwnd, $StartRoot ); #Expanding the working node.
	
	#variable to be use for building a path from the working node to the top node of the Tree
	my ( $currParent, @Path, $parentHwnd );
	
	#===Start building the Path Array.===#
	
	#adding the current node to path array;
	push(@Path,$StartRoot); 
	#who is the parent of current Node
	$parentHwnd = GetParent_H( $Tree_hwnd, $StartRoot ); 
	#Now Add all parents until the top root, into path array
	#so we can get an array of [Root,parent,parent,child]
	while ($parentHwnd) {
		$currParent = $parentHwnd;
		unshift(@Path,$currParent);
		$parentHwnd = GetParent_H( $Tree_hwnd, $currParent );
	}	
	
	#Adding the Path (Array ref. value to the @TreeArr container)
	push( @TreeArr, \@Path);
	
	#Ok Do I have Children? keep going if so.
	my @children = GetChildList_H( $Tree_hwnd, $StartRoot );
	foreach my $child (@children) {
		BuildTree_H( $Tree_hwnd, $child);
	}
}

=head1 Example

	The Following Examples will help you to use some or all of these function to test TreeViewControl.   
	##====================================================================
	##  Please keep in mind that this is not the only way to do it,
	##  but I hope using this would explain how things work in TreeView.pm 
	##====================================================================

=head2 General Procedure

	##======
	## General procedure which will help each of the Example below
	##======
	
	use strict;
	use Win32::GuiTest;
	use Win32::GuiTest::TreeView;
	
	system "start explorer"; #start the explore window
	sleep 1; #wait for the explorer to start;
	
	my @explorer_H = Win32::GuiTest::FindWindowLike(undef, "My Document");
	
	#die if fail to find the explorer window handle
	die "Can't find explorer handle" if (!@explorer_H);
	
	#Explorer started let make sure it is in the front
	Win32::GuiTest::SetForegroundWindow($explorer_H[0]);
	
	#Getting the Tree Control HWND from explorer window
	my @Tree_H = Win32::GuiTest::FindWindowLike($explorer_H[0],undef,'SysTreeView32',0x64);
	
	##======
	##	Here Come the Explorer TreeView Examples
	##======

=head2 EXAMPLE 1 - required General Procedure

	#Lets try to get the root handle and print it out with the name
	
	my $Root_H   = Win32::GuiTest::TreeView::GetRoot_H($Tree_H[0]);  #Root node Hwnd
	
	my $Root_txt = Win32::GuiTest::TreeView::GetItemText($Tree_H[0],$Root_H); #Text of the Root node
	
	printf ("Tree Control HWND:%x\n", $Tree_H[0]);
	printf ("RootHWND:%x -- RootText:$Root_txt\n",$Root_H);

=head2 EXAMPLE 2 - required General Procedure

	#Lets try to get the text of the current selected node:
	
	#current select node will be use if $hitem is not provided
	my $CurrSelText = Win32::GuiTest::TreeView::GetItemText($Tree_H[0]);
	printf ("Current Selected Node: $CurrSelText \n");
	

=head2 EXAMPLE 3 - required General Procedure

	#Lets move the mouse to The First Child of the current selected node and Right Click on it.
	
	#handle of current selected item:
	my $CurrSel_H	= Win32::GuiTest::TreeView::GetSelItem_H($Tree_H[0]);
	
	#handle of the first child of the selected item: 
	my $FirstChild_H= Win32::GuiTest::TreeView::GetFirstChild_H($Tree_H[0],$CurrSel_H);
	
	#get the X,Y of the first child node
	my ($lx,$ty,$rx,$by) = Win32::GuiTest::TreeView::GetItemRec($Tree_H[0],$FirstChild_H);
	
	#Let send the mouse to the middle of the node and right click on it.
	Win32::GuiTest::MouseMoveAbsPix(($rx-$lx)/2+$lx, ($by-$ty)/2+$ty);
	Win32::GuiTest::SendMouse('{RIGHTCLICK}');
	
	#ESC to close the context menu;
	#Win32::GuiTest::SendKeys('{ESC}');  

=head2 EXAMPLE 4 - required General Procedure

	# in this example we will try to use the GetBuildTree_H() function to collect 5 path under "My Document" node;
	
	# we will try to get an array of hwnds which will be easy to construct a tree path at the current state.
	# easy to use with the 2 existing function in GuiTest.pm:
	#--Win32::GuiTest::GetTreeViewSelPath() and Win32::GuiTest::SelTreeViewItemPath()
	
	# Lets get the handle for "My Document" node to be $StartRoot item
	# We know that "My Document" node is the first child right under the root node ("Desktop"), 
	# assuming we didn't know that it is selected by default when starting explorer
	# so we use GetFirstChild_H() to get the "My Document" node hwnd
	my $StartRoot = Win32::GuiTest::TreeView::GetFirstChild_H(
							$Tree_H[0], #Tree control hwnd 
							Win32::GuiTest::TreeView::GetRoot_H($Tree_H[0]) #Root node hwnd
							);
							
	#Let try to collect first 5 path under "My Document"
	my $TreeArr_Ref = Win32::GuiTest::TreeView::GetBuildTreePath_H(
								$Tree_H[0],#Tree Control Hwnd
								$StartRoot,#The Start Root is "My Document" node
								0,         # $StartChild, ignore this param (meaning start from first child)
								5          # $EndChild, Let end at child number 5 of "My Document"
								);
								
	#Ok Lets try to print out the result:
	print "The following is the path that collected:\n";
	foreach my $pathArr (@$TreeArr_Ref){
		foreach my $node (@$pathArr){
			print Win32::GuiTest::TreeView::GetItemText($Tree_H[0],$node),"|"
		}
		print "\n";
	}
	
	# in the end we should get something like the following structure:
	# maybe useful I hope:)
	#
	#  Desktop|My Documents|<FirstChildName>
	#  Desktop|My Documents|<FirstChildName>|<IFANYMORE>
	#  Desktop|My Documents|<FirstChildName>|<IFANYMORE>|<IFANYMORE>
	#  Desktop|My Documents|<SecondChildName>
	#  Desktop|My Documents|<ThirdChildName>
	#  Desktop|My Documents|<ForthChildName>
	#  Desktop|My Documents|<ForthChildName>|<IFANYMORE>
	#  Desktop|My Documents|<FifthChildName>

=head1 Todo

=over

=item *

	Not Sure What todo yet.
	please prefered to Win32::GuiTest project for more information.


=back

=head1 Version

	v-----
	No version, This TreeView.pm is just a temp module, in the hope that
	it will be integrated into Win32::GuiTest module for the future if posible.

=head1 email

	Please feel free to contact me anytime if you have any question.
	Khanh Pham
	kpham.p@gmail.com

=cut
1;
