title: How to select an item in a TreeView using Win32 API
body: <p>I am trying to automate a sequence of user inputs to a compiled application in C# using Win32 API. I do not have any source code for the application I am trying to control and it is running while I am trying to control it. In my code, I have a single button that, when clicked, needs to make a sequence of 3 inputs to the application I am trying to control:</p>
  
  <ol>
  <li>Select an item in a treeview</li>
  <li>Click a button</li>
  <li>Click another button</li>
  </ol>
  
  <p>The way it works is the button in step 2 performs an action depending on the item selected in the treeview in step 1. I am able to get the button clicks to work just fine by simply sending a message, but I cannot figure out how to select the TreeView item I want. The TreeView is static, so the items and layout will never change. It has the following layout:</p>
  
  <p>-itemsA<br>
  -itemsB<br>
  --itemB1<br>
  -itemsC</p>
  
  <p>Where itemB1 is the item that needs to be selected in order for the button clicks in steps 2 and 3 to work. By default ItemsB is collapsed, so I probably need to expand it before I can select ItemB1? Here is my code. I really appreciate any help!!</p>
  
  <pre><code>//Find Window API
  [DllImport("User32.dll")]
  public static extern Int32 FindWindow(String lpClassName, String lpWindowName);
  
  //Find WindowEx API
  [DllImport("user32.dll", SetLastError = true)]
  public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
  
  //Send Message API
  [DllImport("user32.dll", CharSet = CharSet.Auto)]
  public static extern int SendMessage(int hWnd, int msg, int wParam, IntPtr lParam);
  
  
  private const int BN_CLICKED = 245;
  
  //Method called by button click
  public static void Start()
  {
      int hwnd = 0;
      int prod = 0;
      IntPtr hwndChild = IntPtr.Zero;
      IntPtr treeChild = IntPtr.Zero;
      IntPtr prodChild = IntPtr.Zero;
  
      hwnd = FindWindow(null, "Application");
      if (hwnd &gt; 0)
      {
          //Get Handle for TreeView, THIS IS WHERE I AM STUCK!!
          treeChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "AfxMDIFrame80", null);
          treeChild = FindWindowEx((IntPtr)treeChild, IntPtr.Zero, "AfxMDIFrame80", null);
          treeChild = FindWindowEx((IntPtr)treeChild, IntPtr.Zero, "SysTreeView32", null);
          //Need to Add code to select item in TreeView ???
  
          //Click First Button
          hwndChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "AfxMDIFrame80", null);
          hwndChild = FindWindowEx((IntPtr)hwndChild, IntPtr.Zero, "AfxMDIFrame80", null);
          hwndChild = FindWindowEx((IntPtr)hwndChild, IntPtr.Zero, "#32770", null);
          IntPtr scanBtn = FindWindowEx((IntPtr)hwndChild, IntPtr.Zero, "Button", "&amp;Scan");
          SendMessage((int)scanBtn, BN_CLICKED, 0, IntPtr.Zero);
  
          //Click Second Button
          prod = FindWindow("#32770", "Product: WPC");
          prodChild = FindWindowEx((IntPtr)prod, IntPtr.Zero, "Button", "&amp;Collect");
          SendMessage((int)prodChild, BN_CLICKED, 0, IntPtr.Zero);
      }
      }//END Start
  </code></pre>
  
  <p>Hans,</p>
  
  <p>Can you give me an example of how I would do this? The problem I am really having is finding the handle for the treeview item I want to select. If I use Spy++ to find the current handle and hardcode it into my method, it works fine, like this: </p>
  
  <pre><code>SendMessage((int)treeChild, TV_SELECTITEM, TVGN_CARET, (IntPtr)0x092DCB30); 
  </code></pre>
  
  <p>If I use SendMessage and send TVGN_ROOT to the TreeView Handle, will it return an IntPtr with the handle for the item to select in the treeview, or how does that work? I am also experimenting with AutoIt, but I was hoping to keep all of my code in one application.</p>