Как использовать Control.FromHandle? - PullRequest
3 голосов
/ 21 февраля 2010

Я видел метод с именем Control.FromHandle, который (должен) дать вам доступ к нему. Теперь я хотел попробовать это используя этот код

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    // Find window by Caption only. Note you must pass IntPtr.Zero as the first parameter.

    [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
    static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

    [DllImport("user32.dll")]
    private static extern IntPtr GetDC(IntPtr hwnd);
    [DllImport("user32.dll")]
    private static extern bool ReleaseDC(IntPtr hwnd, IntPtr hdc);

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        IntPtr ptr = FindWindowByCaption(IntPtr.Zero, "Download");
        Control f = Control.FromHandle(ptr);
        f.Text = "Something";
    }

но это, очевидно, не сработает. Я лично проверил, что дескриптор правильный ... но метод возвращает нулевой элемент управления. Любое объяснение?

Ответы [ 3 ]

4 голосов
/ 21 февраля 2010

Этот метод работает, только если дескриптор, который вы передаете, фактически равен Control в вашем приложении.

2 голосов
/ 21 февраля 2010

В вашем конкретном случае, поскольку вы просто хотите установить текст, вызовите SetWindowText из user32.dll

0 голосов
/ 08 марта 2011

Для всех, кто ищет в Google этот ответ и интересуется, почему так происходит, этот пост http://www.codeguru.com/forum/showthread.php?t=443191 особенно поучителен, особенно последний пост из «MadHatter»:

хорошо, просто глядя на то, что происходит в Control.FromHandle в отражателе, похоже, что когда окна добавляются в мир .net, в нем хранится таблица того, какие дескрипторы загружены, проблема возникает, когда вы переходите в дескриптор, который не указан в его таблицах. Может быть какой-то хак, который позволит вам зарегистрировать окно во всех подсистемах, которые используются при создании окон из приложения .net, но, вероятно, было бы лучше / более согласованно переносить любую функциональность, которая вам нужна, непосредственно через windows api затем попробуйте взломать Control.FromHandle, чтобы позволить вам получить доступ / манипулировать окном какого-либо другого процесса.

Читая больше в вашем вопросе, кажется, что вы пытаетесь сделать некоторую автоматизацию или, по крайней мере, каким-то образом манипулировать окном. Могу порекомендовать посмотреть на Управляемый Windows API проект на SourceForge. Он довольно хорошо написан, и мы использовали его для целей, которые вы описываете.

...