Tuesday, 21 February 2012

The Ripped abs Function in C++

I wanted to use the abs function in C++. I checked documentation and found a lack of specifications and seeming contradictions. There were also various versions of functions to get an absolute value (abs, labs, fabs). Instead of trying to make sense of what reference was correct or outdated, I plunged ahead with code to see what would work or what didn’t work. Here’s the results.

Note: I used Visual C++ 2010.
Double Note: The MS documentation on this issue was weak.

Attempt No. 1.

My first attempt was simply to use the abs function on a double variable.

double dVal = -10;
dVal = abs(dVal);

It resulted in a compile error: C3861: 'abs': identifier not found

I knew I needed to include a header file, but I tried it this way to see what would happen.

Attempt No. 2.

What if I added a reference to the standard namespace when calling the abs function?

double dVal = -10;
dVal = std::abs(dVal);

No improvement. This time I got two compiler errors:

C3861: 'abs': identifier not found
C2039: 'abs' : is not a member of 'std'

Attempt No. 3.

Right, time to add a header file, but which one?

#include <cstdlib>
#include <stdlib.h>
#include <cmath>
#include <math.h>.

I saw documentation, text and sample code using one or the other. Instead of continued frustration looking for the answer, I decided I would try each library separately with this code.

#include <cstdlib> | <cmath>
...
double dVal = -10;
dVal = abs(dVal);

The standard library <cstdlib> resulted in a compile error:

C2668: 'abs' : ambiguous call to overloaded function

Running the code with either math library worked fine. The variable dVal becomes 10.000000000000000.

Why the compile error and what header file to include? Part of the confusion lies in the fact the abs function shows up in two different header files.

Here’s what I learnt from the ISO C++ Standard documentation (N3337 2012-01-16). It’s known as C++11—the latest standard of C++, and I should have looked here first.

<math.h> and <stdlib.h> are Standard C library headers. That's the C language, not C++, but since the C++ is a superset of C, the C++ Standard library headers <cmath> <cstdlib> are the same as in C except C++ extends them. (I refer you to paragraph 4 of subclause 26.8 of the ISO C++ Standard.)

The abs function in <cstdlib> takes an integer and returns an integer. If you use the <cmath> library, the function takes a float-point number and returns the same. Both have variations depending on the number of bits used for a particular type.

The <cstdlib> header supports:

int abs (int);
long abs (long);
long long abs (long long);

The long long data type is a 64-bit integer and new to the C++11 standard. This implementation exists in Visual C++ 2010. Microsoft also has it’s own integer types of __intN where N is 8, 16, 32, 64 or 128. __int64 is the same as long long.

The <cmath> header supports:

float abs (float);
double abs (double);
long double abs (long double);


Attempt No. 4.

Focusing on the standard library <cstdlib>, I tested the following code.

#include <cstdlib>
...
int iVal = -10;
iVal = abs(iVal);

The code executes as expected and iVal becomes 10.

But here’s a twist.

#include <cstdlib>
...
iVal = -2147483648;
iVal = abs(iVal);

The value of iVal remains the same. It’s still the exact same negative number. How can that be? To get the answer you have to understand the range of the integer data type. On my computer, int variables are signed 32-bit numbers. The range is -2,147,483,648 to 2,147,483,647. The negative number exceeds the maximum positive number. The abs function worked. It took the negative number, made it positive but since it was larger than the upper limit, it became a negative number. You’ll get the same result if you took the upper limit and added one.


Attempt No. 5.

Focusing on the math library <cmath>, I tested the following code.

#include <cmath>
...
float fVal = -10.123456; // Works.
fVal = abs(fVal);

double dVal = -10.123456; // Works.
dVal = abs(dVal);

The data type long double is the same as double in Visual C++ 2010.

There was no problem using the function.

Attempt No. 6.

The previous code had either the standard library or the math library but not both. What happens when both headers are included? I ran code similar to above and it worked. No compiler errors. No unexpected return values.

