I just went through a very frustrating week, trying to fix a design gap in a VB menu, which calls and is called from SQLWindows programs. I'd like to pass on what I have learned, in hopes it will help others.
WORKING DIRECTORY DIFFERENT DEPENDING ON HOW YOU OPEN PROJECT IN DEVELOPMENT ENVIRONMENT.
If you open VB from your C drive and then open your project from a network drive, your default working directory will be C:, not the network drive. If you click on the project file directly, your default working directory will be the directory where the project is located. I recommend this way of doing it, because it is more like what will occur when your app is installed. It becomes significant if you launch other apps from within your app, because they will inherit your working directory.
API CALLS: SIGNED VS. UNSIGNED INTEGERS.
VB does not support unsigned integers, so it misinterprets the return value from an API call such as GlobalAddAtom as signed when it shouldn't be. A number over 32,768 is falsely reported as the negative reciprocal, because the high order bit is set, and is interpreted as the sign bit. For instance, SQLWindows added string in atom 52312, and passed the value 52312 to VB, but VB had to send the value -13324 to the GlobalGetAtomName function to retrieve the atom string. If VB sends 52312 to GlobalGetAtomName, it gets an overflow error. Thus, I had to find out how to get VB to convert 52312 to -13324 in order to find my data. Microsoft.com has a tip called HOWTO: Convert Between Signed and Unsigned Numbers to describe this problem and offer work-arounds. In short, you check to see if it's greater than 32,768 (if the high order bit is set), and if so, subtract 65,536 (max capacity of unsigned 4-byte integer)
This is not a problem when communicating only between VB apps, because VB maintains a consistent mass delusion, and thus you won't notice it. When VB called GlobalAddAtom, it would have reported the result as -13324, and when it sent
-13324, it would have found the Atom. When communicating with C or SQLWindows or some other app that uses unsigned integers, the two will disagree on what the API call really returned, and you have to use the conversion function code recommended by microsoft to convert the value.
LENGTH OF STRING VARIABLE CONTENTS BEFORE API CALL LIMITS WHAT IS RETURNED BY THE API CALL.
When you call the api GlobalGetAtomName (and probably other API's'), the result is to be returned in a string variable. The length of the result is limited to the length of the string that was in the variable BEFORE you make the API call. Therefore, if your string is null, and you make the API call, it will return a null string, because the string is too short to put the result in. The workaround is to initialize the string to something long enough to hold the result. I put 7 spaces in my string, and was able to retrieve my 7-byte result. When I had 1 byte in my string, it only returned 1 byte of my result, which made me suspicious, because it returned the value 7 in the variable which reports the length of the result. I heard a rumour that there is a VB function that you can use to help address this problem, but I haven't found it yet.
I hope someone may find this information useful. I found it all out the hard way. I'd also like thank those on Tek-Tips who tried to help when I was fighting the working directory problem.
Margaret Knapp
Visual Basic Programmer