LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

LabWindows CVI InstallPopup question

Hi all,

I need some user feedback from a popup panel. Unfortunately I cannot use one
of the predefined popup panels, therefore I have tried to create my own.

The problem is this:
After the function calls LoadPanel() and InstallPopup() in my main program,
the next line in my main program is immediately executed (without waiting
for the popup panel to finish or disappear). So I try to halt the main
function by using a while loop:

userhasanswered = NO;
LoadPanel();
InstallPopup();
while (userhasanswered == NO);
RemovePopup(0);

In the popup panel CVICALLBACK I have this:

case EVENT_COMMIT:
userhasanswered=YES;
break;

This does not work, because the popup panel does appear indeed, but does not
respond anymore to any user actions (pro
bably as the while loop consumes
100% of all resources). Neither does the main panel, as the active panel is
the popup window.

Is there a simple solution, or should I have a look at the use of
multithreading?

Kind regards,
Geert
0 Kudos
Message 1 of 6
(4,010 Views)
Geert,

I believe multithreading will be your answer. I am currently doing a similar thing as you.

I run the user interface as a seperate thread. I spawn the thread from main () and cause the main () thread to wait until the user interface is completed before main() continues on.

I use the following calls:

void main(void)
{
....

/******* UI *******/
//start user interface thread (ui.c)
iStatus = CmtScheduleThreadPoolFunctionAdv
(DEFAULT_THREAD_POOL_HANDLE,
UI, (void *)NULL,
THREAD_PRIORITY_NORMAL,
NULL,
EVENT_TP_THREAD_FUNCTION_END,
NULL,
CmtGetCurrentThreadID(),
&uithreadid);

//make main() thread wait for User Interface to
//finish
//main () will stop executi
ng until UI finishes
CmtWaitForThreadPoolFunctionCompletion
(DEFAULT_THREAD_POOL_HANDLE,
uithreadid, //thread id you created in
//CmtScheduleThreadPoolFunctionAdv
OPT_TP_PROCESS_EVENTS_WHILE_WAITING);

...

}

Hope this helps,
Kay
0 Kudos
Message 2 of 6
(4,010 Views)
As we can see, both approaches should work here. The multithreading is "slick" way to solve the problem, allowing you to execute several different functions without interrupting the main function. However, there is a very simple solution which is just to tack in a ProcessSystemEvents().
0 Kudos
Message 6 of 6
(4,010 Views)
One posible solution is to use:
GetUserEvent (1, &pnl, &ctrl);

The GetuserEvent can wait for a user input if you set the first parameter to '1', that way halting you program flow. Other threads or a timer will continue to be executed.
To use it you will need to do the folowing:
LoadPanel ()
InstallPopup ()
GetUserEvent ()
DiscardPanel ()
Process user input (if any) and continue your program.

The only disadvantage to this function is that it returns on ANY commit event generate by the user; this means that:
1. either you can set all controls on the popup panel as 'normal' instead of 'hot' (leave at least one hot control for the user to close the panel)
2. or you must enclose your GetUserEvent in a loop and process the ctrl parameter in order
to discriminate if to proceed or not.
An example of the second option (processing a simple panel with a password control, an 'OK' button and an 'abort' button):
InstallPopup ()
while (TRUE) {
GetUserEvent (1, &pnl, &ctrl);
if (ctrl == pwd_quit) goto Error; // User pressed the 'abort' button
errChk (PasswordCtrl_GetAttribute (pnl, pwd_pw, ATTR_PASSWORD_VAL, pw));
if (strcmp (pw, cg.pw))
MessagePopup ("Password", "Wrong password.");
else
break; // Correct password: exit while loop
}

This solution prevents you to work on multithreading due this problem only, it's simple and it works quite well.

Hope this helps
Roberto


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 3 of 6
(4,010 Views)
It has just occurred to me that the simplest solution at all it to use your while-loop, simply adding a ProcessSystemEvents () inside the loop.

The reason for which the simple loop doesn't works is that while the program is executing the loop, it does nothing else, neither receiving events generated in the UI when you press buttons and so on. Adding the ProcessSystemEvents () gives the program the possibility to process UI events (and such execute the button callback and that way raise the userhasanswered flag.

Roberto


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 4 of 6
(4,010 Views)
> It has just occurred to me that the simplest solution at all it to use
> your while-loop, simply adding a ProcessSystemEvents () inside the
> loop.
>
Indeed simple and very efficient ...
Thanks a lot!

Geert
0 Kudos
Message 5 of 6
(4,010 Views)