Search This Blog

Thursday, December 2, 2010

How to be Controlling

During the project I mentioned last posting, the C# expert created several custom controls using COBOL which we used on the various WinForms in the application.  I myself have never done anything with user controls and since I haven't seen it written up anywhere else, I thought this would make for a good topic for discussion.   How do you create a custom control using COBOL?

Yep.  I'm glad you asked *smile*

Instead of starting from scratch, I figured the right approach would be to capitalize on work done by others.  And by taking that approach, I found an article at which made my job easy.  The article spells out how to create a custom progress bar for your application.  Seems like something useful huh?

Before I get started, let me make it clear that I’m not going to go into all the details on custom controls in this article. You can find more information in much greater detail and deeper understanding than anything I could write (in the referenced article for one).  I’m going to spend my time on recreating the same control Dave (the original author) outlined in his post.  The difference is that I’ll be using Micro Focus Visual COBOL and Visual Studio 2010. So, print out Dave’s directions and follow along with me while I highlight the differences.
 Getting Started
First I created the same project using the same name, but instead of C#, I selected to create a managed COBOL Windows Forms Application (didn't want to strain too much by thinking too hard too soon of course).

Next, just like Dave, I added a new project to the solution and call it “ProgressBar”, making sure to select managed COBOL Class library as the template.
 I then added the reference to the new project as directed and was ready to create the control.   As with the C# example, Visual COBOL created a shell class program for me to use as a base. And as in the example, I deleted it because I wouldn’t be using it.

 From the Solution Explorer, I selected the ProgressBar project and right clicked to Add a new item, selected “User Control” from the menu and named it “ProgressControl”.  

  Once the user control was created, I set the properties as Dave had them:

  •  BackColor: Window
  • BorderStyle: FixedSingle
  • Size: 148, 14
  • Double-Buffered: True
As for the Code
Since I used COBOL, you’ll notice the code behind page that was created for the ProgressControl is very similar to the C# version.

Next, I added the code to allow for the choosing of a foreground color for the progress bar  and added the “System.Drawing” namespace to the program so that I didn’t have to fully qualify things like “System::Drawing::Color” in my COBOL code. I just want to type “Color” same as Dave did in the C# routine. To do this, I typed the appropriate $set statement at the top of the program. While I was there, I also added a line for “System.Windows.Forms” because we’ll need it later.

You’ll also see I added the variable definition to the working storage section for barcolor.  In the original C# example, Dave typed:
The biggest difference is that I had to write a bit more code for the get and set methods than what the C# had. Not much, but I had to spell out each method, along with its own working storage, procedure division, etc.

Once that portion was coded, I had to make a slight change to the code to create the Value property. Because Value is a reserved word in COBOL. So, instead of using “Value” as a variable name, I used pvalue. I placed the the working storage definition directly after the definition for barcolor (see above).

I used COMP-1 because this is the COBOL equivalent of a short Float.  And as with the ForeColor get and set methods above, I wrote the two methods to do what the C# code does:

 Again, you’ll notice that I used COMP-1 when defining the field that is to be used as a short Float. The last bit of code looks like this:

Two items may stand out here. The first is the invoke statement “invoke super::OnPaint(e)”. Simply put, C# uses the keyword “base”, while COBOL uses “super” to refer to the original superset or base version of the method. Dave’s article points out that this particular statement is optional in his simple example but recommended for more complex paint routines. If I had used “self” instead of “super”, the code would be referring to the current version of the method (the code shown above). That would cause a recursive loop where every time the method was called, the first thing it would do is call itself. That situation ultimately consumes the memory of the machine (guess how I know *smile*) causing Visual Studio to abend.

The second item which may stand out in this piece of code is that in the C# example, Dave used “Int” to remove the decimal values from the resulting calculation. Instead of dealing with that, I just created a width field with no decimal value. Everything else, I followed the directions provided by Dave. And much to my surprise it worked first second  third time I hit the run button.

Of course I left out all the mistakes I made trying to decipher the C#, but I never claimed to be a C# programmer now did I? That’s what I call my buddy Mike for.  *smile*

Hopefully you find this of interest / value.  If you find any errors in my code or suggestions on how to make this better, by all means, please share!  All contributions greatly appreciated!