LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
dadreamer

Ability To Get .NET/ActiveX Window Handle By Its Automation Refnum

Status: Declined

Any idea that has received less than 3 kudos within 3 years after posting will be automatically declined.

It's not secret that .NET or ActiveX object on front panel appears to be child window of NI container clipping window, which itself is a child of front panel window. When there's only one object in the container on FP, it is easy to get its window handle (HWND) by calling GetTopWindow or simply by iterating through all child windows of FP. This handle has to-one correspondence with automation refnum on block diagram. But when there are several .NET/ActiveX objects on the panel, it's impossible to identify their handles with refnums on BD.

 

The way of handle obtainment could be implemented by any of the following methods:

 

1.

Autorefnum To HWND.vi

 

2.

 Window Handle Property

(or let it be private property, being activated with special *.ini key)

 

3.

MgErr AutoRefNumToHWND(refNum, hwndp); - this variant is analogue of LabVIEW Manager function FRefNumToFD, where refNum is automation refnum of .NET/ActiveX object (type LVRefNum) and hwndp is pointer to child window handle (type HWND *).

 

Probably many people may consider this idea unimportant, but when it comes to drawing different shapes, displaying text, copying window content etc., my suggestion may be very relevant.

3 Comments
dadreamer
Active Participant

I have found a partial solution to this problem. The trick is in getting pointer to IUnknown interface from autorefnum and passing that pointer to IUnknown_GetWindow function from shlwapi.dll. On success this function returns window handle (HWND) of ActiveX object itself (not NI container clipping window). The code is simple and looks like this:

 

IUnknown_GetWindow.png

 

Brief description of what is going on:

1. By calling Max function from LabVIEW we obtain a handle (i.e. pointer to pointer) to IUnknown interface from our ActiveX refnum. First parameter in CLFN is configured as IUnknown* Pointer.

2. With MoveBlock function from LabVIEW we dereference the handle and get IUnknown pointer. Please note that on 64-bit LabVIEW size of pointer is 8 bytes, not 4.

3. IUnknown_GetWindow function from shlwapi.dll tries to get HWND by executing GetWindow method of different objects which our ActiveX object related to. If successful it returns the window handle in the second parameter. If not, it gives an error code whose description can be found here.

 

Sadly, this technique works only for standard ActiveX objects (e.g. for Microsoft ones) that have their GetWindow methods implemented. So, it likely won't work for most of 3rd party ActiveX objects. Definitely it's not working for .NET objects as they don't have IUnknown or IDispatch interfaces and LabVIEW doesn't allow to pass a pointer to any other .NET interface in CLFN settings.

 

Maybe, there exists another simple (and complete) solution to this issue but currently it's still not discovered.

Darren
Proven Zealot
Status changed to: Declined

Any idea that has received less than 3 kudos within 3 years after posting will be automatically declined.

dadreamer
Active Participant

Well, finally after 5 years I have found a way to *implement* it myself 😁 Even though it uses internal hackery, it's much more reliable than the method proposed above. Moreover it works for both ActiveX and .NET objects in both 32- and 64-bit LV versions from 2009 to 2020. I cannot attach archives here, so this is the link to my post on LAVA - https://lavag.org/topic/7750-hwnd-for-cw3dplot-in-labview/?do=findComment&comment=133841 Feel free to play with it as you like. 😉