Final Thought.

In C, the program has more than one function to determine the absolute value of a number.

abs                 for integers
fabs              for float, double or long double
labs              for long int

Why have variations? Because overloading a function does not happen in C, but it is part of C++. What does that mean? With overloading, the parameters passed to a function can varying depending on their type. In turn, the return value reflects the parameters passed. In C, it needed three different functions to handle the different data types. Not so in C++, yet these C functions  remain because the philosophy of the C++ Standard is to take C and add on to it.

Monday, 20 February 2012

Copy One Dimensional Arrays in C++

If you have two integer variables, you can easily copy the value of one to the other with this code:

int1 = int2;

If you try the same thing with arrays,

mArray1 = mArray2;

the code will not compile. You will get a compile error message.

Each element of the array has to be assigned from one variable to the other.

Sample Code:

The sample code will create array variables, A and B, of integer type. Values are assigned to each element of A then copied to B.

The sample code was created in MS Visual C++ as a Windows Form Application. It contains a form (Form1) that displays when the program runs. The sample code, contained in the Form Load Event, executes and adds text to a RichTextBox named rtOut.

// Declare one-dimension arrays.
int A[10], B[10];
rtOut->Text = "Declare two one-dimension arrays: ";
rtOut->Text += "int A[10], B[10]; \n\n";

// Declare counter.
int i = 0;

// Load array with multiples of 10s.
rtOut->Text += "Load array A with multiples of 10s. \n\n";
for (i; i < 10; i++) A[i] = i * 10;

// Copy value of A to B.
// Can't use: A = B;
rtOut->Text += "Copy value of A to B, element by element with B[i] = A[i]. \n\n";
// Counter i reset to 0.
for (i = 0; i < 10; i++) B[i] = A[i];

// Show content.
// Counter i reset to 0.
for (i = 0; i < 10; i++)
{
rtOut->Text += "The A[" + i + "] value is " + A[i] + ". The B value is " + B[i] + "\n";
}

Output:

Declare two one-dimension arrays: int A[10], B[10];

Load array A with multiples of 10s.

Copy value of A to B, element by element with B[i] = A[i].

The A[0] value is 0. The value of B at index 0 is 0
The A[1] value is 10. The value of B at index 1 is 10
The A[2] value is 20. The value of B at index 2 is 20
The A[3] value is 30. The value of B at index 3 is 30
The A[4] value is 40. The value of B at index 4 is 40
The A[5] value is 50. The value of B at index 5 is 50
The A[6] value is 60. The value of B at index 6 is 60
The A[7] value is 70. The value of B at index 7 is 70
The A[8] value is 80. The value of B at index 8 is 80
The A[9] value is 90. The value of B at index 9 is 90



Problem With One-line if Statement in C++

The simplest if statement in C++ is one line in this form:

if (condition) statement;

But it’s possible to include multiple statements as in:

if (condition) statement[, statement...];

Either use should be contrasted to ones using a block statement.

Note the use of a comma to separate each statement and not a semicolon. To understand what can go wrong, look at the sample code.

Sample Code:

The sample code was created in MS Visual C++ as a Windows Form Application. It contains a form (Form1) that displays when the program runs. The sample code, contained in the Form Load Event, executes and adds text to a RichTextBox named rtOut.

// Declare variables.
int a, b;

// One statement after if leads to an expected result.
if (true) a=10;
rtOut->Text += "a is " + a + ".\n";

// Two statements after if with a comma leads to an expected result.
if (true) a=10, b=20;
rtOut->Text += "a is " + a + " and b is " + b + ".\n";

// Two statements after if using semicolon may be a problem.
// First change a's value.
a = 100;
if (false) a=10; b=200;
rtOut->Text += "a is " + a + " and b is " + b + ".\n";


Output:

a is 10.
a is 10 and b is 20.
a is 100 and b is 200.

The first if statement executed as expected and assigned the value of 10 to variable a.

