/// <summary>
        /// Gets all windows in nested objects usefule for adding to a TreeView.
        /// Includes the extended information: caption, class, handle, parent,
        /// children, and siblings. The list starts with the desktop.
        /// </summary>
        /// <returns>Desktop WindowInformation object with nested children</returns>
        public static WindowInformation GetAllWindowsTree()
        {
            WindowInformation desktopWindow = winInfoGet(GetDesktopWindow());

            desktopWindow.ChildWindows = getChildWindowsInfo(desktopWindow);
            return(desktopWindow);
        }
        /// <summary>
        /// Called by GetAllWindowsExtededInfo. Flattens the nested WindowInformation
        /// object built by GetAllWindowsTree.
        /// </summary>
        /// <param name="winInfo">The nested WindowInformation object created by GetAllWindowsTree.</param>
        /// <returns>Flattened list of WindowInformation objects with extended information.</returns>
        private static List <WindowInformation> winInfoExtendedInfoProcess(WindowInformation winInfo)
        {
            List <WindowInformation> winInfoList = new List <WindowInformation>();

            winInfoList.Add(winInfo);
            foreach (WindowInformation child in winInfo.ChildWindows)
            {
                winInfoList.AddRange(winInfoExtendedInfoProcess(child));
            }
            return(winInfoList);
        }
        /// <summary>
        /// Called by GeAlltWindowsTree and builds the nested WindowInformation
        /// object with extended window information. Recursive function.
        /// </summary>
        /// <param name="parent">The parent window.</param>
        /// <returns>List of WindowInformation objects.</returns>
        private static List <WindowInformation> getChildWindowsInfo(WindowInformation parent)
        {
            List <WindowInformation> result = new List <WindowInformation>();
            IntPtr childHwnd = GetWindow(parent.Handle, GetWindow_Cmd.GW_CHILD);

            while (childHwnd != IntPtr.Zero)
            {
                WindowInformation child = winInfoGet(childHwnd);
                child.Parent       = parent;
                child.ChildWindows = getChildWindowsInfo(child);
                result.Add(child);
                childHwnd = FindWindowEx(parent.Handle, childHwnd, null, null);
            }
            foreach (WindowInformation child in result)
            {
                child.SiblingWindows.AddRange(result);
                child.SiblingWindows.Remove(child);
            }
            return(result);
        }
        /// <summary>
        /// Gets the basic window information from a handle.
        /// </summary>
        /// <param name="hWnd">Window handle.</param>
        /// <returns>WindowInformation object with basic information.</returns>
        private static WindowInformation winInfoGet(IntPtr hWnd)
        {
            StringBuilder caption   = new StringBuilder(1024);
            StringBuilder className = new StringBuilder(1024);

            GetWindowText(hWnd, caption, caption.Capacity);
            GetClassName(hWnd, className, className.Capacity);
            WindowInformation wi = new WindowInformation();

            wi.Handle = hWnd;
            wi.Class  = className.ToString();
            if (caption.ToString() != string.Empty)
            {
                wi.Caption = caption.ToString();
            }
            else
            {
                caption = new StringBuilder(Convert.ToInt32(SendMessage(wi.Handle, WMConstants.WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero)) + 1);
                SendMessage(wi.Handle, WMConstants.WM_GETTEXT, caption.Capacity, caption);
                wi.Caption = caption.ToString();
            }
            return(wi);
        }