Monday, 8 October 2012

c# Window Enumerating the noob way

So today i was faced with a silly noob problem!, At work today i came across a silly problem with the way we were enumerating our windows, So i decided to write my own title enumerator.

You'll see how it works when you run it.



--


using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using Timer = System.Threading.Timer;

namespace Enum
{
    public partial class Form1 : Form
    {   
        public string Window { get; set; } //this window to enumerate

        public Form1()
        {
            InitializeComponent();

            this.Window = this.Text;

            Application.Idle += new EventHandler(Application_Idle);

            new Timer((@trigger) =>
            {
                Application.RaiseIdle(null);
            }).Change(1000, System.Threading.Timeout.Infinite);
        }

        void Application_Idle(object sender, EventArgs e)
        {
            var windows = Enum.GetDesktopWindowsTitles();
            var count = windows.Where(i => i.Contains(Window)).Count();

            if (count > 0)
            {
                var processes = Process.GetProcesses().Where(i => i.MainWindowTitle == Window).ToArray();
                for (var i = 0; i < processes.Length; i++)
                {
                    var str = Window + " " + count;
                    if (windows.Count(j => j == str) == 0)
                    {
                        Enum.SetWindowText(processes[i].MainWindowHandle, str);
                        count++;
                    }
                    else
                    {
                        var titles = windows.Where(z => { return z.Contains(Window + " "); }).Select(k => int.Parse(k.Split(' ')[1])).ToArray();
                        int length = titles.Length,
                               min = titles.Min(),
                               max = titles.Max();

                        var result = Enumerable.Range(1, max).Except(titles);

                        Enum.SetWindowText(processes[i].MainWindowHandle, Window + " " + result.FirstOrDefault());
                        count++;
                    }
                }
            }
        }
    }

    public class Enum
    {
        const int MAXTITLE = 255;
        private static List<string> lstTitles;
        private delegate bool EnumDelegate(IntPtr hWnd, int lParam);

        [DllImport("user32.dll")]
        public static extern bool SetWindowText(IntPtr hWnd, string lpString);

        [DllImport("user32.dll", EntryPoint = "EnumDesktopWindows", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDelegate lpEnumCallbackFunction, IntPtr lParam);

        [DllImport("user32.dll", EntryPoint = "GetWindowText", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int _GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);

        [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool IsWindowVisible(IntPtr hWnd);

        private static bool EnumWindowsProc(IntPtr hWnd, int lParam)
        {
            var strTitle = GetWindowText(hWnd);
            if (!string.IsNullOrEmpty(strTitle) & IsWindowVisible(hWnd))
                lstTitles.Add(strTitle);

            return true;
        }

        public static string GetWindowText(IntPtr hWnd)
        {
            var strbTitle = new StringBuilder(MAXTITLE);
            var nLength = _GetWindowText(hWnd, strbTitle, strbTitle.Capacity + 1);
            strbTitle.Length = nLength;           
            return strbTitle.ToString();
        }

        public static string[] GetDesktopWindowsTitles()
        {
            lstTitles = new List<string>();
            var delEnumfunc = new EnumDelegate(EnumWindowsProc);
           
            var result = EnumDesktopWindows(IntPtr.Zero, delEnumfunc, IntPtr.Zero);
            if (result)
                return lstTitles.ToArray();

            return null;
        }
    }
}

No comments:

Post a Comment