LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

how to make visibal and disable a control within a tab

Hi

In our application we sevarl display screen. we kept each display screen in one tabs. Each tab contains seval controls. Depends on the user input we need to eneable or disable the  controls(this controls we placed inside decoration).If any one knows how to do it kindly reply for the same.

 

Tab->Decoration->Control

 

Thank You..

0 Kudos
Message 1 of 11
(6,061 Views)

Hi shoukat, to enable/disable controls you may use SetInputMode: controls are dimmed (=greyed out) if you pass a status 0 (zero) or enabled if status = 1.

On the other hand, making controls visible / hiding them can be obtained by calling SetCtrlAttribute (panelHandle, controlID, ATTR_VISIBLE, status) with the obvious values of 1 for visible and 0 for hidden.

Putting controls inside decorations has no effect in this respect.

 

What can be confusing is how to obtain the correct panel handle, which is not the one of the panel where the tab is on, but that of the individual tab page controls are in. If you are using native CVI tab control this handle can be obtained by calling GetPanelHandlFromTabPage: online documentation is good and there have been several posts on the forums about this argument, so you should be able to use this function without problems.



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 11
(6,060 Views)

Sorry for bringing back a very old post.  But the forum search led me to this very similar topic.  Roberto, your solution doesn't appear to work.  Here is a very simple test.


Place a button on a tab page on a panel.  Here is the button's callback function:

 

int CVICALLBACK Button (int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
	switch (event)
	{
		case EVENT_COMMIT:
			// change the cursor
			SetWaitCursor(TRUE);
			
			// turn control back off
			SetInputMode(panel,control,FALSE);
			
			// turn off controls while waiting
			SetTabPageAttribute(mainPanel,MAIN_TAB,VAL_ALL_OBJECTS,ATTR_DIMMED,TRUE);
			ProcessSystemEvents();
			ProcessDrawEvents();
		
			// here's where a looping function would be
			Delay(5);
			
			// restore controls
			SetTabPageAttribute(mainPanel,MAIN_TAB,VAL_ALL_OBJECTS,ATTR_DIMMED,FALSE);
			
			// turn control back on
			SetInputMode(panel,control,TRUE);
			
			// change the cursor back
			SetWaitCursor(FALSE);
			break;
	}
	return 0;
}

 

Now as soon as that Delay starts, if I click on my dimmed button again, this callback function will break again after it returns from the first press!  Why and how is that possible?!

 

0 Kudos
Message 3 of 11
(5,667 Views)

Hello electrolund, what is happening in your example is that you are not processing events in Delay () function so that any click remaing queued until the system is able to process it (that is, after you have enabled the button again). This forces natural flow of events in the system, making it to apparently  react to a click on a dimmed button, a fact that is evidently not happening when normally you dim a button and let the system process all pending eventw while your long lasting function is executing.

 

A simple way to prevent this fact from happening is to move ProcessSystemEvents after Delay, so that the environment correctly handles all events. Additionally, if you dim the tabs you do not need to individually dim controls on the tabs. After all this, your function can be changed this way and it will work (I added the DebugPrintf calls to make it evident how many times the function is called):

 

int CVICALLBACK Test (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	switch (event) {
		case EVENT_COMMIT:
			// change the cursor
			SetWaitCursor (TRUE);
			DebugPrintf ("Start\n");
			
			// turn off controls while waiting
			SetTabPageAttribute (mainPanel,MAIN_TAB, VAL_ALL_OBJECTS, ATTR_DIMMED, TRUE);
			ProcessDrawEvents();
		
			// here's where a looping function would be
			PostDelayedCall (testCbk, (void *)panel, 5.0);
			Delay(5);
			ProcessSystemEvents();   // Added to handle events generated during Delay

                        // restore controls
			SetTabPageAttribute (mainPanel,MAIN_TAB, VAL_ALL_OBJECTS, ATTR_DIMMED, FALSE);
			
			DebugPrintf ("End loop\n");
			
			// change the cursor back
			SetWaitCursor (FALSE);
			break;
    }
	return 0;
}

 

In normal situation, in your long lasting function you could periodically issue ProcessSystemEvents () and this will get rid of all clicks the user can issue while the controls are dimmed.

 

BTW, this tricky situation is not limited to controls on a tab page: it happens the same for any button on any panel.



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 11
(5,654 Views)

Thanks, Roberto, moving that ProcessSystemEvents works!  It's not very intuitive to me yet, but it does work.

 

What was your PostDelayedCall for?  Was that just testing? 

0 Kudos
Message 5 of 11
(5,647 Views)

Forget about that call: I was experimenting on methods to permit the system to process events during the call to Delay.

 

It seems quite logical to me what's happening: you disable the control and call ProcessSystemEvents to make this fact visible. Next you call Delay and in this interval the user clicks on the dimmed control: the system is not able to process the event since it is blockek in Delay () and the event (really a Windows message) remains in the queue. Next you enable the button again and quit the callback. In this moment the system starts processing events and finds the click message: the button is enabled and the event is processed "regularly".



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 6 of 11
(5,640 Views)

Hi Roberto,

 

Not that it matters that much for this case, since I assume that Electrlund will be replacing the Delay call with his own loop but, since you were looking for it, there is a function in toolbox.c called DelayWithEventProcessing that would do what you were looking for. You can take a look at it. It's implemented as a fairly basic do-while loop around a call to ProcessSystemEvents.

 

Luis

Message 7 of 11
(5,590 Views)

Thanks Luis, now that you speak about it I remember I saw it in the Toolbox but you know: the Programmer Toolbox is so huge and rich of functions that sometimes I miss some of them even having used it sometimes! Smiley Wink



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 8 of 11
(5,585 Views)

You're welcome!

 

By the way, while your explanation of the problem was exactly correct, your suggested solution of adding a ProcessSystemEvents after the delay is not completely ironclad. It will probably work in most cases but, unfortunately, there's no guarantee that a single call to ProcessSystemEvents will flush all of the pending mouse clicks. Therefore, it really would be preferable to intersperse the ProcessSystemEvents calls within the loop, as much as possible.

 

Luis

0 Kudos
Message 9 of 11
(5,581 Views)

LuisG

Can ProcessSystemEvents() send back a score card of processed events over events in queue? a percentage return?

 

ChipB

0 Kudos
Message 10 of 11
(5,513 Views)