I've developed an application that starts external processes (e.g. like the notepad etc.) and displays the main window of the process inside a panel in my application. (Like described in this thread)
The problem is that I get a lot of focus problems with that. E.g. when a window is over my application's window and I click on the window of the sub process, the main window does not come to the foreground.
I've tried to solve this problem by calling SetForegroundWindow from the main application when the child process receives focus, but as this and this thread describes this only works if the process is being debugged or if it is the foreground process. There is a workaround by calling AttachThreadInput, but that doesn't work 100% reliable.
SetForegroundWindow should also work if "The process was started by the foreground process", but in my case it is the other way arround. (The foreground process was started by the process)
Is there a way to get the right to set the foreground window if the focussed window is a child process of my process?
SetForegroundWindow sets the thread that created the specified window into the foreground.
BringWindowToTop brings the specified window to the top of the Z order.
I am using the method GetForegroundWindow() to get the window a user is using. But if the window is Windows Store App/UWP app (example the calculator) I get the window with a title (Reiknivél in Icelandic), but the process is ApplicationFrameHost. The problem is that I need the underlying process. I am now working on a method that takes that title and returns the process, but I have no idea how to connect the ApplicationFrameHost process to the real process.
I have been trying to get the hwnd for the window shown in the screenshot (link below). I am trying to get at it from one of the threads I can get from the calculator process. When I iterate all the windows from that thread using GetWindowHandlesForThread() I can get the other two and their titles, but the hwnd for the Windows.UI.Core window does not show up. And I know it's there because if I use Spy++ I can see it.
Any Ideas on how to get at it using C#? I have tried EnumWindows, EnumChildWindows, EnumThreadWindows and even GetGUIThreadInfoand all I have gotten from the ones that worked were the other two windows, never the CoreWindow that I need. Any ideas of how I could achieve this?
I've used FindWindow to get a handle to a window of an external application. How can I use this handle to activate the window of the external application, if it is minimized or behind other applications on the windows desktop?
To prevent focus-stealing (or at least make accidental focus-stealing harder), Windows puts up some roadblocks to one process bringing another process's window to the top.
Check MSDN for SetForegroundWindow (especially in the Remarks section) and AllowSetForegroundWindow.
You should either send a message to the process to tell it to restore its own window, or that process has to explicitly allow your process to do this.
FindWindow() followed by ShowWindow().
I have this problem: I have an handler to the mainWindow of a certain application, and I want to simulate a keypress on that application...
I'm using sendMessage/postMessage api calls to do this. The reason why I don't use the .Net SendKeys function or the keybd_event of the win32 api, is that they simulate the keypress at a global level. In my case, the target application is not the top-active one (other application may be running in a higher z-level, hence covering the target app).
The problem with sendMessage and postMessage is that you must pass the handler of the exact childwindow where you want the key to be pressed. For example, in notepad, if I send the key to the handler of the mainWindow, nothing happens, I have to send the key to the handler of the child window that basically consists of the white canvas where you can write.
Obtaining the handler to the active child window is the problem. In the beginning, I was using the GetTopWindow or GetWindow(GW_CHILD) api calls, as it returns the most active child window. What I was doing was to keep calling the GetWindow(GW_CHILD) until I got a childwindow that had no more childWindows. This works ok for some applications like notepad or paint. However, in some cases (like firefox for example), it doesn't work. The reason for that is that the parent window has the whole firefox area, and its childwindow has the opened WebPage (like google). So, when I ask for the most active child window of the mainWindow, it returns the only child window it has, which is the one corresponding to the Webpage area. It only works if the active window is that one (like if the user is writing something on a textbox of a certain page). But if what is active is, let's say, the address bar, it doesn't work because the active window is not the child window but actually the parent... and I can't get this information programatically.
I actually found a way of doing this, using the GetGUIThreadInfo api call, using the following code:
// get thread of the main window handle of the process
var threadId = GetWindowThreadProcessId(firefox.MainWindowHandle, IntPtr.Zero);
// get gui info
var info = new GUITHREADINFO();
info.cbSize = (uint)Marshal.SizeOf(info);
if (!GetGUIThreadInfo(threadId, out info))
throw new Win32Exception();
// send the letter W to the active window
PostMessage(info.hwndActive, WM_KEYDOWN, (IntPtr)Keys.W, IntPtr.Zero);
And it works very well: If the address bar is active, it sends a "W" letter to the address bar. If the search textBox of google is active, it sends the "W" letter to it... Perfect! However, this method can't be used by me for a simple reason:
If the target application is not the active window of the operating system, the ThreadInfo structure comes empty. For example, if I'm targetting firefox, it works if firefox is active (the top-most application, the focused/active one), but if, let's say, notepad is on top of firefox, it doesn't work, it is unable to get the active window handler.
I know I can solve this by using the setForegroundWindow api call to activate the target application and then capture the handler of the active child-window but I didn't want to have to bring the target app to the foreground.
I've also tried other techniques like AttachThreadInput() and GetFocus() api calls, which also works, but has the same problem: If the target application is not the active windows application, it doesn't work.
So basically I need to find some way of getting the handler to the active childwindow of an application even if that application is not the top-active one.
Any ideas?
Thanks
You might want to check out the EnumChildWindows function.
If everything else fails, here is another idea: You might want to consider using a WH_CBT or a WH_CALLWNDPROC hooks to monitor which child window of the target thread has been focused last.
Install a CBT hook (WH_CBT) and listen for the HCBT_SETFOCUS notification.
Or use a WH_CALLWNDPROC hook and listen for the WM_SETFOCUS message.
Don't do much in the hook proc or you'll hog down the system resources. Just save the needed information and post yourself a custom message to process it later.
It a is a c# winform app. I've set ShowInTaskbar prop to false because I don't want the program to appear in taskbar, but like this SetForegroundWindow or ShowWindowAsync don't work.
Raymond Chen explains the things the govern the rules in Windows around foreground activation in his classic article Foreground activation permission is like love: You can't steal it, it has to be given to you. Roughly speaking, you cannot steal foreground activation using a call like SetForegroundWindow, you need to be given it from a process which already has the foreground activation.
In your case, when you have show in taskbar set, the taskbar is able to give your application the foreground activation, because when you click on the taskbar icon for your window, this will (briefly) give the activation to the taskbar. If you don't have the activation shown in the taskbar, you need to find a way to have an application that does give it to you. One way that is explicitly allowed is to use a notification window (tray) icon.