The second if statement again executed the two statements and changed the values of a and b as expected, but the third use of if creates a surprise.

We changed the value of a to 100 and it remained at 100. The assignment statement of a=10 isn’t executed. A quick look at the statement leads you to believe the assignment of 200 to b is part of the if statement and shouldn’t get executed because the condition isn’t true, but the assignment of 200 to b is executed because the if statement ends with the semicolon. The ‘b=200;’ statement is really a new line of C++ code unaffected by the if statement.

This line of code:

if (false) a=10; b=200;

is the same as this:

if (false) a=10;
b=200;

For certainty and readability, it’s better to write the code with a block statement.

The Basics of a One-dimensional Array in C++

Here is a discussion on creating and using a one-dimensional array in C++.

An array is a variable of one data type with multiple values. In C++, each array holds values of the same date type (i.e., all integers or all floating point numbers). It’s a computer version of a matrix from mathematics. A one-dimensional array is similar to a matrix with one row or one column.

An array is created by specifying the data type (e.g., char, int) followed by a user-defined variable name and the maximum number of elements in square brackets.

type name[size];

For example, this declaration

int myArray[10];

creates an array called myArray with 10 elements of type integer.

Each element of the array is accessed by an index. The base index is 0 and increases by 1 to the size of the array less one (size – 1). The indices of an array with 10 elements are 0 to 9.

You access an element of an array by specifying its name followed by the specific index number in square brackets. There can be spaces between the name of the array and the square brackets, but convention is to not have a space.

variable_name[index]  // No space.
variable_name [index] // Space in between.

For example,

myArray[0] = 10;

stores 10 in the first element of the array.

Unlike a stack, an array can be accessed in any order.

The data of an array is stored sequentially in memory and can be accessed directly. The amount of memory used varies with the data type.

Sample Code.

The sample code was created in MS Visual C++ as a Windows Form Application. It contains a form (Form1) that displays when the program runs. The sample code, contained in the Form Load Event, executes and adds text to a RichTextBox named rtOut.

// Declare a one-dimension array of integers.
int sample[10];
rtOut->Text = "Declare one-dimension array: ";
rtOut->Text += "int sample[10]; \n\n";

// Counter.
int i = 0;

// Load array with 0 to 9.
// The value stored in the array is its index.
for (i; i < 10; i++) sample[i] = i;

// Show content.
// Note the counter i is reset to 0.
for (i = 0; i < 10; i++)
{
rtOut->Text += "The value of sample[" + i + "] is " + sample[i] + ".\n";
}

Output:

Declare one-dimension array: int sample[10];

The value of sample[0] is 0.
The value of sample[1] is 1.
The value of sample[2] is 2.
The value of sample[3] is 3.
The value of sample[4] is 4.
The value of sample[5] is 5.
The value of sample[6] is 6.
The value of sample[7] is 7.
The value of sample[8] is 8.
The value of sample[9] is 9.

Saturday, 18 February 2012

The char Data Type in C++

Here is a brief discussion on the char data type in C++.

The sample code was created in MS Visual C++ as a Windows Form Application. It contains a form (Form1) that displays when the program runs. The sample code, contained in the Form Load Event, executes and adds text to a RichTextBox named rtOut.

1. Declaring A Character Variable

The most common way to declare a char variable is:

char cVarName;

char is a C++ keyword used to declare the user-named variable cVarName.

You get the same result by using the signed modifier in the declaration. A modifier is also referred to as a specifier.

signed char cVarName;

In both cases, cVarName is a 1 byte character variable. The range of its value is -128 to 127 for a total of 256 possible values.

You can assign an integer value to the variable when you declare it:

char cVarName = 65;

Or you can assign a single character to the variable.

char cVarName = 'A';

Note the use of the single quotation marks instead of double quotation marks. Single quotes are used for a character. Double quotes are used for strings. If you used double quotes, the compiler will note the error and not finish.

In both cases, the program will store the ASCII code 65 in memory for cVarName.

