Is it possible to set focus on another application's textbox (using its ClassName). I have the window handle as an IntPtr
. But just need some guidance as to what functions/APIs are available for this!
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!
Any help would be great!
...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
}
}
...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
are typical P/Invoke 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
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
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 P/Invoke signatures for Windows API and native calls (similar to MS.Win32.UnsafeNativeMethods
) and it's a static class (see that class or https://pinvoke.net/ – also Accessing Microsoft.Win32.UnsafeNativeMethods?), should be named (Safe/Unsafe)NativeMethods (https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2015/code-quality/ca1060-move-p-invokes-to-nativemethods-class) – 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).