Image of Navigational Map linked to Home / Contents / Search Microsoft Internet Knowledge Base
Add-In for VB

by Murray Cox - GUI Computing
Image of Line Break

The recent release of Microsoft Internet Explorer 3.0 (beta and release) internally use an ActiveX control named "SHDOCVW.OCX", which provides its browsing features. This OCX plugs right into VB, and gives you the identical browsing window that IE3.0 uses (including the display of Java applets and hosting ActiveX controls). Unfortunately, as yet, the control is undocumented - and while the control is fairly simple to use you will have to use the Object Browser and a bit of imagination to work out its properties, methods, and events.

This article showcases a useful VB Add-In for the web browser control. I will describe an Internet Knowledge Base Add-In for Visual Basic 4.0 - 32 bit.

Image of How-To Icon I will not cover the theory on creating a VB Add-In, but feel free to click here to see a brief overview, and other references on the subject.

First an overview of the Add-In. I will create a project named GUIAddIn which contains a public class called KnowledgeBase. This class adds a menu item to the Visual Basic Integrated Development Environment (VB-IDE). When the user (in this case a developer) clicks on this menu item, the class displays a query form. Once the user fills in the form, and clicks the "GO!" command button, a form containing the browser control appears with the results of the knowledge base search. From here the user can navigate with the hyperlinks (and back and forwards) to find the required article, or go back to the query form. I use VB 4.0 - 32 bit, as the OCX is only currently a 32 bit control. This 32 bit VB also lets me compile the OLE Server as a DLL, which results in faster execution and easily allows modal dialogs to be displayed (on top of the VB-IDE).

Knowledge Base Query Form


GUI Add-In Overview


Add-In Menu

Our Add-In adds one menu item to the Add-In menu group when it connects to the VB IDE, labeled "Knowledge Base", which is the way the user displays the query form. This is put in the procedure "ConnectAdd-In" which occurs when Visual Basic starts up and loads the Add-In, or when the Add-In is manually added to the development environment. Here is the code for ConnectAdd-In:

  Public Sub ConnectAddIn(vbinstance As Object)
    ' Store this instance of vb in a member variable
    Set m_vb = vbinstance

    ' Add the menu for knowledge base
    Set m_mnuKnowledgeBase = m_vb.AddInMenu.MenuItems.Add("&Knowledge Base")

    ' Connect the event handler for the menu to this class
    m_hmnuKnowledgeBase = m_mnuKnowledgeBase.ConnectEvents(Me)

    ' Set up a reference in our query form, so it knows what instance of
    ' result form to use
    Set m_frmSearch.m_frmResults = m_frmResults

  End Sub

Similarly we have a DisconnectAddIn, whose job it is to remove any menus created, and clean-up. Here it is:

  Public Sub DisconnectAddIn(Mode As Integer)

    ' In case anything happens
    On Error Resume Next

    ' Unload the form and destroy any memory associated with it
    Unload m_frmResults
    Set m_frmResults = Nothing

    Unload m_frmSearch
    Set m_frmSearch = Nothing

    ' Disconnect the event handler from the menu
    m_mnuKnowledgeBase.DisconnectEvents m_hmnuKnowledgeBase
 
    ' Remove the menu
    m_vb.AddInMenu.MenuItems.Remove m_mnuKnowledgeBase

  End Sub

You must remember that multiple instances of VB may be running that are all using your client. For this reason, you must create new instances of each form that you want to use for each instance of your class. Thus forms must be declared in the class declarations section as:

    dim m_frmResult as new frmResult

These are the declarations for my KnowledgeBase class:

  ' Member variable for the instance of the VBIDE
  Private m_vb As VBIDE.Application

  ' Member variable for the instance of the menu line
  Private m_mnuKnowledgeBase As VBIDE.MenuLine

  ' Member variable storing handle to the menu item
  Private m_hmnuKnowledgeBase As Long

  ' Private member instances of the forms
  Private m_frmSearch As New frmSearch
  Private m_frmResults As New frmResults

In our ConnectAddIn subprocedure, we connected the menu to an event handler. This causes the procedure AfterClick to be called when the menu item is clicked. We declare this procedure in our class, and we put code in to show our query form.

  Public Sub AfterClick()
    m_frmSearch.Show vbModal
  End Sub

Now that we have set up our class, we can concern ourselves with elements that most VB programmers are more comfortable with: designing forms, and writing code for them. But first we set up some global variables for use in the rest of the program. When the Add-In DLL is first loaded, the procedure Main is called. We use this to set up global information that every instance of the Add-In will use.

  Sub main()

    ' Set up global array of strings for parameter of the product selected
    ReDim g_sProductParameters(43)
    g_sProductParameters(0) = "KB_access"
    g_sProductParameters(1) = "KB_automap"
    g_sProductParameters(2) = "KB_basic"
    .
    .
    .
    g_sProductParameters(41) = "KB_works"
    g_sProductParameters(42) = "KB_dosword"
    g_sProductParameters(43) = "KB_word"
    
    ' Set up global array of strings for parameter of the category selected
    ReDim Preserve g_sCategoryParameters(27)
    g_sCategoryParameters(0) = ""
    g_sCategoryParameters(1) = "kbappnote"
    g_sCategoryParameters(2) = "kbbuglist"
    .
    . 
    .
    g_sCategoryParameters(25) = "kbtool"
    g_sCategoryParameters(26) = "kbtshoot"
    g_sCategoryParameters(27) = "kbui"

  End Sub

