Passing Null Pointers
If C were a type-safe language like Basic, passing input strings to the Windows API would always be simple, but many Windows API functions accept a null pointer for string parameters. When you pass a normal string, you are actually passing a pointer to the characters of the string—in other words, the address of the first character. But the C language and the Windows API recognize one special pointer that represents no address. The value of this pointer is 0, but it doesn’t represent address 0 even if that address is valid in the current environment. The null pointer is used as a signal to ignore a given parameter.
Passing a null pointer to a string procedure was a major hassle in previous versions of Visual Basic. A null pointer was a Long constant zero (0&), which you couldn’t pass to a String parameter. You had to write special versions of Declare statements to accommodate parameters that might take null pointers, using one of the choices described earlier (see “Typeless Variables,” page 69). You could either throw away type safety with As Any, or you could write multiple aliases to accommodate all the possible combinations of strings and null pointers. In today’s modern Basic, those hacks are just a bad memory—like those throwaway pop-can tabs that used to litter highways before many readers of this book were born. Now you can simply pass the predefined constant vbNullString as a string argument.
The previous section assumed that you pass the FindWindow API function a window title and a window class, but in reality you can pass a string for one of these and pass a null pointer in the other to signal that you don’t care about it. For example, assume that you know the title of the window but not the class. You might think that you could pass an empty string for the class:
hWnd = FindWindow(“", “Calculator”)
This searches for the window with title Calculator and class nothing—but you’re unlikely to find a window without a class. To search by title only, you must pass a null pointer rather than an empty string. If you skipped from version 3 to version 5, you might try the following:
hWnd = FindWindow(0&, “Calculator”)
Because Basic sees that FindWindow wants a string, it politely converts 0& to "0". You don’t get an error (as you would have in Visual Basic version 3), but neither do you find the window unless you happen to have a window with class 0. (“Evil Type Conversion,” page 280, discusses other side effects of Basic’s new ability to convert integers to strings and vice versa.)
Here’s the correct way to solve this problem in Basic:
hWnd = FindWindow(vbNullString, “Calculator”)
hWnd = FindWindow(“SciCalc", vbNullString)
hWnd = FindWindow(“SciCalc", “Calculator”)
This might seem obvious, but it looks like a miracle to old hands who remember the hacks of yesteryear.
Null and Empty
Don’t let the various definitions of null and empty confuse you:
-
The null character is ASCII character 0. You can represent this string as Chr$(0), but it’s more efficient to use the constant vbNullChar or the VBCore version, sNullChr.
-
The term null string is commonly used to describe what this book calls an empty string, that is, a string with no characters. You can represent this string with empty quotes (""), but it’s more efficient to use the constant sEmpty. The Basic keyword Empty is a Variant constant representing an empty string for string Variants or 0 for numeric Variants. You can use it anywhere you use sEmpty, but it’s significantly less efficient for string operations.
-
A null pointer is a 32-bit integer with value 0 representing address 0. You will normally pass a null pointer to a string parameter with the constant vbNullString (or its equivalent in my type library, sNullStr).
In a few Windows API situations, you might need to pass a null pointer to a numeric parameter. You can use the constant pNull for these cases. Incidentally, the vbNullString constant also works as an empty string, although you can’t use sEmpty as a null pointer.
-
Another null you’ll run into frequently is a null handle. You can use the constant hNull.
-
The Null keyword represents a Variant that contains no valid data. It
is commonly used for databases and gives an error if used in a string context.
-
The Nothing keyword also has nothing to do with strings, but I include it here for completeness. It represents an object variable that hasn’t yet been set to an object. (See Chapter 3.)
The constants sEmpty, pNull, and hNull are not part of Basic, but they are provided as part of the Windows API type library. The constant sNullChr can’t be defined in my type library because of a bug in the MIDL compiler, but for compatibility with the first edition, I provide it in UTILITY.BAS and the VBCore component.
Use constants whenever you can. If you use empty quotes ("") in your program 5000 times, you’ll end up with 5000 empty strings, each taking up at least 5 bytes. If you use sEmpty 5000 times, you’ll get one empty string.