title: Get children windows of window by handle or pid
body: <p>I have handle and pid of main process / window.<br/>
  I want to get the children of the process / window - only the visual windows with title.</p>
  
  <p>to achieve what I want, I used the following:</p>
  
  <pre><code>[DllImport("user32.dll")] private static extern int EnumWindows(EnumWindowsProc ewp, int lParam);
  [DllImport("user32.dll", SetLastError = true)] static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
  [DllImport("user32.dll")] private static extern bool IsWindowVisible(int hWnd);
  [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int GetWindowText(int hWnd, StringBuilder title, int size);
  
  
  public delegate bool EnumWindowsProc(int hWnd, int lParam); //Delegate used for EnumWindows() callback function.
  
  
  public void GetChildren()
  {
      //Declare a callback delegate for EnumWindows() API call.
      EnumWindowsProc ewp = new EnumWindowsProc(EvalWindow);
      //Enumerate all Windows.
      EnumWindows(ewp, 0);
  }
  
  //EnumWindows CALLBACK function
  private bool EvalWindow(int hWnd, int lParam)
  {
      //Get the ThreadProcessId of the Window.
      IntPtr handle = (IntPtr)hWnd;
      uint currentThreadPid;
      GetWindowThreadProcessId(handle, out currentThreadPid);
  
      //Check if the Window is children of the current Window (if it is, it will have the same pid).
      if (currentThreadPid != _threadPid)
          return true;
  
      //Check if Window is Visible or not.
      if (!IsWindowVisible(hWnd))
          return true;
  
      //Get the Window's Title.
      StringBuilder title = new StringBuilder(256);
      GetWindowText(hWnd, title, 256);
  
      //Check if Window has Title.
      if (title.Length == 0)
          return true;
  
      //Add new Window to the _childrenhWnd.
      _childrenhWnd.Add(handle);
  
      return true;
  }
  </code></pre>
  
  <p>where <code>_threadPid</code> is the pid of the parent.</p>
  
  <p>It works great but I feel there's a better way of doing it instead of going through all the opened windows and filter them.</p>
  
  <p>Am I right? how can I do it better?</p>
  
  <p>I saw something about <code>EnumChildWindows</code> but I could achieve the same.</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>Based on RaymondChen comment, I want to clarify what I mean by saying "children":<br/>
   1. If you open sticky notes and add notes - the notes are children.<br/>
   2. If you open Paint.NET and press (f5, f6, f7, f8) to open the panels
      - these are child windows.<br/>
  Every window of the program which is not the main (dialogs also) I call children.</p>
  
  <p><strong>EDIT 2:</strong></p>
  
  <p>Here's my code after applying Hans's method:</p>
  
  <pre><code>[DllImport("user32.dll")] static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
  [DllImport("user32.dll")] private static extern bool IsWindowVisible(int hWnd);
  [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int GetWindowText(int hWnd, StringBuilder title, int size);
  
  
  delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);
  
  
  public void GetChildren()
  {
     foreach (ProcessThread processThread in _process.Threads)
     {
         EnumThreadWindows(processThread.Id,
          (hWnd, lParam) =&gt; 
          {
              //Check if Window is Visible or not.
              if (!IsWindowVisible((int)hWnd))
                  return true;
  
              //Get the Window's Title.
              StringBuilder title = new StringBuilder(256);
              GetWindowText((int)hWnd, title, 256);
  
              //Check if Window has Title.
              if (title.Length == 0)
                  return true;
  
              _childrenhWnd.Add(hWnd);
  
              return true;
          }, IntPtr.Zero);
     }
  }
  </code></pre>
  
  <p>didnt need to use <code>GetWindowLongPtr</code> because all the owned windows must have title and be visible else I dont really care so these conditions already filter the owned windows.</p>