如何使用Control.FromHandle?

时间:2010-02-20 21:28:36

标签: c# forms controls handle findwindow

我看到一个叫做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 个答案:

答案 0 :(得分:4)

此方法仅在您传入的句柄实际上是应用程序中的Control时才有效。

答案 1 :(得分:2)

在您的特定情况下,由于您只想设置文本,请从user32.dll

调用SetWindowText

答案 2 :(得分:0)

对于任何其他谷歌搜索人员发现这个答案,并想知道为什么会出现这种情况,这篇文章http://www.codeguru.com/forum/showthread.php?t=443191特别具有启发性,特别是'MadHatter'的最后一篇文章:

  

从查看反射器中的Control.FromHandle中发生的事情来看,看起来就像窗口被添加到.net世界中一样,它存储了一个处理它已加载的句子的表,当你传入一个未在其表中列出的句柄。可能有一些hack会允许您通过.net应用程序中创建窗口时使用的所有子系统注册窗口,但是通过windows api直接包装您需要的任何功能可能更好/更一致然后尝试入侵Control.FromHandle以允许您访问/操作其他进程的窗口。

在您的问题中阅读更多内容似乎您正在尝试进行一些自动化或至少以某种方式操纵窗口。我可能会建议在SourceForge上查看Managed Windows API项目。它编写得非常好,我们已将它用于您描述的目的。