将SetFocus固定到特定控件 [英] Pinvoke SetFocus to a particular control

查看:146
本文介绍了将SetFocus固定到特定控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个简单的问题:是否可以将焦点设置在另一个应用程序的文本框中(使用它的ClassName).我有一个窗口,例如"intptr"等,但只需要一些有关此功能/API可用的指导即可!

Simple question: is it possible to set focus on another application's textbox (using it's ClassName). I have the window as an "intptr" etc etc but just need some guidance as to what functions/APIs are available for this!

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

Issue is, I use the SetForegroundWindow API to get window focus, but it wouldn't let me send the Ctrl+L keys to focus on the textbox!

任何帮助都会很棒!

推荐答案

...据我所知,这是我必须使用的代码才能使其正常工作-在我的应用程序和更新的Windows上都可以正常工作等等

...as far as I recall, this is the code I had to use to make that work - and that worked well on my apps, and newer Windows etc.

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等.-而且您可能还有其他与目标窗口/应用程序相关的问题,这在大多数情况下都有效,但并非在所有情况下都有效,这是一个很长的故事,正如我所说,这取决于您的特定情况)

...so something along those lines (it does what you need and in the right order, don't forget to detach etc. - but you'd need to adjust it for your specific conditions, control/edit hwnd etc. - and still you might have other issues related to the target window/app, this works for most, but not in all cases, that's a long story and as I said depends on your specific scenario),

(我相信WindowsAPI是典型的PInvoke包装器) 基本上,您需要附加到另一个线程进行输入"操作, 我相信这是一个官方解释,它还允许线程共享其输入状态,因此他们可以调用SetFocus函数将键盘焦点设置为其他线程的窗口." Google提供了AttachThreadInput以获得更多信息(了解原因),并且它通常也与SetFocus和其他输入/键盘操作相关联. 此外,自动化API可以按照建议的方式提供帮助-这是最干净的"方法-但取决于目标应用是否正确公开并处理了该问题-大多数应用仍然不存在",不一致,等等.-如果您想要处理与当时不同的自己的应用程序",则需要问自己什么是最佳方案,等等. 希望对您有帮助

(WindowsAPI are typical PInvoke wrappers I believe) basically you need to attach to another thread for 'input' operations, I believe this is an official explanation "This also allows threads to share their input states, so they can call the SetFocus function to set the keyboard focus to a window of a different thread." Google for AttachThreadInput for more info (to know the reasons), and it's also often associated with the SetFocus and other input/keyboard operations. Also the Automation API could help as suggested - that's the 'cleanest' way to do it - but depends if a target app exposes and handles that properly - which still "isn't there" for most of them, not consistent etc. - if you want to handle your "own application" that's different then, you need to ask yourself what's the best scenario etc. hope this helps

请注意:必须有许多类似解决方案的链接(在SO上),因为这是众所周知的事情,但是我找不到正确的链接

note: there must be a dozen links to similar solutions (and on SO) as this is quite a known thing, but I'm unable to find a right link

我对您的具体情况和关注儿童的问题做了澄清
编辑(2):
该代码是此规范的示例.案例并基于有效的代码-但可能需要测试并找出一些细节(似乎超出了此问题的范围),例如...
WindowsAPI拥有Windows API和本机调用的PInvoke签名(类似于MS.Win32.UnsafeNativeMethods),它是一个静态类(请参见该类或访问Microsoft .Win32.UnsafeNativeMethods?),应命名为(Safe/Unsafe)NativeMethods( IntPtr,SafeHandle和HandleRef-解释(IntPtr有点古老"风格)
EnumAllWindows使用EnumChildWindows和GetClassName Win API (这是我猜的另一个问题),并且需要一个包装器方法(EnumAllWindows是有用的-它只是枚举Windows递归检查类名).

I clarified a bit for your specific case and child focus
EDIT (2):
the code is an example for this spec. case and based on working code - but might need testing and working out some details (which seem out of the scope for this question), e.g...
WindowsAPI holds the PInvoke signatures for windows API and native calls (similar to MS.Win32.UnsafeNativeMethods) and it's a static class (see that class or http://pinvoke.net/ - also Accessing Microsoft.Win32.UnsafeNativeMethods?), should be named (Safe/Unsafe)NativeMethods (http://msdn.microsoft.com/en-us/library/ms182161.aspx) - and also see IntPtr, SafeHandle and HandleRef - Explained (IntPtr is a bit 'old' style)
EnumAllWindows uses EnumChildWindows and GetClassName Win API (and it's for another question I guess) and requires a wrapper method for it to be useful (which EnumAllWindows is - it just enumerates thru windows recursively checking for class names).

这篇关于将SetFocus固定到特定控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