Joseph Frese
Keithley Instruments, Inc.
In Part I of this article, we described most of the VB6 code required to link input controls, such as text boxes and check boxes, to a users test system. These controls allow a remote user to configure a data acquisition (DAQ) card by entering a channel number, channel gain, sampling frequency, and number of samples on an HTML form. The test system then acquires the requested data and displays it on a web page as a JPEG graph, and (optionally) in text form. In this final part of the article, we define the replacements for custom tags that are used with the HTML template that was created. We also present some code that implements the WebClass/User Interaction in this test system. Results are illustrated with typical user screens.
WebClass/Template Interaction The ProcessTag event subroutine is fired every time one of our custom tags is encountered. To define the replacements for the custom tags, use the code in Table 7 in the code window:
Table 7. Template1_ProcessTag() subroutine.
Private Sub Template1_ProcessTag(ByVal TagName As String, _ TagContents As String, _ SendTags As Boolean) Dim I As Integer Select Case LCase(TagName) '... End Select End Sub |
The TagName parameter here is the custom tag as it appears in the template. TagContents is the string wed like to replace the custom tag with, which we must define in the subroutine. SendTags allows you to send XML tokens to the client and is useful for debugging; its default value is false and for our purposes thats just fine.
Because we have three custom tags, lets deal with this subroutine in bite size chunks, one tag at a time. The following three tables present code snippets that you need to insert into the Select block of the Template1_ProcessTag() subroutine above.
Table 8. "[email protected]" code for Select block of the Template1_ProcessTag() subroutine.
Case "[email protected]" 'Show the graph (if one exists) If strPic <> "" Then TagContents = "<P ALIGN=CENTER><IMG SRC=" & strPic & ">" End If If ErrMsg <> "" Then TagContents = TagContents & "<STYLE " & _ "TYPE=""text/css"">P.error {color: " & _ "red;)</STYLE><P ALIGN=Center " & _ "CLASS=""error"">" & ErrMsg End If |
The Case subroutine in Table 8 adds the graph JPG (if it exists) to the document. If it does not exist, then presumably strPic will be empty. The subroutine also displays in red any error messages that may exist.
Table 9. "[email protected]" code for Select block of the Template1_ProcessTag() subroutine.
Case "[email protected]" 'Write the input controls TagContents = "<CENTER><TABLE BORDER=0>" TagContents = TagContents & vbCrLf & _ "<TR><TD>Channel:</TD><TD><INPUT TYPE=""text""" & _ "NAME=""iChannel"" VALUE=""" & Channel & """></TD></TR>" TagContents = TagContents & vbCrLf & _ "<TR><TD>Gain:</TD><TD><INPUT TYPE=""text""" & _ "NAME=""iGain"" VALUE=""" & Gain & """></TD></TR>" TagContents = TagContents & vbCrLf & "<TR><TD>Number of " & _ "Samples:</TD><TD><INPUT TYPE=""text""" & _ "NAME=""iNumSamples"" VALUE=""" & NumSamples & _ """></TD></TR>" TagContents = TagContents & vbCrLf & _ "<TR><TD>Frequency:</TD><TD><INPUT TYPE=""text""" & _ "NAME=""iFrequency"" VALUE=""" & Frequency & _ """></TD></TR>" TagContents = TagContents & vbCrLf & _ "<TR><TD ALIGN=CENTER><INPUT TYPE=""checkbox""" & _ "NAME=""iShowData"" VALUE=""True""" If ShowData Then TagContents = TagContents & "CHECKED" TagContents = TagContents & "> Show data" TagContents = TagContents & vbCrLf & "</TABLE></CENTER>" |
In Table 9, the Case subroutine displays the input controls for the end-user. These include:
If the user checks this last box, then we need to display the data in text format, and that is precisely what the final Case in Table 10 accomplishes:
Table 10. "[email protected]" code for Select block of the Template1_ProcessTag() subroutine.
Case "[email protected]" 'Show the data (if requested) If ShowData Then TagContents = TagContents & vbCrLf & _ "<TR><TD ALIGN=CENTER><BR><HR>" & _ "<P><B><BIG>Data:</BIG></B><P>" & _ "<TABLE WIDTH=300><TR><TD VALIGN=Top>" For I = 0 To NumSamples / 3 - 1 TagContents = TagContents & vbCrLf & Data(I) & "<BR>" Next I TagContents = TagContents & "</TD><TD VALIGN=Top WIDTH=33%>" For I = NumSamples / 3 To 2 * NumSamples / 3 - 1 TagContents = TagContents & vbCrLf & Data(I) & "<BR>" Next I TagContents = TagContents & "</TD><TD VALIGN=Top WIDTH=33%>" For I = 2 * NumSamples / 3 To NumSamples - 1 TagContents = TagContents & vbCrLf & Data(I) & "<BR>" Next I TagContents = TagContents & "</TD></TR></TABLE></TD></TR>" End If |
This final Case uses a lot of HTML code to essentially format our data into three even columns.
(Presumably, the data has been stored in the Data() array and NumSamples has been set to the size of this array.)
That wraps up the Template1_ProcessTag subroutines controlling our WebClass/Template interaction. If we click the RUN button on the Visual Basic debug toolbar to run our code, we begin to see the fruits of our labor. (VB will first ask you to select a Start Component and may ask you to name a Virtual Directory for the project to execute in; for our purposes, accepting the defaults for these values is fine.) Your default web browser should automatically open and display a page similar to the one below:
The fact that our input controls showed up (with the default values we specified in WebClass_Start) means that our project is proceeding as planned; however, if you click the Submit button, youre taken to a blank page. To actually acquire data, we need to implement the Template1_Form1 subroutine.
WebClass/User Interaction Since the Template1_Form1 event is fired when the user hits the "submit" button, we create the code in Table 11 to request the pertinent information from the form. This information is used to execute our data acquisition.
Table 11. Template1_Form1() event subroutine.
Private Sub Template1_Form1() Dim Test As New clsTestSystem 'Get user input from web page Channel = Request("iChannel") Gain = Request("iGain") NumSamples = Request("iNumSamples") Frequency = Request("iFrequency") ShowData = Request("iShowData") 'Validate the input parameters If Not (IsNumeric(Channel) And IsNumeric(Gain) And _ IsNumeric(NumSamples) And IsNumeric(Frequency)) _ Then GoTo InputErr 'Acquire the data If (0 = Test.AcquireData(Channel, Gain, Frequency, _ NumSamples, Data())) Then 'If no error, create the graph and assign name to strPic strPic = Test.CreateGraph(Data, NumSamples) If strPic = "" Then ErrMsg = "Error graphing data!" Else 'Otherwise, set ErrMsg strPic = "" ErrMsg = "Error acquiring data!" End If EndSub: Set Test = Nothing 'Fire the Template1_Respond event Set NextItem = Template1 Exit Sub InputErr: StrPic = "" ErrMsg = "Input error!" GoTo EndSub End Sub |
The subroutine above begins by requesting the values from our input controls. Each of the Request functions take the name property of the appropriate input tag and return that controls value. The subroutine then validates the parameters before feeding them to our test system DLL, which acquires the requested data and (if there are no errors) generates the graph JPG. Relevant global variables (Data(), strPic, and ErrMsg) are updated along the way. Finally, the last line of the routine fires the Template1_Respond event, so our HTML template gets parsed, processed, and written again. If you execute this now-completed project and hit the Submit button, and your test system DLL was written correctly, your browser window should look something like the following:
If you check the "Show data" box and hit the "submit" button again, individual data points will be reported:
Now you can make TestInterface.DLL and share your project with your friends and neighbors. Just make sure your personal web server is running, and point any computer on your network to the proper URL (which should be http://yourIPaddress/Project1/WebClass1.asp, if you kept the default values for the virtual directory and the WebClasss ASP name). Youve just made your test system accessible to everyone on your local Intranet, and if youre on the Internet, to everyone in the world.
Joseph Frese joined Keithley Instruments in Cleveland after receiving a bachelors degree in Computer Engineering from Case Western Reserve University. He currently is a Development Engineer for Keithleys Data Acquisition product line.
# # #