3

我看到了一个名为 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";
    }

但这显然行不通。我亲自检查了句柄是否正确......但该方法返回一个空控件。有解释吗?

4

3 回答 3

4

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

于 2010-02-20T21:35:43.653 回答
2

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

于 2010-02-20T21:53:16.700 回答
0

对于其他任何通过谷歌搜索找到此答案并想知道为什么会出现这种行为的人,这篇文章http://www.codeguru.com/forum/showthread.php?t=443191特别具有启发性,特别是来自“MadHatter”的最后一篇文章:

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

Reading more into your question it seems like you are trying to do some automation or at very least manipulate the window in some way. Might I recommend looking at the Managed Windows API project on SourceForge. It is pretty well written and we've used it for the purposes you are describing.

于 2011-03-07T22:08:59.607 回答