Enhancing a Visual Basic 6.0 Application with MapPoint Web Service

Sales Support: A Hybrid Visual Basic 6.0 & Visual Basic 2005 Application, Part 2

Scott Swigart

February 2008

Summary: This article, the second in a four-part series, demonstrates how to use .NET functionality to expand and modernize a Microsoft Visual Basic 6.0 application by adding mapping capabilities via the Microsoft MapPoint Web Service API. (14 printed pages)

Click here to download the application installer.

Click here to download the application source code.

Contents

Introduction

The Sales Support Application

Customer-Mapping Enhancement

Application Architecture

Visual Basic 2005 Implementation

Interoperability with Visual Basic 6.0

Conclusion

Additional Resources

Introduction

Do you want to modernize your Microsoft Visual Basic 6.0 applications? Would you like to take advantage of Web services, desktop search, and more, but you don't have the time or resources to upgrade (or rewrite) your production applications in Microsoft Visual Basic 2005?

In Part 1 of this article series, Enhancing an Application with Windows Desktop Search and Office Outlook Integration, I showed that it is not necessary to migrate a Visual Basic 6.0 application to Visual Basic 2005 in order to take advantage of .NET functionality. Instead, you can integrate Microsoft Windows Desktop Search into a Visual Basic 6.0 application by using COM objects that have been created with Visual Basic 2005. This approach lets you take advantage of all of the functionality of the Microsoft .NET Framework without having to rewrite your application.

This article demonstrates another practical example of using .NET functionality to expand and modernize a Visual Basic 6.0 application—in this case, adding mapping capabilities via the Microsoft MapPoint Web Service API.

Of course, the example is intended only to show you how to access MapPoint Web Service from Visual Basic 6.0—not to show off everything that MapPoint Web Service can do for your applications. How to make MapPoint Web Service a part of your applications is up to you, but here are a few ideas:

  • You can add a feature to a sales-force automation application that allows sales reps to specify which customers they plan to visit on a particular day, and automatically generate driving directions from one customer site to the next.
  • Perhaps you work for a company that builds new homes, and you manage an application that tracks potential real-estate investments. You could use MapPoint Web Service to add a map of the area—including schools, shops, and so forth—to forms and reports that document those potential investments.
  • Maybe you have to validate addresses. You could use MapPoint Web Service to return possible matches to an address that you have entered into your application.

The Sales Support Application

"Sales Support" is a very simple sales-force support application that allows the user to look up accounts, contacts, and forecasted sales. The application is not intended to be a complete sales-force automation solution. Instead, it is designed to be a representative placeholder for an existing line-of-business Visual Basic 6.0 application. Also, it serves as the anchor for a number of logical application enhancements that are best implemented by using Visual Basic 2005.

Installation

The Sales Support installer has been tested on Microsoft Windows XP SP2 and on Windows Vista, and likely would work on older operating systems, too. Because this is a hybrid Visual Basic 6.0 and Visual Basic 2005 application, the Sales Support installer will install the.NET Framework 2.0 as a prerequisite. This application also stores data in a back-end database. For this reason, the installer will install Microsoft SQL Server 2005 Express Edition, which replaces Microsoft SQL Server 2000 Desktop Engine (MSDE 2000).

If you do not have these prerequisites installed, the installer will download them for you automatically. If they are already installed, the installer will detect their presence and skip to the application installation.

Operation

After the application is installed, you can launch it from the Start menu. Look for the Sales Support8_3 entry. The application will initially prompt you to log on. To simplify use, the user name and password fields default to working values, as shown in Figure 1. You can just click the Login button to continue.

Figure 1. The Sales Support Login form

After you have logged on, the main application window appears, as shown in Figure 2. The application provides three different views of the sales information. The Accounts tab provides the first view and shows each account and associated sales information. This view can be sorted differently by clicking on a column heading. The Contacts tab provides the second view and shows more detailed information about each individual contact. The Forecast tab provides the third view and displays future sales-forecast information.

Figure 2. The main application window

Again, the Sales Support application is not designed to be a working sales-force solution. Instead, it serves only as a basis for realistic application enhancements.

Customer-Mapping Enhancement

Mapping and geographic functionalities are becoming standard features of line-of-business applications, whether they validate addresses or provide driving directions for customer visits. In Visual Basic 6.0, there is no built-in way to generate maps. Microsoft does provide extensive mapping capabilities through MapPoint Web Service, but there’s no easy way to call this service from Visual Basic 6.0. Calling MapPoint Web Service from Visual Basic 2005, however, is almost trivial. By using the extension that is described in this article, you can map a customer location, as shown in Figure 3.

Figure 3. Mapping a customer location

Application Architecture

The core of the application is a Visual Basic 6.0 application that communicates with a SQL Server 2005 Express database. When you click the Map button, the client address is passed to a Visual Basic 2005 form. The Visual Basic 2005 form communicates with MapPoint Web Service to retrieve a map image for the address. The map is rendered on the Visual Basic 2005 form, which also allows the user to zoom in and zoom out.

Figure 4. Application data flow