The third way to use the char declaration is with the unsigned modifier.

unsigned char cVarName;

In this instance, cVarName holds only positive values from 0 to 255. 1 byte (8 bits) allows for 256 possible values.

2. Storing Data In A Character Variable.

You can assign an initial value in your declaration.

char cVarName = 'A';
char cVarName = 65;

The following examples however will result in a compile error.

cVarName = "A";

The use of double quotes is for strings and this variable is a character, not a string.

cVarName = '';

The empty character is not a character nor is it null or zero. The assignment of an empty character will result in a compile error.

cVarName = void;

Similar to the empty character. You cannot assign void to a character variable.

The following assignments will work.

// Space or ASCII code 32.
cVarName = ' ';
cVarName = 32;

// Null.
cVarName = '\0';
cVarName = 0;


3. Char Size & Range

In all instances, the character variable is 1 byte in size. Since 1 byte is 8 bits, we know there are 256 possible variations. 2 to the power of 8 is 256. Since 0 is included, the range is 0 to 255 for unsigned and -128 to 127 for signed.

The compiler will not object to assigning values outside the range, nor will the program crash. For example,

cVarName = 123654987;

will work; however, the value you retrieve from the variable will be some number in the range for the data type and not the out-of-range value.


4. Sample Code: Signed char

// [Signed] Character type.
// 1 byte.
// Range: -128 to 127

// Start.
rtOut->Text = "Character type: [signed] char variable_name";
// Line feed.
rtOut->Text += "\n";

rtOut->Text += "1 byte, Range: -128 to 127";
rtOut->Text += "\n";
rtOut->Text += "\n";

// Declare signed char variable.
signed char cB = ' ';

cB = -129;
rtOut->Text += "Set variable to -129 (cB = -129;) results in " + cB + ". It's out of range. \n";

cB = -128;
rtOut->Text += "Set variable to -128 (cB = -128;) results in " + cB + ". It's in range. \n";

cB = 127;
rtOut->Text += "Set variable to 127 (cB = 127;) results in " + cB + ". It's in range. \n";

cB = 128;
rtOut->Text += "Set variable to 128 (cB = 128;) results in " + cB + ". It's out of range. \n";

Output:

Character type: [signed] char variable_name
1 byte, Range: -128 to 127

Set variable to -129 (cB = -129;) results in 127. It's out of range.
Set variable to -128 (cB = -128;) results in -128. It's in range.
Set variable to 127 (cB = 127;) results in 127. It's in range.
Set variable to 128 (cB = 128;) results in -128. It's out of range.


5. Sample Code: Unsigned char

// Unsigned character type.
// 1 byte.
// Range: 0 to 255

unsigned char cC;

// Start.
rtOut->Text += "Character type: unsigned char variable_name";
rtOut->Text += "\n";
rtOut->Text += "1 byte, Range: 0 to 255";
rtOut->Text += "\n";
rtOut->Text += "\n";

cC = 0;
rtOut->Text += "Set variable to 0 (cC = 0;) results in " + cC + ". It's in range.";
rtOut->Text += "\n";

cC = 127;
rtOut->Text += "Set variable to 127 (cC = 127;) results in " + cC + ". It's in range.";
rtOut->Text += "\n";

cC = 256;
rtOut->Text += "Set variable to 256 (cC = 256;) results in " + cC + ". It's out of range.";
rtOut->Text += "\n";

cC = -1;
rtOut->Text += "Set variable to -1 (cC = -1;) results in " + cC + ". It's out of range.";
rtOut->Text += "\n";

Output:

Character type: unsigned char variable_name
1 byte, Range: 0 to 255

Set variable to 0 (cC = 0;) results in 0. It's in range.
Set variable to 127 (cC = 127;) results in 127. It's in range.
Set variable to 256 (cC = 256;) results in 0. It's out of range.
Set variable to -1 (cC = -1;) results in 255. It's out of range.

The if Statement in C and C++

