Pinvoke SetFocus到特定的控件

时间:2012-02-29 16:37:23

标签: c# pinvoke setfocus

简单问题:是否可以将焦点设置在另一个应用程序的文本框上(使用它的ClassName)。我有窗口作为“intptr”等等,但只需要一些指导,以确定可用的功能/ API!

问题是,我使用SetForegroundWindow API获取窗口焦点,但它不允许我发送Ctrl + L键来关注文本框!

任何帮助都会很棒!

1 个答案:

答案 0 :(得分:3)

...据我所知,这是我必须使用的代码才能完成这项工作 - 这在我的应用程序和更新的Windows等方面运行良好。

void SetFocus(IntPtr hwndTarget, string childClassName)
{
    // hwndTarget is the other app's main window 
    // ...
    IntPtr targetThreadID = WindowsAPI.GetWindowThreadProcessId(hwndTarget, IntPtr.Zero); //target thread id
    IntPtr myThreadID = WindowsAPI.GetCurrentThread(); // calling thread id, our thread id
    try
    {
        bool lRet = WindowsAPI.AttachThreadInput(myThreadID, targetThreadID, -1); // attach current thread id to target window

        // if it's not already in the foreground...
        lRet = WindowsAPI.BringWindowToTop(hwndTarget);
        WindowsAPI.SetForegroundWindow(hwndTarget);

        // if you know the child win class name do something like this (enumerate windows using Win API again)...
        var hwndChild = EnumAllWindows(hwndTarget, childClassName).FirstOrDefault();

        if (hwndChild == IntPtr.Zero)
        {
            // or use keyboard etc. to focus, i.e. send keys/input...
            // SendInput (...);
            return;
        }

        // you can use also the edit control's hwnd or some child window (of target) here
        WindowsAPI.SetFocus(hwndChild); // hwndTarget);
    }
    finally
    {
        bool lRet = WindowsAPI.AttachThreadInput(myThreadID, targetThreadID, 0); //detach from foreground window
    }
}

...所以沿着这些方向(它按照你的需要做正确的顺序,不要忘记分离等等 - 但你需要根据你的具体情况进行调整,控制/编辑hwnd等 - - 你可能还有其他与目标窗口/应用程序相关的问题,这适用于大多数情况,但并非在所有情况下,这是一个很长的故事,正如我所说,取决于您的具体情况),

(WindowsAPI是我认为的典型PInvoke包装器) 基本上你需要附加到另一个线程进行'输入'操作, 我相信这是官方解释“这也允许线程共享其输入状态,因此他们可以调用SetFocus函数将键盘焦点设置为不同线程的窗口。” 谷歌的AttachThreadInput更多信息(了解原因),它也经常与SetFocus和其他输入/键盘操作相关联。 此外,Automation API可以提供帮助 - 这是“最干净”的方式 - 但取决于目标应用程序是否正确暴露和处理 - 对于大多数人来说仍然“不存在”,不一致等等 - 如果你想要处理与你不同的“自己的应用程序”,你需要问自己什么是最好的方案等。 希望这有帮助

注意:必须有十几个类似解决方案的链接(以及SO),因为这是一个众所周知的事情,但我无法找到正确的链接

编辑:我为您的具体案例和儿童焦点澄清了一点
编辑(2):
代码是此规范的一个示例。案例并基于工作代码 - 但可能需要测试并制定一些细节(这似乎超出了这个问题的范围),例如...... WindowsAPI保存Windows API和本机调用的PInvoke签名(类似于MS.Win32.UnsafeNativeMethods),它是一个静态类(请参阅该类或http://pinvoke.net/ - 还Accessing Microsoft.Win32.UnsafeNativeMethods?) ,应该命名(安全/不安全)NativeMethods(http://msdn.microsoft.com/en-us/library/ms182161.aspx) - 并且还看IntPtr, SafeHandle and HandleRef - Explained(IntPtr有点'老'风格)
EnumAllWindows使用EnumChildWindows和GetClassName Win API (这是我想的另一个问题)并且需要一个包装器方法才能使它有用(EnumAllWindows是 - 它只是通过递归检查类名来枚举窗口)。