If you open a header/include (.h) file in LabWindows/CVI, you can generate a function panel using the Options»Generation Function Tree command. In order to clearly define the function tree structure, you should use header file tags. On the other hand, if you generate function panels from a header file that does not include header file tags, all function panels will be located in the root of the instrument tree and all parameters will be created as inputs.
Figure 1. Generate Function Tree Dialog
For example, if you generate a function panel from the following header file, the resulting function panel (.fp) file will look like Figure 2. Notice the flat structure of the function panel tree.
int __stdcall fn1(int a);
int __stdcall fn2(int b);
int __stdcall fn3(int a, int b);
float __stdcall fn4(float a);
float __stdcall fn5(float b);
float __stdcall fn6(float a, float b);
Figure 2. Generated Function Panel from Header File without Tags
Note: The default qualifier field in the Generate Function Tree dialog must be consistent with the default qualifier used in the source header file.
By using header file tags, identified by /// keywords, you have the flexibility to:
First, you can use classes to create hierarchy in an .fp file. The following tag identifies the start of a class:
/// -> Class Name
The following tag marks the end of a class:
/// <- Class Name
Note: The class name for this tag is optional and helps to make the code more readable. The ->
and <-
tags can also be nested.
/// -> Integers
int __stdcall fn1(int a);
int __stdcall fn2(int b);
int __stdcall fn3(int a, int b);
/// <- Integers
/// -> Floats
float __stdcall fn4(float a);
float __stdcall fn5(float b);
float __stdcall fn6(float a, float b);
/// <- Floats
Figure 3 shows the resulting function panels generated from the above code.
Figure 3. Generated Function Panels with -> tags
In order to create a consistent style across auto generated function panels, LabWindows/CVI performs the following actions for each function panel it creates:
Because of the automatic word splitting mechanism, the generated function panel name might be different from the intended name. To correct the generated function panel titles, use the XCHG tag. You may also specify multiple replacement string pairs separated by commas.
Note: You may also use the PXCH tag to replace strings in function panel controls.
/// XCHG Fn/Function
/// -> Integers
int __stdcall fn1(int a);
int __stdcall fn2(int b);
int __stdcall fn3(int a, int b);
/// <- Integers
/// -> Floats
float __stdcall fn4(float a);
float __stdcall fn5(float b);
float __stdcall fn6(float a, float b);
/// <- Floats
/// XCHG
Figure 4 shows the function panel generated from the above code.
Figure 4. Generated Function Panels with XCHG tags
Because the function panel generator is not based on a compiler and does not parse data types defined in header files, any use of a non-ANSI data type will generate a syntax error. To correct this, use the ADDT tag to make the generator aware of any custom data types you intend to use in the header file.
/// ADDT int8
/// ADDT uInt8
The generator will add the type name to the function panels plus some derived array and pointer types.
int8 | uInt8 |
By default, the function panel generator creates input controls. On the other hand, if the generator detects an enum type, it automatically creates a ring control for that parameter, but you have the flexibility to create controls of other types by using the RNG, SLD and BIN tags.
Each tag requires two parameters, separated by a slash. The first parameter is the parameter position ( 1-based index) and the second parameter is optional and can represent the enum name, if the function parameter data type is of type enum.
Note: The BIN tag can only be associated with an enum that has exactly two values.
typedef enum {
ON=1,
OFF=0,
} MyBinaryEnumType;
/// BIN 1
int __stdcall fnX(MyBinaryEnumType binaryInput);
Figure 5. Binary Control
If you want to use a set of values that are defined using the #define preprocessor command, you can group them into a named enum by using the ENUM tag.
Note: The group of #define values must be followed by an empty line in order for the generator to recognize the end of the enum.
/// ENUM enum1
#define ON 1
#define OFF 0
/// ENUM enum2
#define ONE 1
#define TWO 2
#define THREE 3
#define FOUR 4
/// BIN 1/enum1
/// SLD 2/enum2,3/enum2
/// RNG 4/enum2,5/enum2
int __stdcall fnX(int a, int b, int c, int d, int e);
Figure 6 shows the controls generated from the above code.
Figure 6. Generated Controls Using BIN, SLD, and RNG Tags
In the event that you need to add an extra default value to an existing enum, use the EHDV tag for a slider or binary control. The generator will add an extra value at the top of the value list, the label will read "Default", and the control will be set to the value specified.
typedef enum {
kLeftAligned=0,
kRightAlighed=1,
} AlignmentEnumType;
/// SLD 1
/// EHDV 1/-1
int __stdcall fnX(AlignmentEnumType alignment);
Figure 7 shows the control generated by the above code.
Figure 7. Generated Control Using EHDV Tag
If you wish to create different value labels for ring, binary, or slider controls, you can do so by adding comments to each enum value. The generator will replace the enum value names with the commented text.
Note: Avoid using semicolons in the enum comments.
typedef enum {
kLeftAligned= 0, // Left aligned
kRightAlighed=1, // Right aligned
} AlignmentEnumType;
/// SLD 1
/// EHDV 1/-1
int __stdcall fnX(AlignmentEnumType alignment);
Figure 8 shows the control generated by the above code.
Figure 8. Using Comments with the SLD Tag
In order to define output parameters, use the OUT tag. Note that only pointers and arrays may be output parameters. Any other data type will generate an error.
/// OUT 2,3
int __stdcall Sphere_Calc(float radius, float *surface, float *volume);
Figure 9 shows what is generated from the above code.
Figure 9. Generated Controls Using the OUT Tag
The function panel generator creates empty input and output parameters and sets all ring, binary or slider parameters to their first item, but if you need to change the default value of a parameter, use the DFLT tag.
/// OUT 2,3
/// DFLT 1/1.0,2/&surface,3/&volume
int __stdcall Sphere_Calc(float radius, float *surface, float *volume);
Figure 10 shows the generated controls for the above code.
Figure 10. Controls Generated with DFLT Tag
If you need to use a specific parameter type on a function panel, use the PTYP tag to change it from the ANSI-C data type to any other type that is valid on the function panel. For example, a function parameter, declared as void* but is used for numeric arrays, can be changed from void* to LabWindows/CVI's native Numeric Array.
/// PTYP 1/Numeric Array
float __stdcall CalcArrayMean(void *array, int dataType);
Figure 11 shows the generated controls from the above code.
Figure 11. Generated Controls Using PTYP Tag
.SUB files are often used in IVI drivers to specific instrument attributes. If your instrument requires SetAttribute or GetAttribute functions whose attributes are stored in a .SUB file, use the ERNG tag for the attribute parameter and the PTYP tag for the value parameter. For the attribute parameter, the generator will create an empty ring, however when the instrument is loaded, the contents of the ring parameter will be filled with attributes from the .SUB file. For the value parameter, the generator will change the parameter type from void* to LabWindows/CVI's native Any Type.
Note: The structure of .sub files can be found in Chapter 7 of the Instrument Driver Interactive Developer Interface Specification.
/// ERNG 1
/// PTYP 2/Any Type
/// OUT 2
int __stdcall GetAttribute(int attribute, void *value);
Note:.SUB files must be located in the same folder as their associated .fp file and have a common root name.
For this example, we will use the attached FPGen.sub file to populate the instrument attributes. After generating the function panel, open the GetAttribute function and select Options»Operate Function Panel (F9). Figure 12 shows the controls generated from the above code.
Figure 12. Generated Controls Using ERNG Tag
In some cases, you may need to use variable arguments in a function declaration. So if you need additional parameter controls on the function panel, you can add them using the VARG tag.
/// VARG int/More Numbers Ending With Zero
int __stdcall Sum(int number, ...);
Figure 13 shows the controls generated from the above code.
Figure 13. Generated Controls Using VARG Tag
When using a function panel with variable arguments, you can type the first number in the first input control and the rest of the numbers, separated by commas and followed by a zero, in the second control. The resulting function call will look like:
Sum(1, 2, 3, 4, 5, 0);
Figure 14. Generated Controls with Sequence
Additional customizations can be added to function panel parameters. Customizations are indicated by a "..." button to the right of the parameter control. To customize a parameter, use the CUST tag. Specify the parameter position, the DLL that contains the desired customization function and the entry point name. More help on creating customization functions and DLLs can be found in the LabWindows/CVI Help.
Note: The customization DLL must be in the system path or in the same folder where the instrument resides in order for the DLL to be found. You may also use relative or absolute path in the DLL specification.
/// CUST 1/cviLibCust.dll/SelectAnyFile
int __stdcall SaveDataToFile(char filePath[], void *data);
For this example, we will used the attached cviLibCust.dll file. After generating the function panel, open the SaveDatatoFile function and select Options»Operate Function Panel (F9). If you now click on the customization button (or press Enter with the cursor inside the parameter), an Open File dialog will appear as shown in figure 15.
Figure 15. Customizing Parameters
Finally, to document your function panels, you can add help for the instrument, help for each class, help for each function and even help for each parameter with the HFP, HCL, HFUN, HPAR and HRET tags. You can also add the help as either formatted text of HTML, but the help contents need to be saved in a file. Each filename can be associated with one or more help generation tags.
/// HFP FPfileHelp.htm
/// HCL IntegerClassHelp.htm
/// -> Integers
/// HFUN Fn1Help.htm
/// HPAR 1/ParameterAHelp.htm
int __stdcall fn1(int a);
/// HFUN Fn2Help.htm
/// HPAR 1/ParameterBHelp.htm
int __stdcall fn2(int b);
/// HFUN Fn3Help.htm
/// HPAR 1/ParameterAHelp.htm,2/ParameterBHelp.htm
int __stdcall fn3(int a, int b);
/// <- Integers
Note: The HTML files used in this example are attached below for your reference.
After generating your function panel file, you can position the cursor at the first parameter of function fn3 and select menu Edit » Show Prototype (or press Ctrl+Shift+Space) and the function prototype will display in a tooltip.
You can bring up the parameter help by clicking on the question mark button (or pressing F1).
Figure 16. HTML Function Help
The proven LabWindows/CVI development environment can make your ANSI C application development more productive with various documentation tools, including source code tags, the ability to generate function panels from headers files, and the ability to generate HTML documentation from function panels.