10-10-2007 07:56 PM
10-11-2007 02:01 AM
I'm not sure to understand exactly what you are aiming to and why you want to treat control constant names instead of their handles, but I suppose your find_control function could be rewritten in a simpler way:
int find_control (int panel, char *control_name)
// Finds a control on a panel
{
int pNameLen, next;
char cName[64], msg[128];
GetPanelAttribute (panel, ATTR_CONSTANT_NAME, cName);
DebugPrintf ("Panel name: %s\n", cName);
strcat (cName, "_"); pNameLen = strlen (cName);
GetPanelAttribute (panel, ATTR_PANEL_FIRST_CTRL, &next);
// Iterate through all controls on the panel
while (next) {
GetCtrlAttribute (panel, next, ATTR_CONSTANT_NAME, msg);
strcpy (cName + pNameLen, msg);
DebugPrintf ("Control #%d: %s\n", next, cName);
if (!strcmp (name, control_name)) break;
GetCtrlAttribute (panel, next, ATTR_NEXT_CTRL, &next);
}
if (next)
DebugPrintf ("Found: %d\n", next);
else
DebugPrintf ("Not found.\n");
return next;
}
10-11-2007 12:12 PM
10-11-2007 01:04 PM
This works for me since I was only using integer values for the set ctrl attribute. You would have to code with a switch like in the set ctrl val to pull out the right argument. Alternately, CVI could have the vectorized versions of the base calls and people could wrap them more easily.
Robertos find control is better above.
int find_control(int panel,char *control_name)
{
char *cname;
int count;
int i;
char name[500];
//works only if panel constants are of the form P_SOMENAME
if(control_name[0] == 'P') //always put a P_ in panel names
{
cname = strstr(&control_name[2],"_");
cname++; //strip out P_XXXX_ to get just the control name
}
GetPanelAttribute (panel, ATTR_NUM_CTRLS,&count);
count +=2;
for(i=2;i<count;i++)
{
GetCtrlAttribute (panel, i, ATTR_CONSTANT_NAME, name);
if(strcmp(name,cname) == 0) break;
}
if(i>= count) i = 0;
return(i);
}
int SetCtrlAttributeW(int panel,char *control_name,int attribute,...)
{
va_list ap;
int i;
i = find_control(panel,control_name);
if(i) {
va_start(ap,attribute);
SetCtrlAttribute(panel,i,attribute,va_arg(ap,int));
va_end(ap);
}
return(0);
}
int GetCtrlAttributeW(int panel,char *control_name,int attribute,void *v)
{
int i;
i = find_control(panel,control_name);
if(i) {
GetCtrlAttribute(panel,i,attribute,v);
}
else
{
char x[1000];
strcpy(x,"Control not found: ");
strcat(x,control_name);
MessagePopup("Problem",x);
}
return(0);
}
int GetCtrlValW(int panel,char *control_name,void *v)
{
int i;
i = find_control(panel,control_name);
if(i)
{
GetCtrlVal(panel,i,v);
}
else
{
char x[1000];
strcpy(x,"Control not found: ");
strcat(x,control_name);
MessagePopup("Problem",x);
}
return(0);
}
int SetCtrlValW(int panel,char *control_name,...)
{
int type;
va_list ap;
int i;
i = find_control(panel,control_name);
if(i) {
GetCtrlAttribute (panel, i, ATTR_DATA_TYPE, &type);
va_start( ap,control_name);
switch(type)
{
case VAL_SHORT_INTEGER: return(SetCtrlVal(panel,i,va_arg(ap,short)));
case VAL_INTEGER: return(SetCtrlVal(panel,i,va_arg(ap,int)));
case VAL_CHAR: return(SetCtrlVal(panel,i,va_arg(ap,char)));
case VAL_UNSIGNED_CHAR: return(SetCtrlVal(panel,i,va_arg(ap,unsigned char)));
case VAL_UNSIGNED_INTEGER: return(SetCtrlVal(panel,i,va_arg(ap,unsigned int)));
case VAL_UNSIGNED_SHORT_INTEGER: return(SetCtrlVal(panel,i,va_arg(ap,unsigned short)));
case VAL_STRING: return(SetCtrlVal(panel,i,va_arg(ap,char *)));
case VAL_FLOAT: return(SetCtrlVal(panel,i,va_arg(ap,float)));
case VAL_DOUBLE: return(SetCtrlVal(panel,i,va_arg(ap,double)));
}
va_end(ap);
}
return(0);
}
Just change the function calls to the X version and then use this switch to call the new stuff above or the standard calls.
#if 1
#define SetCtrlValX(panel,control,value) SetCtrlValW(panel,#control,value)
#define GetCtrlValX(panel,control,value) GetCtrlValW(panel,#control,value)
#define SetCtrlAttributeX(panel,control,attribute,value) SetCtrlAttributeW(panel,#control,attribute,value)
#define GetCtrlAttributeX(panel,control,attribute,value) GetCtrlAttributeW(panel,#control,attribute,value)
#else
#define SetCtrlValX(panel,control,value) SetCtrlVal(panel,control,value)
#define GetCtrlValX(panel,control,value) GetCtrlVal(panel,control,value)
#define SetCtrlAttributeX(panel,control,attribute,value) SetCtrlAttribute(panel,control,attribute,value)
#define GetCtrlAttributeX(panel,control,attribute,value) GetCtrlAttribute(panel,control,attribute,value)
#endif
10-12-2007 01:29 AM
Just an idea I got from your message: if the different panels are *really* very similar one to each other you could consider designing only one panel in the UIR editor with all elements needed and load it more than once adapting its aspect to that particular instance characteristics (hiding / showing some controls, changing some text message or so). Operating this way, both control constant names and control callbacks remains unchanged so your software could end to be simpler than expected.
This solution is feasible is panels have little difference between them, becoming more and more complex as they differentiate, so it's up to your application characteristics to define if this can be a practical option for you.
10-12-2007 12:21 PM