Jump to content

WinWaitActive/WinActivate on MDI Child Windows


Recommended Posts

I am (attempting) to automate an internal (.NET) MDI program and running into difficulty.

The problem is that the main window is always considered active (according to WinGetTitle("[active]")) no matter which MDI child has the focus. (Meaning that it returns the title of my main app) I have worked around this by combining the techniques mentioned in this thread to get the MDI child's HWND then doing a WinActivate($hwnd); this solves the problem for data input.

HOWEVER The problem I have now is I need to detect when a MDI child closes and focus returns to another.

The MDI children titles do show under the visible text in the AutoIt info tool, the problem is that the window i am waiting on is always open (although underneath others at times) so as long as my main app has focus then a WinActive("main app title", "mdi child text") always returns true.

I noticed in the info tool that my window has a line called Advanced Mode: [NAME:RegistrationSearchForm] however I am either been looking at too much documentation or I am just stupid because I can NOT get that to work for the life of me.

I can't be the only one to have had this issue, can someone give me some pointers please?

Link to comment
Share on other sites

This returns the handle of the current active window, so you can detect if it changes, regardless of the title\text\etc.

$hActive = WinGetHandle("[ACTIVE]", "")

:D

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Thank you for the reply PsaltyDS; however it does not work.

My code:

While 1
    $hActive = WinGetHandle("[ACTIVE]", "")
    ConsoleWrite("Active Handle=" & $hActive & @CRLF)
    Sleep(500)
WEnd

It always returns the handle to the main MDI Parent container, not the MDI Children. Going into my MDI application (while the above is running) and switching between [child] windows does not change the active handle :D

Link to comment
Share on other sites

Don't know what to tell you, this works:

$hMain = GUICreate("Parent", 300, 300, 100, 100, Default, Default)
ConsoleWrite("$hMain = " & $hMain & @LF)
GUISetState()

Sleep(2000)
$hChild1 = GUICreate("Child1", 300, 300, 300, 300, Default, Default, $hMain)
ConsoleWrite("$hChild1 = " & $hChild1 & @LF)
GUISetState()

Sleep(2000)
$hChild2 = GUICreate("Child2", 300, 300, 500, 500, Default, Default, $hMain)
ConsoleWrite("$hChild2 = " & $hChild2 & @LF)
GUISetState()

Do
    $hActive = WinGetHandle("[ACTIVE]", "")
    ToolTip("Active = " & $hActive)
Until GUIGetMsg() = -3

:D

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

  • 2 weeks later...

PsaltyDS,

I think is see the failure of my communication after running your demo code. Your code does not create MDI parent/child windows, which is what I am attempting to access.

Here is an image I found on a quick google image search (it is NOT my application):

Posted Image

The problem is that no matter which child form is active (1 or 2) the active hwnd that returns is always the parent form.

Thank you for your work in helping me with this.

Link to comment
Share on other sites

The problem is that no matter which child form is active (1 or 2) the active hwnd that returns is always the parent form.

Thank you for your work in helping me with this.

Watch the Summary tab of AU3Info while checking out the MDI child windows. Maybe they are more like controls in the parent window? Do they show a different control handle?

Do you know of another app people on this forum might have installed that shows the same issue?

:mellow:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Watch the Summary tab of AU3Info while checking out the MDI child windows. Maybe they are more like controls in the parent window? Do they show a different control handle?

The window handle does not change, which is to be expected given the results we are seeing. The information in the Control section does change; however I am not sure of how to leverage this to see which control/form is active given that a textbox (for example) on that child window/control may be the 'actual' active control.

Here is an example of the changing information from summary (Visible/Hidden Text, ToolsBar, StatusBar does not change):

>>>> Window <<<<
Title:  TESTING iDMV - ABURNS                         >>>>>>>>>>> TESTING <<<<<<<<<<<
Class:  WindowsForms10.window.8.app.0.202c666
Position:   -4, -4
Size:   1288, 972
Style:  0x17CF0000
ExStyle:    0x00050100
Handle: 0x00470CC4

>>>> Control <<<<
Class:  WindowsForms10.window.8.app.0.202c666
Instance:   7
ClassnameNN:    WindowsForms10.window.8.app.0.202c6667
Name:   RegistrationSearchForm
Advanced (Class):   [NAME:RegistrationSearchForm]
ID: 2
Text:   RegistrationSearchForm
Position:   475, 104
Size:   742, 512
ControlClick Coords:    7, 399
Style:  0x56C80000
ExStyle:    0x00050541
Handle: 0x00230D28

Second window:

>>>> Window <<<<
Title:  TESTING iDMV - ABURNS                         >>>>>>>>>>> TESTING <<<<<<<<<<<
Class:  WindowsForms10.window.8.app.0.202c666
Position:   -4, -4
Size:   1288, 972
Style:  0x17CF0000
ExStyle:    0x00050100
Handle: 0x00470CC4

>>>> Control <<<<
Class:  WindowsForms10.window.8.app.0.202c666
Instance:   6
ClassnameNN:    WindowsForms10.window.8.app.0.202c6666
Name:   SetDefaultPrinterForm
Advanced (Class):   [NAME:SetDefaultPrinterForm]
ID: 1
Text:   SetDefaultPrinterForm
Position:   295, 510
Size:   382, 208
ControlClick Coords:    131, 26
Style:  0x56CB0000
ExStyle:    0x00050140
Handle: 0x00240C6E

I have tried several differing methods of using the advanced class text (as that is the actual .NET form name) but nothing works.

Do you know of another app people on this forum might have installed that shows the same issue?

:mellow:

The only one I can find quickly is Excel with multiple workbook views you can tile them then resize to get the actual MDI child windows. I was able to re-produce the above results with the summary tab using this method. I will continue to search to see if there is a better example.
Link to comment
Share on other sites

Working with Excel 2002 as an example, the two documents are controls as Excel71 and Excel72, with different handles. So _WinAPI_WindowFromPoint() will get the correct handles for the document windows (controls), and _WinAPI_GetWindowLong() gets the status, which changes for the active one.

Maybe that will help.

:mellow:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

PsaltyDS

Thank you so much! With your guidance I was able to accomplish what I needed in the following manner:

1: Find the [actual] container for the MDI child forms. This is a child window of the main app/window and is found by:

Func MDI_GetAppContainerHandle($title)
    Local $classes = StringSplit( WinGetClassList($title), @LF)
    For $i = 1 to $classes[0]
        Local $cName = $classes[$i]
        If StringLeft($cName, 29) = "WindowsForms10.MDICLIENT.app." Then
            ;ConsoleWrite("***Class=" & $cName & @CR)
            Return ControlGetHandle($title, "", "[CLASS:" & $cName & "]")
        EndIf
    Next
EndFunc

2: Once I have the container handle I can get the actual active form (with much help / inspiration from PsaltyDS):

Func MDI_ChildFormActive($appTitle, $formName)
    Local $appHwnd = WinGetHandle($appTitle)
    Local $hMdiContainer = MDI_GetAppContainerHandle($appHwnd)
    
    ; Get the active child window for the MDI container & the requested form
    Local $hActiveChild = _WinAPI_GetWindow($hWndCtr, $GW_CHILD)
    Local $hForm = ControlGetHandle($appHwnd, "", "[NAME:" & $formName & "]")
    
    Return $hActiveChild = $hForm
EndFunc

The ControlGetHandle call will return the handle to the form with the specified [.NET] name.

From here it should be a simple matter to write a MdiChildWaitActive() function.

Thank you again!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...