C # winform - получить расположение и размер дочернего процесса внешних программ - PullRequest
0 голосов
/ 28 сентября 2018

после 1 месяца онлайн-охоты Я не нашел решения для моей проблемы.Теперь я чувствую, что пришло время опубликовать этот пост для любой помощи.

Мой проект : он находит внешнее работающее программное обеспечение на панели задач, получает местоположение, имя, идентификатор процесса и заголовок окна и сохраняет его в сетке данных.Я использую c # в winform с windows 7

Проблема: мой код может найти процесс запущенного программного обеспечения (processID) и может получить размер и другие детали.но проблема в том, что мой код не может найти размер дочернего / дочернего окна или любую другую деталь.

Пример информации: Я приложил примеры изображений и код, который работает, найти без каких-либо ошибок.но не захватывая другие программы, работающие с дочерними окнами.На изображениях, которые вы видите, программное обеспечение Webex может найти дочернее окно и прикрепить всплывающее окно над ним (это просто для примера, что можно найти дочернее окно)
на моем втором изображении вы можете видеть, что мой код находит только главноеокно Skype (Lync)

Любое предложение или направление будет большой помощью, спасибо

Импорт DLL

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr FindWindow(string strClassName, string strWindowName);

    [DllImport("user32.dll")]
    public static extern bool GetWindowRect(IntPtr hwnd, ref Rect rectangle);
    public struct Rect
    {
        public int Left { get; set; }
        public int Top { get; set; }
        public int Right { get; set; }
        public int Bottom { get; set; }
    }

    [DllImport("user32.dll")]
    static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

Запустите код, чтобы найти окно и размер по нажатию кнопки и выполните некоторые вычисления для w и h.

        Process[] processes = Process.GetProcesses();
        foreach (Process p in processes)
        {
            if ((int)p.MainWindowHandle != 0)
            {

                if (!String.IsNullOrEmpty(p.MainWindowTitle))
                {

                    myCurrentProcessName = p.ProcessName;
                    //listBox1.Items.Add(p.MainWindowTitle); // add all process to listbox

                    //find windows size and location
                    IntPtr ptr = p.MainWindowHandle;
                    Rect appRect = new Rect();
                    GetWindowRect(ptr, ref appRect);

                    x = appRect.Left;
                    y = appRect.Top;
                    r = appRect.Right;
                    b = appRect.Bottom;
                    //
                    //calculate size of the app
                    w = r - x;
                    h = b - y;
                    dataGridView1.Rows.Add(p.Id, p.MainWindowHandle, p.ProcessName, p.MainWindowTitle, IsIconic(wHnd), appState, x, y, w, h);
                 }
           }
         }

Skype child conversation windows capture result shows main windows location only

обновление: в соответствии с рекомендациями Абье.Я пытался гуглить EnumChildWindows.я нашел код по этой ссылке Как я могу получить дочерние окна окна, учитывая его HWND? Я пытался реализовать его в своем коде, но не знаю, как его использовать и получить расположение и размер дочернего окна.

private delegate bool EnumWindowProc(IntPtr hwnd, IntPtr lParam);

    [DllImport("user32")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr lParam);

    private IntPtr _MainHandle;

    public Form1(IntPtr handle)
    {
        this._MainHandle = handle;
    }

    public List<IntPtr> GetAllChildHandles()
    {
        List<IntPtr> childHandles = new List<IntPtr>();

        GCHandle gcChildhandlesList = GCHandle.Alloc(childHandles);
        IntPtr pointerChildHandlesList = GCHandle.ToIntPtr(gcChildhandlesList);

        try
        {
            EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
            EnumChildWindows(this._MainHandle, childProc, pointerChildHandlesList);
        }
        finally
        {
            gcChildhandlesList.Free();
        }

        return childHandles;
    }

    private bool EnumWindow(IntPtr hWnd, IntPtr lParam)
    {
        GCHandle gcChildhandlesList = GCHandle.FromIntPtr(lParam);

        if (gcChildhandlesList == null || gcChildhandlesList.Target == null)
        {
            return false;
        }

        List<IntPtr> childHandles = gcChildhandlesList.Target as List<IntPtr>;
        childHandles.Add(hWnd);

        return true;
    }


 private void button5_Click(object sender, EventArgs e)
    {
     Process[] anotherApps = Process.GetProcessesByName(textBox1.Text);
        if (anotherApps.Length == 0) return;
        if (anotherApps[0] != null)
        {
            var allChildWindows = new Form1(anotherApps[0].MainWindowHandle).GetAllChildHandles();
         }
     }

Это возвращаемое значение из кода GetAllChildHandles (), но как использовать его для получения местоположения и размера дочернего окна?

enter image description here

enter image description here

...