LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Problem: MessagePopup( ) in secondary thread

(1) First l call InstallPopup( ) to display a popup panel in front of Main Panel;
(2) After  popup panel display there is a function running in secondary thread and  this function calls MessagePopup() .But the  MessagePopup dialog box cannot keep front of popup panel or  Main Panel. If I click popup panel,this MessagePopup box is hiden back of Main Panel.
 
Capture:
 
0 Kudos
Message 1 of 8
(4,282 Views)
Your problem arise from the different threads the panels and messages are handled: to maintain the message popup panel on top of other panels thrown by the thread that owns the other panels you must emit the popup message in that same thread. One way to do it is to use PostDeferredCall if the panels are handled by the main thread or PostDeferredCallToThread if the panels are handled in another thread: these functions call a function in the main or another thread in which you can emit your message popup which will remain on top of the other panels in the program.


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 2 of 8
(4,277 Views)

Hi Whatcall,

The overall concept you are seeing is that pop-up panels are modal only with respect to panels of the same thread. Check out the Different Approaches to MultiThreaded User Interface Programming help topic in the LabWindows/CVI Help.

Check out the MultiPanel shipping example (
<CVI>\samples\utility\Threading\ThreadPool\MultiPanel) which uses the PostDeferredCalltoThread function. Also, here is post with some good discussion and code snippets on PostDefferedCalltoThread.

Hope this helps!

Best Regards,

Jonathan N.
National Instruments
0 Kudos
Message 3 of 8
(4,260 Views)
Thanks very much!
0 Kudos
Message 4 of 8
(4,246 Views)

I have the same problem that a call the MessagePopup from a secondary thread, which is then not always on top.

 

As this thread is from 2007, is there in the later Versions of CVI a new solution?

It would be really nice if SetSystemPopupsAttribute() has the option of "float always", similar like panels. Would be simple and good.

Instead of PostDefferedCalltoThread i think a go with a new Panel with "float always" active.

 

Is there some new feature from CVI or is it still the same?

 

Best regards,

Dorian

0 Kudos
Message 5 of 8
(3,740 Views)

I faced the same problem. The following code is the solution that I have just started to use. After adding the following code, I used “MessageBoxForThread” in the secondary thread and also in the main thread instead of “MessagePopup”. It seems to work.  Message popups are always on top.

 

void CVICALLBACK MessageForThread (void *callbackData);

void MessageBoxForThread(char *text1,char *text2);

 

#define StringSize 1000  

int stop_thread; char *global_text1;char *global_text2;

 

void CVICALLBACK MessageForThread (void *callbackData)

{

                MessagePopup(global_text1,global_text2); 

                stop_thread=1;

                return;

}

 

void MessageBoxForThread(char *text1,char *text2)

{

                int callbackData;

                global_text1=malloc( sizeof(char) * (StringSize) ); 

                global_text2=malloc( sizeof(char) * (StringSize) );

                sprintf(global_text1,"%s",text1); sprintf(global_text2,"%s",text2);

                stop_thread=0;PostDeferredCall (MessageForThread, &callbackData);

                do{ProcessSystemEvents();}while(stop_thread==0);

                return;

}

0 Kudos
Message 6 of 8
(1,739 Views)

Thanks for this practical implementation of the paradigm. I just want to warn you about some possible improvements:

 

  • You are facing a memory leak problem since you are never freeing the dinamic memory allocated for global_text1 and 2
  • Since you're not using callbackData parameter you can pass NULL to it, thus avoiding the need for an unused int variable
  • Using a tight loop like yours to wait for the callback to terminate will raise CPU usage to 100% until the popup is released and will prevent other tasks in your program to execute. Consider adding a Sleep (10) or even a Sleep (100) inside the loop to let time to other tasks and lower down CPU usage (you are waiting for user respone, right? There's no need to saturate your system!)

Finally, you may want to use PostDeferredCallToThreadAndWait function in the Programmer's Toolbox, which already accomplishes part of the task; you could call it this way:

PostDeferredCallToThreadAndWait (MessageForThread , NULL, CmtGetMainThreadID (), POST_CALL_WAIT_TIMEOUT_INFINITE);

 



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?
Message 7 of 8
(1,719 Views)

Thank you RoberttoBozzolo for this very useful feedback,

Your feedback will really improve the code.

0 Kudos
Message 8 of 8
(1,651 Views)