How to get an active application ChildWindow application?

I have this problem: I have a mainWindow handler for a specific application, and I want to simulate a click on this application ...

I am using sendMessage / postMessage api calls for this. The reason I don't use the .Net SendKeys or keybd_event function from win32 api is because they mimic global keystrokes. In my case, the target application is not the most active (another application may run at a higher level z, therefore, covering the target application).

The problem with sendMessage and postMessage is that you have to pass the handler of the exact child window in which you want to press the key. For example, in notepad, if I send a key to the mainWindow handler, nothing happens, I have to send the key to the handler of the child window, which basically consists of a white canvas where you can write.

Getting an active child window handler is a problem. At first, I used the GetTopWindow or GetWindow (GW_CHILD) api calls, as it returns the most active child window. What I did was to keep calling GetWindow (GW_CHILD) until I had a child window that no longer had childWindows. This works fine for some applications, such as notepad or paint. However, in some cases (e.g. firefox) this does not work. The reason for this is that the parent window has the entire firefox scope, and its child branch has open WebPage (e.g. google). Therefore, when I request the most active mainWindow child window, it returns the only child window that it has that matches the area of ​​the web page. It only works ifif the active window is this (for example, if the user writes something in the text box of a specific page). But if, say, the address bar is active, it does not work, because the active window is not a child window, but actually a parent ... and I can not get this information programmatically.

, api GetGUIThreadInfo, :

    // 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);

: , "W" . google , "W"... ! : , ThreadInfo . , firefox, , firefox ( , /), , , firefox, , .

, , setForegroundWindow api , , , .

, AttachThreadInput() GetFocus() api-, , : Windows, .

, .

?

+3
2

, . , WH_CBT WH_CALLWNDPROC .

CBT (WH_CBT) HCBT_SETFOCUS. WH_CALLWNDPROC WM_SETFOCUS.

. , .

0

Source: https://habr.com/ru/post/1707857/


All Articles