LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Hide controls while drawing?

Solved!
Go to solution

I'm generating some controls on a tab programatically with the NewCtrl function call (up to 180 controls) when a separate control is pressed by a user.  Currently they are displayed individually as they are generated (takes about 1 second) .  I'd prefer for all the controls to be drawn in an initially hidden state and then displayed all at once after they have been created. I've tried placing a canvas in front of the contros while they are being created, but since the controls are created after the canvas, the z-plane index puts the canvas to the back.  I'm wondering if there is a better way to accomplish this like pausing draw events or something similar?  

 

Thanks!

0 Kudos
Message 1 of 15
(4,767 Views)

Normally controls are not drawn to screen until the system processes graphic or system events, which can happen either explicitly or implicitly in some cases (for example when a callback finishes executing). If you see the controls appearing on the screen one by one while they are created, you should check which is the condition for your program to process events: if you can eliminate this condition then you should not have this effect anymore.

If you can't eliminate it, you could try hiding every control immediately after it is created [using SetCtrlAttribute (..., ..., ATTR_VISIBLE, 0) ], placing a loop for displaying them all after creation process has finished. Using SetAttributeForCtrls () or SetAttributeForList () functions can help in this last task.



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 15
(4,756 Views)

Roberto Bozzolo wrote:

If you see the controls appearing on the screen one by one while they are created, you should check which is the condition for your program to process events: if you can eliminate this condition then you should not have this effect anymore.


Not really sure how to go about doing this.  The control are all created in a loop.  I assume the events are processed each time through the loop? 

 

 


@Roberto Bozzolo wrote:
If you can't eliminate it, you could try hiding every control immediately after it is created [using SetCtrlAttribute (..., ..., ATTR_VISIBLE, 0) ], placing a loop for displaying them all after creation process has finished. Using SetAttributeForCtrls () or SetAttributeForList () functions can help in this last task.

The List functions look quite powerful, and may help solve my problem quite well.  Unfortunatly, I'm having problems getting them to work. It seems to be a very simple concept, but everytime I call the SetAttributeForList function, I get a General Protection Fault.  Here's what I'm doing:

 

void setupControls(unsigned short num)

 

    int i;
    ListType controlList;
    controlList = ListCreate(6*num*sizeof(int));

 

    for (i = 0; i < num; i++)
    {

         controlId_struct[i].labelID   = NewCtrl(tabPageHandle, CTRL_TEXT_MSG, "", top, left);
         SetCtrlAttribute(tabPageHandle, rlyCtrl_lut[i].labelID , ATTR_VISIBLE, HIDDEN);

         ListInsertItem(controlList, &rlyCtrl_lut[i].labelID , END_OF_LIST);

 

         controlId_struct[i].swtchID = NewCtrl(tabPageHandle, CTRL_VSWITCH , "", top, left);
         SetCtrlAttribute(tabPageHandle, rlyCtrl_lut[i].swtchID , ATTR_VISIBLE, HIDDEN);

         ListInsertItem(controlList, &rlyCtrl_lut[i].swtchID , END_OF_LIST);

 

         controlId_struct[i].led1ID   = NewCtrl(tabPageHandle, CTRL_SQUARE_LED_LS, "", top, left);        

         SetCtrlAttribute(tabPageHandle, rlyCtrl_lut[i].led1ID   , ATTR_VISIBLE, HIDDEN);

         ListInsertItem(controlList, &rlyCtrl_lut[i].led1ID   , END_OF_LIST);

 

         controlId_struct[i].led2ID   = NewCtrl(tabPageHandle, CTRL_SQUARE_LED_LS, "", top, left); 

         SetCtrlAttribute(tabPageHandle, rlyCtrl_lut[i].led2ID   , ATTR_VISIBLE, HIDDEN);

         ListInsertItem(controlList, &rlyCtrl_lut[i].led2ID   , END_OF_LIST);

 

         controlId_struct[i].led3ID   = NewCtrl(tabPageHandle, CTRL_SQUARE_LED_LS, "", top, left);

         SetCtrlAttribute(tabPageHandle, rlyCtrl_lut[i].led3ID   , ATTR_VISIBLE, HIDDEN);

         ListInsertItem(controlList, &rlyCtrl_lut[i].led3ID   , END_OF_LIST);

 

         controlId_struct[i].spltrID   = NewCtrl(tabPageHandle, CTRL_VERTICAL_SPLITTER , "", top, left);

         SetCtrlAttribute(tabPageHandle, rlyCtrl_lut[i].spltrID   , ATTR_VISIBLE, HIDDEN);

         ListInsertItem(controlList, &rlyCtrl_lut[i].spltrID   , END_OF_LIST);

    }

 

    SetAttributeForList (tabPageHandle, controlList, ATTR_VISIBLE, VISIBLE);

 

    return;

 }

 

 Thanks for the help.  The List functions look like they may come in handy for many different applications.

