0

有一些 PInvoke 函数可用于获取窗口句柄,但如何获取正在使用的确切窗口句柄:例如应用程序中的 richTextBox1 窗口?还是 Notepad.exe 的文本框句柄?还有 chrome/firefox 网页上的文字。

抓住所有三个的例子将是糟糕的......最受赞赏的是在 Google Chrome 或 Firefox 中:无论是文本框还是PAGE

[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static extern IntPtr GetFocus();

这适用于应用程序本身的窗口,但在记事本和 chrome 中失败

4

1 回答 1

1

如您所说,GetFocus仅适用于由当前线程的消息队列管理的窗口句柄。您需要做的是临时将您的消息队列附加到另一个进程:

  1. 使用 获取前景窗口的句柄GetForegroundWindow
  2. 获取您的线程和拥有前台窗口的线程的线程 ID,使用GetWindowThreadProcessId.
  3. 使用 .将消息队列附加到前台窗口的线程AttachThreadInput
  4. 调用GetFocus将从前台窗口的线程返回窗口句柄。
  5. 再次断开与前台窗口的线程的连接AttachThreadInput

像这样的东西:

using System.Runtime.InteropServices;

public static class WindowUtils {
    [DllImport("user32.dll")]
    static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll")]
    static extern IntPtr GetWindowThreadProcessId(
        IntPtr hWnd,
        IntPtr ProcessId);

    [DllImport("user32.dll")]
    static extern IntPtr AttachThreadInput(
        IntPtr idAttach, 
        IntPtr idAttachTo,
        bool fAttach);

    [DllImport("user32.dll")]
    static extern IntPtr GetFocus();

    public static IntPtr GetFocusedControl() {
        IntPtr activeWindowHandle = GetForegroundWindow();

        IntPtr activeWindowThread = 
            GetWindowThreadProcessId(activeWindowHandle, IntPtr.Zero);
        IntPtr thisWindowThread =
            GetWindowThreadProcessId(this.Handle, IntPtr.Zero);

        AttachThreadInput(activeWindowThread, thisWindowThread, true);
        IntPtr focusedControlHandle = GetFocus();
        AttachThreadInput(activeWindowThread, thisWindowThread, false);

        return focusedControlHandle;
    }
}

(来源:其他过程中的控制焦点

于 2013-02-11T05:20:29.977 回答