While it’s possible to write code without ever using the if statement, you’ll probably use it all the time. Below is a summary of its use in C and C++.

1. If Statement—One Line No Else

The simplest form of the if statement is one line and executes when the condition is true.

if (condition) statement[,statement...];

If is a C++ keyword and must be in lowercase. C++ is case sensitive. The code after (condition) to the semicolon will execute if the condition is true. Note, the word THEN is not used.

Sample Code:

The sample code was created in MS Visual C++ as a Windows Form Application. It contains a form (Form1) that displays when the program runs. The sample code, contained in the Form Load Event, executes and adds text to a RichTextBox named rtOut.

// Declare Boolean variable.
bool bCondition;
// Set to true.
bCondition = true;
// Add text to text property of RichtextBox rtOut.
if (bCondition) rtOut->Text += "bCondition = true;\n";

Since bCondition is true, the code will add the string "bCondition = true;\n" to the text property of rtOut.

Output:

bCondition = true;

While you can write a one-line if statement with several C++ statements after the condition, it’s preferable to use a block statement as discussed below. Block statements are easier to read.

Declaring the Boolean variable and assigning an initial value at the same time also works.

bool bCondition = true;
if (bCondition) rtOut->Text += "bCondition = true;\n";


2. If Statement—One Line With Else

You can use the keyword else to execute code when the condition is false.

if (condition) statement[,statement...];
else statement[,statement...];

Sample:

// Set to false.
bCondition = false;
// Add text to text property of RichtextBox rtOut.
if (bCondition) rtOut->Text += "bCondition = true;\n";
else  rtOut->Text += "bCondition = false;\n";

Since bCondition is false, "bCondition = false;\n" is added to rtOut;

Output:

bCondition = false;


3. If Statement—Block Statements

If you want to execute many lines of code instead of one. You do that by creating a block statement. Sometimes referred to as a compound statement or compound statements. A block statement starts with a curly opening bracket { and ends with the closing bracket }. Some people refer to them as braces. (See wikipedia for more.)

if (condition)
{
   statement;
   statement;
}
else
{
   statement;
   statement;
}

An example with true.

// Set to true.
bCondition = true;
if (bCondition)
{
  // Text added to rtOut.
  rtOut->Text += "bCondition = true;\n";
  rtOut->Text += "It really is true.\n";
}

An example with false.

// Set to false.
bCondition = false;
if (bCondition)
{
  // Not executed.
  rtOut->Text += "bCondition = true;\n";
}
else
{
  // Text added to rtOut.
  rtOut->Text += "bCondition = false;\n";
  rtOut->Text += "Honest. It's false.\n";
}

Output:

bCondition = true;
It really is true.
bCondition = false;
Honest. It's false.

Placing the curly brackets on separate lines is not a requirement. It’s a convention to make the code more readable for humans, not the computer. To the compiler, the source code is one long series of characters.

4. If…Else If…Else Statement

The if…else statement allows for a binary execution of code, true or false. The use of the if…else if…else allows for more than two conditions. It’s structured as follows:

if (condition) statement[,statement...];
else if (condition) statement [,statement...];
else statement [,statement...];

Or with block statements.

if (condition)
{
   statement;
   statement;
}
else if (condition)
{
   statement;
   statement;
}
else (condition)
{
   statement;
   statement;
}

You can have more than one else if lines.

This sample code acts on the value of an integer variable being positive, zero or negative.

// Declare integer variable.
int iCondition;

// Positive.
iCondition = 10;
rtOut->Text += "iCondition set to 10\n";
if (iCondition > 0 ) rtOut->Text += "iCondition > 0;\n";
else if (iCondition < 0 ) rtOut->Text += "iCondition < 0;\n";
else  rtOut->Text += "iCondition = 0;\n";

// Negative.
iCondition = -10;
rtOut->Text += "iCondition set to -10\n";
if (iCondition > 0 ) rtOut->Text += "iCondition > 0;\n";
else if (iCondition < 0 ) rtOut->Text += "iCondition < 0;\n";
else  rtOut->Text += "iCondition = 0;\n";

