LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

SetActivePanel bug in tab

Hello all,
if I call SetActivePanel on a panel that is a tab (obtained from the
GetPanelHandleFromTabPage function), afterwards clicking on the various
other tabs doesn't change the content of the tab itself (the one made active
stays).
Unless you clic on the tab corresponding to the activated panel, at which
point things start to work again.

Is it a bug and if so is there a workaround ? Maybe finding the tab number
and making it active, but that's not so easy.

Or is it a feature and in this case what is the rationale behind it ?
--
Guillaume Dargaud
http://www.gdargaud.net/
0 Kudos
Message 1 of 7
(3,083 Views)
> Maybe finding the tab number and making it active, but that's not so easy.

Knowing a panel handle, is it possible to know if the panel is in a tab
without exploring the whole list of controls ?
--
Guillaume Dargaud
http://www.gdargaud.net/
0 Kudos
Message 2 of 7
(3,076 Views)

Not sure about being a tab panel, but at least you can see whether it is a child panel or not: a tab page is a child of the panel that holds the tab control.



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 3 of 7
(3,071 Views)

When you get the panel handle of a tab page, there are restrictions to what you can do with it. For example, you can't call DiscardPanel on it, because that would cause the tab control to which it belongs to be in a bad state. Likewise, you are not supposed to call SetActivePanel on a panel that is a tab page because the tab control tracks which tab page is the active one. You are supposed to set the active tab page with SetActiveTabPage or SetCtrlAttribute(ATTR_CTRL_INDEX) so that the tab control's state is correct.

 

The only way to know if a particular panel is part of a tab control is to itereate through all the controls of the panel looking for a tab control. Then for each tab control, iterate through all the tab pages and check if it is a tab panel. Of course, you only have to do this if the panel is a child panel (if it is not a child panel, then it can't be a tab panel).

 

Hope this helps.

0 Kudos
Message 4 of 7
(3,061 Views)

 

This might be a good suggestion.

 

http://forums.ni.com/t5/LabWindows-CVI-Idea-Exchange/idb-p/cviideas

 

 

 

0 Kudos
Message 5 of 7
(3,050 Views)

Back in EasyTab days, a callback was chained to the panels added to the EasyTab control with a special identifier that you could retrieve with:

 

void   *cbkd = NULL;

GetChainedPanelCallbackData (tabPanelHandle, "Sheet Panel", &cbkd);

 

Since the tab control has been moved to Userint library this particular mechanism is no more available but there could be some other similar hidden/undocumented method to discriminate whether the panel is a tab page or not.

You could eventually install some meaningful callbackData to the panel once loaded and use it for this purpose.

As a last resource, you may consider returning back to EasyTab, which is still available in CVI (but I don't know whether it can be used in CVI for Linux or not).



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 7
(3,048 Views)
Hi Luis,

> When you get the panel handle of a tab page, there are restrictions to
> what you can do with it. For example, you can't call DiscardPanel on it,
> because that would cause the tab control to which it belongs to be in a
> bad state. Likewise, you are not supposed to call SetActivePanel on a
> panel that is a tab page because the tab control tracks which tab page is
> the active one. You are supposed to set the active tab page with
> SetActiveTabPage or SetCtrlAttribute(ATTR_CTRL_INDEX) so that the tab
> control's state is correct.

OK, I'll add a suggestion: http://forums.ni.com/t5/LabWindows-CVI-Idea-
Exchange/Tighter-association-between-tab-and-their-member-panels/idi-
p/1913071

> The only way to know if a particular panel is part of a tab control is to
> itereate through all the controls of the panel looking for a tab control.
> Then for each tab control, iterate through all the tab pages and check if
> it is a tab panel. Of course, you only have to do this if the panel is a
> child panel (if it is not a child panel, then it can't be a tab panel).
>   Hope this helps.

OK, according to your suggestion I wrote the following function which seems
to get things right:

///////////////////////////////////////////////////////////////////////////////
/// HIFN Set a panel (and its parent) active, or, if it is part of a
tab, activates the tab
/// HIFN This function is an almost drop-in replacement for
SetActivePanel()
/// HIPAR Panel/The panel which you want make active
/// HIPAR Ctrl/If !=0, also activate that control, if possible
/// HIRET 0 if no associated tab was found
///////////////////////////////////////////////////////////////////////////////
int SetActivePanelOrTab(int Panel, int Ctrl) {
int Nb, i, Parent=0, TabPanel, Style;
if (Panel==0) return 0;

if (Ctrl!=0) {
i=SetBreakOnLibraryErrors(0);
SetActiveCtrl(Panel, Ctrl); // Because
the control may be inoperable
SetBreakOnLibraryErrors(i);
}

GetPanelAttribute (Panel, ATTR_PANEL_PARENT, &Parent);
if (Parent!=0) { // Find
all tabs and see if that panel belong to them or if it's only a child panel
SetActivePanel(Parent); // In any case, make
the parent active (we could go on and on...)
GetPanelAttribute (Parent, ATTR_PANEL_FIRST_CTRL,
&Ctrl);
while (Ctrl!=0) { // Find
all controls belonging to the parent
GetCtrlAttribute (Parent, Ctrl,
ATTR_CTRL_STYLE, &Style);
if (Style==CTRL_TABS) {
GetNumTabPages (Parent,
Ctrl, &Nb);
for (i=0; i<Nb; i++) {
// Find all tabs

GetPanelHandleFromTabPage (Parent, Ctrl, i, &TabPanel);
if
(TabPanel==Panel) {

SetActiveTabPage(Parent, Ctrl, i);

return 1;
}
}
}
GetCtrlAttribute (Parent, Ctrl,
ATTR_NEXT_CTRL, &Ctrl);
}
}
// Either a top panel or a child not found as a tab, so it's a
simple child panel
SetActivePanel(Panel);

return 0;
}

--
Guillaume Dargaud
http://www.gdargaud.net/
0 Kudos
Message 7 of 7
(3,041 Views)