Search code examples
c#winapienumerationwindow-handles

manipulating window / process by its handle (even if there's no title or a window)


I want to check on this code and see if you can help me implement it

if so , is there a way to query faster getting only process that starts with "a" and process starts with "b"

(is it by using the filter parameter )

could it be done via other method with parameters required by

EnumDesktopWindows(IntPtr.Zero, filter, IntPtr.Zero)

how can i call EnumDesktopWindows() with another maybe not only using native method - filtering as mentioned ... kind'a "helper" method

 private const string USER32 = "user32.dll";

    internal delegate bool EnumDelegate(IntPtr hWnd, int lParam);

    [DllImport(WindowsFunctions.USER32, EntryPoint = "GetWindowText", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
    internal static extern int GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);

    [DllImport(WindowsFunctions.USER32)]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool IsWindowVisible(IntPtr hWnd);

    [DllImport(WindowsFunctions.USER32)]
    internal static extern int GetWindowThreadProcessId(IntPtr hWnd, out int processId);

    [DllImport(WindowsFunctions.USER32)]
    internal static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDelegate lpfn, IntPtr lParam);







public class WindowData
{
    public string Title { get; set; }
    public long ProcessId { get; set; }
    public long ThreadId { get; set; }
    public IntPtr HWindow { get; set; }
}


        var collection = new List<WindowData>();

        EnumDelegate filter = delegate(IntPtr hWnd, int lParam)
        {
            StringBuilder strbTitle = new StringBuilder(255);
            int nLength = WindowsFunctions.GetWindowText(hWnd, strbTitle, strbTitle.Capacity + 1);
            string strTitle = strbTitle.ToString();

            if (IsWindowVisible(hWnd) && !string.IsNullOrEmpty(strTitle))
            {
                int pid;
                int threadId = WindowsFunctions.GetWindowThreadProcessId(hWnd, out pid);

                collection.Add(new WindowData()
                {
                    Title = strbTitle.ToString(),
                    ProcessId = pid,
                    ThreadId = threadId,
                    HWindow = hWnd
                });
            }

            return true;
        };



        if (EnumDesktopWindows(IntPtr.Zero, filter, IntPtr.Zero))
        {
            return collection.ToArray();
        }

        return null;
    }

Solution

  • this is what i came up with as temporary solution

    public static class MyProc
        {
            public static IntPtr WoWhWnd;
            public static string WoWProcName;
            public static string WowMainWinTitle;
            public static int WowID;
            public static IntPtr MyApphWnd;
            public static string MyAppProcName;
            public static string MyAppMainWinTitle;
            public static int MyAppID;
        }
    
    
        public void bring(string handletoFront)
        {
            switch (handletoFront)
            {
                default:
    
                    SetForegroundWindow(MyProc.WoWhWnd);
    
                    break;
                case "MyApp":
    
                    SetForegroundWindow(MyProc.MyApphWnd);
                                        break;
            }
    
    
        }
    
    
               #region <<=========== Enumerating Processes   ============>>
    
            void  ShowP1(){
    
                IEnumerable<Process> processes = from p in Process.GetProcesses() where p.ProcessName.StartsWith(TBXSearchWindowTerm.Text) || p.ProcessName.StartsWith("WindowsF") orderby p.ProcessName select p;
                MyProc.MyApphWnd = processes.ElementAt(1).MainWindowHandle;
                MyProc.MyAppMainWinTitle = processes.ElementAt(1).MainWindowTitle;
                MyProc.MyAppID = processes.ElementAt(1).Id;
                MyProc.WoWhWnd = processes.ElementAt(0).MainWindowHandle;
                MyProc.WowMainWinTitle = processes.ElementAt(0).MainWindowTitle;
                MyProc.WowID = processes.ElementAt(0).Id;
                pause(350);
                SetForegroundWindow(MyProc.WoWhWnd);
                pause(850);
                SetForegroundWindow(MyProc.MyApphWnd);
            }
    

    in one of the queryies i have used a text box value so it could be one constant search and a dynamic optional one , if you see somthing that i did wrong or i could do better , please do comment . thank you .