LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

How to programaticaly send a string to an Edit Box of another application

Solved!
Go to solution

Hello,

 

I have a question about how can one application send a string,  representing a barcode, to the Edit Box (or Text Box) of a second application (no info about this application ctrl's is available), that  is processing all the barcodes. Also, first application must "press" an 'OK' button on the second application dialog box. 

 

First application, that will be written in CVI, starts by enumerating top level windows, using Windows API function - EnumWindows. Enumeration will stop when the desired window caption is found. A handle for that window will also be available. I don't know how to find a handle to the Edit Box Control. There are no Child Windows of that top level window. 

Any suggestion about how to implement this is realy appreciated.

 

Regards

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

miniMe wrote:

"There are no Child Windows of that top level window."

 

are you sure of that ? have you verified with Spy++ or a similar tool ? if this is the case, it means that this window does not use windows common controls.

 

if it were, i would have suggested sending a WM_SETTEXT message to that control, or using the SetWindowText() function in the Windows SDK.

 

but if it is not... it has been built using a gui framework which draws its own child window (like CVI does for example). can you find any information about the framework or compiler used to build this executable ? it may reveal some very useful informations to solve your problem.

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

Hello, I check with spy++, and it also shows there are no child windows of the top one. See attachment.

The "second application" that I use for my tests is Teststand, top window I'm looking for is "UUT Information". On this window there is a Text Box labeled "Enter UUT Serial Number", in this control I want to insert the string from the first application.  

However, if I want to implement my application on a window that is not using windows common controls, what information about the framework should I look for ? Let's say I'd like to use it on a VB.NET application.

 

What if the window is implemented with windows common controls, will EnumChildWindows enumerate al the controls on the top level window ? Probably FindWindowEx can also be used ?!

 

Regards

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

I forgot to mention that "UUT Information" top window class, as reported by Spy++, is "CVIRTLVDChild285212672".

 

Regards

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

from the class name of your application, it seems obvious the application you want to remotely control was built using CVI. i am not aware of any way to control such a window remotely, nor do i know any way of enumerating child windows. this is so because CVI redefines everything and draws its own controls instead of using the native functions from the window manager. it would be nice if someone at NI could answer this thread.

 

(off topic: that's where a gui framework like the one coming with CVI shows its limitations. could the same person at NI answer those other questions: how does a CVI application behave under text-to-speech ? how does the accessibility features of windows interact with a CVI application ?)

0 Kudos
Message 5 of 9
(4,545 Views)

@dummy_decoy: not sure if this answers your question about accessibility, but I tested that a CVI application responds correctly when using the On screen keyboard (OSK) utility, both on parent and child panels.

 



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 6 of 9
(4,529 Views)

on-screen keyboard is quite a different beast, since it injects standard keyboard events at a very low level (MouseKeys, a quite unknown feature of windows will work as well (Alt+Shift+NunLock)).

 

but i would like to see the result with the screen reader or a high-contrast profile for vision impaired people (in fact, i don't have a CVI based application at hand to test, and i don't have a sound card at work)

0 Kudos
Message 7 of 9
(4,513 Views)
Solution
Accepted by miniMe

Hello All - 

 

@miniMe - I couldn't help but notice from the information that the window you are looking to interact with is part of the standard TestStand installation (modelsupport2), for which the source code is readily available.  While modifying modelsupport2 is not for the faint of heart, your task is specific enough that I was able accomplish it with only a handful of lines of code (be sure to copy the modelsupport2 files to the public location before making changes).  The important components are below:

 

The application that is going to be sending the UUT number can send the WM_COPYDATA message to the TestStand application.  Using this message is pretty straightforward, and allows you to pass data (such as a UUT string) across process boundaries.  Here is the relevant piece from my small test app that sent the message: 

 

 

 

#include <windows.h>
#define UPDATE_TEXT_MSG (WM_APP + 1)
...

COPYDATASTRUCT dataToPass;
char msg[80];

strncpy (msg, "test message", sizeof (msg)); 
dataToPass.dwData = UPDATE_TEXT_MSG;
dataToPass.cbData = sizeof (msg);
dataToPass.lpData = msg;
// gHostHwnd was obtained from EnumWindows
 SendMessage (gHostHwnd, WM_COPYDATA, 0, (LPARAM)&dataToPass);

 

The receiving end of this is also pretty straight forward.  In the modelsupport2 project in CVI, you just need to make a couple modifications to the uutdlg.c module.  Specifically, you need to use InstallWinMsgCallback in the function DisplayUUTInformationDialog to receive the WM_COPYDATA message.  It should look pretty similar to this:

 

 

// existing code in uutdlg.c
errChk( panel = LoadPanelEx (0, UIR_FILE_NAME, UUTPANEL, __CVIUserHInst));
RecessFrame (panel, UUTPANEL_SERIALNUMBER);
AlignRingButtonWithString (panel, UUTPANEL_PREVUUTLIST, UUTPANEL_SERIALNUMBER);

// Nick Beer - added for customer functionality...
errChk (InstallWinMsgCallback (panel, WM_COPYDATA, SetUUTNumberCB,
    VAL_MODE_INTERCEPT, &panel, &postingHwnd));

 

Finally, again in uutdlg.c, you need to define the implementation for the WinMsgCallback. My implementation looked like this:

 

 

#define UPDATE_TEXT_MSG (WM_APP + 1)

...

int CVICALLBACK SetUUTNumberCB (int panelHandle, int message,
unsigned int* wParam, unsigned int* lParam, void* callbackData)
{
    PCOPYDATASTRUCT pUUTInfo;
    int panel;

    if (message == WM_COPYDATA)
    {
        pUUTInfo = (PCOPYDATASTRUCT)(*lParam);
        panel = *(int *)callbackData;
        if (pUUTInfo->dwData == UPDATE_TEXT_MSG)
            SetCtrlVal (panel, UUTPANEL_SERIALNUMBER, (char *)pUUTInfo->lpData);
    }
    return 0;
}

 

Also - don't forget to call RemoveWinMsgCallback.  Once you've made these changes, you just need to rebuild modelsupport2.dll, and the messaging should work as expected.

 

Feel free to let me know if you have any questions about this.  I left out some of the TestStand specifics assuming you may know about the public directories etc.  Let me know if you're unsure about any of this.

 

@dummy_decoy - I don't have a complete answer to your question, but want to point out that one thing that must be remembered about CVI is that it was and is intended to be multi-platform.  This is the primary reason our controls and panels don't always play nice with the Win32 api.  We've done what we can to make sure there are workarounds for users who need this functionality - as I hope my solution demonstrates - and are always open to suggestions on how we can improve interoperability with the Win32 platform.  

 

I personally don't have any experience with the other specific aspects of your question, and so am not comfortable making any statements about them at the moment.

 

NickB

National Instruments  

Message 8 of 9
(4,506 Views)
@nickb: there exists a multitude of GUI frameworks which are multi-platform but still are using native controls. the first step to improve interoperability would be to make all controls or panels real child windows (that is one which is known by Windows with a HWND and a defined parent). on windows, there are multiple ways of achieving this while still retaining the look and feel of CVI. i can't tell for other platform but i am pretty sure you can do the same. also note that the true meaning of a framework is to abstract a concept and hide the implementation details, thus you can have a very different code on 2 different platforms without the user noticing.
0 Kudos
Message 9 of 9
(4,477 Views)