Visual Basic 2005 Implementation

For some time, mapping capabilities have been available through Web sites, many of which make it easy for a user to look up a location. However, pulling maps into an application is more challenging. To use a typical Web site, you would have to write code to download and parse the HTML; if the site changed its layout, your application could easily break.

Web services offer an alternative to screen-scraping Web sites. Web services are not intended to be used by a human being with a browser. Instead, Web services take requests as XML over HTTP, and return results as XML. Web services use the same infrastructure as Web sites, but they’re designed specifically to communicate with applications—not with people.

By using Visual Studio 2005, communicating with Web services is even easier. Visual Studio 2005 generates classes for you that take care of creating and parsing the XML. You just create an instance of a class, call a function, and get a result.

In the case of mapping data, a Web service makes perfect sense, because you would not want to deploy worldwide detailed maps to every desktop, and you would not want to have to keep that mapping data updated. Instead, it would make much more sense just to retrieve the map for a specific area, on demand. Microsoft MapPoint Web Service provides exactly that capability.

To begin using MapPoint Web Service, you have Visual Studio 2005 download a definition file for the service and generate client-side "proxy" classes. You do this through the Project | Add Web Reference menu command in Visual Studio 2005.

Figure 5. Adding a Web reference

The definition for a Web service is contained in a Web Services Description Language (WSDL) document—in this case, https://staging.mappoint.net/standard-30/mappoint.wsdl. Visual Studio 2005 downloads this WSDL document and generates a proxy class under a MapPointService namespace.

Looking up Addresses by Using MapPoint Web Service

After the Web reference has been added, you can begin writing code to make requests and process responses from the Web service.

Dim address As New MapPointService.Address()
address.FormattedAddress = Me.Address

Dim findOptions As New MapPointService.FindOptions()
findOptions.ThresholdScore = 0

Dim findAddressSpec As New MapPointService.FindAddressSpecification
With findAddressSpec
    .InputAddress = address
    .DataSourceName = "MapPoint.NA"
    .Options = findOptions
End With

findService.Credentials = credentials
findResults = findService.FindAddress(findAddressSpec)

Listing 1. Looking up an address in MapPoint Web Service

The first step in using MapPoint Web Service is to find the latitude and longitude for an address. You begin by creating an instance of the Address class. This class was automatically generated when the Web service was referenced. You set the FormattedAddress property to the text address that you want to look up.

When you search for an address, multiple possible matches could be returned if the address is not exactly matched. The ThresholdScore property of the FindOptions class lets you control how closely an address must match to be returned. Regardless of the ThresholdScore value, address matches are returned in order from best to worst.

The address and options are then linked to a FindAddressSpecification. In addition, the specification lets you specify which data source you want to search. For example, you can search North America, Europe, or other data sources.