These global string arrays store the parameters that will be passed to the Microsoft Knowledge Base URL, via the browser control.

GO! button

Basically the only code we have in the frmSearch module is to respond to the user's click of the Go button. When this occurs, there are two things we must do:

  1. If the query has not been entered before, add it to the combo box. This enables users to re-execute previous queries
  2. Navigate the web browser control to the correct URL, and display the page.

To check if the query has not been entered before, I use SendMessageA to send a CB_FINDSTRINGEXACT message to the combo-box asking, if it has been entered yet.

' Store the search string sSearch = Trim(cboSearch) ' See if the search string is in the ComboBox's list portion nFoundEntry = SendMessage(cboSearch.hwnd, CB_FINDSTRINGEXACT, ByVal -1, ByVal sSearch) 'If it isn't - add it If nFoundEntry = -1 Then cboSearch.AddItem cboSearch.Text End If

To generate the correct URL for the search we want to conduct, I examined the way Microsoft's Knowledge Base Search web page did it. Here is an example of the URL generated from a search:
Knowledge Base Search URL

Presumably, Microsoft are using their Internet Information Server with an ISAPI DLL named "Fts.dll", which receives the parameters passed to it, and passes back the HTML code to the browser - representing the Search Results. What we are interested in is the stuff after the "?" - the parameters. It is not too difficult to decide that the URL that we need to use is based on the following line:

  http://www.microsoft.com/isapi/fts.dll?db=PRODUCT_PARAM&qu=CATEGORY_PARAM
                                                         &qu=QUERY_PARAM&mh=MAX_HITS_PARAM

Here's the code:

  ' Replace any spaces with the character "+"
  nPositionSpace = InStr(sSearch, " ")
  Do While (nPositionSpace <> 0)
    Mid(sSearch, nPositionSpace, 1) = "+"
    nPositionSpace = InStr(sSearch, " ")
  Loop

  ' Navigate to the Microsoft URL based on
  ' http://www.microsoft.com/isapi/fts.dll?db=PRODUCT_PARAM&qu=CATEGORY_PARAM
                                                           &qu=QUERY_PARAM&mh=MAX_HITS_PARAM
  m_frmResults.wbResults.Navigate "http://www.microsoft.com/isapi/fts.dll?" _
  & "db=" & g_sProductParameters(cboProduct.ListIndex) _
  & "&qu=" & g_sCategoryParameters(cboCategory.ListIndex) _
  & "&qu=" & sSearch _
  & "&mh=" & txtMaximumHits

First we replace any spaces in the query with the character "+" (as required by fts.dll). Next we use the global arrays of strings, that we set up a minute ago, to pass the product and category parameters. Now we just show the frmSearch form.

  If m_frmResults.Visible = False Then
    m_frmResults.Show vbModal
  End If

Knowledge Base Results We should get something similar to the image on the left. The code in this form is limited to the resizing of the screen, and clicking of the toolbar buttons. Note that much of the functionality of the Internet Explorer is exposed in the web browser control. For example, you could implement status text and status bars, describing the progress of the download. Even the context sensitive right mouse-clicks on the browsers are fully functional.

Here is the code for the toolbar buttons (all one liners).

  Private Sub tbrToolBar_ButtonClick(ByVal Button As Button)

    ' To handle navigation too far back or too far forward. Could easily implement 
    ' disabling the relevant button when the user navigates to the beginning or end
    ' of the history list.
    On Error Resume Next

    Select Case Button.Key
      Case "Search"
          m_frmSearch.Show vbModal
      Case "Refresh"
          wbResults.Refresh
      Case "Back"
          wbResults.GoBack
      Case "Forward"
          wbResults.GoForward
    End Select

  End Sub

Now, once we have compiled the OLE DLL, add the following line to your vb.ini file in the windows directory under the [Add-Ins32] section:

  GUIAddIn.KnowledgeBase=1

This causes the Add-In to be added to the VBIDE when it is started. A value of 0 indicates that the Add-In will be manually added.

The code for this Add-In is included in the downloadable zip file (25 KB).
Any questions or comments, mail me...murrayc@gui.com.au



Written by: Murray Spenser Cox
August '96

Image of Arrow linked to Previous Article Image of Arrow linked to Next Article
Image of Line Break
[HOME] [TABLE OF CONTENTS] [SEARCH]