LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Detect the presence of child window in exernal application

I am trying to send mouse clicks to an external application. The external application controls a power supply and runs through a number of set tests. At the end of each test a child or more probably grand child window pops up to say that that each individual test is complete and results can be read from any connected test equipment. In this case an oscilloscope is connected and I want to take a screen shot at the end of each test and have Labview click on the OK button to start the next test.

The problem I have is that using the Labview windows utilities labview_win_util32_8.6 that make calls to LVWUtil32.dll There does not seem to be any way of getting access to child windows.
I did find a reference on the forum to using .Net, this gave an example using an invoke node Process>GetProcess. As child windows are created by other programs this does not show any change in the number of processes.
It may be that accessing the  EnumChildWindows function in user32.dll may work, but I have not been able to successfully make any call to this dll. Examples work OK but even when I try to copy them they fail. I'm obviously missing something here, not least relating Labview types to Windows types and how to actually make the call. 

All other parts of my program are functional, I'm just held up trying to find out when this window pops op. Does anyone know how to use Labview determine the presence of a child window.
 
 Thanks in advance
 Peter

0 Kudos
Message 1 of 9
(4,490 Views)

Hi Peter,

 

I looked into this and also think the Windows API is perhaps the only way. 

This forum suggests other functions than the ones you mention though, like a Hook procedure. And if you know the name of the child then maybe FindWindowExa is also handy.

 

Do you know why this fails?

Would it be nice if I try this on my end and help troubleshoot? Then please share the test files you made and I'm happy to take a closer look.

 

Best,

Andrés

 

 

0 Kudos
Message 2 of 9
(4,443 Views)

Hi Peter, 

 

This Windows API Function Utilities (32-bit) for LabVIEW has a Get Task List.vi in the Winevent.llb library. This lists all currently running tasks, if you know the name of the generated tasks you could use it to detect if a child was spawned as well. 

 

Take a look and let me know what you think. 

 

Best,

Andrés

0 Kudos
Message 3 of 9
(4,437 Views)

Hi Peter, 

 

More information.

EnumChildWindows needs a pointer to a Callback function, LabVIEW is not capable of generating such a pointer natively but a workaround exists. Is this perhaps why this has not worked for you yet? 

The FindWindowExA approach needs a data structure that defines the type of child window to search for, I don't have more details though. 

 

Best,

Andrés

0 Kudos
Message 4 of 9
(4,432 Views)

Hey Peter,

Additionally to the two approaches Andrés posted there is another way, and it works in some cases (just give it a try...):

GetWindowA from Windows API.

 

An important thing to notice is what a "client window" is in Windows API. This screenshot of my Registry Editor shows three client windows, all marked with a red rectangle:

regedit_2019-02-19_15-25-18.png

 

The following search window however is not a child window!

2019-02-19_15-26-44.png

 

The attached VI can find them both. The following screenshot shows the result when searching all Child Windows of a window called "Registry Editor":

FindChildWindowsDemo_FP.png

So it can find the main window, and all parts of it. The Find window is not accessible using this "find all childs" approach (I also tested the GW_ENABLEDPOPUP parameter value and childs' childs).

 

However, I can find a window titled "Find" directly:

FindChildWindowsDemo.png

I am using Windows API functions contained in user32.dll.

  • FindWindowA searched for a window's title and get its handle.
  • GetWindowA can be used to find child windows (the window parts as shown above). Parameter value "5" returns the first child window, parameter value 2 the next one. There are more parameters available, see the linked reference.
  • In case you know the class(!) name of the child window you are looking for, you can use FindWindowExA to find its handle. Please not that using the class's name only is not very specific. The approach Andrés described (using a fully defined LPCSTR lpszClass) is the better one.

Be aware! Other than EnumChildWindows, this traversing approach is prone to errors in case a child window / child's parent window is destroyed while executing the traverse.

 

Regarding your application, you could use the traversal approach to find the class of the windows you are looking for once, and every time afterwards use FindWindowExA to pick it directly.


Ingo – LabVIEW 2013, 2014, 2015, 2016, 2017, 2018, NXG 2.0, 2.1, 3.0
CLADMSD
Message 5 of 9
(4,421 Views)

Thank you both very much for your efforts. I was following up Notanae's suggestions without much success. I'm not a windows programmer at all and having to keep looking up what I'm doing at each stage take ages.

ikaiser, your routines look like they will do what I'm trying to do. I'll put it into my program and let you know what happens.

Your description together with the routines make a good example of how to use the dll calls, the only examples I've found so far assume that you know quite a bit about windows; perhaps not unreasonable.

Thanks again

Peter 

 

0 Kudos
Message 6 of 9
(4,415 Views)

I've been taken away from the job for a day or so and have just got back to it.

I have succeeded in getting the functionality that I need, albeit by a bit of a kludge. The program that I am trying to interact with has up to 4 popup windows running, fortunately the one I need to interact with is always the top most.

I have attached (I hope) the routine I am using, it is not that robust and probably not the correct way to go about it, but it does work for me and may help someone else in the same situation. It needs the library  referred to by Notanae for one of the routines that finds top level windows using only part of the name. This was the routine I was originally intending to use when I found out that it did not find popups.

The part that finds the popups is adapted from ikaiser's routines.

Finding popups from 'normal' seems to be straightforward, but the PPSC program I am interfacing with seem to work differently, hence the switch and extra steps to find the top level popup.

As I said I'm not a windows programmer and have made It work almost by trial and error. The examples have been very helpful and I've learned a bit more about interfacing with user32.dll from them.

Thank you both again

Peter

Message 7 of 9
(4,394 Views)

Hi Peter,

 

I am happy we were able to help you move forward. 

Thank you for sharing this back with the forum for future reference, it's always nice to set the next person up for success as well. 

Have a lovely rest of your day.

 

Best,

 

Andrés

0 Kudos
Message 8 of 9
(4,389 Views)

Same here, thanks for reporting back and sharing your code!


Ingo – LabVIEW 2013, 2014, 2015, 2016, 2017, 2018, NXG 2.0, 2.1, 3.0
CLADMSD
0 Kudos
Message 9 of 9
(4,384 Views)