0 Kudos
Message 3 of 15
(4,739 Views)

Q1. Events are not automatically processed while inside a loop; you should have a ProcessSystemEvents () or at least a ProcessDrawEvents () inside it to have the events processed. If the loop you are using is the one you showed us I'd expect the controls be visoble only after the loop terminates. Unless you have some other functions that are processing events like timer callbacks or threaded functions: if this is the case you could try testing the application while all these functions are disabled.

 

Q2. Not sure wether it is a typo or not, but you are storing control IDs in controlId_struct[i].xxID struct elements, and you are inserting in the list values of rlyCtrl_lut[i].xxID struct

 

 

PS Don't forget to dispose of the list after when you have finished using it to avoid memory leaks.



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 4 of 15
(4,728 Views)

I see a couple of problems with this code snippet, although I'm not sure if they would explain the GPF you're seeing in SetAttributeForList:

 

1. The argument that you pass to ListCreate should be the size of each element in the list, not the overall size of the list. So you should be passing it sizeof(int), not 6*num*sizeof(int).

 

2. You're storing the control IDs in the controlId_struct variable, but you're using the rlyCtrl_lut variable to set the visible/hidden attribute. What values are in rlyCtrl_lut?

 

If these have no impact on your problem, I would recommend that you debug SetAttributeForList to see if you find out more about what's causing it. It's a pretty simple function, so hopefully it will be obvious. SetAttributeForList is implemented in the Programmer's Toolbox, which is open-source. So you could temporarily add <cvidir>\toolslib\toolbox\toolbox.c to your project, recompile, and then step into that function when you're debugging.

 

Luis

0 Kudos
Message 5 of 15
(4,726 Views)

There is a timer function ticking off at 1Hz.  I didn't think that would be nearly fast enough to cause issues.

 

That was a typo above.   I was trying to replace some of the specific terms with more generic names for simplicity.  Looks like I made it more complicated instead.  I'm still puzzled why I'm getting the faults though.  Doesn't seem like it should be an issue...

Message Edited by byrd01 on 04-15-2010 11:02 AM
0 Kudos
Message 6 of 15
(4,724 Views)
I modified a sample application I wrote some times ago (in response to this thread if you're interested to) in order to use SetAttributeForList to set the ATTR_VISIBLE attribute; I received no GPF error: please test it on your machine and see if it works correctly.
Message Edited by Roberto Bozzolo on 04-15-2010 06:19 PM


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 7 of 15
(4,715 Views)

I didn't see LuisG's response before.  My use of ListCreate was the source of the General Protection Faults. So that problem is solved.

 

Now that I'm using the List functions, I'm seeing that the creation of the NewCtrl(tabPageHandle, CTRL_TEXT_MSG, "", top, left) seems to be the culprit.  If I remove the 3 lines accossiated with the text message, then the panel is generated and displayed as I would expect.  However with these lines included, I can see the each new text message created and then hidden one at a time in quick succession. Does the creation of a text messege generate a draw event?

 

I see the same behavior even if I disable the timer that was mentioned above.

Message Edited by byrd01 on 04-15-2010 11:44 AM
0 Kudos
Message 8 of 15
(4,700 Views)

Creating a text message does not automatically show it and the other controls, as you can see in the attached project which I modified adding repetitive creation of textmessage controls.

There must be something in your code that produces this effect.



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 9 of 15
(4,672 Views)
Thanks Roberto.  I've taken a look at the project that you attached.  It looks very similar to what I'm now doing in my code.  I'll keep doing some trial and error with my code to see if I can figure out what's causing the issue.  It's at least good to know that I'm heading in the right direction.  I'll post back if I do track down the problem.
0 Kudos
Message 10 of 15
(4,666 Views)