10-11-2013 09:11 AM
I'm writing a LabVIEW application which on occasion must call a second LabVIEW application. Now when the host application decides it needs to call the client, it must block, waiting for it to finish. LabVIEW doesn't make this easy out of the box since when calling a LabVIEW application control is returned to the caller before the application is finished. However I'm platform locked to Windows, so this is easily mitigated through a few kernel calls to the Windows event functions (CreateEvent, WaitForSingleObject, CloseHandle in the host and OpenEvent, SetEvent, CloseHandle in the client).
My problem is the client application also presents a user interface which I'd like to make modal while it is being called. Is there a creative way of doing this from LabVIEW or through the Windows API?
10-11-2013 10:13 AM - edited 10-11-2013 10:13 AM
Interesting,
"Modal" means "On top of and blocking any user access to any other pane in the same application instance." Each LabVIEW built exe will open in its own application instance so MyLVApp1 panes will not be blocked by a modal pane in MyLVApp2.
Pass a VI Server ref to MyLVApp1 to the Modal dialog in MyLVApp2 and use set / unset busy. Caution: I have not ever done this but, according to proficy it "Should" do the trick.
There is also some risk that if "Bad Things" happen the unset busy will not be called. Try not to let that happen it would make you sad.
10-11-2013 10:44 AM
Right, the distinct application instances prevent the client from being modal over the host application.
I'm trying to avoid VI Server calls across application boundaries becuase I don't want to invoke any TCP/IP permissions (even if it is just localhost). But I don't imagine there would be any trouble with the host disabling itself before invoking the client, then re-enabling when the client returns.
A quick test later...
No dice. While the Set Busy call does indeed prevent any interaction on the panel, it doesn't prevent the actual Window from receiving focus and thus hiding the client application window. Nice try though, it would have been a simple and elegant solution and I hadn't thought to try it until you suggested.
10-11-2013 11:05 AM
You could set the "Host's" fp.mode=Hidden/Normal and avoid user interaction with the hosts pane that way too.
10-11-2013 03:16 PM
That works too. Of course that can be tedious since the host application can have an unbounded number of windows open (usually only 3 or 4, but technically not limited).
The client exe's UI was a progress box since it can be pretty slow. It may be best to just crack open the source code of the client and supress the UI, instead feeding status updates through a named pipe which the host can pick up. That way host can have it's own UI and easily make it modal.
Thanks for sounding ideas off Jeff!
kegg/mje
10-12-2013 11:59 AM
@kegghead wrote:
It may be best to just crack open the source code of the client and supress the UI, instead feeding status updates through a named pipe which the host can pick up.
I would agree with that, but in cases where you don't have access to the source or you don't want to touch the client, you could also try using the Windows reparenting functions to make the client window a child window of the host's window. You then might also be able to set it as modal through the Windows API function. The reparenting functions are simple enough, but there should also be some examples lying around if you search for "MDI".
Note that this method isn't necessarily super stable or elegant (for instance, since you don't use CreateWindow, you need to get the handle using the name, which may not be unique, or because LV does its own updates inside the window, you might get some weird artifacts), but in general I expect it should work.