Get the Message
Now that you've seen the Win32 Network API functions that NetMessage uses, let's see how the program uses them. The
Form_Load event is the first piece of code NetMessage executes. Listing 1 shows the Form_Load subroutine.
Form_Load prepares the NetMessage utility to run. At callout A in Listing 1, Form_Load first creates a VB
collection and then fills that collection with the network system names. These names are returned by the
GetNetworkSystemNames function. (This function is a slightly revised version of the GetServerInfo function I used in
prior VB Solutions. Besides GetNetworkSystemNames having a more descriptive name, the only difference between the old
and new functions is that GetNetworkSystemNames accepts an argument that specifies the type of system to return and then
returns a collection with the names of the networked systems.) The names in the collection are then added to the
drop-down box displayed in Screen 2.
After the names of the networked systems are returned, Form_Load calls function GetDomainName to retrieve the
network domain name that's added to the bottom of the list displayed in the drop-down box. At B in Listing 1, notice
that the domain name has an appended asterisk. The NetMessageBufferSend function can use this special value (domainname*)
to send broadcast messages to all systems in a domain.
Listing 2 shows how the GetDomainName function works. At A in Listing 2, GetDomainName calls the NetWkstaGetInfo
function. NetWkstaGetInfo can return a variety of information about a local system's network connection. Here,
the value 100 in the second parameter tells the NetWkstaGetInfo function to return the WKSTA_INFO_100 structure shown in
Listing 3, page 186.
After the call to NetWkstaGetInfo is successfully completed, the WKSTA_INFO_100 structure is filled with
data. The first field in this structure specifies the information level for retrieving platform-specific information.
The second field contains the local computer name. Although the GetDomainName function doesn't use this field now, a
later call retrieves this information. The third parameter contains the network domain name--the information you want
the GetDomainName function to retrieve. The last two fields return the version number of the NT networking support that
the local system uses.
At B in Listing 2, GetDomainName processes the information returned by NetWkstaGetInfo. Because NetWkstaGetInfo
returns a pointer, you must use the native Win32 RtlMoveMemory API call to copy the data from the location identified by
the pointer to the corresponding storage area defined by the twkstaInfo100 user-defined data type.
From there, GetDomainName retrieves the wki100_langroup field (which contains the domain name) from the
WKSTA_INFO_100 structure. Because the Win32 network API functions return data only in Unicode format, the code at C in
Listing 2 extracts every other byte from the string that contains the domain name. After extracting the ASCII portion of
the domain name, the GetDomainName function returns the domain name to the calling routine--in this case,
NetMessage's Form_Load subroutine.
Back in Form_Load, at B in Listing 1, the domain name and its special asterisk suffix are added to the bottom of
the list of network system names that will appear in the drop-down box. The NetMessage program then displays the main
window.
After selecting or entering the target system or network username and entering the message text, the user clicks
Send to send the message. Listing 4 contains the code that handles the Send button's click event, the Command_Send_Click
subroutine.
Send the Message
Command_Send_Click is where the real action takes place in the NetMessage utility. Command_Send_Click takes the
target message name and the message text data that you entered in the main window and then calls the
NetMessageBufferSend function to send the message across the network.
To send a message, NetMessageBufferSend requires three pieces of information: the name of the target user or
system, the message text, and the name of the system sending the message. The target system name and message text come
from the main window. Command_Send_Click uses the GetLocalSystemName function to dynamically retrieve the sending system
name at A in Listing 4.
The GetLocalSystemName function, shown in Listing 5, works much like the GetDomainName function. Both functions
call the NetWkstaGetInfo function to retrieve the required network information, and both use the WKSTA_INFO_100 data
structure to return network data.
The primary difference between these two functions is the information each retrieves from the WKSTA_INFO_100
structure. Whereas GetDomainName returns WKST_INFO_100's third field (wki100_langroup), GetLocalSystemName returns the
second field (wki100_computername), which contains the local system name. Just like GetDomainName, GetLocalSystemName
extracts every other byte from the Unicode string and then returns the extracted system name to the calling
routine--NetMessage'sCommand_Send_Click subroutine.
StrConv
At A in Listing 4, you can see that the StrConv function uses the value that GetLocalSystemName returns. StrConv is
a built-in VB function that converts VB strings to various formats, including Unicode. When you work with the Win32
network API functions, you must be aware of one gotcha: You must submit all string parameters in Unicode. Although most
of the Win32 API set supports dual APIs, one for ASCII and one for Unicode, the Win32 network API functions support only
Unicode strings.
Readers who are familiar with VB may think, "No problem. VB 4.0 already uses Unicode internally, so I don't
have to do anything." Wrong. Although VB 4.0 uses Unicode internally, when VB 4.0 calls external functions, it
automatically (maliciously?) converts all strings to ASCII. To pass Unicode values to external functions, I first use
the StrConv function to explicitly convert each VB string to Unicode at B in Listing 4.
The Final Stretch
Finally, at C in Listing 4, the NetMessage utility calls the NetMessageBufferSend function to send the network message. The first parameter is a null string that forces NetMessageBufferSend to be executed on the local system.
The second, third, and fourth parameters are Unicode strings containing the destination name, sending system name, and
message text, respectively. The fifth parameter contains the length of the message text.
After NetMessageBufferSend finishes executing, subroutine Command_Send_Click checks the return code for a
successful completion and displays the send status in NetMessage's main window.
The Power of the Win32 Network API Functions
Taking advantage of a few NT network API functions let me create a simple VB utility for sending impromptu messages
across a network. To learn about the Win32 API and network API functions, refer to the Win32 Software Development Kit
(SDK) in the Microsoft Developer's Network CD-ROM. Look for more VB solutions that you can put to work to solve some
common problems your business faces.