TM
TM
Course Software Version 8.0 March 2006 Edition Part Number 321057G-01 LabWindows/CVI Basics II Course Manual
Copyright 19962006 National Instruments Corporation. All rights reserved. Under the copyright laws, this publication may not be reproduced or transmitted in any form, electronic or mechanical, including photocopying, recording, storing in an information retrieval system, or translating, in whole or in part, without the prior written consent of National Instruments Corporation. National Instruments respects the intellectual property of others, and we ask our users to do the same. NI software is protected by copyright and other intellectual property laws. Where NI software may be used to reproduce software or other materials belonging to others, you may use NI software only to reproduce materials that you may reproduce in accordance with the terms of any applicable license or other legal restriction. Trademarks National Instruments, NI, ni.com, and LabVIEW are trademarks of National Instruments Corporation. Refer to the Terms of Use section on ni.com/legal for more information about National Instruments trademarks. Tektronix and Tek are registered trademarks of Tektronix, Inc. Other product and company names mentioned herein are trademarks or trade names of their respective companies. Members of the National Instruments Alliance Partner Program are business entities independent from National Instruments and have no agency, partnership, or joint-venture relationship with National Instruments. Patents For patents covering National Instruments products, refer to the appropriate location: HelpPatents in your software, the patents.txt file on your CD, or ni.com/legal/patents.
Worldwide Technical Support and Product Information ni.com National Instruments Corporate Headquarters 11500 North Mopac Expressway Austin, Texas 78759-3504 USA Tel: 512 683 0100 Worldwide Offices Australia 1800 300 800, Austria 43 0 662 45 79 90 0, Belgium 32 0 2 757 00 20, Brazil 55 11 3262 3599, Canada 800 433 3488, China 86 21 6555 7838, Czech Republic 420 224 235 774, Denmark 45 45 76 26 00, Finland 385 0 9 725 725 11, France 33 0 1 48 14 24 24, Germany 49 0 89 741 31 30, India 91 80 41190000, Israel 972 0 3 6393737, Italy 39 02 413091, Japan 81 3 5472 2970, Korea 82 02 3451 3400, Lebanon 961 0 1 33 28 28, Malaysia 1800 887710, Mexico 01 800 010 0793, Netherlands 31 0 348 433 466, New Zealand 0800 553 322, Norway 47 0 66 90 76 60, Poland 48 22 3390150, Portugal 351 210 311 210, Russia 7 095 783 68 51, Singapore 1800 226 5886, Slovenia 386 3 425 4200, South Africa 27 0 11 805 8197, Spain 34 91 640 0085, Sweden 46 0 8 587 895 00, Switzerland 41 56 200 51 51, Taiwan 886 02 2377 2222, Thailand 662 278 6777, United Kingdom 44 0 1635 523545 For further support information, refer to the Additional Information and Resources appendix. To comment on National Instruments documentation, refer to the National Instruments Web site at ni.com/info and enter the info code feedback.
Contents
Student Guide
A. B. C. D. E. F. LabWindows/CVI Training and Certification Sequence......................................vii Course Description ...............................................................................................vii What You Need to Get Started .............................................................................viii Installing the Course Software..............................................................................ix Course Goals.........................................................................................................ix Course Conventions ..............................................................................................x
iii
Contents
Tree Control ................................................................................................................2-47 Exercise 2-6 Tree Controls ....................................................................................2-50 Intensity Graphs ..........................................................................................................2-56 Intensity GraphsPlotIntensity Function ..................................................................2-57 Intensity GraphsColor Map Array ..........................................................................2-59 Exercise 2-7 Intensity Graph Controls ..................................................................2-61 User-Defined Custom Controls ..................................................................................2-64 Predefined Custom Controls .......................................................................................2-65 Predefined Custom ControlsPath Control...............................................................2-66 Predefined Custom ControlsPassword Control ......................................................2-67 Predefined Custom ControlsCombo Box ...............................................................2-68 Predefined Custom ControlsFile Browser ..............................................................2-69 Exercise 2-8 Predefined Custom Controls.............................................................2-71 Predefined Custom ControlsToolbar ......................................................................2-73 Predefined Custom ControlsToolbar Functions .....................................................2-74 Exercise 2-9 Toolbars............................................................................................2-77 Predefined Custom ControlsOther Controls ...........................................................2-81 Summary Lesson 2......................................................................................................2-82
Contents
DataSocket Features ...................................................................................................3-41 Data Entities and Attributes ........................................................................................3-42 DataSocket API...........................................................................................................3-43 Structure of a Data Writer...........................................................................................3-44 Structure of a Data Reader..........................................................................................3-45 Exercise 3-5 Creating DataSocket Writer and Reader Applications.....................3-47 DataSocket Binding ....................................................................................................3-51 Exercise 3-6 Using DataSocket Binding ...............................................................3-53 Using LabVIEW (Optional)........................................................................................3-56 Exercise 3-7 Using the CVI Function Panel Converter (Optional) .......................3-58 Controlling VIs from LabWindows/CVI Using VI Server (Optional) .......................3-61 Exercise 3-8 Communicating with LabVIEW VIs (Optional) ..............................3-63 Transmission Control Protocol (Optional) .................................................................3-68 TCP Client-Server Architecture..................................................................................3-69 TCP Servers and Clients .............................................................................................3-70 TCP Callback Functions .............................................................................................3-71 TCP Server/Client Functions ......................................................................................3-72 ServerTCPRead/ClientTCPRead ................................................................................3-73 Exercise 3-9 Examining a TCP Application in LabWindows/CVI.......................3-75 Summary Lesson 3......................................................................................................3-78
Contents
vi
ni.com
Student Guide
Thank you for purchasing the LabWindows/CVI Basics II course kit. This course manual and the accompanying software are used in the two-day, hands-on LabWindows/CVI Basics II course. You can apply the full purchase price of this course kit toward the corresponding course registration fee if you register within 90 days of purchasing the kit. Visit ni.com/training to register for a course and to access course schedules, syllabi, and training center location information.
Certification Track
B. Course Description
The LabWindows/CVI Basics II course is a follow-up to the LabWindows/CVI Basics I course. This course is ideal for new and intermediate users. After attending the course, you can design powerful multithreaded applications that use Internet communication, DLLs, and ActiveX. You will learn how to create powerful user interfaces using active menus, canvas controls, and toolbars. You will be able to take full advantage of the PC with your application by learning how to program a multithreaded application. This course assumes that you have completed LabWindows/CVI Basics I course or you are familiar with the LabWindows/CVI environment and possess basic C programming skills.
vii
Student Guide
The course is divided into lessons, each covering a topic or a set of topics. Each lesson consists of the following parts: An introduction that describes what you will learn. A discussion of the topics. A set of exercises that reinforces the topics presented in the discussion. Some lessons include optional exercises or challenge steps to complete if time permits. A summary that outlines important concepts and skills taught in the lesson.
Description Folder containing the exercises used in the course and for saving LabWindows/CVI files created during the course Folder containing the solutions to all the course exercises
Solutions
viii
ni.com
Student Guide
E. Course Goals
This course presents the following topics: Create user interfaces with toolbars and menus. Use ActiveX within the LabWindows/CVI environment. Compile modules as DLLs so they can be used with other applications. Use LabWindows/CVI to access DLLs. Develop efficient multithreaded applications. Develop applications that can communicate with the Internet. Decrease development time using debugging features.
This course does not include following topics: Every built-in function or library. Refer to the NI LabWindows/CVI Help for more information about LabWindows/CVI features not described in this course Detailed explanation of ActiveX technology Detailed explanation of TCP/IP protocol Operation of the GPIB bus Developing a customized application for any student in the class.
ix
Student Guide
F. Course Conventions
The following conventions are used in this course manual: <> Angle brackets that contain numbers separated by an ellipsis represent a range of values associated with a bit or signal namefor example, AO <3..0>. Square brackets enclose optional itemsfor example, [response]. The symbol leads you through nested menu items and dialog box options to a final action. The sequence FilePage SetupOptions directs you to pull down the File menu, select the Page Setup item, and select Options from the last dialog box. This icon denotes a tip, which alerts you to advisory information. This icon denotes a note, which alerts you to important information. bold Bold text denotes items that you must select or click in the software, such as menu items and dialog box options. Bold text also denotes parameter names, buttons on the User Interface (*.uir), and sections and components of dialog boxes. Window names and palette names are also denoted in bold. Italic text denotes variables, emphasis, a cross-reference, or an introduction to a key concept. Italic text also denotes text that is a placeholder for a word or value that you must supply. Text in this font denotes text or characters that you enter from the keyboard, sections of code, programming examples, and syntax examples. This font also is used for the proper names of disk drives, paths, directories, programs, subprograms, subroutines, device names, functions, operations, variables, filenames, and extensions. Bold text in this font denotes the messages and responses that the computer automatically prints to the screen. This font also emphasizes lines of code that are different from the other examples. Italic text in this font denotes text that is a placeholder for a word or value that you must supply.
[]
italic
monospace
monospace bold
monospace italic
ni.com
Introduction
In this lesson, you will learn about the concepts that are the foundation for building LabWindows/CVI programs.
1-1
Lesson 1
1-2
ni.com
Lesson 1
Introduction to Messaging
A message queue is set up when the operating system starts your application As events occur, the operating system stores different messages in the queue Your application continuously checks the queue to take action on the various messages
Introduction to Messaging
When discussing the general callback function mechanism internal structure, it is necessary to look at the concept of operating system messaging. A common construct in modern operating systems (Windows 2000/NT/9x included), a messaging scheme offers applications a consistent and straightforward way to respond to modern graphical user interfaces and other types of actions. In addition to other services provided to every application, the operating system (OS) manages a message queue for the application. When the OS detects events such as a mouse movement, it places well-defined messages in this queue. An application loops and polls to check for messages in the queue. If messages exist, the application removes the messages and takes appropriate action. In a LabWindows/CVI application, think of ProcessSystemEvents as the function that checks the queue and takes appropriate action. As discussed in LabWindows/CVI Basics I, RunUserInterface manages the core looping of your application and relies on the functionality of ProcessSystemEvents.
ProcessSystemEvents examines the new message and determines how to handle it. In the case of a user interface action, ProcessSystemEvents determines the appropriate control and calls
1-3
Lesson 1
Messaging
ProcessSystemEvents
CVICALLBACK function () switch(event) { case EVENT_LEFT_CLICK:
Message queue
Messaging
The figure above illustrates the general message processing scheme. Consider the following example: A LabWindows/CVI application with a simple one-button panel is running. When the user clicks and releases the left mouse button, the OS queues the appropriate messages. ProcessSystemEvents, whether you call it directly or call it through RunUserInterface, detects these messages and extracts them from the queue. Upon examining the messages, ProcessSystemEvents determines that the user clicked and released the button on the application. First, the function sends an EVENT_LEFT_CLICK to your buttons callback function. Then, when that call returns, ProcessSystemEvents calls the function again with the EVENT_COMMIT. ProcessSystemEvents does the message-handling work for you. For this reason, it is important that you understand the callback function mechanism because you must always first check the event passed into the function and determine what action to take. The switch-case C language structure is the best way to do this.
Note User interface callback functions typically return 0. If the function returns a nonzero number, any subsequent callbacks resulting from that particular event are not called. This process is known as swallowing the event.
1-4
ni.com
Lesson 1
1-5
Lesson 1
1-6
ni.com
Lesson 1
1-7
Lesson 1
Summary Lesson 1
Lesson 1 reviews and extends core LabWindows/CVI concepts from the Basics I course. Callback function programming model Instrument drivers as user libraries Toolslib instrument drivers
Summary Lesson 1
This lesson describes key programming concepts with the LabWindows/CVI libraries. Lesson 2 gives you hands-on experience developing programs with toolslib instrument drivers to implement advanced user interface features.
1-8
ni.com
Lesson 1
Notes
1-9
Lesson 1
Notes
1-10
ni.com
Introduction
With LabWindows/CVI user interface functions and features, you can build powerful, event-driven GUIs quickly. As you develop LabWindows/CVI applications, you add user interface controls to panels, edit their properties, and then create the corresponding callback functions to handle user events that are generated by operations on those controls. You can enhance your applications with advanced user interface controls, custom controls, and built-in user interface features that increase usability and flexibility for the end user. This lesson focuses on user interface programming style and taking advantage of your own user interface elements.
2-1
Lesson 2
Project
Lesson 2 Project
In this lesson, you will create a project that uses several LabWindows/CVI user interface (UI) features. The project integrates menus, toolbars, canvas controls, multiple panels, intensity graphs, table controls, and tree controls. You add each feature one at a time, so that you can see how each benefits the overall application. The final section in this lesson covers many of the custom control instrument drivers that ship with LabWindows/CVI.
2-2
ni.com
Lesson 2
Exercise 2-1
OBJECTIVE
To run the application that you create To explore the functionality of the application
2-3
Lesson 2
Exercise 2-1
Objective:
1. Run the uiproject.exe executable located in the directory C:\Exercises\CVI Basics II\Lesson 2\execs. 2. Examine the features you will add throughout Lesson 2. Menus Intensity graphs Canvas controls Table controls Tree controls Toolbars
3. Click the Quit button when you finish studying the application.
2-4
ni.com
Lesson 2
Attributes
All user interface objects have attributes such as color, visibility, position, or size. For example, this STOP button has the following attributes: Color: Red
Visibility: True GetCtrlAttribute and SetCtrlAttribute retrieve and set control attribute values.
Attributes
In LabWindows/CVI, every UI object has attributes such as color, visibility, position, and size. Some objects have specific attributes. For example, a graph has attributes for grid lines and its X and Y axes. You can set the attributes of objects in the User Interface Editor. You also can set the attributes programmatically. Use the User Interface Library GetCtrlAttribute and SetCtrlAttribute functions to change the appearance and functionality of UI objects.
2-5
Lesson 2
Exercise 2-2
OBJECTIVE
2-6
ni.com
Lesson 2
Exercise 2-2
Objective:
Search
In this exercise, you will add search functionality to the application to allow the user to search for a string entered in the Find text control. After the application finds the string, the application highlights the appropriate text in the text box control. If the application does not find the string, the application displays a message stating that the string does not exist.
Examine the following code for the SearchRoutine function that you will create in this exercise. Complete the steps following the code to use LabWindows/CVI to quickly develop the code for the SearchRoutine function.
2-7
Lesson 2
Open uiproject.c. The code is partially completed for you. 2. Place your cursor inside the SearchRoutine function, which already is declared. 3. Use the FindPattern function to search the contents of the text box for the search string stored in the buffer FindThis. Press the <Ctrl-Shift-P> key to find a function panel. You can use this technique whenever you need a function panel.
Tip
Alternatively, you can also find the FindPattern function panel by selecting Formatting and I/O LibraryString Manipulation FindPattern from the Library Tree. Complete the function panel as shown in the following table. Buffer Starting Index Number of Bytes Pattern Case Sensitive? Start From Right? Result
Buffer searchposition 1 FindThis
No No
result
2-8
ni.com
Lesson 2
4. Select CodeInsert Function Call. The input parameters already are declared. FindPattern searches Buffer starting at searchposition for the pattern stored in FindThis. 5. Declare the variable result in the function SearchRoutine. Use the value of result to determine if the search string exists. If the string exists, highlight the text in the text box.
Tip You can declare the variable result from the FindPattern function panel by pressing <Ctrl-D> in the Result control.
6. Insert an If-Else statement to test if a result was found from the search string. FindPattern returns 1 if the string is not found. Select Edit Insert ConstructIf Else. In the If Else dialog box, enter result >= 0 for the condition. Click OK to insert the construct. 7. FindPattern uses searchposition to determine where to start searching for a particular text string. In order for FindPattern to find multiple instances of the same search string, it is necessary to set the value of searchposition equal to one character after the FindPattern result. This allows FindPattern to search for the text string after the current search instance. Enter the following code in the if statement:
searchposition = result + 1;
8. If the search string is found, the code located in the if statement executes. In the if statement, highlight the found text. Use SetCtrlAttribute to highlight the text. You must call the SetCtrlAttribute function twice. The first function call defines the start position where the highlighting begins. The second function call defines the length of the highlighted text. a. From the Library Tree, select User Interface Library Controls/Graphs/Strip ChartsGeneral Functions SetCtrlAttribute and complete the function panel for the first function call as shown in the following table. After you finish, select CodeInsert Function Call. Panel Handle Control ID Control Attribute Attribute Value
mainPanel MAINPANEL_TEXTBOX
b. Insert the second SetCtrlAttribute function call as shown in the following table. You must calculate the length of the string to highlight. Use the ANSI C strlen function to calculate the length.
2-9
Lesson 2
mainPanel MAINPANEL_TEXTBOX
9. Use SetActiveCtrl to make the text box the active control so that the user can see the highlighted text. From the Library Tree, select User Interface LibraryControls/Graphs/Strip ChartsGeneral FunctionsSetActiveCtrl and complete the function panel for the function call, as shown in the following table. After you finish, select CodeInsert Function Call. Panel Handle Control ID
mainPanel MAINPANEL_TEXTBOX
10. In the else statement, call MessagePopup to display a message that the search string was not found. From the Library Tree, select User Interface LibraryPop-up PanelsMessage/Prompt Popups MessagePopup and complete the function panel as shown in the following table to display a meaningful error message. After you finish, select CodeInsert Function Call. Title Message
String Not Found The Search String Was Not Found
11. FindPattern uses searchposition to determine where to start searching for a particular text string. In cases in which the user inserts a new string for the search after the error message, FindPattern should search the entire text from the beginning. This is possible if searchposition points to the first character in the text. To add this functionality to your program, enter the following code after the MessagePopup statement:
searchposition = 0;
12. Save and run the project. Test the application to confirm that the search function works properly and highlights the appropriate string in the text box when the search string is found.
2-10
ni.com
Lesson 2
Menus
Create menus in the User Interface Editor You must load a menu onto a panel Menus have callbacks similar to controls and panels
Menu Menu Item Menu Bar Submenu
Menus
In LabWindows/CVI Basics I, you learned how to create GUIs. Now, you will learn how to add pull-down menus to your panels so that your program looks and feels like a modern application. Menus are primarily for user input. You do not display information in a menu as you do in a numeric indicator. The following list describes important menu terms: Menu barA menu bar is the entire menu associated with a panel. For example, the Source window in LabWindows/CVI has a menu bar consisting of File, Edit, View, Build, and so on. MenuA menu is one element of the menu bar. File is one menu, Edit is another. Menu itemA menu item is an element from the pull-down menu. Open is an item of the File menu. SubmenuA submenu is a menu displayed by selecting a menu item. Immediate Action MenuAn immediate action menu is a menu that has no menu items placed beneath it. An exclamation point appears next to the immediate action menu name.
2-11
Lesson 2
Menu bar prefix combined with constant name creates the MENU_FILE Control ID Name that appears in menu
Menu Editor
Menu Editor
You can program and identify menu bars and panels in a similar way. Remember that a panel has a constant name. The Control ID of any control placed on that panel consists of this panel constant name followed by the controls own constant name. For example, PNL_GRAPH is the Control ID of a graph that has the constant name GRAPH and is placed on a panel that has the constant name PNL. You use this Control ID when you need to refer to a specific control programmatically. Menu bars also have constant names, and any menu or menu item placed on the menu bar inherits that name. For example, if you add a File menu with the constant name FILE to a menu bar with the constant name MENU, the File menu ID is MENU_FILE. If you add an Open menu item with the constant name OPEN under the File menu, the Open menu item ID is MENU_FILE_OPEN. To create menus in the User Interface Editor, select CreateMenu Bar. Menu Editor Terms Menu Bar Constant PrefixThe constant name associated with a menu bar. This prefix is similar to the constant name given to a panel. Constant NameThe unique name that identifies a menu or menu item on the menu bar. This name is similar to the constant name given to a control on a panel. Item NameThe text shown in the menu bar such as File, Edit, and so on. You can use this text for a pull-down menu or a menu item. Callback FunctionThe name of the function that executes when you select the menu item. Modifier Key and Shortcut KeyThe hot key combination accesses the menu item. Using this combination is equivalent to using the mouse to select the menu item.
2-12
ni.com
Lesson 2
The buttons on the right-hand side of the menu editor position the menu item in the menu hierarchy. You can move a menu item up, down, right, or left in the menu hierarchy. For example, to create a File menu with Open and Exit as two menu items, place File in the menu hierarchy and insert the Open and Exit menu items into the menu. Then highlight the Open item and click the right-hand Change Level button to position the Open item as a child item of File. Repeat this process with the Exit menu item. You also can insert items below an item by clicking the Insert Child Item button.
2-13
Lesson 2
Menu callbacks work like control callbacks, except there is no event parameter in menu callbacks Any idea why?
menuBarThe handle of the menu bar that contains the item. Handles are returned from the LoadMenuBar function. This is similar to LoadPanel. menuItemThe specific control ID of the item selected. If several menu items use the same callback function, use this parameter to determine which menu item was selected. callbackDataA pointer to user-defined data. panelThe panel handle of the panel displaying the menu.
2-14
ni.com
Lesson 2
This function returns a handle to the menu bar that is used in subsequent calls to menu functions. destinationPanelHandleThe handle returned by LoadPanel, NewPanel, or DuplicatePanel that indicates the panel on which the menu bar appears. filenameThe absolute or relative pathname for the .uir file that contains the menu bar resource. menuBarResourceIDThe defined constant assigned to the menu bar in the User Interface Editor.
2. You can create menus and menu bars programmatically using NewMenuBar, NewMenu, and NewMenuItem. You also can retrieve and change the attributes of a menu bar, such as font style, with the GetMenuBarAttribute and SetMenuBarAttribute functions.
2-15
Lesson 2
Exercise 2-3
OBJECTIVE
2-16
ni.com
Lesson 2
Exercise 2-3
Objective:
Menus
In this exercise, you will add a menu to the application. This exercise illustrates the use of menu callback functions and the ease of adding menus to an application. 1. Open the uiproject.uir file located in the directory
C:\Exercises\CVI Basics II\Lesson 2\uiproject.uir and select CreateMenu Bar to display the Edit Menu Bar dialog box, as shown in the following figure.
2. Use this dialog box to create the menu bar. To add entries to the menu, fill in the list boxes. a. Create the File menu with the following entries. Menu Bar Constant Prefix Constant Name
MENU FILE
2-17
Lesson 2
File
Leave blank
b. Click the Insert Child Item button to create the Open menu item under the File menu. Use the following entries in the Edit Menu Bar dialog box. Menu Bar Constant Prefix Constant Name Item Name Callback Function Modifier Key Shortcut Key
MENU OPEN Open OpenText
MenuKey (Ctrl) O
c. Click the Insert Item button to create the Save menu with the following entries. Menu Bar Constant Prefix Constant Name Item Name Callback Function Modifier Key Shortcut Key
MENU SAVE Save SaveText
MenuKey (Ctrl) S
d. Click the Insert Item button to create the Exit menu item with the following entries. Menu Bar Constant Prefix Constant Name Item Name Callback Function Modifier Key Shortcut Key
MENU EXIT Exit ExitProgram
2-18
ni.com
Lesson 2
e. Click the Insert Item button to create the Search menu with the following entries. Menu Bar Constant Prefix Constant Name Item Name Callback Function Modifier Key Shortcut Key
MENU SEARCH Search
Click the <<Change Level button so the Search menu is not indented under the File menu. f. Click the Insert Item button to create the Find menu item with the following entries. Menu Bar Constant Prefix Constant Name Item Name Callback Function Modifier Key Shortcut Key
MENU FIND Find FindString
Click the Change Level>> button so the Find item is indented under the Search menu. Select MenuKey (Ctrl) for the Modifier Key and F for the Shortcut Key. You cannot select modifier and shortcut keys for top level menu items. Therefore, you must change the Search menu item level before you set the menu items modifier and shortcut keys.
Note
g. Click the Insert Item button to create the Case Sensitivity menu item with the following entries. Menu Bar Constant Prefix Constant Name Item Name
MENU CASE Case Sensitivity
2-19
Lesson 2
SetCaseSensitivity
Ensure that the Edit Menu Bar dialog box is similar to the one shown in the following figure. After you verify that your dialog box matches the one shown, click OK. Save uiproject.uir.
3. Verify that CodeSet Target File is set to uiproject.c. 4. Use CodeBuilder to generate the callback functions for the menu. a. Click the uiproject.uir file. b. Select CodeGenerateMenu Callbacks. c. In the Select Menu Bar Objects dialog box, click the Check All button and then click OK. d. Verify that CodeBuilder generated the following five functions in the uiproject.c file.
OpenText SaveText
2-20
ni.com
Lesson 2
5. Navigate to the /*Load Menu Bar Here*/ comment in the main function of uiproject.c. a. Insert the LoadMenuBar function under the comment to load the menu bar on the main panel. b. From the Library Tree, select User Interface LibraryMenu StructuresMenu BarsLoadMenuBar and complete the function panel as shown in the following table. After you finish, select Code Insert Function Call. Destination Panel Handle Filename Menu Bar Resource ID Menu Bar Handle
mainPanel "uiproject.uir" MENU hMenu
c. Use the Declare Variable dialog box to declare hMenu as a global variable at the top of uiproject.c. Press <Ctrl-D> to open the Declare Variable dialog box and select Add declaration to top of target file uiproject.c. Deselect the other options.
Note If prompted with a message stating that the user interface file has been modified, then click OK.
6. Fill in the code for the menu callback functions as shown in the following figure.
a. In the uiproject.c, navigate to the OpenText callback function and enter ReadDataFile(); to call the function, which has
2-21
Lesson 2
already been defined. The ReadDataFile function opens a file dialog box, opens the selected file, reads the contents of the file, and finally displays the contents of the file in the text box control. b. In the SaveText callback function, enter WriteDataFile(); to call the function, which has already been defined. The WriteDataFile function opens a file dialog box, opens the selected file, and writes the contents of the text box control to the file. c. In the ExitProgram callback function, enter QuitUserInterface(0); to stop the application. d. Modify the FindString callback function to load the buffer with the text box contents, display a prompt dialog box with PromptPopup, and call the SearchRoutine function on the returned string. The final code for the function should be similar to the following code.
e. The SetCaseSensitivity callback toggles case sensitivity in the SearchRoutine. The Case Sensitive menu item is checked when case sensitivity is active. Complete the code as shown in following figure.
To specify ATTR_CHECKED as the attribute to set, select Menu Item Checked for Menu Bar Attribute in Attribute Constant dialog box. Declare the variable CaseSensitive as a global integer variable.
2-22
ni.com
Lesson 2
f. Modify the FindPattern function call to include the CaseSensitive variable for the case sensitive argument as shown in the following code segment:
result = FindPattern (Buffer, searchposition, -1,FindThis,CaseSensitive, 0);
7. Save and run the project. Verify that menu functions and the command buttons work properly.
2-23
Lesson 2
Canvas Control
Arbitrary drawing port Low-level functions Speed and flexibility Use for text, lines, and bitmaps
Canvas Control
The canvas control is an arbitrary drawing surface for drawing text, shapes, and bitmap images. The major advantages of using a canvas over a graph are speed and flexibility. The canvas control functions consist of low-level functions for bitmap manipulation and for drawing lines, text, and points. With graphs, you can plot static, numerical data. If you want to display items that require more capabilities than a graph, you can take advantage of a canvas control.
2-24
ni.com
Lesson 2
2-25
Lesson 2
Using a Canvas
Use a canvas for the following tasks:
To draw objects using low-level primitives, such as pie charts and Smith charts To use and manipulate bitmaps (animation) To avoid the overhead associated with graphs
Using a Canvas
When deciding between the various display options available to you, choose the UI object that provides the most built-in features for your purpose. Use graphs and strip chart controls to graph data in standard ways and use canvas controls for specialty purposes. One thing to remember is that graphs have a wide range of capabilities. Study the examples that ship with LabWindows/CVI to determine the possibilities of both graphs and canvas controls. When programming with canvas controls, remember that canvases have attributes you can change programmatically, such as the draw policy, overlapped policy, and coordinate system. You also can use the bitmap functions in close association with the canvas functions.
2-26
ni.com
Lesson 2
2-27
Lesson 2
You can embed these functions into a canvas function call to eliminate the need to declare the structure
CanvasDrawLineTo (hPanel, PANEL_CANVAS, MakePoint(100, 200));
To understand these functions, consider the CanvasDrawLineTo function. This function draws a line between the current pen position and the specified end point and sets the pen position to the end point. The function draws the line with the current pen attributes including color, mode, width, and style. The end point is defined by a structure of type Point, which specifies the x and y coordinates.
CanvasDrawLineTo (hPanel, PANEL_CANVAS, MakePoint (100, 200));
This function draws a line from the current pen position to x = 100, y = 200, where the top left corner of a canvas control is x = 0, y = 0.
2-28
ni.com
Lesson 2
Canvas Functions
Located in the Library Tree under User Interface Library Controls/ Graphs/Strip Charts Canvas
Canvas Functions
The canvas control functions are located in the Library Tree under User Interface Library Controls/Graphs/Strip ChartsCanvas. You can create a wide variety of shapes with the CanvasDraw functions. To draw a point, use CanvasDrawPoint. Other options include line, rectangle, oval, arc, polygon, text, and bitmap. Use CanvasSet/GetPenPosition to control an imaginary pen within the canvas control. You can fully control the pen attributes and location. You can determine whether the pen touches the user interface, the pen thickness and color, and so on. Because you cannot delete individual traces on a canvas control, you must either retrace or clear everything within a specified area. Use CanvasClear to retrace or clear the area. To update any changes to the canvas control immediately, call CanvasUpdate. If you make several canvas function calls in a row, nest the calls between CanvasStartBatchDraw and CanvasEndBatchDraw because there is an associated system overhead for each canvas function call that these functions eliminate.
2-29
Lesson 2
Exercise 2-4
OBJECTIVE
2-30
ni.com
Lesson 2
Exercise 2-4
Objective:
Canvas Controls
Modify the project to allow users to draw on a canvas control. This exercise shows how easy it is to respond to the mouse and scribble on the screen. 1. Load the uiproject.prj file located in the directory
C:\Exercises\CVI Basics II\Lesson 2\uiproject.prj.
2. Complete the following steps to add a new panel to uiproject.uir for the drawing canvas. a. Open uiproject.uir. b. Add a command button to the main panel to launch the canvas panel. Double-click the command button to open the Edit Command Button dialog box. Complete the dialog box as shown in the following table. Constant Name Callback Function Label
SHOWCANVAS ShowCanvasPanel Show __Canvas
After you create the button, the main panel should be similar to the following figure.
2-31
Lesson 2
d. Right-click the Show Canvas button and select Generate Control Callback, which generates the callback function for the button in a new .c file. Leave this new .c file open. e. Select CreatePanel to create a new panel in the uiproject.uir file. Double-click the newly created panel and specify the following entries. Constant Name Panel Title
CNVSPANEL Canvas Drawing Panel
In the following steps, you modify the newly created panel so that it contains a canvas control, timer control, and Close button. After you finish the steps, your canvas should be similar to the following figure.
f. Select CreateCanvasCanvas to add a new canvas control to the new panel. Double-click the canvas control and specify the constant name CANVAS, the callback function DrawCanvas, and the label Drawing Area. g. Add a command button to the panel with the constant name CLOSE, the callback function CloseCanvasPanel, and the label __Close. h. Add a timer control to the panel with the constant name TIMER, the callback function TimerTick, and the label Timer. Set the Interval to 0.010 and disable the Enabled checkbox. i. To generate the callback functions for the Close and Timer buttons, right-click each control and select Generate Control Callback. j. Before you generate the callback function for canvas drawing area, select CodePreferencesDefault Control Events and select EVENT_LEFT_CLICK as the only event. Click OK.
2-32
ni.com
Lesson 2
k. To generate the callback functions for the canvas drawing area, right-click the control and select Generate Control Callback. l. Save the new .c file as canvas.c and select FileAdd canvas.c to Project to add the file to your project. m. Save and close the uiproject.uir file. You now have a .c file in your project called canvas.c with four empty callbacks. Before proceeding, set the target file to canvas.c. Complete the following steps to write the four callback functions. 3. Place your cursor in the EVENT_COMMIT case in the ShowCanvasPanel callback function. Write this function to display the CNVSPANEL as a pop-up panel. You must call LoadPanel to load the panel. From the Library Tree, select User Interface Library PanelsLoadPanel and complete the function panel as shown in the following table. When you finish, select CodeInsert Function Call. Parent Panel Handle Filename Panel Resource ID Panel Handle
0 "uiproject.uir" CNVSPANEL canvasPanel
Declare the variable canvasPanel at the top of canvas.c as the panel handle. 4. From the Library Tree, select User Interface LibraryPop-up Panels InstallPopup and enter canvasPanel as the panel handle. When you finish, select CodeInsert Function Call. 5. At the top of the file, declare global variables that are used for drawing in the canvas with the mouse. Add the variable declarations at the top of the file as shown in the following figure. Include uiproject.h if it is not included.
2-33
Lesson 2
6. The DrawCanvas function detects when the user clicks the canvas to start drawing. The drawing continues as long as the user continues to hold down the left mouse button. Use the following code for this function.
DrawCanvas starts the timer so that if the user holds down the left mouse button, the timer callback function draws a line between the current pen position and a specified end point. This function also obtains the position of the mouse within the canvas and sets the canvas pen to that position.
7. TimerTick draws a continuous line while a user holds down the left mouse button. The code for this function is as follows.
TimerTick obtains the position of the mouse and checks the value of the variable lButtonDown. If lButtonDown is set to true from the DrawCanvas function, TimerTick draws a line from the previous pen position to the current mouse position. If lButtonDown is set to false, TimerTick turns the timer off.
2-34
ni.com
Lesson 2
8. In the CloseCanvasPanel callback function, call the RemovePopup function to close the pop up panel. To do this, select User Interface LibraryPop-up PanelsRemovePopup from the Library Tree and then insert the function call. To remove the panel from memory select User Interface LibraryPanelsDiscardPanel from the Library Tree. Enter canvasPanel as PanelHandle and then insert the function call. 9. Save the canvas.c file and run the project. Verify that the canvas panel works properly by scribbling on it while you hold down the left mouse button.
2-35
Lesson 2
Table Control
Provides a spreadsheet-type interface Has built-in functions to search, sort, and select data Accepts numeric, string, or picture data types
Table Control
One of the more advanced controls in LabWindows/CVI is the table control. The table control is a powerful and flexible tool for storing and operating on tabular data. With the table control, you can display arrays, perform spreadsheet operations, and sort data. The table control has built-in functionality to select and edit data, which is similar to the functionality of a spreadsheet program. Data can be selected by row, column, or individual cell. The table control also provides built-in searching and sorting functions and provides the ability to jump to certain cells automatically. The table control can contain several data types including strings, numbers, and even pictures.
2-36
ni.com
Lesson 2
2-37
Lesson 2
2-38
ni.com
Lesson 2
When a mouse event occurs on a table control, the cell can be found with the following code:
Point mouse, cell; mouse = MakePoint (eventdata2, eventdata1); GetTableCellFromPoint (panel, TABLE, mouse, &cell);
2-39
Lesson 2
Exercise 2-5
OBJECTIVE
2-40
ni.com
Lesson 2
Exercise 2-5
Objective:
Table Controls
1. Load the uiproject.prj file located in the directory
C:\Exercises\CVI Basics II\Lesson 2\uiproject.prj.
2. Select EditAdd Files to ProjectSource (*.c) to add table.c to the project. 3. Open table.c. This file contains a utility function called GenerateTestData that generates the data for a row of the table. Examine this function and how the data is generated. Leave the file open. 4. Open uiproject.uir. 5. Add a command button to the main panel that launches the table panel. 6. Double-click the command button to open the Edit Command Button dialog box. Complete the dialog box as shown in the following table. Constant Name Callback Function Label
SHOWTABLE ShowTablePanel Show __Table
After you create the button, the main panel should be similar to the following figure.
2-41
Lesson 2
7. Make sure that CodeSet Target File is set to table.c. Before you generate the callback function for the Show Table button, select CodePreferencesDefault Control Events and select only EVENT_COMMIT. Click OK. Right-click the Show Table button and select Generate Control Callback. This command generates the callback function for the button in the table.c file. 8. Select CreatePanel to create a new panel. Double-click the panel and specify TABLEPANEL as the panel constant name and Table Control Panel as the panel title. 9. Select CreateLists & TablesTable to add a table control to the new panel. Double-click the table control to open the Edit Table dialog box. In this dialog box, you can create rows and columns, initialize cells, and format the table. a. Enter Test Results as the label of the table. b. Disable the Row Labels Visible checkbox. c. Set the Scroll Bars option to Vertical Scroll Bar. d. Click the Insert Column After button to add the first column to the table. e. Click the Edit Column button. Enable the Use Label Text checkbox and enter Test ID in the Label textbox as shown in the following figure.
2-42
ni.com
Lesson 2
f. Click the Edit Default Cell Values button to change the Type to Numeric and the Data Type to int. g. Click OK to close the Edit Default Cell Values dialog box. h. Click OK again to close the Edit Column dialog box and return to the Edit Table dialog box. 10. Click Insert Column After button to add new column. Repeat the process in step 9 parts d through h with the values in the following tables. Column 2 Width Label Text Cell Type Numeric Data Type Column 3 Width Label Text Cell Type Numeric Data Type Column 4 Width Label Text Cell Type Numeric Data Type
50 Meas. 2 50 Meas. 1 130 Date/Time
String int
Numeric double
Numeric double
2-43
Lesson 2
Confirm that your table has four columns and the Edit Table dialog box is similar to the one shown in the following figure.
11. Close the Edit Table dialog box by clicking OK and size the table to show all four columns completely. 12. Add a command button to the panel with the constant name RUNTEST, the callback function RunTest, and the label __Run Test. 13. Add another command button to the panel with the constant name CLOSE, the callback function CloseTablePanel, and the label __Close. 14. For each new button, right-click the button and select Generate Control Callback to generate the callback functions in table.c. The completed panel should be similar to the following figure. 15. Save and close the uiproject.uir file.
2-44
ni.com
Lesson 2
The table.c now contains three empty callback functions that require modifications 16. Place your cursor in the EVENT_COMMIT case in the ShowTablePanel callback function. You must call LoadPanel to load the panel. From the Library Tree, select User Interface LibraryPanelsLoadPanel and complete the function panel as shown in the following table. When you finish, select CodeInsert Function Call. Parent Panel Handle Filename Panel Resource ID Panel Handle
0 "uiproject.uir" TABLEPANEL tablePanel
a. From the Library Tree, select User Interface LibraryPop-up PanelsInstallPopup and enter tablePanel in the panel handle textbox. When you finish, select CodeInsert Function Call. b. Set the value of the global variable testID to zero in this function. Enter testID = 0; below the InstallPopup function. 17. The RunTest callback function calls GenerateTestData to obtain data for one row of the table. InsertTableRows inserts a row in the table. Four function calls to SetTableCellVal place the data in the table. The MakePoint function references a particular cell in the table with the x-coordinate and y-coordinate position of the cell in the table. The code for this callback is similar to the following example.
2-45
Lesson 2
18. The CloseTablePanel callback function hides the table panel with RemovePopup. From the Library Tree, select User Interface Library Pop-up PanelsRemovePopup and then insert the function call. 19. To remove the panel from memory select User Interface Library PanelsDiscardPanel from the Library Tree. Enter tablePanel as PanelHandle and then insert the function call. 20. Save table.c and run the project. Verify that the table panel works properly and the Run Test button adds a row of data to the table. Also, right-click the table to try the built-in pop-up context functions.
2-46
ni.com
Lesson 2
Tree Control
Provides an easy way to visualize hierarchical data, such as files in a directory structure Has built-in functions to search, sort, and select data
Tree Control
Another advanced control in LabWindows/CVI is the tree control. The tree control is a powerful and flexible tool for storing and operating on data that has a parent-child relationship, such as files in a directory. With the tree control, you can easily search and sort data stored in the tree. The tree control uses all of the same functionality as a list box control. This means that you can use list box functions on tree controls. You also can use functions that are specific to tree controls. These functions are located in the Library Tree under User Interface Library Controls/Graphs/Strip ChartsList/Tree (Label/Value) ControlsTrees. The tree control uses a row index to identify items in the tree. The first item in the tree has the row index of zero. The second item in the tree has the row index of one, and so on. The level of the tree item depends on whether the item is a parent, a child, or a sibling. An item that has one or more child items associated with it is called a parent item. A child item always is indented from its parent. Items that are at the same level are considered sibling items. An item that has no parent is a root item and is always at the top of the hierarchy. You can expand or collapse a parent node to display or hide its child items. Select CreateLists & TablesTree to create a tree control in the User Interface Editor. Use the Edit Tree dialog box to add items to the tree and to edit these items.
2-47
Lesson 2
2-48
ni.com
Lesson 2
Exercise 2-6
OBJECTIVE
2-49
Lesson 2
Exercise 2-6
Objective:
Tree Controls
A tree control is a powerful way to organize complex data that is hierarchical in nature. In this project, you will programmatically add items to a tree. The tree in this project allows users to delete items. You can delete only items that do not have any descendents.
2. Add a command button to the main panel that launches the tree panel. Double-click the command button to open the Edit Command Button dialog box. Complete the dialog box as shown in the following table. Constant Name Callback Function Label
SHOWTREE ShowTreePanel Show __Tree
After you create the button, the main panel should be similar to the following figure.
3. Make sure CodeSet Target File is set to <New Window>. Right-click the Show Tree button and select Generate Control Callback.
2-50
ni.com
Lesson 2
4. Create a new panel. Give the panel the constant name TREEPANEL and the panel title Tree Control Panel. Populate the newly created panel with a tree control and command buttons. Create a panel similar to the following figure.
5. Add a tree control to the new panel. Right-click the panel and select Lists & TablesTree. Double-click the tree control to open the Edit Tree dialog box. a. Enter Tree Test as the label of the table. b. Assign the tree control the constant name TREE. 6. Add the Insert Child command button to the panel. Assign the button the constant name INSERTCHILD, the callback function InsertChild, and the label Insert __Child. 7. Add the Insert Sibling command button to the panel. Assign the button the constant name INSERTSIBLING, the callback function InsertSibling, and the label Insert __Sibling. 8. Add the Delete Item command button to the panel. Assign the button the constant name DELETEITEM, the callback function DeleteItem, and the label __Delete Item. 9. Add the Close command button to the panel. Assign the button the constant name CLOSE, the callback function CloseTreePanel, and the label C__lose. 10. Right-click each button and select Generate Control Callback. 11. Access the untitled .c file through the Window menu. Save the new .c file as tree.c. Add the file to the project by selecting FileAdd tree.c to Project. 12. Save the uiproject.uir file.
2-51
Lesson 2
Part B: Code
The tree.c now contains five empty callback functions that require the following modifications. 1. Use LoadPanel to modify the ShowTreePanel function to launch the TREEPANEL. a. Complete the function panel as shown in the following table. Parent Panel Handle Filename Panel Resource ID PanelHandle b. Insert the function call. c. Enter static int treePanel; at the top of the tree.c to store the panel handle for the tree panel. 2. Use InstallPopup to modify the ShowTreePanel function to launch the TREEPANEL. Enter panel handle as treePanel and insert the function call. 3. Enter static int index; at the top of tree.c. Set the value of index equal to 1 in the ShowTreePanel function. The variable index keeps track of the location of the item that is inserted. 4. In the InsertChild callback function, call the InsertTreeItem function. Select User Interface LibraryControls/Graphs/Strip ChartsLists/Tree (Label/Value) ControlsTreesInsertTreeItem and complete the function panel as shown in the following table. When you finish, select CodeInsert Function Call. Panel Handle Control ID Relation Relative Index Position Item Label Tag Base
treePanel TREEPANEL_TREE 0 "uiproject.uir" TREEPANEL treePanel
Child
index
Last
"Child" 0
2-52
ni.com
Lesson 2
0 index
This function inserts an item as a descendent of the item before it. If the item is the first item to be inserted into the tree, the function ignores the Relation parameter and always inserts the item as a parent item. 5. Enter index = index + 1; to increment the value of index by one after the child item is inserted into the tree. 6. In the InsertSibling callback function, call the InsertTreeItem function as you did in step 4. Complete the function panel as shown in the following table and insert the function call. Panel Handle Control ID Relation Relative Index Position Item Label Tag Base Tag Item Value
treePanel TREEPANEL_TREE
Sibling
index
Last
"Sibling" 0 0 index
This function inserts an item at the same level as the last item placed into the tree. If the inserted item is the first to be inserted into the tree, the function ignores the Relation parameter and inserts the item as a parent item. 7. Enter index = index + 1; to increment the value of index by one after the sibling item is inserted into the tree. 8. In the DeleteItem callback function, you want to implement code that deletes only an item that has been selected by the user. Only items that do not have any descendents can be deleted. This step shows how you also can use the list functions to control the tree control.
2-53
Lesson 2
Complete the DeleteItem function using the following steps a. Call GetActiveTreeItem to determine which item the user has selected. Select User Interface LibraryControls/Graphs/Strip ChartsList/Tree (Label/Value) ControlsTrees GetActiveTreeItem and complete the function panel as shown in the following table. When you finish, select CodeInsert Function Call. Panel Handle Control ID Active Index
treePanel TREEPANEL_TREE &active
Enter int active; inside the DeleteItem function to declare active as variable. GetActiveTreeItem returns the location of the item in the tree that the user selects. If the user does not select an item or there are no items in the tree, the function returns 1. b. Test the value of active to make sure that an item exists and that the user has selected an item. To test the value of active, select EditInsert ConstructIf and enter active > 1 for the Condition. Click OK when done. c. In the if statement, call GetTreeItemNumDescendents to determine if the item selected has any descendents. Select User Interface LibraryControls/Graphs/Strip ChartsList/Tree (Label/Value) ControlsTreesGetTreeItemNumDescendents
2-54
ni.com
Lesson 2
and complete the function panel as shown in the following table. When you finish, select CodeInsert Function Call. Panel Handle Control ID Item Index Number of Descendents
treePanel TREEPANEL_TREE active &descendents
Enter int descendents; inside the DeleteItem function. If an item has any descendents, GetTreeItemNumDescendents returns a positive non-zero number. d. To check if the number of descendents is equal to zero, select Edit Insert ConstructIf and enter descendents == 0 for the Condition. Click OK when done. Inside the if statement, call DeleteListItem. This function illustrates how you can use list functions on trees. Select User Interface Library Controls/Graphs/Strip ChartsList/Tree (Label/Value) ControlsDeleteListItem and complete the function panel as shown in the following table. When you finish, select CodeInsert Function Call. Panel Handle Control ID Item Index Number of Items
treePanel TREEPANEL_TREE active 1
e. When the item has been deleted, subtract one from the variable index, since an item has been removed from the tree. To do this, enter index = index - 1; in the if statement. Remember that the variable index indicates where the item needs to be placed into the tree when a child or sibling is inserted into the tree. 9. The CloseTreePanel callback function hides and removes the panel from memory with RemovePopup and DiscardPanel as in the previous exercise. 10. Save tree.c and run the project. Verify that the tree functions correctly. Later in the course you will create a tree control that displays a directory listing of the files on your computer.
2-55
Lesson 2
Intensity Graphs
Useful in displaying terrain and temperature patterns, spectrum analysis, and image processing Use a standard graph control to display the intensity graph Use the PlotIntensity function
Intensity Graphs
You can use intensity graphs to display patterned data such as temperature patterns and terrain. Use the PlotIntensity function with a standard graph control to create an intensity graph. PlotIntensity draws a solid rectangular plot in a graph control. The plot consists of pixels whose colors correspond to the magnitude of data values in a two-dimensional array and whose coordinates correspond to the locations of the same data values in the array. For instance, the pixel associated with zArray[2][3] is located at {x = 3, y = 2}. Use PlotScaledIntensity to apply scaling factors and offsets to the data values.
2-56
ni.com
Lesson 2
a two-dimensional array containing the values to be plotted. Each element in the array is mapped to a specific x-y coordinate in the format:
z[y][x] z[1][2] = 10.0;
At x = 2, y = 1, the color assigned to the value 10 is plotted. Colors are defined in the colorMapArray parameter
Remember that the z-array uses [y][x] values rather than [x][y].
For example, if an array value is given by z[1][2] = 10.0, at x = 2, y = 1, PlotIntensity plots whatever color is assigned to a data value of 10. colorMapArray defines how to translate these data values into color values. It is an array of 255. ColorMapEntry structures that are defined are as follows:
typedef struct { union { char valChar; int valInt; short valShort; float valFloat; double valDouble; unsigned char valUChar;
2-57
Lesson 2
unsigned long valULong; unsigned short valUShort; } dataValue; int color; } ColorMapEntry;
2-58
ni.com
Lesson 2
2-59
Lesson 2
Exercise 2-7
OBJECTIVE
2-60
ni.com
Lesson 2
Exercise 2-7
Objective:
2. Open the intgraph.c file and add it to the project. This file contains a utility function called GenerateData, which generates the data for the intensity graph. Examine this function and how the data is generated. Leave the file open in the Source window. 3. Open the uiproject.uir file. a. Add a command button to the main panel that launches the tree panel. Double-click the command button to open the Edit Command Button dialog box. Complete the dialog box as shown in the following table. Constant Name Callback Function Label
SHOWGRAPH ShowGraphPanel Show __Graph
After you create the button, the main panel should be similar to the following figure.
2-61
Lesson 2
c. Right-click the button and select Generate Control Callback to generate the callback function for the button in the intgraph.c file. 4. Create a new panel that contains the intensity graph. Assign the panel the constant name GRAPHPANEL and the panel title Intensity Graph Panel. Complete the intensity graph as shown in the following figure.
a. Add a graph control to the panel with the constant name INTGRAPH and a label of Intensity Graph. b. Add a command button to the panel with the constant name PLOT, the callback function PlotData, and the label __Plot. c. Add a command button to the panel with the constant name CLOSE, the callback function CloseGraphPanel, and the label __Close. d. Right-click each button and select Generate Control Callback to generate the callback functions in intgraph.c. e. Save and close the uiproject.uir file. 5. Write the three new callback functions. a. Write the ShowGraphPanel callback function to display the GRAPHPANEL panel. Use LoadPanel to load the panel and use InstallPopup to display the panel. Use the variable graphPanel as the Panel Handle for the Intensity Graph Panel. Finally, insert the function call. b. Write the PlotData callback function to call GenerateData and then plot the data with the PlotIntensity function. c. Enter GenerateData(); in the PlotData callback function. d. Select User Interface LibraryControls/Graphs/Strip Charts Graphs and Strip ChartsGraph Plotting and Deleting PlotIntensity and complete the function panel as shown in the
2-62
ni.com
Lesson 2
following table. When you finish, select CodeInsert Function Call. Panel Handle Control ID Z Array Number of X Points Number of Y Points Z Data Type Color Map Array HiColor Number of Colors Interp Colors? Interp Pixels
graphPanel GRAPHPANEL_INTGRAPH dataPoints XPOINTS YPOINTS double precision colors HICOLOR COLORS 1 1
e. Write the CloseGraphPanel callback function to hide and remove the panel from memory using RemovePopup and DiscardPanel function. f. Run the program and test the intensity graph panel. The graph should be similar to the following figure when you click Plot.
6. (Challenge) Write your own data generation function that creates the data and the Color Map Array for the PlotIntensity function.
Lesson 2
2-64
ni.com
Lesson 2
2-65
Lesson 2
2-66
ni.com
Lesson 2
2-67
Lesson 2
2-68
ni.com
Lesson 2
2-69
Lesson 2
Exercise 2-8
OBJECTIVE
2-70
ni.com
Lesson 2
Exercise 2-8
Objective:
To use a predefined custom control to quickly add powerful user interface features to an application. This project shows how you can use a LabWindows/CVI custom control in an application. In the project, you will use the File Browser custom control to add a File Manager to an application. 1. Create a new project in LabWindows/CVI and save the project as
C:\Exercises\CVI Basics II\Lesson 2\ CustomControl.prj.
2. Create a new user interface file by selecting FileNewUser Interface (*.uir). 3. Change the panel title to File Manager. 4. Build the following user interface, which contains a command button and a File Browser custom control.
a. Place a QUIT button on the panel by selecting CreateCustom ControlsQuit Button. b. Place a File Browser on the panel by selecting CreateCustom ControlsToolslib ControlsFile Browser. Double-click the File Browser control to open the Edit Tree dialog box. Change the Label to File Manager. 5. Save the user interface as CustomControl.uir. 6. Generate the code for the user interface by selecting CodeGenerate All Code. In the Target Files section of the Generate All Code dialog box, select Add to Current Project. Verify that the source filename is CustomControl.c. Confirm that PANEL is checked in the Select panels to load and display at startup section of the dialog box.
2-71
Lesson 2
Confirm that QuitCallback is selected in the Select QuitUserInterface Callbacks box. Click OK. 7. LabWindows/CVI generates code for the user interface. Look at the main function in CustomControl.c. Notice that CodeBuilder inserted a call to FileBrowser_Create below the LoadPanel function. The FileBrowser_Create function converts the tree control into a File Browser. You can add a custom control to a pre-built user interface. In order to generate code for the custom control, right-click the custom control and select Generate Custom Control Code from the context menu.
Note
8. Run the project. 9. When you finish the project, save and close all files.
2-72
ni.com
Lesson 2
2-73
Lesson 2
This function creates a new toolbar on the specified panel at the position specified by top and left. menuBar is the menu handle associated with the toolbar, if any. newToolbar is the toolbar handle for the new toolbar (passed by reference). The Toolbar_Display function displays the toolbar. If the toolbars parent panel is not visible, the toolbar does not appear until the parent is displayed. To set a particular toolbar item value, use Toolbar_SetItemVal. The following function adds items to the toolbar:
int Toolbar_InsertItem (ToolbarType toolbar, int position, int itemType, int active, const char *description, int callbackType, int menuItem, CtrlCallbackPtr controlCallbackFunction, void *callbackData, const char *imageFile);
toolbarThe handle returned from Toolbar_New. positionSpecifies where in the toolbar the button is placed, relative to other buttons.
2-74
ni.com
Lesson 2
itemTypeThe control type of the item, which can be a command button, toggle button, separator, or ring. activeSpecifies whether the item is visible. descriptionA string describing the button. This string appears when the user holds the mouse cursor over the given button. callbackTypeSpecifies the type of callback function associated with the toolbar item like control callback, menu callback, or no callback. menuItemThe Control ID for the menu item that the button is associated with if callbackType is set to menu callback. Otherwise, this parameter is ignored. controlCallbackFunctionThe name of the control callback executed when an event occurs on the button if callbackType is set to control callback. callbackDataA pointer to user-defined data. imageFileThe filename, including any path, of the image for the button.
2-75
Lesson 2
Exercise 2-9
OBJECTIVE
2-76
ni.com
Lesson 2
Exercise 2-9
Objective:
Toolbars
In this exercise, you will use a LabWindows/CVI built-in instrument driver to add toolbar functionality to the user interface of your application. Adding toolbar icons provides flexibility and ease-of-use to the end user. 1. Load the uiproject.prj file located in the directory
C:\Exercises\CVI Basics II\Lesson 2\uiproject.prj.
2. To load the toolbar instrument driver, right-click the Instruments tree and select Load Instrument. In the Load Instrument dialog box, navigate to C:\Program Files\National Instruments\ CVI\toolslib\custctrl and double-click toolbar.fp. 3. Declare a handle for the toolbar as a global variable at the top of uiproject.c with static ToolbarType hToolbar; 4. In the main function, use Toolbar_New to create the toolbar. Add Toolbar_New after your call to LoadMenuBar. From the Library Tree, select InstrumentsToolbarToolbar functionsNew and complete the function panel as shown in the following table. When you finish, select CodeInsert Function Call. Parent Panel Menu Bar Title Top Left Conform Bitmap Colors Conform to System New Toolbar
mainPanel hMenu "Search Toolbar" 0 0
Yes Yes
&hToolbar
Note Remember that hMenu was declared in Exercise 2-3. The toolbar functions can use the existing callback functions that are defined with the menu for toolbar callbacks. This is the reason for specifying the Menu Bar parameter when you create a new toolbar.
5. Add the toolbar items. The toolbar shows five buttons and two separators as shown in the following figure.
2-77
Lesson 2
a. Make sure that CodeSet Target File is set to uiproject.c. To create the Open File button, select InstrumentsToolbarToolbar Item FunctionsInsertItem and complete the function panel as shown in the following table. Toolbar Position Description Active Item Type Callback Type Menu Item Control Callback Function Callback Data Image File
hToolbar 1 "Open Text File"
b. Select CodeInsert Function Call to add the function into the source code. Using the preceding information as a template, add the rest of the items to the toolbar with the same function. The necessary changes to the arguments are listed in the following tables. Save File button Position Description Menu Item Image File First Separator Position Description
3 "" 2 "Save Text File" MENU_FILE_SAVE "buttons\\save.pcx"
2-78
ni.com
Lesson 2
Item Type Callback Type Menu Item Image File Find button Position Description Item Type Callback Type Menu Item Image File Case Sensitivity button Position Description Item Type Menu Item Image File Second Separator Position Description Item Type Callback Type Menu Item Image File
Separator No Callback
0 ""
4 "Find"
5 "Case Sensitivity"
Toggle Button
MENU_SEARCH_CASE "buttons\\case.bmp"
6 ""
Separator No Callback
0 ""
2-79
Lesson 2
Terminate Program button Position Description Item Type Callback Type Menu Item Image File
7 "Terminate Program"
6. To display the toolbar, from the Library Tree, select Instruments ToolbarToolbar functionsDisplay. Pass hToolbar to the function. 7. To toggle the case sensitivity button, insert the following function in the SetCaseSensitivity function:
Toolbar_SetItemVal (hToolbar, 5, CaseSensitive);
8. Save and run the program. When LabWindows/CVI prompts you to add the necessary include file at the top of the file, select Yes. Verify that the toolbar is present and functions properly.
2-80
ni.com
Lesson 2
2-81
Lesson 2
Summary Lesson 2
Lesson 2 describes several user interface features that enhance standard LabWindows/CVI GUI application development. User interface features Attributes Menus Canvas controls Table controls Tree controls Intensity graphs User-defined custom controls Predefined custom controls Remember that you can create your own custom controls.
Summary Lesson 2
After completing the exercises in this lesson, you are now familiar with a wide assortment of user interface featuresattribute programming, menus, custom controls, and other user interface objects. The purpose of the lesson is not only to help you learn about these user interface features but also to help you become more familiar with LabWindows/CVI user interface programming style. The LabWindows/CVI programming methodology is consistent, which helps you move from user interface programming to instrumentation-based programming quickly.
2-82
ni.com
Lesson 2
Notes
2-83
Lesson 2
Notes
2-84
ni.com
A. B. C. D.
Controlling software servers through ActiveX Automation Transferring live data through DataSocket Interfacing with LabVIEW Communicating over a network through TCP
Introduction
In interapplication communication, concurrently running applications communicate with each other. Communication involves sharing data or higher-level tasks such as initiating actions in other applications, sending events, and so on. In this lesson, you will learn about popular technologies used to implement interapplication communication, including ActiveX Automation, TCP, and DataSocket. You also will learn how to use ActiveX Automation to extend the functionality of an application by reusing code from a separate application that implements the desired functionality. This chapter describes in brief Microsofts ActiveX technology. Complete description of the ActiveX technology is beyond the scope of this course.
3-1
Lesson 3
ActiveX Technologies
ActiveX is a set of technologies that uses the Microsoft Component Object Model (COM) ActiveX technologies include ActiveX controls in containers ActiveX documents ActiveX Automation
ActiveX Technologies
ActiveX technologies are a diverse set of technologies based on the Microsoft Component Object Model (COM). The COM standard allows developers to create code and applications from many different languages and build a defined interface to that code, making the code easily accessible to other applications. An application can access another applications functionality through standard interfaces. The following list presents common ActiveX technologies: ActiveX ControlsA control is an object that resides on a panel to accept input from the user and to display information. ActiveX controls are components external to LabWindows/CVI, which can be used in the same way as built-in LabWindows/CVI controls. ActiveX controls vary in the functionality they provide. For example, an ActiveX control might store and manipulate different types of data for word processing and report generation, for mathematical calculations, or to access the internet. An application that houses an ActiveX control is called the control container. The control container communicates with the control through methods and properties. Thus, you can use Interactive objects, such as the calendar control, in containers, such as Web browser. ActiveX DocumentsEnable users to view documents, such as Microsoft Word documents or Excel spreadsheets, in an ActiveX container, such as a LabWindows/CVI panel. ActiveX AutomationUse of one applications code/functionality, in the form of methods and properties inside an exported object, from inside another application.
3-2
ni.com
Lesson 3
Client-Server Relationship
The application and the component have a client-server relationship. The application acts as a client that uses the component services.
3-3
Lesson 3
Type Library
To create and access objects, automation clients need information about a server objects, properties, and methods. Often, properties have data types, and methods return values and accept parameters. The documentation of the server application contains extensive information about the exposed objects, methods, and properties. A list of exposed objects is provided in the application type library. A type library contains specifications for all objects, methods, or properties exposed by an automation server. The type library file usually has a .tlb filename extension. When LabWindows/CVI acts as an ActiveX client, it uses information in the servers type library to generate wrapper code that can be used to control the server. This wrapper code is organized as a LabWindows/CVI instrument driver. Interfaces A COM interface is a group of related functions that forms the means of communication between a client and a server.
3-4
ni.com
Lesson 3
Server A Step 3. instantiates Object 2 Step 2. interfaces with Type Lib 2 Server B Object Step 3. instantiates
3-5
Lesson 3
Automation
ActiveX Server
(LabWindows/CVI)
ActiveX Control
(component controls)
Containment
ActiveX Container
(Visual C++, LabVIEW, LabWindows/CVI)
3-6
ni.com
Lesson 3
3-7
Lesson 3
3-8
ni.com
Lesson 3
3-9
Lesson 3
Exercise 3-1
OBJECTIVE
3-10
ni.com
Lesson 3
Exercise 3-1
Objective:
1. Load the 3DGraph.prj file located in the directory C:\Exercises\ CVI Basics II\Lesson 3\3DGraph.prj. 2. Run the example and try changing the graph settings and the graph style. Click Quit when you finish. 3. Open the 3DGraph.c file and look at the code associated with the 3D Graph ActiveX control. Look at the call to GetObjHandleFromActiveXCtrl. This function gets a handle that is used to reference the ActiveX control. The functions that start with CW3DGraphLib are located in the National Instruments CW 3D Graph 6.0 library. 4. To access the CW3DGraph functions, select InstrumentsNational Instruments CW 3D Graph 6.0 from the Library Tree. Notice how this instrument driver is structured in the same way as other libraries in the Library Tree.
3-11
Lesson 3
5. Open 3DGraph.uir. Double-click the 3D Graph control to open the Edit ActiveX Control dialog box. You can use the Edit ActiveX Control dialog box to edit the features of an ActiveX control.
3-12
ni.com
Lesson 3
ActiveX Automation
With ActiveX Automation, you can
Create applications that expose objects (automation servers) Create and control objects exposed in an automation server application from another application (automation clients)
ActiveX Automation
In ActiveX Automation, one application acts as the server, and the other application acts as a client. The server exposes methods (actions) and properties (data) that a client can control and change. For example, a spreadsheet application can be an automation server. An automation server might expose objects, such as charts, ranges of cells, and so on, with methods to get and set these objects properties. An automation client creates and controls objects exposed by the server application. For example, a LabWindows/CVI program can launch Excel and open existing spreadsheets. A class defines the type of properties and methods contained in an object. An ActiveX Automation object is an instance of a class that exposes properties, methods, and events to ActiveX clients. An automation object can have both methods and properties. For example, the methods of a Windows object are actions, such as restore, minimize, and maximize, which you can perform using a Windows control menu. The properties, such as height and width, describe the appearance of the window.
3-13
Lesson 3
Automation Server
Defines and exposes automation objects
Type Library
Describes servers objects to the automation clients
3-14
ni.com
Lesson 3
3-15
Lesson 3
Lesson 3
Wizard-Generated Functions
The instrument functions that the wizard creates contain calls to the functions in the LabWindows/CVI ActiveX Library with appropriate arguments based on the information in the type library of the automation server. For each top-level object, the wizard generates the necessary functionsNew to create a new object, Open to open an object from a file, and Active to get a handle to an existing object. The other objects are created by calling the methods of top-level objects. At least one top-level object must be initially created/referenced in the client object. Use the GetProperty, SetProperty, and SetPropertyByRef functions to get/set the server properties. To create the client application, use the functions that the wizard generates in combination with other LabWindows/CVI functions, especially those in the LabWindows/CVI ActiveX Library.
ActiveX Functions
ActiveX Automation uses specially defined data types to handle data so that the data is compatible with different programming environments. These data types are different from the ANSI C data types. The LabWindows/CVI ActiveX Library provides functions to convert between the two kinds of data types. The ActiveX Library also contains functions to handle the error information, if any, returned by the automation server. The ActiveX Library contains low-level functions that you can use instead of the wizard-generated functions or for special circumstances.
3-17
Lesson 3
The LabWindows/CVI ActiveX Library contains functions for converting between these and ANSI C data types Usually, the wizard-generated functions accept C data types and internally convert them for you
Automation Data Types
Because automation clients and servers can be written in a number of programming languages, it is necessary to use consistent data types when transferring data between clients and servers. Automation defines three special data types:
VARIANTCan contain any other automation data type. Basically, a VARIANT is a union of all
When using the ActiveX Library functions or the wizard-generated functions, you might need to send/receive data in one of the preceding data types. This action requires you to handle these data types and convert between these data types and C data types. You can use functions in the LabWindows/CVI ActiveX Library to perform these conversions. The library has VARIANT-related functions, SAFEARRAY-related functions, and BSTR-related functions. For example, to convert a C string to a BSTR, call the CA_CStringToBSTR function as follows:
status = CA_CStringToBSTR (cStr, &bStr);
3-18
ni.com
Lesson 3
Low-level functions
Creating, getting, and loading objects Calling methods and properties
3-19
Lesson 3
Exercise 3-2
OBJECTIVE
3-20
ni.com
Lesson 3
Exercise 3-2
Objective:
You can load an ActiveX control on the panel by right-clicking the panel and selecting ActiveX. Then, select the ActiveX object from the Select ActiveX Object dialog box and click OK.
Note
a. Double-click the Windows Media Player container to open the Edit ActiveX Control dialog box. All ActiveX properties can be manipulated in this dialog box. Make the Constant Name of the control MEDIAPLAYER and the Label Media Player. You can turn off the controls that are displayed on the Media Player by scrolling through the properties list. For now, set ShowControls to False. Notice that the Quick Edit Window shows how the object will
3-21
Lesson 3
appear without the controls. Click OK to exit the Edit ActiveX Control dialog box. b. Add three command buttons and complete the Edit Command Button dialog box as indicated in the following table. Button Name Constant Name Callback Function Control Mode Label
Note PLAY playMovie WHICHPLAYER whichPlayer QUIT quit
Hot
__Play Movie
Hot
__Which Player?
Hot
__Quit
You can use EditCopy and Paste to create the second and third buttons. Resize a button by dragging its corner. c. Save the user interface file. d. Generate the code for the user interface by selecting Code GenerateAll Code. e. Complete the Generate All Code dialog box as shown in the following figure and click OK.
3-22
ni.com
Lesson 3
When you click OK, LabWindows/CVI launches the ActiveX Controller Wizard. Use the ActiveX Controller Wizard to create an instrument driver for the ActiveX server. Click Compatibility Options. Set Property Access Functions to be Per Property and click OK. Click Next until the instrument driver is created. Finally, click the Close button. f. LabWindows/CVI generates the file container.c. In the main function before the panel is displayed, it is necessary to get the object handle from the ActiveX control on the panel. From the Library Tree, select User Interface Library Controls/Graphs/Strip ChartsActiveX Controls GetObjHandleFromActiveXCtrl. Complete the function panel as shown in the following table and insert the function call. Panel Handle Control ID
panelHandle PANEL_MEDIAPLAYER
3-23
Lesson 3
panelHandle &playerHandle
Declare playerHandle as a static global variable of type CAObjHandle at the top of container.c.
g. Clicking the Play Movie button prompts the user for an MPEG file to be played in the Windows Media Player. The following instructions show you how to add the code for the playMovie callback function. The final playMovie callback function appears as the following code.
The first function asks the user for a path to a file that will be displayed in the Windows Media Player. Place your cursor inside the playmovie callback function. From the Library Tree, select User Interface LibraryPop-up PanelsFile/Directory Popups FileSelectPopup. Complete the function panel as shown in the following table and insert the function call.
3-24
ni.com
Lesson 3
Default Directory Default File Spec File Type List Title Button Label Restrict Directory? Restrict Extension? Allow Cancel? Allow Make Directory? Path Name Selection Status
load no no yes no
path
Declare the path variable within the playMovie function as a character string with length MAX_PATHNAME_LEN. From the Library Tree, select InstrumentsWindows Media PlayerIMediaPlayer2IMediaPlayer2SetFileName. Complete the function panel as shown in the following table and insert the function call. Object Handle Error Info Pbstr File Name
playerHandle NULL path
h. Pressing the Which Player? button opens the About dialog box for the Windows Media Player. The following instructions show you how to add the code for the whichPlayer callback function. The final whichPlayer callback function appears in the following code.
3-25
Lesson 3
Place your cursor inside the whichPlayer callback function. From the Library Tree, select InstrumentsWindows Media Player IMediaPlayer2IMediaPlayer2AboutBox and complete the function panel as shown in the following table and insert the function call. Object Handle Error Info
playerHandle NULL
i. Clicking the Quit button discards the ActiveX object handle and closes the application. Place your cursor inside the quit callback function. From the Library Tree, select ActiveX LibraryResource ManagementDiscardObjHandle to open the CA_DiscardObjHandle function. Pass playerHandle to the function. j. Save and run the program. If prompted to add necessary include statements to the top of the file, select Yes.
Note Newer versions of Windows Media Player may have different ActiveX methods and properties.
3-26
ni.com
Lesson 3
Exercise 3-3
OBJECTIVE
To create a LabWindows/CVI ActiveX client application that controls Microsoft Internet Explorer
3-27
Lesson 3
Exercise 3-3
Objective:
To create a LabWindows/CVI ActiveX client application that controls Microsoft Internet Explorer. In this exercise, you will create an ActiveX client that launches Microsoft Internet Explorer, loads a Web page in the browser, and closes the browser all through a LabWindows/CVI application. This exercise shows the power of ActiveX technologies. In the Web browser, an ActiveX client displays the data that is acquired or processed in LabWindows/CVI.
1. Open IE.prj located in the directory C:\Exercises\CVI Basics II\Lesson 3\IE.prj. 2. The GUI and the skeleton code have been built for you. Open IE.uir and study the controls. IE.c contains the skeleton code generated using CodeBuilder. 3. First, create an instrument driver for the Internet Explorer ActiveX server. a. Select ToolsCreate ActiveX Controller to open the ActiveX Controller Wizard screen, which you use to generate an instrument driver for an ActiveX server. b. Click Next. The wizard searches for all registered ActiveX servers on your computer. Select Microsoft Internet Controls from the list as shown in the following figure. Click Next.
3-28
ni.com
Lesson 3
c. On the ActiveX Controller Wizard Configure panel, leave the Instrument Prefix as SHDocVw. To create internet.fp, set Target .fp File to C:\Exercises\CVI Basics II\Lesson 3\ internet.fp. Make sure that the Add .fp File To Project option is enabled. d. Click the Compatibility Options button. Set Property Access Functions to Per Server. Selecting the Per Server option generates a single GetProperty and SetProperty function through which all get and set properties are accessed for the server. Click OK. e. Select As automation server objects for How will you be using ActiveX controls and document objects from this server?. This option determines whether the object creation functions support the placement of controls and document objects on panels. f. Click Next. g. On the ActiveX Controller Wizard Advanced Options panel, click the Advanced Options button. The ActiveX Controller Advanced Options dialog box allows you to select the objects to generate in the type library.
3-29
Lesson 3
h. Deselect all objects except IWebBrowser2. Your screen will look like the following figure.
i. Click OK. Then click Next. The ActiveX Controller Wizard generates only the methods needed for this application. j. The instrument driver has been created for accessing the Internet Explorer ActiveX server. Close the ActiveX Controller Wizard. 4. Clicking the Launch button opens Internet Explorer. Complete the following instructions to add code for the Launch callback function. The following figure shows the final Launch callback function.
3-30
ni.com
Lesson 3
a. Open the IE.c. Place your cursor in the Launch callback function. b. Use InternetExplorerIWebBrowser2 to create a new Internet Explorer browser object and obtain a handle to the object. Select InstrumentsMicrosoft Internet ControlsIWebBrowser2New InternetExplorerIWebBrowser2 from the Library Tree. Complete the function panel as shown in the following table and insert the function call. Server Support Multithreading Locale Reserved Object Handle
NULL 1 LOCALE_NEUTRAL 0 &IEHandle
Declare IEHandle, which is a CAObjHandle, at the top of IE.c, as follows: static CAObjHandle IEHandle; c. Use the SHDocVwSetProperty function to make the newly allocated Internet Explorer browser visible. Place your cursor below the NewInternetExplorerIWebBrowser2 function and select InstrumentsMicrosoft Internet ControlsSetProperty from the Library Tree. Complete the function panel as shown in the following table and insert the function call. Object Handle Error Info Property ID Property Type Value
IEHandle &error
Visible CAVT_BOOL
VTRUE
3-31
Lesson 3
Enter the static ERRORINFO error; variable in the Launch callback function. 5. Clicking the Load Web Page button prompts the user to select an HTML file. Complete the following instructions to add the code for the Load callback function. The following figure shows the final Load callback function.
a. The first function asks the user for a path to a file to display in the Web browser. Place your cursor in the Load callback function. Select User Interface LibraryPop-up PanelsFile/Directory PopupsFileSelectPopup from the Library Tree. Complete the function panel as shown in the following table and insert the function call. Default Directory Default File Spec File Type List Title Button Label Restrict Directory? Restrict Extension? Allow Cancel? Allow Make Directory? Path Name Selection Status
"" "*.html" "" "Select a Web Page"
load No No Yes No
path
3-32
ni.com
Lesson 3
Enter char path [MAX_PATHNAME_LEN]; in the Load callback function. b. Add a function to convert the path returned from FileSelectPopup into a VARIANT that can understand by the ActiveX server. A CA_VariantSetCString converts a string to a VARIANT. Place your cursor below the FileSelectPopup function and select ActiveX LibraryVariant Related Functions Assigning Values to VariantsVariantSetCString from the Library Tree. Complete the function panel as shown in the following table and insert the function call. Variant Value
&pathToVariant path
Enter the VARIANT pathToVariant; variable within the Load callback function. c. After determining the path to the file and converting the path to a VARIANT, you can pass the path to the ActiveX server to navigate to that location. Place your cursor below the VariantSetCString function and select InstrumentsMicrosoft Internet Controls IWebBrowser2IWebBrowser2Navigate2 from the Library Tree. Complete the function panel as shown in the following table and insert the function call. Object Handle Error Info URL Flags Target Frame Name Post Data Headers
IEHandle &error pathToVariant CA_DEFAULT_VAL CA_DEFAULT_VAL CA_DEFAULT_VAL CA_DEFAULT_VAL
Declare error as a ERRORINFO variable within the Load function. 6. Clicking the Back button loads the previous Web page (if any). Place your cursor within the Back callback function and select Instruments Microsoft Internet ControlsIWebBrowser2 IWebBrowser2GoBack from the Library Tree. Now, enter IEHandle as the Object Handle and insert the function. Remember that it is always a good practice to discard any ActiveX objects that have been created in a program to reduce the potential of any memory leaks in your application.
Note
3-33
Lesson 3
Tip
Set IEHandle as a parameter for the Object Handle for steps 7 and 8. 7. Clicking the Close button closes and exits the browser application without quitting the program. a. Use the SHDocVw_IWebBrowser2Quit function, located in InstrumentsMicrosoft Internet ControlsIWebBrowser2 IWebBrowser2Quit, to create this functionality. b. It is very important to discard the object handle using the CA_DiscardObjHandle function. You can access this function by selecting ActiveX LibraryResource Management DiscardObjHandle from the Library Tree. After you discard the object handle, set IEHandle to 0. 8. Clicking the Quit button closes the program. If the browser application is still running, close the application and discard the handle before quitting the program. Include an if condition by selecting EditInsert ConstructIf. Insert IEHandle!=0 in the Condition field of the If dialog box. .
Tip You can determine if the browser is still running by checking if IEHandle is not set to 0. Remember that it is necessary to explicitly set IEHandle to 0 when the handle has been discarded.
9. Save the program. If prompted to add a necessary include statement, click Yes. 10. Open the program and load ieExercise.html from the C:\Exercises\CVI Basics II\Lesson 3 directory. Make sure everything works as expected.
3-34
ni.com
Lesson 3
3-35
Lesson 3
3-36
ni.com
Lesson 3
Create and modify objects and interfaces in your ActiveX server Part of the initial server creation process Can update server settings anytime
3-37
Lesson 3
Exercise 3-4
OBJECTIVE
3-38
ni.com
Lesson 3
Exercise 3-4
Objective:
7. Click the Launch Server button to launch the server and enable the Server Visibility option to see the server. 8. Manipulate the controls on the server application to see the server functionality. Quit and close the server client when you finish.
Note simpleEXE.prj creates and registers an ActiveX server with the name simpleEXE. This server can be called from any ActiveX client application, which can
be created with LabVIEW, Microsoft Visual Basic, Visual C++, and other compatible compilers.
3-39
Lesson 3
DataSocket Technology
DataSocket Technology
Many instrumentation solutions involve a single local application for acquisition, logging, analysis, and presentation. However, because of the rise in popularity of the Internet and company Intranets and the need to monitor and control your data acquisition remotely, you often need to exchange live data with other applications on different computers around the world. DataSocket simplifies live data exchange between different applications on one computer or between computers connected through a network. A variety of different technologies, including TCP/IP and Dynamic Data Exchange (DDE), exist today to share data between applications, but most of these tools are not targeted for live data transfer to multiple clients. With TCP/IP, you must convert your data into an unstructured stream of bytes in the broadcasting application and then parse the stream of bytes back into its original format in subscribing applications. DataSocket, however, simplifies live data transfer. DataSocket implements an easy-to-use, high-performance programming interface designed specifically to share and publish live data in measurement and automation applications. In addition, DataSocket features interapplication connectivity, rich data types, and security to make sharing data easy.
3-40
ni.com
Lesson 3
DataSocket Features
Live data transfer Multiple clients One high-level API for different source types Avoids the burden of parsing DataSocket Server manages networking URL to specify connection
DataSocket Features
DataSocket is a single, unified, end-user Application Programming Interface (API) for connecting to data from a number of sourceslocal files, files on FTP or Web servers, and data items on OPC servers. To specify data locations, a DataSocket application uses a familiar networking standard, the URL. Just as a Web browser uses a URL to connect to a Web page, a DataSocket application uses a URL to connect to data. By using an industry-standard URL, you can quickly bring data into or share data from your DataSocket applications. In addition, the DataSocket Transfer Protocol connects a DataSocket application to live data by specifying a connection to a DataSocket Server. The DataSocket Server, a lightweight, stand-alone component, manages most of the networking tasks for you. With the DataSocket Server programs using DataSocket, you can broadcast live measurement data at high rates across the Internet to multiple remote clients concurrently. These client applications use DataSocket to subscribe to the live measurement data. Because the DataSocket Server is a stand-alone component, it simplifies network (TCP/IP) programming by automatically managing connections to clients and automatically converting your measurement data to and from the stream of bytes sent across the network. You do not need to write the parsing code. The DataSocket Server can run on any machine on your network, which improves performance and provides security by isolating the Web connections from your acquisition application.
3-41
Lesson 3
Data attributes
Transfer data properties Can be easily configured/modified Avoids user parsing
3-42
ni.com
Lesson 3
Main functions
DataSocket API
DS_Open DS_OpenEx DS_DiscardObjHandle DS_GetDataType DS_GetDataValue DS_Update DS_SelectURL DS_FreeMemory DS_GetLibraryErrorString
DataSocket API
The DataSocket API contains the following functions: Main functionsFunctions that open and discard handles to connections, get/set data values, browse and select URLs, free resources, and update the connection. These are the functions you need for most applications. Attribute functionsFunctions that you use to work with data attributes. Use these functions when you associate attributes, such as time-stamping data, information about physical units, and so on. Status functionsFunctions that provide status information about the DataSocket connection. Local Server Control functionDS_ControlLocalServer. Programmatically launch, display, hide, and close the DataSocket Server on the local machine. Polling Queue functionsFunctions that you use to get and set properties of DataSocket polling queues. Currently, only the DataSocket Transfer Protocol (DSTP) supports polling.
3-43
Lesson 3
3-44
ni.com
Lesson 3
3-45
Lesson 3
Exercise 3-5
OBJECTIVE
To create DataSocket writer and reader applications to write/read a DSTP data entity
3-46
ni.com
Lesson 3
Exercise 3-5
Objective:
To create DataSocket Writer and Reader applications to write/read a DSTP data entity.
DSConst_WriteAutoUpdate
NULL NULL
Event Model
DSConst_Asynchronous &dsHandle
Declare dsHandle as a global DSHandle variable to use for the DataSocket handle. 4. When you click the DISCONNECT button, the application disconnects from the DSTP target. Create this functionality by adding the DS_DiscardObjHandle function to the disconnectCB callback function. Select DataSocket LibraryDiscardObjHandle and enter dsHandle as the DS Handle parameter. Insert the function call when you are done. 5. When you change the value of the Writer control, the application sends a COMMIT event to the valueCB function. When this event occurs, get the value from the numeric control by adding the GetCtrlVal function to the valueCB callback function. From the Library Tree, select User Interface LibraryControls/Graphs/Strip ChartsGeneral
3-47
Lesson 3
FunctionsGetCtrlVal. Complete the function panel as shown in the following table and insert the function call into your source code. The variable value has already been declared to store the value from the numeric control. Panel Handle Control ID Value
panelHandle PANEL_VALUE &value
6. Pass value to DS_SetDataValue to update the value on the DataSocket server. Select DataSocket LibrarySetDataValue and complete the function panel as shown in the following table. DS Handle Type Value Dimension 1 Dimension 2
dsHandle
double
&value 0 0
7. Start the DataSocket server by selecting StartAll ProgramsNational InstrumentsDataSocketDataSocket Server. 8. Build and run the project. When you click the CONNECT button, the number of connections on the DataSocket server increments by 1, and when you click the DISCONNECT button, the number decrements by 1 (if greater than zero). 9. Create a release executable of this project, and name it dsWriter.exe. To create the release executable, select BuildConfigurationRelease and then select BuildCreate Release Executable.
3-48
ni.com
Lesson 3
DataSocket LibraryOpenEx and complete the function panel as shown in the following table. URL Access Mode Event Function Callback Data Execution Model Timeout DS Handle
dstp://localhost/value
DSConst_ReadAutoUpdate
DataSocketEvent NULL
Event Model
DSConst_Asynchronous &dsHandle
Declare dsHandle as a global DSHandle variable to use for the DataSocket handle. 4. Create a DataSocketEvent function. You must write this function to handle the events from the DataSocket connection. First insert the following function prototype at the top of the file below the global variables.
void DataSocketEvent (DSHandle dsHandle, int event, void *CallbackData);
At the bottom of the file, create the function shown in the following figure. You will complete the code for this function later in this exercise.
a. When the value of the data source changes, the DataSocket callback function (DataSocketEvent) is called with the DS_EVENT_DATAUPDATED event. Insert a switch statement in the DataSocketEvent callback to handle this event, as shown in the previous figure. b. To retrieve the value on the DataSocket server, insert DS_GetDataValue. From the Library Tree, select DataSocket LibraryGetDataValue and complete the function panel as shown in the following table.
3-49
Lesson 3
dsHandle
double
&value sizeof(double) NULL NULL
Declare the variable value as type double in the function DataSocketEvent. c. Display the value in the Reader control on the GUI. From the Library Tree, select User Interface Library Controls/Graphs/Strip ChartsGeneral FunctionsSetCtrlVal. Complete the function panel as shown in the following table and insert the function call into your source code. Panel Handle Control ID Value
panelHandle PANEL_VALUE value
5. When you click the DISCONNECT button, the application disconnects from the DSTP target. Call DS_DiscardObjHandle in the disconnectCB callback function to perform this action. Select DataSocket LibraryDiscardObjHandle and enter dsHandle as the DS Handle parameter. 6. Run the DataSocket server and the dsWriter.exe applications if they are not running. Connect the server to the dsWriter application. Now build and run the dsReader.prj project and connect to the server. The number of connections on the DataSocket Server increments by 1. Now change the value of the Writer control on the DATASOCKET WRITER panel. The value displayed on the DATASOCKET READER panel updates to show the current value. 7. (Challenge) If you click the DISCONNECT button more than once, you receive an error. Develop error handling code to prevent the application from crashing. When you click CONNECT or DISCONNECT, the callback function that responds to the event you generate creates or discards DataSocket object, respectively. If you click CONNECT or DISCONNECT repeatedly, you will change the number of connections on DataSocket Server only once because the callback function always refer to the same DataSocket object.
Note
3-50
ni.com
Lesson 3
DataSocket Binding
Codeless DataSocket communication Available with:
Numeric controls Text box controls Strip charts Graphs Tables String controls
DataSocket Binding
LabWindows/CVI allows you to quickly publish and subscribe data on a DataSocket Server without having to write any code. Using this feature, you can easily transfer data between applications and platforms. DataSocket Binding is available with numeric controls, text box controls, string controls, strip charts, graphs, and tables. To enable DataSocket Binding, double-click the control and click the DataSocket Binding button in the Edit Control dialog box. In the DataSocket Binding dialog box you can enable the binding, specify the location of the data, and specify whether the control is a data publisher or subscriber.
3-51
Lesson 3
Exercise 3-6
OBJECTIVE
To create a DataSocket writer and reader application that uses DataSocket binding
3-52
ni.com
Lesson 3
Exercise 3-6
Objective:
To create a DataSocket Writer and Reader application that uses DataSocket Binding.
a. Double-click the panel and enter DSWPANEL for the Constant Name and DataSocket Writer for the Panel Title. Click OK. b. Add a dial to the panel by right-clicking in the panel and selecting NumericDial. c. Double-click the dial to open the Edit Numeric Dial dialog box and enter Data to Write as the Label. d. Click the DataSocket Binding button. Select the Enable Data Binding checkbox and complete the dialog box as shown in the following table. Server Connection Type
dstp://localhost/data
Write
e. Click OK when done. Then click OK again to exit the Edit Numeric Dial dialog box.
3-53
Lesson 3
f. Add a command button to the panel. Double-click the command button to open the Edit Command Button dialog box. Make the constant name of the control QUIT, the callback function quit, and the label __Quit. 5. Save the user interface as DSBWriter.uir. 6. Select FileAdd DSBWriter.uir to Project. 7. Select CodeGenerateAll Code. 8. In the Generate All Code dialog box, select Add to Current Project in the Target Files section. Select quit in the Select QuitUserInterface Callbacks section. Click OK to generate the code. 9. Create a release executable of this project and save it as DSBWriter.exe. To create the release executable, select Build ConfigurationRelease and select BuildTarget TypeExecutable. Then, select BuildCreate Release Executable.
a. Double-click the panel and enter DSRPANEL for the Constant Name and DataSocket Reader for the Panel Title. Click OK when done.
3-54
ni.com
Lesson 3
b. Add a strip chart to the panel by right-clicking the panel and selecting GraphStrip Chart. c. Double-click the strip chart to open the Edit Strip Chart dialog box. Make the label Data to Read. d. Click the Y-axis button and change the Minimum to -10 and the Maximum to 10. Click OK. e. Click the DataSocket Binding button. Select the Enable DataBinding checkbox and complete the dialog box as shown in the following table. Server Connection Type
dstp://localhost/data
Read
f. Click OK when done. Then click OK again to exit the Edit Strip Chart dialog box. g. Add a command button to the panel. Double-click the command button to open the Edit Command Button dialog box. Make the constant name of the control QUIT, the callback function quit, and the label __Quit. Then click OK. 5. Save the user interface as DSBReader.uir. 6. Select FileAdd DSBReader.uir to Project. 7. Select CodeGenerateAll Code. 8. In the Generate All Code dialog box, select Add to Current Project in the Target Files section. Select quit in the Select QuitUserInterface Callbacks section. Click OK to generate the code. 9. Create a release executable of this project and save it as DSBReader.exe. To create the release executable, select Build ConfigurationRelease and select BuildTarget TypeExecutable. Select BuildCreate Release Executable.
Part C: Test
1. Run the DataSocket server if it is not running. 2. Run the DSBWriter.exe application and the DSBReader.exe application. 3. Rotate the dial on the DataSocket Writer panel. Notice that the strip chart plots the value of the dial when the dial value changes.
3-55
Lesson 3
3-56
ni.com
Lesson 3
OBJECTIVE
3-57
Lesson 3
Exercise 3-7
Objective:
To use the Convert CVI .FP File utility in LabVIEW to convert a LabWindows/CVI instrument driver for use in LabVIEW.
Note This Exercise will work if LabVIEW Interface Generator for LabWindows/CVI 1.1 is installed on your computer. This installer is located in the C:\Exercises\CVI Basics II\Lesson 3 directory. This installer creates LabVIEW VIs from instrument drivers. You must have the following software installed before you can install and use the LabVIEW Interface Generator for LabWindows/CVI Instrument Drivers.
Windows 2000/XP LabVIEW 8.0 or later 1. Create a new project in LabWindows/CVI. 2. Save the project as C:\Exercises\CVI Basics II\Lesson 3\ Devsim.prj. 3. Add the files associated with the Device Simulator instrument driver: Devsim.c, Devsim.h, and Devsim.fp. You can find these files in the C:\Exercises\CVI Basics II\Lesson 3\ directory. 4. Select BuildTarget TypeDynamic Link Library. 5. Select BuildConfigurationRelease. 6. Select BuildTarget Settings to open the Target Settings dialog box. Enter the name of the DLL as Devsim_32.dll and copy DLL to the VXIplug&play directory, as shown in the following figure.
3-58
ni.com
Lesson 3
a. Click the Change button in the Exports section. b. In the DLL Export Options dialog box, check the Devsim.h file to export the functions that are prototyped in that header file. Click OK to close DLL Export Options dialog box. c. Click OK to close the Target Settings dialog box. 7. Select BuildCreate Release Dynamic Link Library to create the DLL. 8. Select StartAll ProgramsNational InstrumentsLabVIEW 8.0 LabVIEW and open a blank VI. 9. Select ToolsInstrumentationCreate VI Interface to CVI Instrument Driver. 10. LabVIEW opens the LabVIEW Interface Generator for LabWindows dialog box. Select Advance and click Next. 11. In the Function panel (.fp) file field, specify C:\Exercises\CVI Basics II\Lesson 3\Devsim.fp using the Browse button. When you select this .fp file, LabVIEW includes Devsim.h in Header(.h) File field. Select LabVIEW/instr.lib for Destination Directory. Make sure your dialog box looks like the following figure. Then click Next.
12. Select all the files in the Select the files to generate during the conversion process panel and click Next until you reach Accept or skip help string replacement and deletion panel. Click the Accept All and click Next. This completes the conversion.
3-59
Lesson 3
13. Clicking the View the Report and View VI Tree buttons displays the report and the generated VI. When completed, click the Done button. 14. LabVIEW generates all the VIs and saves them in the destination directory you specified in the conversion process. The default directory is \National Instruments\LabVIEW 8.0\instr.lib\Devsim. LabVIEW also puts the icons associated with these VIs in the Instr.lib section of the Functions palette. You can access these VIs by right-clicking a block diagram window and selecting Instrument I/OInstrument DriverDevsim. 15. Open one of the generated VIs and study it. The VI uses a Call Library Function to call the appropriate function in the Devsim_32.dll. The following figure is the block diagram of DevSim Initialize.VI generated by LabVIEW Interface Generator.
16. (Challenge) If your instrument simulator is correctly configured as a GPIB simulator, create a simple VI in LabVIEW using the generated instrument driver VI to communicate with the instrument.
3-60
ni.com
Lesson 3
Refer to the wizard-generated function panel and the LabVIEW Help files for a comprehensive discussion of each of the other methods and properties.
3-61
Lesson 3
OBJECTIVE
3-62
ni.com
Lesson 3
Exercise 3-8
Objective:
3. Select ToolsCreate ActiveX Controller to create an ActiveX controller instrument for the LabVIEW server. a. In the ActiveX Controller Wizard, select the LabVIEW 8.0 Type Library from the ActiveX Server list and click Next. Enter LabVIEW as the Instrument Prefix and C:\Exercises\CVI Basics II\Lesson 3\LabVIEWServer.fp as Target .fp File to path. Enable the Add .fp File To Project option. Then click Compatibility Options. Select Per Property for the Property Access Function options. Click OK and then click Next. b. On the Advanced Options panel of the ActiveX Controller Wizard, click the Advanced Options button. The ActiveX Controller Advanced Options dialog box allows you to select the objects to generate in the type library. c. Deselect all objects except Application and VirtualInstrument. Your screen will look like the following figure.
3-63
Lesson 3
d. Click OK. Then click Next. The ActiveX Controller Wizard generates only the methods needed for this application. e. Click Next until you get a message that you have generated an instrument driver. Then click the Close button to exit the ActiveX Controller Wizard. 4. When the user clicks the Launch LabVIEW button, the program launches LabVIEW. Instantiate the LabVIEW application object in the LaunchCB callback function. From the Library Tree, select InstrumentsLabVIEW 8.0 Type Library_ApplicationNewApp. This function returns a handle, which you can use in the other functions, to the LabVIEW application. Use the variable &LabviewHandle, which has already been declared, as the Object Handle and leave the other parameters as the defaults. 5. When the user clicks the Load VI button, the add.vi in the Exercises folder loads. To place the VI in memory, add AppGetVIReference function in the LoadCB callback function. From the Library Tree, select InstrumentsLabVIEW 8.0 Type Library _ApplicationAppGetVIReference. Complete the function panel as shown in the following table and insert the function call.
3-64
ni.com
Lesson 3
Object Handle Error Info VI Path Password Resv For Call Options Return Value
VFALSE
0 &labviewVI
6. When the user clicks the Run Add button, add.vi runs, the sum is calculated in LabVIEW and displayed in the sum control. The add.vi has two inputs, num1 and num2, and one output, sum. add.vi adds num1 and num2 and returns the value to sum.
a. In order to set the inputs num1 and num2 in add.vi, call the VirtualInstrSetControlValue method. Place your cursor after the comment. /* Set the values for the different inputs on the VI */ in the AddRunCB callback function. From the Library Tree, select InstrumentsLabVIEW 8.0 Type LibraryVirtualInstrumentVirtualInstrSetControlValue and complete the function panel as shown in the following table to set the value of num1. Object Handle Error Info Control Name Value
labviewVI NULL num1 myValue1
following parameters.
3-65
Lesson 3
c. To execute the VI, call the VirtualInstrRun method and place it below the comment /* Run the VI as a top-level VI */. Select InstrumentsLabVIEW 8.0 Type Library VirtualInstrumentVirtualInstrRun and complete the function panel as shown in the following table. Object Handle Error Info Async
labviewVI NULL
VTRUE
d. To get the value of sum from the VI, call the VirtualInstrGetControlValue method and place it below the comment /* Get the value from the VI's output */. From the Library Tree, select InstrumentsLabVIEW 8.0 Type LibraryVirtualInstrumentVirtualInstrGetControlValue and complete the function panel as shown in the following table. Object Handle Error Info Control Name Return Value
labviewVI NULL sum &returnedValue
e. The VirtualInstrGetControlValue method returns a VARIANT. It is necessary to convert the VARIANT to a double. Call the VariantGetDouble function to convert the VARIANT return value to a C type double. From the Library Tree, select ActiveX LibraryVariant Related FunctionsRetrieving Values from VariantsVariantGetDouble and complete the function panel as shown in the following table. Variant Value
&returnedValue &sum
3-66
ni.com
Lesson 3
f. Update the sum control on the panel with SetCtrlVal. From the Library Tree, select LibrariesUser Interface Library Controls/Graphs/Strip ChartsGeneral FunctionSetCtrlVal and complete the function panel as shown in the following table to set the value of num1. Panel Handle Control ID Value
panelHandle PANEL_SUM sum
7. When the user clicks the Call Add button, add.vi is called as a subVI. The VirtualInstrCall method in the VirtualInstrument class is invoked. This function has arguments for the control values so you do not need the VirtualInstrSetControlValue and VirtualInstrGetControlValue methods. The code for the function has already been written for you. Study how the function calls the VI like a C function call, where the parameters are passed by calling the function. 8. The Unload VI button discards add.vi, and the EXIT LabVIEW button exits LabVIEW. This action occurs with the DiscardObjHandle function in the ActiveX Library. Unload VI discards the VI handle, and EXIT LabVIEW discards the LabVIEW handle. The Quit button quits the program. The code has already been written to discard the VI and exit the program. 9. Run the program. Ensure that the correct sum returns when the VI runs, as well as when the VI is called as a subVI.
3-67
Lesson 3
3-68
ni.com
Lesson 3
Server
Provides data and service to client
3-69
Lesson 3
3-70
ni.com
Lesson 3
xType is the event that occurred Data is not transmitted with the event Explicit read function must be called
handleNumber that identifies the client-server connection. xTypeNumber that identifies a specific event for the client or server. The following table lists the TCP transaction types that can trigger a callback function. xType
TCP_CONNECT TCP_DISCONNECT TCP_DATAREADY
Server Client Y Y Y N Y Y
When? when a new client requests a connection when conversation partner quits when conversation partner sends data
errCodeIndicates if the connection terminates due to an error. *callbackDataA pointer to user-defined data.
3-71
Lesson 3
ServerTCPWrite ClientTCPWrite
ServerTCPRead ClientTCPRead
Client Functions
ConnectToTCPServerEstablishes a conversation between your application and an
existing server.
DisconnectFromTCPServerDisconnects your application from the server.
Both
ServerTCPRead/ClientTCPReadReads data from the conversation partner. ServerTCPWrite/ClientTCPWriteSends data to the conversation partner.
3-72
ni.com
Lesson 3
ServerTCPRead/ClientTCPRead
Server/Client Sends Data Server/Client Disconnects Client Connects TCP Event Manager
TCP_DATAREADY TCP_DISCONNECT TCP_CONNECT
ServerTCPRead/ClientTCPRead
The events that a TCP callback function recognizes are shown in the figure above. The following code shows a typical TCP callback function.
int TCPcallback (int handle, int xType, int errCode, void *callbackData) { switch (xType) { case TCP_DATAREADY: /* handle incoming data. break; case TCP_DISCONNECT: /* notify user that the conversation partner has disconnected */ break; case TCP_CONNECT: /* server only. notify user that a client has connected */ break; } } use Server/ClientTCPRead*/
3-73
Lesson 3
Exercise 3-9
OBJECTIVE
3-74
ni.com
Lesson 3
Exercise 3-9
Objective:
To examine a TCP client/server application written in LabWindows/CVI. If the teaching facility has networked computers, you can try running the application across the network. The client program requests one of several waveforms to be generated by the server. The server either acquires the data from the GPIB device simulator or creates the data using the signal generation routines in the Advanced Analysis Library. This allows you to try out the application without the GPIB device simulator. After either acquiring or creating the data, the server plots the data on the user interface and sends the waveform data back to the client. Upon receiving the entire array of data, the client also plots the waveform.
2. Run the server executable. Enter an unused port number and select a data source. If the data source is GPIB, enter the GPIB address of the device simulator (most likely 2).
Run the client executable. Click the Connect to Server button. Enter the IP address and port number of the server in the respective fields. When connected, the client shows the IP address and the port number in the Connected to field. After the client connects to the server, the Request Data button is enabled. Select a waveform type and then click the
3-75
Lesson 3
Advanced button. After the server gathers the data and sends it to the client, the client automatically plots the waveform to the screen. 3. When you are done, quit the programs by clicking the Quit button.
Upon receiving a TCP_DATAREADY event, the client reads the data array with ClientTCPRead. In this function, specify the conversation handle, the name of the array to store the data in, the amount to read, and a timeout. Once the data is received, it is plotted to the user interface with PlotY. Upon getting a TCP_DISCONNECT event, the client informs the user that the server has terminated connection.
The RequestData callback executes when the user clicks the Request Data button. This function then reads the Waveform Select ring control and formats a command string using the Fmt function, which is similar to the ANSI C sprintf function. This command string is passed to ClientTCPWrite along with the conversation handle, the number of bytes, and a timeout.
3-76
ni.com
Lesson 3
The Quit function disconnects the client from the server with DisconnectFromTCPServer and exits the user interface. Close the Source window. Do not save any changes.
The last tagged function is Quit. In this callback, the server executes an UnregisterTCPServer to unregister itself and exit the user interface. Close the Source window. Do not save any changes.
3-77
Lesson 3
Summary Lesson 3
ActiveX Automation and how to create ActiveX clients in LabWindows/CVI DataSocket technology, which provides a high-level API to transfer data between different entities Connecting to LabVIEW from LabWindows/CVI using ActiveX TCP and using TCP to control applications on the network
Summary Lesson 3
In this lesson, you learned how LabWindows/CVI can interact with other applications using a variety of methods. ActiveX AutomationWith ActiveX Automation, you can use the methods and control the properties of objects from other applications instead of recreating the functionality within LabWindows/CVI. DataSocketWith DataSocket, you can transfer live data from application to application(s) regardless of the underlying data protocol. TCPWith TCP, you can communicate between simultaneously running applications over a network connection.
Each technology has a client-server architecture, and it is important that you understand the role each one plays. If you want to combine the power of graphical programming with C-based programming, you can connect to LabVIEW through VI Server or convert LabWindows/CVI instrument drivers to LabVIEW instrument drivers.
3-78
ni.com
Lesson 3
Notes
3-79
Lesson 3
Notes
3-80
ni.com
Introduction
When you develop large applications, consider designing them in a modular fashion. This means that the application is partitioned into distinct modules. Each module possesses a logical grouping of functions or achieves a specific functionality. This modularity serves several purposes: Helps organize code development among a team of programmers Simplifies future code modification Aids in the reuse of code in other programs
Modules can be source files, object files, static libraries, and dynamic link libraries (DLLs). Each of these modules has different advantages and disadvantages. In this lesson, you will learn how to create and use DLLs. Later in this lesson, we will discuss issues regarding porting code between development environments.
4-1
Lesson 4
Modules
What are modules? Types of modules
Source files (*.c) Object files (*.obj) Static libraries (*.lib) Dynamic link libraries (*.dll)
Modules
In C programming, the instructions to the computer reside in one or more files. The files that actually contain code and are translated into machine instructions are called modules. Normally, a program consists of more than one module. The following list describes the different kinds of modules. Source files.c files are text files that contain code in C grammar. The compiler compiles this code into an object file and generates executable code out of the source file. Object files.obj files, which are in binary format, are usually generated from source files and are linked with other object and library files to generate the final program. The object files contain tables with symbolic information about the functions and variables in the original source code. Static Library files.lib files, which are in binary format, are usually a collection of object files. These files are used to organize a set of related functions into one module, which allows for easy access from various other source and object modules. For example, the analysis functions in LabWindows/CVI are organized in the analysis.lib module. These files are linked in by the LabWindows/CVI linker to create the executable program. Dynamic Link Libraries (DLLs).dll files are binary files, but they differ from object and static library files in that they are fully resolved, meaning that the functions inside a DLL do not depend on any other module. The code inside a DLL is linked in only when the program is executed, not when the program is created.
How does the compiler know, when creating the program, which functions to call in the DLL and where the functions are located inside the DLL? This information is provided by a file known as the import library for that DLL. The import library, .lib, is a static library file and contains code
4-2
ni.com
Lesson 4
to reliably link to the functions in the DLL at run time. As the name suggests, import libraries contain code to import code from DLLs. Header (.h) files are not modules. Header files do not contain code that can be translated into machine instructions. Header files provide prototyping information for functions defined in modules. The information inside a header file is always reproduced in source modules by the #include directive.
4-3
Lesson 4
4-4
ni.com
Lesson 4
The disadvantage of using DLLs is that the complexity of application development increases. Your application is no longer simply packaged into a single executable file. The executable requires the DLLs it calls to be present on the target system. Because the code inside DLLs does not depend on any other modules, you can port code from one environment to another in the form of DLLs, rather than in the form of object and library files.
4-5
Lesson 4
Creating DLLs
Relationship between DLL, import library, and header files Target Settings dialog box
DLL Source Code Function Definitions DLL Header Prototypes of Exported Functions DLL Files
.dll .lib (import library)
Creating DLLs
Creating a DLL is not any more difficult than creating a static C library or an object module. Although DLLs are linked at run time whereas static libraries are linked when the build occurs, their source code can be identical. For example, you can take an existing source file for a static library, change the BuildTarget Type setting in LabWindows/CVI to Dynamic Link Library, and build the DLL. One difference in source code is that a DLL can contain a DllMain function. The DllMain function is called whenever an application loads or unloads the DLL. This action provides you with a mechanism to perform initializations when the DLL is first loaded, which is similar to a constructor in C++, and to free system resources/cleanup when the DLL is unloaded, which is similar to a destructor in C++. If you do not explicitly define a DllMain, LabWindows/CVI creates a default one that does nothing. The functions inside a DLL can either be internal to the DLL or callable from other modules. The functions that are callable from other modules are said to be exported from the DLL. To create the DLL properly, the compiler must know which functions to export. In LabWindows/CVI, create a header file containing the prototypes of the functions you want to export from the DLL. Add this header file to the project. When a program uses a DLL, it can access only the functions or variables that the DLL exports. The DLL can export only globally declared functions and variables. The DLL cannot export functions and variables you declare as static. In the Target Settings dialog box, you select from a list of all the include files in the project. The include file method does not work with other compilers. However, it is similar to the .def method that some other compilers use. LabWindows/CVI creates the DLL and the appropriate import library for that DLL, and this import library must be linked to any program that calls the functions exported from the DLL.
4-6
ni.com
Lesson 4
Calling Conventions
What are calling conventions for functions? How do you specify a calling convention? Terms to know
__stdcall __cdecl DLLSTDCALL
Calling Conventions
When functions are called from your program, the arguments of the function are placed on the stack in a particular order. In addition, either the calling program or the function itself is responsible for cleaning up the stack. To set up this order and cleaning role, use a calling convention within your function declaration. If you intend for only C or C++ programs to use your DLL, you can use the __cdecl calling convention for the functions you want to export. If you want your DLL to be callable from programs written in Microsoft Visual Basic or Pascal, you must declare the functions you want to export with the __stdcall calling convention. You must explicitly define functions with the __stdcall keyword (notice the double underscore __ in front of the words) whether or not you choose to make __stdcall the default calling convention for your project. You must use the __stdcall keyword in the declarations in the include file you distribute with the DLL. Other platforms, such as Windows 3.1, do not recognize the __stdcall keyword. If you work with source code that you might use on other platforms, use a macro in place of __stdcall. The macro translates to the appropriate calling convention. The cvidef.h include file defines the DLLSTDCALL macro for this purpose. The following example code uses the DLLSTDCALL macro.
int DLLSTDCALL MyIntFunc (void); char * DLLSTDCALL MyStringFunc (void);
4-7
Lesson 4
Using DLLs
Link in the import library Call functions as prototyped in the header Put the DLL in the Windows system folder or in the current project folder
Program module1 Import Library module2 Header DLL
Using DLLs
When you use the functions of a DLL in one of your programs, you must add the import library to your project so that it gets linked into the program. You also must call the functions in the DLL according to the prototypes in the DLL header file, which you can accomplish by #including the header file into the modules from which the functions are called. Place the DLL in the Windows system folder or the folder in which the project exists, so that the DLL can be located and loaded at run time.
4-8
ni.com
Lesson 4
Exercise 4-1
OBJECTIVE
4-9
Lesson 4
Exercise 4-1
Objective:
3. Create a new source file. Enter the following code or copy and paste the code from firstdll.c in the C:\Solutions\CVI Basics II\ Exercise 4-1 directory.
4-10
ni.com
Lesson 4
Notice that DllMain has the __stdcall keyword before it. This keyword defines the calling convention for the function. Microsoft Windows contains two calling conventionsthe C calling convention, denoted by __cdecl, and the standard calling convention, formerly the Pascal calling convention, denoted by __stdcall. 4. Save this file in the C:\Exercises\CVI Basics II\Lesson 4 directory as firstdll.c and add it to the project by selecting File Add firstdll.c to Project. 5. Create a new header file and enter the following code:
void fnDLLTest(void);
Save this file as firstdll.h and add it to the project. 6. Save the project as firstdll.prj. 7. Select BuildTarget Settings. The Target Settings dialog box appears.
4-11
Lesson 4
8. Click the Import Library Choices button. In the DLL Import Library Choices dialog box, select Generate import libraries for both compilers and click OK. When you select this option, LabWindows/CVI creates import libraries for both supported compilers in subdirectories under the projects root.
9. Click the Change button in the Exports section. In the DLL Export Options dialog box, check firstdll.h, then click OK. LabWindows/CVI uses this header file to determine what functions to export. The only function prototype in the header file is for fnDLLTest, so it is the only function exported. Click OK to return to the Workspace window. 10. Select BuildConfigurationRelease. 11. Select BuildCreate Release Dynamic Link Library. Click OK if prompted to set debugging to none to create the DLL.
4-12
ni.com
Lesson 4
By default, the DLL and import libraries created have the same base name as the project. In this case, firstdll.dll is created along with three copies of firstdll.lib, the import library. LabWindows/CVI always creates one import library in the same directory as the DLL. That import library is created with the current compatibility mode, Visual C++. Import libraries for both supported compilers also are created and stored in their respective subdirectories (msvc and borland). If you want to distribute this DLL and you know which compiler your DLL will be used with, then you need to ship the DLL, the header file, and the import library for that particular compiler. 13. Click OK in the LabWindows/CVI message, save any changes, and close all open windows except the Workspace window.
4-13
Lesson 4
Exercise 4-2
OBJECTIVE
4-14
ni.com
Lesson 4
Exercise 4-2
Objective:
3. Save the file as testdll.c and add the file to the project. 4. Add the import library to the project so that the function can be resolved. In the Workspace window, select EditAdd Files to ProjectLibrary (*.lib). In the Add Files to Project dialog box, select firstdll.lib. Click Add and then click OK. 5. Run the project. Four message pop-ups appear. One for loading the DLL One for the call to fnDLLTest One for the internal call from fnDLLTest to fnInternal One for unloading the DLL
6. Return to the Source window and add the following bolded lines to the code:
#include "firstdll.h" void fnInternal(void); main() { fnInternal(); fnDLLTest(); }
7. Recall that fnInternal was not exported when you created the DLL. Therefore, when you try to run the project, you get an "Undefined symbol" error when the project is linked. 8. Close testdll.c. Do not save any changes.
4-15
Lesson 4
To debug a DLL that another LabWindows/CVI project uses, you must run the project with the debugging level set to a value other than none. When LabWindows/CVI loads the DLL, it loads the corresponding debug information from the auxiliary debug files. LabWindows/CVI honors the breakpoints you set in DLL source files. LabWindows/CVI saves in the project any breakpoints you set in source files, regardless of whether the source file is in the project. You also can set watch expressions for a debuggable DLL. For each watch expression, you must choose whether the watch expression applies to a project or a DLL. If the watch expression applies to a DLL, you must enter the name of the DLL. LabWindows/CVI stores this information in the project.
4-16
ni.com
Lesson 4
To debug a DLL that an external process uses, load the DLL project into LabWindows/CVI. Make sure you set the debugging level to a value other than none. Select RunSpecify External Process. A dialog box appears in which you enter the pathname and command line arguments to an external program. LabWindows/CVI stores this information in the project. The RunRun Project command changes to Debug xxx.exe, where xxx.exe is the filename of the external program. When you execute the Debug xxx.exe command, LabWindows/CVI starts the external process and attaches to it for debugging. If you have set any breakpoints in the source files for the DLL, LabWindows/CVI honors them. If the external process loads other debuggable DLLs, you can debug them even though the project for a different DLL is open.
4-17
Lesson 4
Exercise 4-3
OBJECTIVE
4-18
ni.com
Lesson 4
Exercise 4-3
Objective:
5. Click OK in the LabWindows/CVI message. 6. Open the testdll.prj project. 7. Open firstdll.c, the source file for the DLL created in step 3. 8. Place your cursor on line 12 (MessagePopup ("In DLLMain", "I've been unloaded");) and insert a breakpoint by selecting RunToggle Breakpoint. 9. Run the testdll.prj project. LabWindows/CVI breaks at the appropriate statement in the DLL source file. You also can add watch expressions for variables in the DLL through the Watch window, as shown in the following figure.
4-19
Lesson 4
Try adding watch expressions for other variables and see the different settings applicable for variables defined in DLLs. 10. After testing the different DLL debugging features, close all files.
4-20
ni.com
Lesson 4
DLL Recommendations
Use DLLSTDCALL Use the include file method Avoid exporting variables. Use functions to set/get the values of variables Debug your DLL code as much as possible before creating the DLL. Use DLL debugging to debug run-time problems.
DLL Recommendations
To simplify DLL creation, use the following recommendations: Use the DLLSTDCALL macro in the declaration and definition of all functions you want to export. Do not export functions with a variable number of arguments. Identify the symbols you want to export using the include file method. Do not use export qualifiers. If you use an external compiler, use the .def file method. Do not export variables from the DLL. For each variable you want to export, create functions to get and set the variable value or create a function that returns a pointer to the variable. Do not use import qualifiers in the include file.
These recommendations bring the following benefits: You can distribute with your DLL the same include file that you include in the source files you use to make the DLL. This distribution is especially useful when you create DLLs from instrument drivers. You can use the same source code to create the DLL in LabWindows/CVI and both of the compatible external compilers. You can use your DLL in Microsoft Visual Basic or other non-C environments.
4-21
Lesson 4
4-22
ni.com
Lesson 4
TCP Support, and Utility Library functions If you use an external compiler that requires a WinMain entry point, include cviwmain.lib. Using this .lib file, you can define only main in your program. To initialize the LabWindows/CVI Run-Time Engine, you must call InitCVIRTE before calling any other LabWindows/CVI functions. Normally, you call this function in your modules entry-point, like main, WinMain, or DllMain. When you finish with the LabWindows/CVI Run-Time Engine, call CloseCVIRTE.
4-23
Lesson 4
You can add the analysis.lib static library file, which contains the Analysis (or Advanced Analysis) Library, from C:\Program Files\National Instruments\CVI\extlib directory to your external compiler project.
4-24
ni.com
Lesson 4
The cvirt.lib library file contains symbols for all the LabWindows/CVI libraries, except the ANSI C Library. When you create an executable or DLL in an external compiler, you use the compilers own ANSI C standard library. Because of this, you must use the external compilers include files for the ANSI C library when compiling source files. Although the include files for the other LabWindows/CVI libraries are in the C:\Program Files\National Instruments\ CVI\include directory, the LabWindows/CVI ANSI C include files are in the C:\Program Files\National Instruments\CVI\include\ansi directory. Thus, you can specify C:\Program Files\National Instruments\CVI\include as an include path in your external compiler while, at the same time, using the external compilers version of the ANSI C include files.
4-25
Lesson 4
One effect of using the external compilers ANSI C standard library is that the printf and scanf functions do not use the LabWindows/CVI Standard Input/Output window. To use printf and scanf, you must create a console application. To continue using the LabWindows/CVI Standard Input/Output window, call the FmtOut and ScanIn functions in the Formatting and I/O Library.
4-26
ni.com
Lesson 4
Compiling in an External Compiler for Linking in an External Compiler Use the SDK and ANSI C include files from the external compiler. This action happens automatically. Specify C:\Program Files\National Instruments\CVI\include as an include path in the external compiler for the LabWindows/CVI library include files.
4-27
Lesson 4
LabWindows/CVI does not work with all non-ANSI extensions each external compiler provides. Also, in cases where ANSI does not specify the exact implementation, LabWindows/CVI does not always agree with external compilers. Most of these differences are unclear and rarely encountered. Refer to the Programmer Reference section in the LabWindows/CVI Help for details. C++ Name Decoration Use extern "C" {/* definitions in source code */ } to prevent C++ compilers/linkers from decorating symbol names. Doing so allows for portability of code that might be linked in a C or C++ compiler/linker. The following code is an example:
#ifdef __cplusplus extern "C" { #endif /* Definitions in the Source Code*/ #ifdef __cplusplus
4-28
ni.com
Lesson 4
} #endif
Compatibility Issues with DLLs Only the DLL import library must be created for the current compatible compiler. Some cases exist, however, in which you cannot call a DLL that you created using one compiler from an executable or DLL that you created using another compiler. If you want to create DLLs that you can use in different compilers, design the Application Programming Interface (API) for your DLL to avoid such problems. Refer to the Programmer Reference section in the LabWindows/CVI Help for information about possible problems and solutions to these problems.
4-29
Lesson 4
4-30
ni.com
Lesson 4
When you pass the DLL module handle to LoadPanelEx and LoadMenuBarEx, the User Interface Library searches the table of callback functions the DLL contains before searching the table that the executable contains. In summary, if you want to use LabWindows/CVI user interface features in an external compiler, you must create the user interface resource in LabWindows/CVI. You can then write your callback functions within a LabWindows/CVI DLL or you can write them inside an external compiler. If you take the latter approach, you must include the UIR Callbacks object file.
4-31
Lesson 4
OBJECTIVE
To create an object file containing UIR callback support for use in an external compiler
4-32
ni.com
Lesson 4
Exercise 4-4
Objective:
To create an object file containing UIR callback support for use in an external compiler.
Note This exercise requires that you use the Borland external compiler. To import a LabWindows/CVI project into Microsoft Visual C++, choose the NI Measurement Studio AppWizard when you create a new project in Measurement Studio. This utility provides the option to automatically convert LabWindows/CVI programs, applications, and libraries into Microsoft Visual C++ applications.
1. Create a new project. Save the project as chart.prj in the directory C:\Exercises\CVI Basics II\Lesson 4\chart.prj. 2. Open chart.uir located in the directory C:\Exercises\ CVI Basics II\Lesson 4\chart.uir. Add this UIR to the project. The UIR contains a chart, a timer control, and command button. The timer control has a callback named PlotToChart and an interval of 100 ms. The command button has a callback function named QuitProgram. 3. Create a program shell using CodeBuilder. Select CodeGenerate All Code. 4. In the Generate All Code dialog box, enable Generate WinMain() instead of main() and select QuitProgram in the Select QuitUserInterface Callbacks box. Also, make sure that you select Add to Current Project in the Target Files section and click the OK button.
4-33
Lesson 4
5. Add the following line to the PlotToChart callback function in the case statement for EVENT_TIMER_TICK.
PlotStripChartPoint (panelHandle, PANEL_STRIPCHART, rand()/327.67);
6. Use LabWindows/CVI to test the program before going to the external compiler to create the executable. Run the project, add any necessary header files and view the strip chart.
4-34
ni.com
Lesson 4
7. If the program runs as expected, click Quit to return to the Workspace window. 8. Now that you have verified that the program works, you can take this source file to an external compiler to run. Recall that you must create a callback object file for callbacks to work in the external environment. In the Workspace window, select BuildExternal Compiler Support. In the External Compiler Support dialog box, select Object File for UIR Callbacks, browse to chartcb.obj in the name field, and click the Create button. 9. Click the OK button.
10. After creating the file, close all windows except the Workspace window.
4-35
Lesson 4
OBJECTIVE
To create a DLL in LabWindows/CVI that contains callback functions for use in an external compiler
4-36
ni.com
Lesson 4
Exercise 4-5
Objective:
To create a DLL in LabWindows/CVI that contains callback functions for use in an external compiler. 1. Create a new project and select BuildTarget TypeDynamic Link Library. This step is necessary for CodeBuilder to generate the appropriate code. Save the project as chart2.prj in the directory C:\Exercises\CVI Basics II\Lesson 4\chart2.prj. 2. Open C:\Exercises\CVI Basics II\Lesson 4\chart.uir. Save the file as chart2.uir in the directory C:\Exercises\CVI Basics II\Lesson 4\chart2.uir and add it to the project. 3. Select CodeGenerateAll Code. 4. In the Generate All Code dialog box, enable Generate WinMain() instead of main() and select QuitProgram in the Select QuitUserInterface Callbacks box. Also, make sure that you select Add to Current Project in the Target Files section. Click OK. 5. The resulting Source window contains the callback functions for PlotToChart and Shutdown and the DllMain function. In addition, the InitUIForDLL function loads and displays the user interface panel. Uncomment RunUserInterface line as shown in the following figure.
6. Add the following line to the PlotToChart callback function in the case statement for EVENT_TIMER_TICK.
PlotStripChartPoint (panelHandle, PANEL_STRIPCHART, rand()/327.67);
7. Select BuildCompile chart2.c. Add any necessary header files when prompted. Close the Source window, saving any changes.
4-37
Lesson 4
8. The InitUIForDLL function is called from the external compiler to enable the GUI. Therefore, you must export this function for the external compiler. To do so, create a new header (.h) file. 9. In the header file, enter
int InitUIForDLL (void);
Save this file as exportme.h. Add it to the project and close the window. 10. In the Workspace window, select BuildTarget Settings. 11. Click the Import Library Choices button. In the DLL Import Library Choices dialog box, select Generate import libraries for both compilers and click OK. Selecting this option creates import libraries for both supported compilers in subdirectories under the projects root. 12. Click the Change button in the Exports section. In the DLL Export Options dialog box, check exportme.h, then click OK. LabWindows/CVI uses this header file to determine what functions to export. 13. Click OK to exit the Target Settings dialog box. 14. Select BuildConfigurationRelease. 15. To create the DLL, select BuildCreate Release Dynamic Link Library.
19. Save the source file as testdll2.c in the directory C:\Exercises\ CVI Basics II\Lesson 4\testdll2.c and add this file to the project. 20. Run the project. The program should run as it did in Exercise 4-4. 21. Click the Quit button to exit.
Lesson 4
Summary Lesson 4
Use DLLs to add modularity to your programming design You can create and use DLLs from within LabWindows/CVI DLL debugging is available for DLLs created in LabWindows/CVI Understand the issues underlying the porting of code between compilers
Summary Lesson 4
In this lesson, you learned about DLLs and the issues regarding the porting of code between compilers. Because a DLL is compiled code, follow the recommendations stated in the lesson when creating a DLL. When troubleshooting programs, you can usually trace the source of the problem to a DLL. For example, if you use a particular calling convention in your project and your DLL has a different calling convention, the program might not function. If you have only the header file for the DLL and not the import library, you can generate the import library from the header file. Select OptionsGenerate DLL Import Library when you open the header file.
Note
When porting code between development environments, make sure that if you use LabWindows/CVI functions, you include the necessary header files, libraries (static or import), and the LabWindows/CVI Run-Time Engine. Refer to the Programmer Reference section of the LabWindows/CVI Help for information about portability and compatibility.
4-39
Lesson 4
Notes
4-40
ni.com
Additional Topics
Lesson 5: Additional Topics
A. Multithreaded programming B. Integrating the Windows Platform SDK C. Useful utility functions
Introduction
This lesson covers the following topics, which extend the core functionality of LabWindows/CVI. Using multiple threads in the same program to improve performance on multiprocessor machines Using the Platform SDK to add power and flexibility to your LabWindows/CVI application Using miscellaneous utility functions for memory access, error handling, and handling executables
This lesson also covers several advanced programming topics that can be optionally covered for the individual needs of LabWindows/CVI users.
5-1
Lesson 5
Additional Topics
Multithreading Terms
Multitasking
Multiple executables running concurrently Preemptive versus non-preemptive
Multithreading
Multiple threads in a single executable
Multiprocessor machines
Multiple processors (CPUs) in a machine
Multithreading Terms
MultitaskingMultiple executables run at the same time. For example, you can download a file using FTP while you edit a document in a word processing program. Cooperative MultitaskingPrograms must explicitly give control back to the system periodically so that another program is given a chance to execute. Windows 3.1 and MacOS are examples of cooperative multitasking systems. Windows 3.x relies on cooperative, non-preemptive multitasking, which requires that each running application periodically yield control to Windows, which then allows another application to run. Preemptive MultitaskingSystem periodically suspends a program to give other programs a chance to execute. The program does not need to explicitly give control to the system. Each program is executed for a few milliseconds and then suspended while other programs execute. Windows NT/9x and Solaris are examples of preemptive multitasking systems. MultithreadingMultiple threads execute in the same program. Unlike multitasking, all of the threads have access to the global data in the program. Multithreaded programs require support from the operating system. Windows XP/2000/NT/9x, Linux and Solaris 2 provide support for multithreading. Multiprocessor MachinesMachines with multiple processors increase performance if you have preemptive multitasking or multithreading. Separate programs or threads run on each CPU.
5-2
ni.com
Lesson 5
Additional Topics
Multithreaded Programs
T I M E Thread 1 Thread 2 Program Word Processor Process UI Printing
Multithreaded Programs
The large box represents a single process. The smaller boxes represent a single thread of execution. From the user perspective, the UI responds to user input while the program is printing. On multiprocessor machines or fast machines, the user might not be able to see a degradation of UI responsiveness while a print operation is running.
5-3
Lesson 5
Additional Topics
Benefits of Multithreading
Keep time-critical tasks from being greatly affected by UI Keep UI responsive while performing command in background
Printing in background
Improve throughput and performance on multiprocessor machines Logical separation of independent program parts
Benefits of Multithreading
The reliability of your data acquisition or control can increase by executing the data acquisition or control in one thread while the UI executes in another thread. You can execute lengthy operations in a spawned thread so that the main application thread always can respond to UI events. You can implement algorithms so that different pieces of the algorithm execute in separate threads. If an algorithm that is implemented in such a manner is executed on a machine with multiple processors, the algorithm executes faster than a traditional, single-threaded implementation of the algorithm. A classic example is a compiler implemented in such a way that the preprocessor runs in one thread and the actual compile runs in another thread, which results in improved throughput. A more efficient implementation is a program in which independent pieces of the program run in separate threads. For example, a TCP server application that responds to multiple clients is easier to write if each client is handled by a separate thread in the server application.
5-4
ni.com
Lesson 5
Additional Topics
Multithreading in LabWindows/CVI
Thread Pool Thread creation Thread Safe Queue Passing data safely between multiple threads Thread Safe Variables Protecting data used in multiple threads Thread Lock Critical section or mutex in C Prevents multiple access of data Thread Local Variables Per thread values for variables Note: All threading functions are in Utility Library
Multithreading in LabWindows/CVI
With thread pools, you can schedule functions for execution in separate threads. Thread pools handle thread caching to minimize the overhead associated with creating and destroying threads. Thread safe queues abstract passing data between threads. One thread can read from a queue at the same time that another thread writes to the queue. Thread safe variables effectively combine a critical section and an arbitrary data type. You can call a single function to acquire the critical section, set the variable value, and release the critical section. Thread lock simplifies using a critical section or mutex by providing a consistent API and using the appropriate mechanism when necessary. For example, a mutex is used if the lock needs to be shared between processes or if threads need to process messages while waiting for the lock. A critical section is used in other cases because it is more efficient. Thread local variables provide per-thread instances of variables. The operating system places a limitation on the number of thread local variables available to each process. The LabWindows/CVI implementation consolidates the thread local variables, using only one process thread local variable for all of the thread local variables in your program. You can find all of the multithreading functions in the LabWindows/CVI Library Tree under Utility LibraryMultithreading.
5-5
Lesson 5
Additional Topics
Thread Pools
Thread pools manage groups of threads Programs have a default thread pool
Max threads = 2 + 2*NumberOfProcessors
You can create additional thread pools Use scheduling functions to create threads in a thread pool Thread functions must have the following prototype: int CVICALLBACK FuncName (void *functionData);
Thread Pools
Thread pools are the mechanism for creating and managing threads in LabWindows/CVI. LabWindows/CVI applications have one default thread pool. For many cases, creating additional thread pools is unnecessary, and you can use the default thread pool instead. The default thread pool can hold a maximum of 2 + 2*(NumberOfProcessors) threads, which translates into a maximum of 4 threads for single processor machines and 6 threads for dual processor machines. If you need more threads than the one that fits in the default thread pool, you can create an additional thread pool. You also might want to create additional thread pools to group threads that have logical connections. For example, you can use one thread pool for all data acquisition threads. Creating thread pools does not create any actual threads. Threads are created by scheduling functions in the thread pool with the CmtScheduleThreadPoolFunction. Functions that are scheduled in threads can be named by anything. However, they must have a specific function prototype:
int CVICALLBACK FuncName (void *functionData);
5-6
ni.com
Lesson 5
Additional Topics
When a function is scheduled in the default thread pool, the default thread pool is initialized and the function begins running in a separate thread. In this case you can use the CmtNewThreadPool function to create a second thread pool. CmtNewThreadPool returns a handle to the new thread pool that you can use to schedule functions. Another function, func2, can be scheduled in the second thread pool and begins running in another thread. This second thread pool must be discarded in the program when it is no longer needed or when the program exits. To discard the second thread pool, use CmtDiscardThreadPool.
5-7
Lesson 5
Additional Topics
...
5-8
ni.com
Lesson 5
Additional Topics
Exercise 5-1
OBJECTIVE
5-9
Lesson 5
Additional Topics
Exercise 5-1
Objective:
Multithreading in LabWindows/CVI
1. Open the threadpool.prj located in the directory C:\Exercises\ CVI Basics II\Lesson 5\threadpool.prj. This project is partially completed. The user interface, shown in the following figure, is composed of a panel with two command buttons, Create Thread and Quit.
2. Open threadpool.c. The source code consists of four functions: the main function, callbacks for the Create Thread and Quit buttons (NewThread and Quit) and the thread function called MyThreadFunction. 3. You must instantiate a thread pool before beginning to schedule threads. Navigate to the /* Create thread pool here */ comment in the main function. Insert the CmtNewThreadPool function under the comment. From the Library Tree, select Utility Library MultithreadingThread PoolAdvanced Functions CmtNewThreadPool function and complete the function panel as shown in the following table. Maximum Number of Threads Pool Handle
Note MAXTHREADS &poolHandle
After you complete the function panel, select CodeInsert Function Call to insert the function call into your source code.
5-10
ni.com
Lesson 5
Additional Topics
Note The default thread pool is not used because more threads are needed than are available in the default thread pool.
4. The NewThread callback function is called when you click the Create Thread button. This function checks to see if the maximum number of threads (MAXTHREADS) has been reached. The NewThread function instantiates a new control and places the control on the panel. MyThreadFunction, which has already been written, updates the control. You need to write code to create and schedule a thread that runs the MyThreadFunction function. Navigate to the /* Schedule new thread function here */ comment in the NewThread function and insert a function call to the CmtScheduleThreadPoolFunction below the comment to create a new thread. From the Library Tree, select Utility LibraryMultithreadingThread PoolCall Scheduling FunctionsCmtScheduleThreadPoolFunction and complete the function panel as shown in the following table. Pool Handle Thread Function Thread Function Data Thread Function ID
poolHandle MyThreadFunction (void *)ctrlID NULL
5. Add the following line to increment the numThreads variable below the CmtScheduleThreadPoolFunction. This keeps track of how many threads have been allocated.
numThreads++;
6. Navigate to the Quit callback function. This function shuts down all of the threads and causes the program to stop executing. Enter exiting = 1; below the /* Discard thread pool here and set exiting flag */ comment to stop the threads. After setting the exiting flag, select Utility LibraryMultithreadingThread PoolAdvanced FunctionsCmtDiscardThreadPool from the Library Tree and pass poolHandle as the Pool Handle parameter. Insert the CmtDiscardThreadPool function into the Source window. 7. Examine the thread function, MyThreadFunction. Notice how the function uses the exiting flag to exit the function. 8. Build and run the project. Verify that the Create Thread button works properly. As more threads are added, notice that they continue to run. Also notice how the speed of each thread decreases as more threads are created.
5-11
Lesson 5
Additional Topics
5-12
ni.com
Lesson 5
Additional Topics
Read Level
TSQ
5-13
Lesson 5
Additional Topics
Exercise 5-2
OBJECTIVE
To complete an example application that uses a thread safe queue to communicate data between threads
5-14
ni.com
Lesson 5
Additional Topics
Exercise 5-2
Objective:
To complete an example application that uses a thread safe queue to communicate between threads. Often data within a thread needs to be passed outside of the thread. This data is critical data and generally needs to be protected from external processes that can corrupt the data. One way to pass data outside a thread is to use a global variable. Using a global variable can cause the data to be corrupted if other threads try to access the data. Therefore using a global variable is not the best solution, even though it is easy. One way to protect data that is being transferred from a thread is to use a queue. LabWindows/CVI comes with a set of functions to protect data using thread safe queues. Thread safe queues enable data to be easily transferred between threads. In this exercise, you will complete an example application that spawns a thread that calculates a sine wave to be displayed on a chart. When a thread safe queue receives data, an event is created to handle the data that has been written to it. This exercise shows you how to create a callback function for thread safe queues and how to develop an architecture to create advanced multithreaded applications. You must perform the following steps to create an application that uses thread safe queues to protect critical data. 1. Create a thread safe queue. 2. Install a thread safe queue callback function. 3. Create the thread. 4. Using the thread write data to the thread safe queue. 5. Using the thread safe queue callback function read the data from the thread.
Note Notice that creating a thread pool was not mentioned in the preceding steps. The DEFAULT_THREAD_POOL that is created by LabWindows/CVI can contain up to 2 + 2 * (number of processors in computer) threads. In most computers with only one processor there can be four threads running at any time. Most of the time it is not necessary to create a new thread pool if the application requires only two or three threads. If you do not know in advance how many threads the application will require, then it is a good idea to create a new thread pool.
5-15
Lesson 5
Additional Topics
1. Open the tsq.prj located in the directory C:\Exercises\CVI Basics II\Lesson 5\tsq.prj. This project is partially completed for you. The user interface, shown in the following figure, consists of a panel with a strip chart and three command buttons: Start, Stop, and Quit. The Start button begins simulated data acquisition in a new thread. This thread passes data back to the user interface thread through a thread safe queue. The Stop button halts the simulated data acquisition thread. The Quit button stops the simulated data acquisition, if necessary, and exits the program. In this exercise, you add the functions to create and communicate between threads.
2. Open tsq.c. Navigate to the main function. The following figure shows the completed main function.
5-16
ni.com
Lesson 5
Additional Topics
In the main function place your cursor below the /* Create Thread Safe Queue */ comment. Insert the CmtNewTSQ function under the comment to create a new thread safe queue before starting the user interface. From the Library Tree, select Utility Library MultithreadingThread Safe QueueGeneral Functions CmtNewTSQ and complete the function panel as shown in the following table. Number of Items Item Size Options Queue Handle
QUEUE_SIZE sizeof(double) 0 &TSQHandle
Note After you complete the function panel, select CodeInsert Function Call to insert the function call into your source code.
Use the constant QUEUE_SIZE for the number of items in the queue. The queue holds double values, so the item size is sizeof(double). Use the global variable TSQHandle, which is already declared in tsq.c, for the thread safe queue handle.
5-17
Lesson 5
Additional Topics
3. Place your cursor below the /* Install callback function for TSQ */ comment. Insert the CmtInstallTSQCallback function under the comment. From the Library Tree, select Utility Library MultithreadingThread Safe QueueCallbacks CmtInstallTSQCallback and complete the function panel as shown in the following table and insert the function call. Queue Handle Event Event Threshold Value Callback Function Callback Data Callback Thread ID Callback ID
TSQHandle
Items in Queue
50 ReadDataFromTSQ &callbackID CmtGetCurrentThreadID() &callbackID
This function installs the thread safe queue event callback function so that when 50 items are in the queue, the ReadDataFromTSQ function is called. 4. Place your cursor below the /* Uninstall the thread safe queue callback function */ comment. Insert the CmtUninstallTSQCallback function under the comment. From the Library Tree, select Utility LibraryMultithreadingThread Safe QueueCallbacksCmtUninstallTSQCallback and complete the function panel as shown in the following table. Then, insert the function call in the code. Queue Handle Callback ID
TSQHandle callbackID
5. Add the following line of code below CmtUninstallTSQCallback function, to set callbackID to 0.
callbackID = 0;
Setting callbackID to zero allows you to safely destroy the TSQ. 6. Discard the thread safe queue before the application exits by calling CmtDiscardTSQ after the comment /* Discard Thread Safe Queue */. Insert the CmtDiscardTSQ function under the comment. From the Library Tree, select Utility LibraryMultithreading Thread Safe QueueGeneral FunctionsCmtDiscardTSQ and complete the function panel as shown in the following table. Queue Handle
TSQHandle
5-18
ni.com
Lesson 5
Additional Topics
1. All of the code to determine if the thread is running has already been written. It is always good practice to write code that checks to make sure that the maximum number of threads for the application has not been reached in the code that schedules the thread. Place your cursor below the /* Create new thread to generate data by scheduling function */ comment. Insert the CmtScheduleThreadPoolFunction function under the comment. From the Library Tree, select Utility LibraryMultithreading ThreadPoolCall Scheduling Functions CmtScheduleThreadPoolFunction and complete the function panel as shown in the following table. Pool Handle Thread Function Thread Function Data Thread Function ID
DEFAULT_THREAD_POOL_HANDLE SimulateData &threadID &threadID
This function schedules the SimulateData function in a thread. Notice that the StartAcquisition function sets the runThread flag to 1. The runThread flag is used to stop the thread from executing. Notice that runThread was declared as volatile. All global variables that will be accessed by a thread need to be declared as volatile.
5-19
Lesson 5
Additional Topics
1. The code for the function has already been written. This function creates a random number that specifies the length of the sine wave to generate. The only thing that you must do is send the sine data from the thread to the main calling application. Remember that this data is critical data and must be protected. Place your cursor below the /* Add the data in the write buffer to the thread-safe queue */ comment. Insert the CmtWriteTSQData function under the comment. From the Library Tree, select Utility LibraryMultithreadingThread Safe QueueReading/WritingCmtWriteTSQData and complete the function panel as shown in the following table. Queue Handle Buffer Number of Items Timeout(ms) Number of Items Flushed
TSQHandle writeBuffer numItemsInWriteBuffer TSQ_INFINITE_TIMEOUT NULL
The variables writeBuffer and numItemsInWriteBuffer have already been declared. The timeout that is specified with CmtWriteTSQData guarantees that the function waits until all of the items have been written to the queue. Therefore, if there is not enough space in the queue, the function waits.
5-20
ni.com
Lesson 5
Additional Topics
This function has already been written for you. Notice that the function alternates between plot colors of red and blue each time the event function is called. It is necessary to determine how many items are in the queue. This is accomplished using the CmtGetTSQAttribute function. If an error occurs, this function returns a negative number. CmtReadTSQData reads the data from the queue. Notice how the function dynamically allocates an array to store the data items from the queue.
5-21
Lesson 5
Additional Topics
Perform the following steps to complete the StopAcqAndCleanup function. 1. Once the runThread flag has been set to 0, it is necessary to wait for the thread to completely finish executing. The CmtWaitForThreadPoolFunctionCompletion function waits for the specified thread to complete. Insert this function below the /* Wait for acquisition thread to exit */ comment. From the Library Tree, select Utility LibraryMultithreadingThread Pool Call Scheduling Functions CmtWaitForThreadPoolFunctionCompletion and complete the function panel as shown in the following table. Pool Handle Thread Function ID Options
DEFAULT_THREAD_POOL_HANDLE threadID 0
2. After the thread finishes executing, you can unschedule the thread function from the thread pool. Insert the CmtReleaseThreadPoolFunctionID function below the CmtWaitForThreadPoolFunctionCompletion function. From the Library Tree, select Utility LibraryMultithreadingThread Pool Call Scheduling FunctionsCmtReleaseThreadPoolFunctionID and complete the function panel as shown in the following table. Pool Handle Thread Function ID
DEFAULT_THREAD_POOL_HANDLE threadID
5-22
ni.com
Lesson 5
Additional Topics
Part F: Run
Save and run the program. Verify that the Start, Stop, and Quit buttons work properly. Notice how the rate of data going to the strip chart changes while the simulation is running. This action occurs because the data simulation thread sends random sizes of data to the thread safe queue. Notice that the application is passing data from the thread to the main application to display the data on the strip chart. The data that is generated in the SimulateData function will not get corrupted with the use of thread safe queues.
5-23
Lesson 5
Additional Topics
Well-Behaved Applications
Well-Behaved Applications
If you spend much time inside a callback function, then periodically call ProcessSystemEvents or ProcessDrawEvents. ProcessSystemEvents allows LabWindows/CVI to check if other events, such as Windows messages, are waiting to be processed. ProcessDrawEvents updates the user interface only. Refer to the messaging section of Lesson 1. Use PostDeferredCall to execute functions after your callback has ended. The function does not execute until the next call to GetUserEvent, RunUserInterface, or ProcessSystemEvents.
5-24
ni.com
Lesson 5
Additional Topics
All Windows applications rely on services that system DLLs provide The Platform SDK is shipped with the LabWindows/CVI Full Development System
5-25
Lesson 5
Additional Topics
5-26
ni.com
Lesson 5
Additional Topics
Additional Functions
I/O and Memory Access Useful Utilities Error Handling Creating Well-Behaved Applications Using Executables
Additional Functions
This lesson discusses additional functions that are useful for certain types of LabWindows/CVI applications. However, many other functions are beyond the scope of this course. For these functions, refer to the function panel help, help in the LabWindows/CVI Help, or the LabWindows/CVI examples.
5-27
Lesson 5
Additional Topics
0x378
outp
WriteToPhysicalMemory MapPhysicalMemory
pointer
UnMapPhysicalMemory
extended versions of these functions to specify the actual byte transfer size. Every time you use these functions, you are mapping and unmapping physical memory. To reduce this overhead, use the MapPhysicalMemory/UnMapPhysicalMemory functions to obtain pointers to portions of memory. You can treat these pointers like any other C pointers, incrementing and manipulating objects in a familiar manner. When you use Windows 2000/XP, these functions require you to load a low-level support driver, cvintdrv.sys, that is shipped with LabWindows/CVI. The LabWindows/CVI libraries automatically load the low-level support driver, cvintdrv.sys, at startup if it is on disk. To ensure that the driver is loaded before you proceed, call the CVILowLevelSupportDriverLoaded function at the beginning of your program. To include the driver when creating your stand-alone executables, enable the Low-Level Support Driver option in the Drivers & Components tab of the Edit Installer dialog box.
Note
5-28
ni.com
Lesson 5
Additional Topics
5-29
Lesson 5
Additional Topics
5-30
ni.com
Lesson 5
Additional Topics
A companion function to LaunchExecutable is system, an ANSI C function. The main difference between the two is that system waits for the executable to finish before continuing with the program.
5-31
Lesson 5
Additional Topics
Error Handling
Library errors
SetBreakOnLibraryErrors GetBreakOnLibraryErrors
Protection errors
SetBreakOnProtectionErrors GetBreakOnProtectionErrors
Error Handling
LabWindows/CVI user protection allows the compiler to monitor all types of pointer manipulations in your code and store data structures internally for each type. At run time, LabWindows/CVI dynamically watches your pointer manipulations and informs you of illegal accesses. LabWindows/CVI does the same action for simple out-of-bounds indexing of statically declared arrays and more complex series of dynamic allocations with malloc, calloc, and so on. With these user protection features, you do not need to spend time tracking down pointer bugs, which are typically some of the most difficult bugs to find. LabWindows/CVI displays a run-time dialog box that lists any instances of illegal access due to an out-of-bounds pointer or an attempt to free an invalid pointer and highlights the erroneous line in your code. You can configure LabWindows/CVI to display a run-time error dialog box and suspend execution when an NI library function reports an error. To enable this type of debugging, select RunBreak onLibrary Errors or use the Utility Library SetBreakOnLibraryErrors/GetBreakOnLibraryErrors functions. You also can work around user protection errors flagged by LabWindows/CVI by using the SetBreakOnProtectionErrors/GetBreakOnProtectionErrors functions. Normally, you apply these functions around a small section of code as a workaround to some pointer problems you have coded into your program. LabWindows/CVI keeps track of all library function calls and watches all pointer accesses as it executes your program and informs you when it detects an error. When you do not perform a debug build, these features are disabled.
5-32
ni.com
Lesson 5
Additional Topics
Sleep More
checks an event from the operating system, it can put itself in the background, in sleep mode, for a specified period of time. While LabWindows/CVI is in sleep mode, other applications have more processor time. The disadvantage of increasing the amount your application sleeps is that your application responds slightly slower to events. To view or change the current LabWindows/CVI sleep policy, select OptionsEnvironment. CVI environment sleep policyYou can specify how much LabWindows/CVI sleeps by selecting one of the following sleep policy choices: Do not sleep Sleep some Sleep more
You also can view or change the sleep policy programmatically by calling either GetSleepPolicy or SetSleepPolicy. By using SetSleepPolicy, you might free some CPU use. The figure above demonstrates the effect of the sleep policy on a Windows XP system. Changes in sleep policy have different effects depending on the operating system. Experiment with the various sleep options for your particular application. Increase the sleep mode if you want to free processor usage and decrease the sleep mode if you want LabWindows/CVI to poll the user interface faster for user events.
5-33
Lesson 5
Additional Topics
Additional Functionality
Use <Ctrl-Shift-P>, Find Function Panel, to search for functions based on keywords Check out the built-in LabWindows/CVI instrument drivers in the C:\Program Files\National Instruments\CVI\toolslib directory Increase your Windows programming skills with the Windows SDK functions
Additional Functionality
Because of the large number of functions and utilities within LabWindows/CVI, it is important that you know how to find the functions you need to complete or refine your application. In the Source window, use the ViewFind Function Panel command (<Ctrl-Shift-P>) to search for functions based solely on keywords. Remember to use a variety of synonyms, because the function might be spelled differently than you expected. LabWindows/CVI includes functionality through its built-in instrument drivers. As you learned in this course, LabWindows/CVI provides many drivers for custom controls but also provides several miscellaneous functions in the toolbox instrument driver. You can supplement the built-in instrument drivers by purchasing add-on toolkits. Currently, you can purchase toolkits for SQL (database manipulation), TX (test function management), SPC (statistical process control), IMAQ (image processing), PID (process control for automation), and INET (internet). If a function does not exist, you can create the function through Windows SDK. Creating a function using the Windows SDK requires that you have some knowledge of Windows programming.
5-34
ni.com
Lesson 5
Additional Topics
Toolkits
Enhance LabWindows/CVI through add-on toolkits: TestStandtest management SQLdatabase manipulation PIDfeedback control IMAQimage processing
Toolkits
As a stand-alone package, LabWindows/CVI includes a wealth of features. However, you can enhance LabWindows/CVI with toolkits that include functions for specific business applications. These toolkits are sold as separate packages because they include functionality that not all LabWindows/CVI programmers need. TestStand TestStand is a ready-to-run, customizable test executive used in automated test environments. A test executive relieves test engineers from worrying about the repetitive tasks of test program management, such as logging test results to file and handling multiple levels of users. TestStand allows a test engineering group to spend the bulk of its time on one specialized purposedeveloping test functions. SQL ToolkitInterfacing with Databases With the Structured Query Language (SQL toolkit) LabWindows/CVI programs can manipulate database files. Use the SQL toolkit to do basic database functions, such as creating, fetching, and sorting records. PID Toolkit PID, Proportional-Integral-Derivative is a defined control strategy standard used in industry. The PID toolkit is an instrument driver with functions to access the process parameters associated with PID algorithms. IMAQ Vision IMAQ Vision is an add-on package for adding image processing and machine vision features to your applications.
5-35
Lesson 5
Additional Topics
Toolkits (cont.)
Enhance LabWindows/CVI through add-on toolkits: Motion Controlmotion sequencing SPCstatistical process control Signal Processing Toolsetsignal processing and spectral analysis
Toolkits (cont.)
Motion Control The Motion Control Module for LabWindows/CVI provides an interactive development environment for motion sequencing. The Motion Control Module integrates with NI vision, data acquisition, and instrument control software and hardware. SPC Toolkit The SPC Toolkit contains functions to determine the statistics necessary for process controldeviation, control limits, ranges, process capability. Signal Processing Toolset The Signal Processing Toolset is a software package that gives users ready-to-run, stand-alone signal processing capabilities and developers high-level digital signal processing (DSP) tools and utilities. The toolset provides four toolkits for digital filter design, joint time-frequency analysis, wavelet and filter bank design, and super-resolution, model-based spectral analysis. You can access all LabWindows/CVI toolkits through instrument drivers. Instrument drivers are general tools for hiding low-level complexity, not just for controlling stand-alone instruments. Though you purchase toolkits in addition to the LabWindows/CVI package, toolkits actually reduce development costs. Before you start developing your application, calculate the time you would spend creating the basic functionality that might already exist in the toolkits. Development time builds quickly. In addition, the maintenance costs of in-house development are higher than buying tools that you can customize.
5-36
ni.com
Lesson 5
Additional Topics
Note There might be licensing issues regarding toolkits if you want to distribute applications that use them.
5-37
Lesson 5
Additional Topics
Summary Lesson 5
This lesson describes a wide variety of topics about the powerful set of LabWindows/CVI features. Multithreaded Programmingusing the threading tools of LabWindows/CVI to create efficient programs Platform SDKadding the power of Windows programming to LabWindows/CVI Utility functionsuncovering the depth of LabWindows/CVI functions
Summary Lesson 5
This lesson describes an assortment of features that extend the basic functionality of LabWindows/CVI. To develop programs that take advantage of multiprocessor machines and can do multiple functions at once, break the program into multiple threads using functions in the Multithreading class of the Utility Library. If you cannot find a particular way to accomplish an objective using LabWindows/CVI libraries, you can integrate the Platform SDK into your applications. The Utility Library provides several functions to meet specialized needs, such as handling executables.
5-38
ni.com
Lesson 5
Additional Topics
LabWindows/CVI Publications
LabWindows/CVI Programming for Beginners by Shahid F. Khalid Advanced Topics in LabWindows/CVI by Shahid F. Khalid
LabWindows/CVI Publications
The books listed in the figure above are just a few of the publications written about LabWindows/CVI programming and applications. The National Instruments Web site contains a list of all the LabWindows/CVI books and links to locations where you can purchase these books.
5-39
Lesson 5
Additional Topics
5-40
ni.com
Lesson 5
Additional Topics
Notes
5-41
Lesson 5
Additional Topics
Notes
5-42
ni.com
This appendix contains additional information about National Instruments technical support options and LabWindows/CVI resources.
For more information, contact your local office or NI corporate headquarters. Phone numbers for our worldwide offices are listed at the front of this manual. You also can visit the Worldwide Offices section of ni.com/niglobal to access the branch office Web sites, which provide up-to-date contact information, support phone numbers, email addresses, and current events.
A-1
Appendix A
LabWindows/CVI Resources
This section describes how you can receive more information regarding LabWindows/CVI.
A-2
ni.com
Course Evaluation
Course _______________________________________________________________________________________ Location _____________________________________________________________________________________ Instructor _________________________________________ Date ____________________________________
Instructor
Please evaluate the instructor by checking the appropriate circle. Instructors ability to communicate course concepts Instructors knowledge of the subject matter Instructors presentation skills Instructors sensitivity to class needs Instructors preparation for the class
Unsatisfactory Poor Satisfactory Good Excellent
Course
Training facility quality Training equipment quality Was the hardware set up correctly? The course length was Yes No Too much Just right Not enough Yes No Sometimes Yes No Too long Just right Too short
The detail of topics covered in the course was The course material was clear and easy to follow. Did the course cover material as advertised?
I had the skills or knowledge I needed to attend this course. Yes No If no, how could you have been better prepared for the course? ____________________________________________________________________ _____________________________________________________________________________________________ What were the strong points of the course? __________________________________________________________ _____________________________________________________________________________________________ What topics would you add to the course? ___________________________________________________________ _____________________________________________________________________________________________ What part(s) of the course need to be condensed or removed? ____________________________________________ _____________________________________________________________________________________________ What needs to be added to the course to make it better? ________________________________________________ _____________________________________________________________________________________________ How did you benefit from taking this course? ________________________________________________________ _____________________________________________________________________________________________ Are there others at your company who have training needs? Please list. ____________________________________ _____________________________________________________________________________________________ _____________________________________________________________________________________________ Do you have other training needs that we could assist you with? _________________________________________ _____________________________________________________________________________________________ How did you hear about this course? NI Web site NI Sales Representative Mailing Co-worker Other _____________________________________________________________________________________