// Zero.
iCondition = 0;
rtOut->Text += "iCondition set to 0\n";
if (iCondition > 0 ) rtOut->Text += "iCondition > 0;\n";
else if (iCondition < 0 ) rtOut->Text += "iCondition < 0;\n";
else  rtOut->Text += "iCondition = 0;\n";

Output:

iCondition set to 10
iCondition > 0;
iCondition set to -10
iCondition < 0;
iCondition set to 0
iCondition = 0;


5. Condition & Data Types

Any valid C++ expression can be used to control the if statement.  The type of conditional expression need not be restricted to only those involving the relational and logical operators or to the operands of the type bool. All that is required is that the controlling expression evaluate to either a true or false. A value of zero is automatically converted into false and all non-zero values are converted into true. Thus any expression that can be converted into a number can be used as the control for an if statement.

Here are some data types that can be used as a condition to control an if statement.

bool bCondition = true | false;

int iCondition = non-zero | zero;

float fCondition = non-zero | zero;

char cCondition = non-zero | zero;

While you would normally use the keywords true or false with a Boolean data type, C++ won’t object to assigning a numeric value to a Boolean variable. The condition will equate zero as false and non-zero as true.

// Declare Boolean variable.
bool bCondition;

// Set to positive value.
bCondition = 10;
if (bCondition) rtOut->Text += "bCondition = 10;\n";

// Set to negative value.
bCondition = -10;
if (bCondition) rtOut->Text += "bCondition = -10;\n";

// Set to zero.
bCondition = 0;
if (bCondition) rtOut->Text += "bCondition != 0;\n";
else  rtOut->Text += "bCondition = 0;\n";

Output:

bCondition = 10;
bCondition = -10;
bCondition = 0;

A character variable can act as a condition expression for an if statement.

// Declare character variable.
char cBol;

// Non-zero value.
cBol = 'A';
if (cBol) rtOut->Text += "cBol = 'A';\n";

// Null or zero value.
cBol = '\0';
if (cBol) rtOut->Text += "cBol != '\\0';\n";
else rtOut->Text += "cBol = '\\0';\n";

Output:

cBol = 'A';
cBol = '\0';


As well for floating-point variables.

// Declare a floating point variable.
float fBol;

fBol = 123.456;
if (fBol) rtOut->Text += "fBol = 123.456;\n";

fBol = 0;
if (fBol) rtOut->Text += "fBol != 0;\n";
else rtOut->Text += "fBol = 0;\n";

Output:

fBol = 123.456;
fBol = 0;


Thursday, 16 February 2012

The First Steps in Coding. Only 124K of RAM.

I’ve been using computers since the original IBM PC came out. That computer had an 8088 Intel CPU (8 bits). I don’t remember the clock speed but 4.4 MHz sounds familiar. There was 124K of memory and one 5.25 include floppy drive. Later the memory was doubled to 256K and a second floppy drive added. There was no modem. No networking. It was a stand alone computer that could only do what your programs would allow you to do. No free apps to download.

To run the computer you would first boot it up with the operating system disc in the drive. Once up and running, a simple “A:>” starred at you and waited for you to type something like DIR A: or debug myprogram.exe. Windows and GUI weren’t here. There was a keyboard, but no mouse. The screen had one colour: a dark green. A monochrome screen.

Throw in a second floppy disc to run Word Star--an adequate word processing program. Or another disc for Lotus 123, a spreadsheet app. I had some use for these programs, but I spent most of my time on it coding and reading. I had a subscription to PC Magazine which had all sorts of cool code and write ups. I had the PC DOS manual. A small binder. I read through every page. I tried all the commands. Learnt about the operating system.

I played about with the debug program to learn about the machine code driving it all. At first it all seemed alien, but after a while, it became clear. There’s a reason for all those cryptic codes.

