LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

MessagePopup dissappears behind active panel

Hello,

I am working on a project in LabWindows/CVI 6.0 and I am using ActiveX controls for a SCARA robot. Before calling RunUserInterface I run an initialization function that creates an ActiveX control, opens a port to the robot software, builds a project in the robot software, and sets up an events received callback from the robot software. This event callback is fired by the robot software when certain events occur, such as motors turning on/off, estops activating, and robot errors occurring.

The problem I am experiencing is when I receive an event with the event received callback I display a MessagePopup with text reflecting the error that occurred. With the MessagePopup displayed, clicking on a panel outside the popup region causes the popup to disappear. Using alt-tab I can then switch to the popup and acknowledge it but this is not acceptable for my application.

I always thought a MessagePopup would remain on top all other panels until a user acknowledges it. This problem only occurs when the MessagePopup is created from the event received callback. How do I prevent this popup from dissappearing when I user clicks on a panel behind it? I could create a dedicated message panel and when an event is received dim all currently displayed panels before displaying the message panel, but I thought this was the purpose in having message popups.

My panel structure consists of a parent background_panel with two child panels displayed at the same time, one named navigation_panel and the other database_panel. Both of these child panels have their ATTR_ACTIVATE_WHEN_CLICKED_ON set to 0 immediately after being loaded.

Thanks for the assitance.
- Aaron
0 Kudos
Message 1 of 10
(6,889 Views)
If you use the Windows SDK MessageBox function, you have control over making the box task modal, application modal, or system modal. Look at the following example.
0 Kudos
Message 2 of 10
(6,871 Views)
Sorry, here's the example.
You need to add user32.lib to your project.
Application modal: window is on top of the parent window in the calling thread.
Task modal: window is on top of top-level windows in this application (in any thread).
System modal: window is on top of all applications.
0 Kudos
Message 3 of 10
(6,870 Views)
Thank you for the response and information Al S. I have experimented with the three MessageBox types. Application modal & Task modal message boxes are moved behind my CVI application panels when a keypress occurs outside of the message box's boundary.

With the System modal message box a keypress outside the boundary of the message box does not cause my CVI application to be brought in front of the message box. However, a keypress on the CVI application still operates command buttons, etc with the message box in front of the CVI app. So, I can dim all panels before generating the message box to force the user to acknowledge the message box and not allow the user to operate buttons on the CVI app. Then undim all panels after the message box is acknowledged.

The above approach works, I am still curious if there is a better way.

Thanks!
0 Kudos
Message 4 of 10
(6,862 Views)
Here's a long shot -- If you go to your UI Editor and go the panel's properties, then hit the "Other Attributes" button, and go to the bottom, is the floating style set to "Never"? That may have an effect on the main panel always overlapping the message box. Otherwise, can you post a small sample application?
Jeremy L.
National Instruments
0 Kudos
Message 5 of 10
(6,850 Views)
Aaron,

I have only skim read your note but I think the problem you are seeing is because message popups are only modal (i.e. on top) with respect to other panels in the same thread. If you call raise a popup in a secondary thread it will not stay on top of panels generated in the main thread. The way round this is to post a deferred procedure call to the main thread, pass an appropriate struct with the message and title you want and generate the popup from the main thread. In that way it will stay modal to your other GUI panels.

Let me know if that is not the problem you are experiencing.

Jamie
0 Kudos
Message 6 of 10
(6,838 Views)
Thanks for the post Jeremy L. When I originally identified the disappearing popup problem I tried changing the floating style. None of the floating styles fixed the problem.

It seems that the problem stems from the fact that a callback occurs as an event handler from my robot software. It is not a callback occurring from a uir control. As a result the MessagePopup that is executed from the callback does not act like it is associated with a panel, at least not the active panel at the time the callback occurs. Therefore the clicking any panels appearing in the background of the popup cause the popup to be sent behind the clicked panel.

I am not sure how I may post a small sample application because I do not think you will have the ActiveX library for the robot software on your system. Even if you had the library, you would need a the robot hardware attached in order to generate an event for the event handler callback to catch. Any suggestions?

Thank you,
-Aaron T
0 Kudos
Message 7 of 10
(6,817 Views)
I agree with Aaron. If you have the Popup called in a secondary thread to your uir, then the solution might be to PostDeferredCalltoThread. All you need then is the thread ID of the main uir thread.
Jeremy L.
National Instruments
0 Kudos
Message 8 of 10
(6,812 Views)
It might be that the callback is happening in a different thread because the ActiveX client by default is set to use multi-threaded apartments (MTA) . So the callback will happen in a non-UI RPC thread.

Try adding this function to the very beginning of your app, before you make any activex calls.

CA_InitActiveXThreadStyleForCurrentThread (0, COINIT_APARTMENTTHREADED);

Here is the snippet of the help

You must call this function with COINIT_APARTMENTTHREADED if you register any ActiveX event callbacks and want the callbacks to be called from the thread in which you register the callbacks. If you do not call this function with COINIT_APARTMENTTHREADED, your callbacks are called from a system thread.

Hope this helps
Bilal Durrani
NI
Message 9 of 10
(6,796 Views)
Thanks everybody for the assitance on this issue. Bilal, your suggestion solved the problem. I added the CA_InitActiveXThreadStyleForCurrentThread function as the first statement in my program initialization routine. Now a MessagePopup generated by an ActiveX event handler acts like the typical MessagePopup, it does not dissappear when another panel is clicked on with the popup present.

Thanks!
0 Kudos
Message 10 of 10
(6,761 Views)