Team LiB
Previous Section Next Section

Other Data Sources

Data can take many forms. You have seen data entered from the keyboard. You have seen data entered via the mouse. You have now seen data that comes from a database. What about other data sources? Here are a few different sources of data:

Let's first take a peek at serial connections.

RS-232 Data

I have done quite a bit of serial communication work in just about all programming languages. When .NET came out, I went searching through the namespaces and lists of controls and did not find any reference at all to any RS-232 device. Bummer!

After thinking about it for a while, I realized that serial connections are becoming a thing of the past, at least in the mainstream programming world. More and more devices are leaning toward TCP/IP or USB communication. If you need to talk to a device via an RS-232 device or a modem, though, what can you do?

If you have been using VB 6.0 you already have the answer: Use the MSComm control. This RS-232 and modem OCX has been around for ages. It is a bit outdated these days, but it still works somewhat OK.

Working with the MSComm control (or for that matter, any OCX control) requires a little diversion from normal .NET operating parameters. You will need to use the Component Object Model Interoperability (COM Interop) capability of .NET.

The COM Interop capability of .NET allows you to generate a .NET program that acts as a client or a server to any IDispatch-based COM object. Essentially, you can take an OCX, or perhaps an ActiveX EXE server made in VB 6.0, and use it in a .NET program. This is great news for those of you who want to migrate to .NET slowly—you are still able to use some of your legacy code as is.

The Platform Invocation Services (PInvoke) and COM Interop capabilities of .NET are quite involved, and it would take a whole book to describe them to you. In the case of COM Interop, it is easier to show you how to use it than to tell you what is going on behind the scenes. The next small example shows you how to include and set up the MSComm serial control in a C# program.

Note 

To follow along with this example, you need to have Visual Studio 6.0 installed on your machine. Even if you do not have Visual Studio 6.0 installed, this example is still good to look at, as it is applicable to any OCX control you may want to use.

Start a new project. Mine is called "MSComm." Once you have the form on your screen, you will need to get a reference to the MSComm RS-232 control.

  1. Go to the form and bring the Toolbox into view.

  2. Right-click the Toolbox and choose Customize Toolbox.

  3. Choose the COM Components tab in the Customize Toolbox window and check the Microsoft Communications Control option, as shown in Figure 6-9.

Click To expand
Figure 6-9: Choosing the Microsoft Communications Control in the COM Components tab

Notice that I have the Microsoft Communications Control, version 6.0 highlighted in this window. Double-click it and click OK to select it. Your Toolbox should now have this control in it. Drag the control over to your form and you will see the phone icon on your form.

Notice that adding this control automatically added a couple of references for you, as shown in Figure 6-10.


Figure 6-10: New Communications Control references

Change the name of the control from AxMSComm1 to COM1.

Now that you have an MSComm control on your form, you can write some code to use it. Listing 6-3 presents code for the constructor and code to handle the input event of the control.

Listing 6-3: C# Code for the MSComm Constructor and Delegate
Start example
    public Form1()
    {
      InitializeComponent();

      COM1.CommPort    = 1;
      COM1.Handshaking = MSCommLib.HandshakeConstants.comRTSXOnXOff;
      COM1.Settings    = "9600, O, 7, 1";
      COM1.InputMode   = MSCommLib.InputModeConstants.comInputModeText;
      COM1.InputLen    = 0;
      COM1.NullDiscard = false;
      COM1.OnComm      += new EventHandler(this.CommEvent);
    }

    private void CommEvent(object sender, EventArgs e)
    {
      if (COM1.InBufferCount <= 0)
        return;

      //Do some processing and validation here.
    }
End example

I don't bother presenting the VB code here, because it is virtually identical to the C# code. I would like to note one thing in this code snippet. I set the NullDiscard property to false. In case you have not run across it yet, null can be a very important character. It is especially important in the RS-232 world. For instance, if you were to program a Class 1 fax program, you would use a string of a few thousand nulls as training characters. If this property were set to true (by default), you would never be able to train to the sending fax machine.

Null has also become very important in the last several years with the rise in importance of Unicode character storage. For the uninitiated, Unicode is used in VB 6.0 and in .NET to hold internal representations of characters. In simple terms, Unicode is a 2-byte representation of a character.

You may have heard of the American Standard Code for Information Interchange (ASCII) coding scheme. Since the dawn of time,[2] ASCII has defined the characters you can type in a computer and the binary representation of their storage. ASCII relies on a 256-byte set of characters whose lower 127 bytes are fixed as the normal Latin/English character set. In order to handle multiple languages, a code page scheme was developed to represent characters of another language. For instance, if you switched your code page to CP1251, you would get a set of Russian characters.

Using ASCII to save strings of characters is all but dead. Since Windows NT, most programs store characters as Unicode. As you can guess, though, there has to be some compatibility between ASCII and Unicode. There is. The normal IBM code page 437 for Latin/US English is at the beginning of the Unicode character set. To be compliant with the 4-byte rule of Unicode, the first 2 bytes are null (i.e., 0x00 in hex). So the Unicode representation of the letter N is 0x004E. The ASCII representation of this letter is 0x4E.

Tip 

As a programmer, you should be thoroughly familiar with Unicode. The standard is published on the Web at http://www.unicode.org and there are numerous tomes available regarding Unicode.

So the upshot of all this Unicode stuff is that you may get a Unicode data stream from an RS-232 device (such as another computer), and if you discard null characters you will get only half the information.[3]

Incidental Data

You can treat the other sources of data I mentioned earlier, such as USB devices and barcode readers, in the same way as RS-232 data. Basically, you are getting a data stream from an outside source. Most likely, you will have an interface DLL that comes with a third-party barcode reader or USB device. These DLLs will often have all the necessary methods to allow you to get the data from the device.

Once you have the data, your program should not care where the data came from. It only needs to know how to handle and validate the data. Too often I have seen programs that have the data gathering code hopelessly intertwined with the data management code. This is so wrong.

If you are going to get data from an external source, you should encapsulate the method of getting the data in a class. This class should have an interface that the rest of the program could use to access that data.

Here's a real live "for-instance" situation. I work for a company that interfaces with high-end biometric identification devices (e.g., fingerprint scan, iris scan, hand geometry, and so forth). One of these devices has several ways to communicate with the outside world: serial connection, modem, and network IP. My programmatic interface to this device is not dependent upon the method of communication. I have a self-contained class that detects how the device is connected to my PC. This class saves data to the same internal structure whether it is talking via RS-232, network, or modem. This class has an interface to the outside world that serves up data the same way no matter how it was obtained. I use this program with up to several hundred devices, all of which are a mix of RS-232 and network devices. I make no changes in my code based on the communication method. If the RS-232 protocol was enhanced for speed, I would need to change only this one class to take advantage of that.

What I am saying here is that you should not choke if someone asks you to create a program whose data is not in a database. Encapsulate and debug the data gathering class, and then move on to the rest of the code. Once you get the data, you are in familiar territory.

[2]Many years, anyway.

[3]My wife often claims that she talks in Unicode and I only listen in ASCII!


Team LiB
Previous Section Next Section