P/Invoke SetFocus 到特定控件

Jor*_*dan 5 .net c# pinvoke winapi setfocus

是否可以将焦点设置在另一个应用程序的文本框上(使用其 ClassName)。我的窗口句柄是IntPtr. 但只需要一些关于可用于此功能/API 的指导!

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

任何帮助都会很棒!

NSG*_*aga 5

...据我记得,这是我必须使用的代码来使其工作 \xe2\x80\x93 并且在我的应用程序和较新的 Windows 等上运行良好。

\n
void SetFocus(IntPtr hwndTarget, string childClassName)\n{\n    // hwndTarget is the other app\'s main window \n    // ...\n    IntPtr targetThreadID = WindowsAPI.GetWindowThreadProcessId(hwndTarget, IntPtr.Zero); //target thread id\n    IntPtr myThreadID = WindowsAPI.GetCurrentThread(); // calling thread id, our thread id\n    try\n    {\n        bool lRet = WindowsAPI.AttachThreadInput(myThreadID, targetThreadID, -1); // attach current thread id to target window\n\n        // if it\'s not already in the foreground...\n        lRet = WindowsAPI.BringWindowToTop(hwndTarget);\n        WindowsAPI.SetForegroundWindow(hwndTarget);\n\n        // if you know the child win class name do something like this (enumerate windows using Win API again)...\n        var hwndChild = EnumAllWindows(hwndTarget, childClassName).FirstOrDefault();\n\n        if (hwndChild == IntPtr.Zero)\n        {\n            // or use keyboard etc. to focus, i.e. send keys/input...\n            // SendInput (...);\n            return;\n        }\n\n        // you can use also the edit control\'s hwnd or some child window (of target) here\n        WindowsAPI.SetFocus(hwndChild); // hwndTarget);\n    }\n    finally\n    {\n        bool lRet = WindowsAPI.AttachThreadInput(myThreadID, targetThreadID, 0); //detach from foreground window\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

...所以沿着这些路线(它按照正确的顺序执行您需要的操作,不要忘记分离等。 \xe2\x80\x93 但您需要根据您的具体条件调整它,控制/edit hwnd 等 \xe2\x80\x93 并且您仍然可能遇到与目标窗口/应用程序相关的其他问题,这适用于大多数情况,但并非在所有情况下,这是一个很长的故事,正如我所说取决于您的具体场景),

\n

WindowsAPI我相信是典型的 P/Invoke 包装器)\n基本上,您需要附加到另一个线程来进行“输入”操作,\n我相信这是官方解释“这也允许线程共享其输入状态,因此它们可以调用SetFocus 函数将键盘焦点设置到不同线程的窗口。” \nGoogle 搜索“AttachThreadInput”以获取更多信息(以了解原因),它也通常与SetFocus其他输入/键盘操作相关。\n自动化 API 也可以按照建议提供帮助 \xe2\x80\x93是“最干净”的方法 \xe2\x80\x93 但取决于目标应用程序是否公开并正确处理 \xe2\x80\x93 对于大多数应用程序来说仍然“不存在”,而不是一致等。 \xe2\x80\x93 如果您想处理不同的“自己的应用程序”,您需要问自己什么是最好的场景等。\n希望这有帮助

\n

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

\n

该代码是该规范的示例。案例并基于工作代码 \xe2\x80\x93 但可能需要测试和计算出一些细节(这似乎超出了这个问题的范围),例如..
\nWindowsAPI保存 Windows API 和本机调用的 P/Invoke 签名(类似于MS.Win32.UnsafeNativeMethods)并且它是一个静态类(请参阅该类或https://pinvoke.net/\xe2\x80\x93访问 Microsoft.Win32.UnsafeNativeMethods?),应命名为 (Safe/Unsafe)NativeMethods ( https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2015/code-quality/ca1060-move-p-invokes-to-nativemethods-class ) \xe2\x80\x93另请参阅IntPtr、SafeHandle 和 HandleRef - 解释IntPtr有点“旧”风格)
\nEnumAllWindows使用EnumChildWindowsGetClassNameWin API(我猜它是为了另一个问题)并且需要一个包装方法才能有用(这EnumAllWindows是 \xe2\x80\x93 它只是通过窗口递归地枚举检查类名)。

\n