Then there was the BASIC computer program. On my IBM it was BASIC or BASICA. On the MS systems, it was GWBASIC. Both were similar. There was a manual in a three-ring binder and I went through every page testing all the statements and functions. I spent hours and hours running different code. I never had any specific task in mind, it was simply seeing what I could or couldn’t do. The most memorable aspect was the graphics. Being able to draw lines and move them around. Draw circles and change them. You’d think I’d got into gaming, but I’m not a gamer. I never played the ones in the arcades or on computers.

To run a BASIC program you would first create your source code in a file then type: basica myprog.doc to see it run. It was an interpreted language. No compiler (There were, but not the one I had).

I thought it’d be cool to run a program straight from the command prompt as in: A:>myprog.exe. That happened when I got hold of the 8088 Assembler Program and started coding in it. That’s a different world of programming, but I learnt it. My first program in assembler was DEC2HEX.EXE.

Type in the name of the program on the command prompt followed by a decimal number and press enter. The program would read this number, convert it from decimal to hexadecimal and display the hex number. Cool. I was so proud I could do it.

Those were the days.

Years later I’m still coding, still learning about computers. There’s no shortage of things to learn and this blog is about lessons in computer coding.

Tuesday, 1 March 2011

Installing VB6 on Windows 7


Some time around the year 2000 I bought Microsoft’s Visual Basic 6.0 Professional Edition. It’s an IDE (Integrated Development Environment) for VB on Windows computers. At the time one of my computers ran Windows 98 and I had no problems running it with that computer. Then I upgraded to a much faster, larger computer running Windows 2000. Loved it. Everything worked. I wrote many programs in VB6 on that computer. While I had these desktop computers, I had laptops but didn’t use it for programming. Then in 2009 It was time to get a new computer. I looked at desktops and laptops. It was clear the price of laptops have come way down in comparison to desktops. The performance gap narrowing. It made sense to buy one laptop instead of a desktop and a laptop.

This new laptop runs Windows 7. Fortunately I avoided Vista.

As you’d expect, I pulled out some CDs and began to install software on my new computer. One of those programs was VB6.0. The computer didn’t like it. Capability issues. Wouldn’t install the program. It’s understandable to a certain extent. This computer has 64-bit processor while VB was first designed for 16 bit then 32 bit CPUs. I put the box and CDs away and forgot about it. Who needs VB6? It’s old. I had VB Bloat and C++.

But I did need VB6 because of legacy software. Lots of software written in VB6 and still in use. That brings up many issues in itself, but Microsoft brought in VB.NET and basically trashed VB6. It was no longer basic and what could have worked in .NET didn’t necessarily work. Legacy issues.

I kept my older desktop computer up and running so I could use VB6 and other programs. (Adobe Acrobat 5.0 wouldn’t install on Windows 7. It’s no fun to pay $500 for software that won’t last beyond a few years.)

As time passed, I wanted to run VB6 on my new laptop. I was having some success running certain programs on Windows 7 even though they “weren’t compatible.” I did a search of some web sites and found a solution that worked. Here’s the work around. (You don’t need it if you have the virtual machine feature.)

1. Create an empty file named MSJAVA.DLL in your document folder (or of your choosing). You can do that by create a new notepad text file and change the name.
2. Copy that file to your windows directory.
3. Insert your VB6 install CD and run the installation. It should work.
4. Delete the file from your windows directory.
5. Reboot your computer.
6. Change compatibility properties for the VB6.exe to run as Windows XP.


5. Run VB6.

In my case, the installation conflicted with a previously installed program that appears to have been written in VB6. When I ran VB6 it popped up a window looking for the installation files for this program. Annoying. The fix? Reinstall the second program and all was well.

How anyone would know about this Java DLL and why it would be a problem boggles the mind.
 
Also, have I corrupted my Windows 7 machine. Will I know have surprise conflicts? Not sure. You never know.

Here’s some technical details on the issue from MS (link).