To communicate with MapPoint Web Service, you must specify credentials. In this example, the application is connecting to the MapPoint Web Service staging service, not to the production Web service, so that developer credentials will suffice. (For your convenience, I've hard-coded credentials into the application. If those credentials stop working at some future date, you can apply for your own developer credentials at https://mappoint-css.partners.extranet.microsoft.com/MwsSignup/Eval2.aspx.)

At this point, you have configured the information that is necessary for MapPoint Web Service to look up the address and return latitude and longitude information—key inputs for any mapping service. When the FindAddress method of findService is called, the request is packaged as XML and sent over the Internet to MapPoint Web Service. The results are obtained, and they are returned as XML. The proxy class, which is created by Visual Studio 2005, parses the XML and returns the results in the findResults object.

Requesting a Map from MapPoint Web Service

Now, you're ready to request a map image for the address. You accomplish this by using the code that is shown in Listing 2.

' Set the centerpoint on and scale of
' the map location you want to display
Dim mapViews(0) As ViewByScale
mapViews(0) = New ViewByScale
With mapViews(0)
    .CenterPoint = Me.findResults.Results(0).FoundLocation.LatLong
    .MapScale = ZoomScrollBar.Value * ZoomScrollBar.Value
End With

' Add a pushpin to the map
Dim pushPins(0) As Pushpin
pushPins(0) = New Pushpin
With pushPins(0)
    .PinID = "pin0"
    .Label = PushPinName
    .IconName = "0"
    .IconDataSource = "MapPoint.Icons"
    .LatLong = mapViews(0).CenterPoint
End With

' Customize the map display options
Dim options As New MapOptions
With options
    .Format = New ImageFormat
    .Format.Height = PictureBox1.Height
    .Format.Width = PictureBox1.Width
End With

Dim mapSpec As New MapSpecification
With mapSpec
    .Views = mapViews
    .Options = options
    .DataSourceName = "MapPoint.NA"
    .Pushpins = pushPins
    .HideEntityTypes = New String() {"School"}
End With

' Retrieve the map image
renderService.Credentials = credentials
Dim mapImages() As MapImage = renderService.GetMap(mapSpec)

PictureBox1.Image = New System.Drawing.Bitmap(New _
    System.IO.MemoryStream(mapImages(0).MimeData.Bits))

Listing 2. Requesting a map for the address

There are a number of objects that must be sent to request a map image. First, you create a ViewByScale object. The CenterPoint property is set to the latitude and longitude of the address that was previously retrieved. Next, you set the MapScale property. This controls how zoomed in or zoomed out the map is. In this application, this value is controlled by a scroll bar, so that the user can control the zoom level. In addition, it works better to change this value logarithmically instead of linearly, so that the value of the scroll bar is squared when you set the MapScale property (otherwise, zooming out could take a very long time).

To create a label on the map by using the business name, you create pushpins. You use the Label property to specify the text that you want, and the Icon property to specify the icon to appear on the map. Next, you create an instance of a MapOptions class, and set properties to define the height and width of the image that you want returned. This information is all connected to a MapSpecification object, and sent to the MapPoint Web Service RenderService. The RenderService generates an image of the requested area, and returns the image (encoded in XML) back to the application.

Again, the application parses the XML and returns the data. There's just one small bit of conversion to convert the image data to an actual BitMap data type, and then the image can be displayed in a PictureBox. The results are rendered as shown in Figure 3.

Interoperability with Visual Basic 6.0

Now, you have .NET code with mapping capability. However, how do you tie that to your existing Visual Basic 6.0 application? The answer is: You use the Interop Forms Toolkit 2.0 (https://msdn2.microsoft.com/en-us/vbasic/aa701259.aspx) to create a Visual Basic 2005 form that can easily be called from Visual Basic 6.0. When you install the Interop Forms Toolkit 2.0 into Visual Studio 2005, it provides a new Visual Basic 6.0 InteropForm item type that you can add to your projects. This is a .NET form that is easily callable from Visual Basic 6.0.

Figure 6. Adding a Visual Basic 6.0 InteropForm item type

The InteropForm is a standard .NET form that contains a number of attributes that control which portions of the form are COM-callable. Listing 3 shows a section of this form code.

Imports System.Windows.Forms
Imports Microsoft.InteropFormTools
Imports VBNET_Extensions.MapPointService

<InteropForm()> _
Public Class MapPointForm
    Private findResults As FindResults
    Private renderService As New RenderServiceSoap
    Private findService As New FindServiceSoap

    Private isInitialized As Boolean = False

    Private m_address As String
    <InteropFormProperty()> _
    Public Property Address() As String
        Get
            Return m_address
        End Get
        Set(ByVal value As String)
            If value <> m_address Then
                m_address = value
                findResults = Nothing
                RenderTimer.Enabled = True
            End If
        End Set
    End Property
    
    ...

End Class

Listing 3. Visual Basic 6.0 InteropForm item type

The form contains an InteropForm attribute, and any properties or methods that you want to make available to Visual Basic 6.0 are also decorated with an attribute, such as the InteropFormProperty and InteropFormMethod attributes.

There are two steps to compiling your Visual Basic 2005 COM objects. First, you select the Tools | Generate InteropForm Wrapper Classes menu command. This generates COM wrapper code that is based on your attributes. Then, you just build the project by using the Build | Build Solution menu command.

Figure 7. Generating the InteropForm wrapper classes

Calling the .NET Form from Visual Basic 6.0

After you have created an interoperable form, you can call it from Visual Basic 6.0, as with any other COM object. From Visual Basic 6.0, you can just add a reference to your Visual Basic 2005 code.

Figure 8. Referencing a Visual Basic 2005 component from Visual Basic 6.0

As soon as the component is referenced, you can create an instance of your Visual Basic 2005 form, set properties, and perform other operations.

Private Sub cmdMap_Click()
    Dim frmMap As VBNET_Extensions_MapPointForm
    Set frmMap = New VBNET_Extensions_MapPointForm
    
    frmMap.Address = rsAccount("Address") & ", " & _
        rsAccount("City") & ", " & _
        rsAccount("Region") & "  " & _
        rsAccount("PostalCode")
    
    frmMap.PushPinName = rsAccount("CompanyName")
    frmMap.Show
End Sub

Listing 4. Calling into a Visual Basic 2005 form from Visual Basic 6.0

Here, customer data from the database is passed to the Address property of the form. The PushPinName property is set to the company name, which will cause the company name to appear on the map image. Finally, the form is shown displaying the map.

Conclusion

If you have applications that are written in Visual Basic 6.0, you can preserve those investments, and just extend them by using Visual Basic 2005. In this article, I showed how to call a Web service via Visual Basic 2005 and add MapPoint Web Service functionality to a Visual Basic 6.0 application.

Additional Resources

For more information on using MapPoint Web Service, check out the following links:

About the author

Scott Swigart spends his time consulting, authoring, and speaking about converging and emerging technologies. With development experience going back over 15 years, and by staying in constant contact with future software-development technologies, Scott is able to help organizations get the most out of today's technology while they prepare to leverage the technology of tomorrow. Scott is also the author of several .NET books, a certified Microsoft trainer (MCT) and developer (MCSD), and a Microsoft MVP. Feel free to contact the Scott at scott@swigartconsulting.com, or check out his latest musings at blog.swigartconsulting.com.