An add-in is a tool, written specifically for the Visual Basic development environment, that is designed to make life easier for the developer. Some versions of Visual Basic 4.0 come with a few such tools, for example, the Data Manager and the Report
Designer. The Data Manager makes the investigation and querying of databases easier, and the Report Designer aids in preparing reports generated from databases.
You access all add-in tools through the Add-Ins menu. When Visual Basic is installed, this menu looks like Figure 17.1. You use the Add-In Manager option when you want to add other add-ins to the menu.
Figure 17.1. The initial Add-Ins menu.
This chapter will explain how add-in tools link to the Visual Basic development environment. It will also show you some examples of how to create add-ins. Finally, it will explain the Visual Basic IDE OLE interface and how to create standardized dialog
boxes using an add-in tool.
Within a few months after the release of Visual Basic 4.0, there is sure to be an emerging market in add-ins for developers. This chapter will help you get in on the ground floor of an entirely new programming opportunity.
Add-ins can attach either temporarily or permanently to the Integrated Development Environment (IDE). The examples in this section create temporary links. The section later in this chapter, "Creating a Permanent Add-In," discusses how to
create a permanent link.
Choosing Add-Ins | Add-In Manager opens the Add-In Manager dialog box shown in Figure 17.2. Checking an add-in tool adds that tool to the Add-Ins menu.
Figure 17.2. The Add-In Manager dialog box.
The example project that this section describes adds one menu option to the Add-Ins menu. Figure 17.3 shows the Add-Ins menu after the AddIns Example has been checked in the Add-In Manager dialog box.
Figure 17.3. The Add-Ins menu with the example add-in.
Linking to the Add-In Manager involves two parts. The first part is to create a connector class that defines the menu structure and description of the add-in. The second part is to place an entry in the VB.INI file to indicate that the add-in is
available for use.
Each add-in tool needs its own class module that contains the program code to link the add-in to the Add-In Manager. This code consists of, at the minimum, the ConnectAddIn event, the DisconnectAddIn event, and some global variables.
The ConnectAddIn event is called when the user selects the Add-Ins check box in the Add-In Manager dialog box. This event is responsible for adding the appropriate menu items to the Add-Ins menu by calling methods of the MenuItems collection. The
following code snippet, pulled from a larger program, shows how this is done:
Set NewMenu = VBInstance.AddInMenu.MenuItems.AddMenu("&New Menu") Set MenuLines = NewMenu.MenuItems.Add("&First Option")
The first line adds the second level menu option, and the second line adds a subsidiary menu. The new Add-Ins menu looks like Figure 17.3. Figure 17.1 shows what the original menu looked like.
At this point, the menu interface is defined. You now need to tell Visual Basic what method is attached to the menu's Click event. Each menu's Click event must be attached to a different AfterClick method. For this example, the AfterClick method is
defined in the same class as the connecting method, but you don't have to do it this way.
You use the ConnectEvents method to link the menu option with the class of the AfterClick method. A typical line of code might look like the following:
ConnectID = MenuLines.ConnectEvents(Me)
The Me variable refers to the current instance of the class. This variable basically says to look inside the current class for the AfterClick method.
You also need to let the Add-In Manager know what description to show in the Add-In Manager dialog box. Follow these steps:
Figure 17.4. Setting the connector class description in the Object Browser.
In order for the Add-in Manager to be aware of an add-in, there must be an entry in the VB.INI file in either the section named [Add-Ins32] or the section named [Add-Ins16]. You can create this entry by using the WritePrivateProfileString API function
as shown in the following line of code:
WritePrivateProfileString "Add-Ins32", "AddIn.Connector", "0", "VB.INI"
The first argument is the name of the section (with the square brackets), the second argument is the name of the profile string, the third is the value of the profile string, and the last is the name of the INI file.
Take a closer look at the second argument. Notice that it has two names separated by a period. The syntax of the second argument is as follows:
projectName.className
The project name is taken from the Project Name field of the Tools/Options dialog box shown in Figure 17.5. The className is the name of the class that implemented the ConnectAddIn and DisconnectAddIn events.
Figure 17.5. The Project tab of the Tools Options dialog box.
When you are finished using the add-in, you need to unlink it from the Add-In Manager. Like the connection process, the unlinking process has two parts. First, you must sever the connection to the Add-Ins menu, and then you must remove the VB.INI
profile string.
The DisconnectAddIn event is called when the user de-selects the add-in from the Add-In Manager dialog box. The add-in needs to call the DisconnectEvents method to disconnect the AfterClick method from the menu, as shown in the following line of code:
MenuLines.DisconnectEvents ConnectID
Then the subsidiary menu item is removed:
NewMenu.MenuItems.Remove MenuLines
Finally, the menu option in the Add-Ins menu is removed:
VBInstance.AddInMenu.MenuItems.Remove NewMenu
The ConnectId, MenuLines, NewMenu, and VBInstance variables are all variables that were assigned a value when the link to the Add-In Manager was created.
Removing the VB.INI entry is necessary so that subsequent instances of Visual Basic will not present the developer with the add-in tool when it is not available. To remove the Addin.Connector string from the VB.INI file, run the following line of code:
WritePrivateProfileString "Add-Ins32", "AddIn.Connector", "", "VB.INI"
When you remove a profile string, its value must be a zero-length string.
The purpose of the simple add-in you create in this section is to display a dialog box that says "Click!" when the Add-Ins menu option is selected. To create the add-in, follow the steps in example 1.
' Declarations for the API functions used to manipulate ' initialization files. Private Declare Function WritePrivateProfileString _ Lib "Kernel32" Alias "WritePrivateProfileStringA" _ (ByVal AppName$, ByVal KeyName As Any, _ ByVal KeyDefault As Any, ByVal FileName$) As Long Private Declare Function GetPrivateProfileString Lib _ "Kernel32" Alias "GetPrivateProfileStringA" (ByVal AppName$, _ ByVal KeyName$, ByVal KeyDefault$, ByVal ReturnString$, _ ByVal NumBytes As Long, ByVal FileName$) As Long ' This method adds a profile string to the VB.INI file. The ' instance of VB that is started will see it. Private Sub Command1_Click() prof$ = String$(255, Chr$(0)) ' If profile string is not present, return "NotFound" as the ' result. GetPrivateProfileString "Add-Ins32", "AddIn.Connector", _ "NotFound", prof$, Len(prof$) + 1, "VB.INI" ' get rid of trailing blanks. prof$ = Left(prof$, InStr(prof$, Chr(0)) - 1) If prof$ = "NotFound" Then WritePrivateProfileString "Add-Ins32", _ "AddIn.Connector", "0", "VB.INI" End If ' Change the directory in the next line to reflect ' the directory in which Visual Basic is installed. Shell "\vb4.32\vb32.exe", vbNormalFocus End Sub Private Sub Command2_Click() Unload Form1 End Sub ' Perform some control initialization. Private Sub Form_Load() With Screen Left = (.Width - Width) / 2 TOP = (.Height - Height) / 2 End With Command1.Caption = "Start Add-In" Command2.Caption = "End Add-In" End Sub ' Remove the profile string so that new instances ' of VB will not look for it. Private Sub Form_Unload(Cancel As Integer) WritePrivateProfileString "Add-Ins32", _ "AddIn.Connector", "", "VB.INI" End End Sub
Figure 17.6. Form1 of the add-in example 1 project.
' This class connects the add-in to the VB menu. Dim NewMenu As VBIDE.SubMenu Dim MenuLines As VBIDE.MenuLine Dim ConnectID As Long Dim thisInstance As VBIDE.Application Sub ConnectAddIn(VBInstance As VBIDE.Application) Set thisInstance = VBInstance Set NewMenu = thisInstance.AddInMenu.MenuItems.AddMenu("&New Menu") Set MenuLines = NewMenu.MenuItems.Add("&First Option") ConnectID = MenuLines.ConnectEvents(Me) End Sub Sub DisconnectAddIn(Mode As Integer) MenuLines.DisconnectEvents ConnectID NewMenu.MenuItems.Remove MenuLines thisInstance.AddInMenu.MenuItems.Remove NewMenu End Sub Public Sub AfterClick() MsgBox "Click!" End Sub
You can see that creating an add-in tool is somewhat involved. However, now that you have a working add-in tool, you can simply modify the AfterClick method in the Connector class module to develop a more advanced tool.
Example 1 showed you how to create a simple add-in tool. The AfterClick method that responded to the new option on the Add-Ins menu was located in the same class as the connection methods. This example shows you how to locate the AfterClick method in a
separate class. The following steps build on the code from Add-In Example 1:
Public Sub AfterClick() MsgBox "click!" End Sub
This example works in exactly the same way as the first example. The only difference is the location of the AfterClick event. The key to linking another class to the Connector class is that the ConnectEvents method is set to clickHandler, which holds
the instance of the new class. With this information in hand, try adding a second option to the Add-Ins menu by following the steps in the next example.
This example adds a menu option called Second Option to the Add-Ins menu. This example builds on the code in example 2. First, create a new class module called ADDIN2.CLS. Change its Name property to AddInClass2. Then enter the following
lines of code in Listing 17.4:
Public Sub AfterClick() MsgBox "click two!" End Sub
In the CONNECT.CLS file, change and add code as indicated by the highlighted lines in List-ing 17.5:
' This class connects the add-in to the VB menu. ' Dim NewMenu As VBIDE.SubMenu Dim MenuLines As VBIDE.MenuLine Dim MenuLines2 As VBIDE.MenuLine Dim clickHandler As AddInClass Dim clickHandler2 As AddInClass2 Dim ConnectID As Long Dim ConnectID2 As Long Dim thisInstance As VBIDE.Application Sub ConnectAddIn(VBInstance As VBIDE.Application) Set thisInstance = VBInstance Set clickHandler = New AddInClass Set clickHandler2= New AddInClass2 Set NewMenu = thisInstance.AddInMenu.MenuItems.AddMenu("&New Menu") Set MenuLines = NewMenu.MenuItems.Add("&First Option") Set MenuLines2 = NewMenu.MenuItems.Add("&Second Option") ConnectID = MenuLines.ConnectEvents(clickHandler) ConnectID2 = MenuLines2.ConnectEvents(clickHandler2) End Sub Sub DisconnectAddIn(Mode As Integer) MenuLines.DisconnectEvents ConnectID MenuLines2.DisconnectEvents ConnectID2 NewMenu.MenuItems.Remove MenuLines NewMenu.MenuItems.Remove MenuLines2 thisInstance.AddInMenu.MenuItems.Remove NewMenu End Sub
The project is ready to be run. When you select the AddIn Example from the Add-In Manager, two menu options should be added to the Add-Ins menu.
You can turn your temporary link to the Add-In Manager into a permanent one by following these steps:
The application will start, permanently register the add-in, and then immediately close.
Microsoft has turned everything in the Visual Basic project into an object of one type or another. Low-level objects, such as text boxes and labels, are combined into high-level objects, such as forms and modules, and these are in turn combined into the
highest-level object, your application. Microsoft calls the application-level object App.
The App object stores information about the currently executing application. It has no methods or events associated with it, only properties. The App object is available to every method in the application. In other words, it has a global scope. Table
17.1 shows a list of the properties of the App object.
Property |
Description |
| |
Major Minor Revision |
These three properties relate to the version number of the application. They become especially important if you are making a DLL or EXE file. |
| |
Comments CompanyName FileDescription LegalCopyright LegalTrademarks ProductName |
These five properties serve to identify your application in a way people can understand. They can be set to any string value. |
| |
OLERequestPendingMsgText OLERequestPendingMsgTitle OLERequestPendingTimeout OLEServerBusyMsgText OLEServerBusyMsgTitle OLEServerBusyRaiseError OLEServerBusyTimeout |
These seven properties allow you to override the default timeout values and message text of the dialog boxes that Windows uses to respond to OLE Request Pending and OLE Server situations. |
| |
Title |
The name of the application as displayed in the Windows Task List. |
EXEName |
The name of the executable file or, if in the IDE, the project name. |
HelpFile |
The name of the help file associated with the project. Its value is usually set in the initialization section of applications. |
hInstance |
The handle of the instance of the application. When running in the IDE, its value is the handle of the Visual Basic instance. |
Path |
The value of the current path. A path is a list of directories where Windows can look for needed files. This property is read-only. |
PrevInstance |
The value of this property indicates whether a previous instance of the application is already running. You can use this property in a Load event procedure to specify whether a user is already running an instance of an application. |
StartMode |
This property governs whether the application runs as a standalone project (vbSModeStandalone) or as a OLE server (vbSModeAutomation). |
TaskVisible |
This property determines if a task is visible in the task list. |
Using the App object is very straightforward. For example, you can set the HelpFile property in the following manner:
App.HelpFile = "C:\MYPROJ.HLP"
Most of the properties of the App object are blank or equal to zero until you set them yourself. The OLE properties are used later in this chapter.
Each time that Visual Basic is started, an object of the VBIDE.Application class that contains all of the other objects in the project, except for the App object, is created. This VBIDE.Application object can be referred to as the instance value. When
the check box in the Add-In Manager dialog box is checked, the ConnectAddIn method is called and the instance value is passed as the parameter, VBInstance. Table 17.2 shows the properties of the VBIDE.Application object. You can refer to any of these
properties in your AfterClick method if you store the value of VBInstance in a global variable. The AddIn example program used the global variable called thisInstance.
Property |
Description |
ActiveProject |
This is an object of the class ProjectTemplate. You can use this property to access the current ActiveForm object, add new objects to the project, or determine the currently selected components. |
AddInMenu |
This is an object of the class Menu. You can use this property to modify the Add-Ins menu of a project. |
Application |
The Application object representing the current instance of Visual Basic. You don't need to use this property because VBInstance also represents the current instance of Visual Basic. |
FileControl |
The FileControl object of Visual Basic. Using this property allows you to register to receive all file control events. See the SPY sample project for more information. |
LastUsedPath |
The path used for the File dialog boxes. You can modify this property if needed. |
Name |
The name used in code to identify the current object. The value of this property seems to always be Microsoft Visual Basic, so you can ignore it. |
Parent |
The object that contains the current object. This property is useful when talking about a control object, but when the object is the application instance itself, you can ignore this property. |
Version |
The version number of the application the add-in is connected to. The value of this property seems to always be 4.0. You can ignore this property also, unless you need to know which version of Visual Basic is being used. |
The ActiveProject property of the VBIDE.Application object is a member of the class VBIDE.ProjectTemplate. Table 17.3 lists the methods of the VBIDE.ProjectTemplate class, and Table 17.4 lists its properties.
Method |
Description |
AddFile |
This method adds a file to the project. It takes a file name as an argument. Visual Basic automatically adds the file as a form, module, or class, depending on the file extension. This method returns a string identifying the type of file added. |
AddFormTemplate |
This method adds a blank form to the project. The added form becomes the active form. This method returns a FormTemplate object so that you can further manipulate the form. |
AddMDIFormTemplate |
This method adds a MDI form to the project. The added form becomes the active form. This method returns a FormTemplate object so that you can further manipulate the form. |
AddReference |
This method adds a reference (.OLB file) to the project. You can specify the reference by library name or by file name. |
AddToolboxProgID |
This method adds a compound document object to the toolbox. The programmatic identifier of the compound document object is a required parameter. |
AddToolboxTypelib |
This method places the objects from a type library into the toolbox. |
AddToolboxVBX |
This method adds a VBX control to the toolbox. The file name of the VBX control is a required parameter. |
RemoveComponent |
This method removes a component from a project. It requires two parameters. The first is a Component object specifying the component to be removed. The second specifies whether to save the component before removal. |
Property |
Description |
ActiveForm |
The form that is the active window. This property is a member of the FormTemplate class. If an MDI form is active or referenced, this property specifies the MDI form. |
Application |
The Application object representing the current instance of Visual Basic. You don't need this property because VBInstance also represents the current instance of Visual Basic. |
FileName |
The file name of the currently selected file. |
Parent |
This property points to the object that contains the current object. This property should always be equal to VBInstance. |
SelectedComponents |
A collection of the currently selected components. The Align sample project uses this property. |
The AfterClick method refers to the VBIDE.ProjectTemplate object by using the VBInstance.ActiveProject variable. The most useful property is ActiveForm, which is a member of the VBIDE.FormTemplate class. The VBIDE.FormTemplate class is discussed in the
next section.
The ActiveForm property of the VBIDE.ProjectTemplate object is a member of the class VBIDE.FormTemplate. Table 17.5 lists the methods of the VBIDE.FormTemplate class, and Table 17.6 lists its properties.
Method |
Description |
AddMenuTemplate |
This method adds a Menu object to a form. It has two required arguments. The first is a string naming the new menu. The second is the name of a ControlTemplate object representing the parent menu item. If this object is set to Nothing, the menu will be added to the end of the menu bar. |
InsertFile |
This method inserts code from a file into the code module of a form immediately after the declarations and before the first procedure. |
Property |
Description |
Application |
The Application object representing the current instance of Visual Basic. You don't need this property because VBInstance also represents the current instance of Visual Basic. |
ControlTemplates |
The collection of all the controls on a form. This property is a member of the ControlTemplates class. |
Parent |
The object that contains the current object. This property should always be equal to VBInstance.ActiveProject. |
Properties |
The collection of all properties relating to the active form. This property is a member of the Properties class. |
SelectedControlTemplates |
The collection of all selected controls on the form. This property is a member of the SelectedControls class. |
The next section shows you how to use some of these properties and methods to programmatically create a form.
One possible use for an add-in tool might be to add standardized dialog boxes to new projects. Once you have designed a dialog box that you like, you can create an add-in tool to automatically add it to a new project.
Listings 17.6, 17.7, and 17.8 contain an entire project that demonstrates how to add new forms to your project. Listing 17.6 is the code behind Form1; it performs the INI file changes if needed. Listing 17.7 is the ADDIN.CLS file. Call its class by the
name of AddInClass. Listing 17.8 is the CONNECT.CLS file. Call its class by the name of Connector.
Option Explicit Public thisInstance As VBIDE.Application Public bar As Integer Private Declare Function WritePrivateProfileString Lib "Kernel32" _ Alias "WritePrivateProfileStringA" (ByVal AppName$, _ ByVal KeyName As Any, ByVal KeyDefault As Any, ByVal FileName$) As Long Private Declare Function GetPrivateProfileString Lib _ "Kernel32" Alias "GetPrivateProfileStringA" (ByVal AppName$, _ ByVal KeyName$, ByVal KeyDefault$, ByVal ReturnString$, _ ByVal NumBytes As Long, ByVal FileName$) As Long Private Sub Command1_Click() Dim prof As String prof = String$(255, Chr$(0)) ' If profile string is not present, return "NotFound" as the ' result. GetPrivateProfileString "Add-Ins32", "AddIn.Connector", _ "NotFound", prof, Len(prof) + 1, "VB.INI" ' get rid of trailing blanks. prof = Left(prof, InStr(prof, Chr(0)) - 1) If prof = "NotFound" Then WritePrivateProfileString "Add-Ins32", _ "AddIn.Connector", "0", "VB.INI" End If Shell "\vb4.32\vb32.exe", vbNormalFocus End Sub Private Sub Command2_Click() Unload Form1 End Sub Private Sub Form_Load() With Screen Left = (.Width - Width) / 2 TOP = (.Height - Height) / 2 End With Command1.Caption = "Start Add-In" Command2.Caption = "End Add-In" End Sub Private Sub Form_Unload(Cancel As Integer) WritePrivateProfileString "Add-Ins32", _ "AddIn.Connector", "", "VB.INI" End End Sub
Public thisInstance As VBIDE.Application Dim numDialog As Integer Public Sub AfterClick() numDialog = numDialog + 1 ' This With statement is changing the ' properties of a VBIDE.FormTemplate With thisInstance.ActiveProject.AddFormTemplate .Properties("BackColor") = &H800080 .Properties("BorderStyle") = 1 .Properties("Caption") = "About Add-In Examples" .Properties("ControlBox") = False .Properties("Height") = 2500 .Properties("Left") = 1000 .Properties("Name") = "AboutFrm" + Right(Str(numDialog), 1) .Properties("MaxButton") = False .Properties("MinButton") = False .Properties("Top") = 1000 .Properties("Width") = 5000 ' This With statement is changing the ' properties of a VBIDE.ControlTemplate With .ControlTemplates.Add("CommandButton") .Properties("Caption") = "&OK" .Properties("Left") = 2000 .Properties("Width") = 1000 .Properties("Top") = 1320 End With With .ControlTemplates.Add("Label") .Properties("BackColor") = &H800080 .Properties("Caption") = "Copyright 1995, SAMS" .Properties("ForeColor") = &H80FFFF .Properties("Left") = 1550 .Properties("Height") = 250 .Properties("Width") = 1700 .Properties("Top") = 850 End With With .ControlTemplates.Add("Label") .Properties("Alignment") = 2 ' center .Properties("BackColor") = &H800080 .Properties("Caption") = "AddIn Examples 3 - Version 1.0" .Properties("ForeColor") = &H80FFFF .Properties("Height") = 250 .Properties("Left") = 250 .Properties("Width") = 4500 .Properties("Top") = 250 End With End With End Sub
' This class connects the add-in to the VB menu. ' Dim NewMenu As VBIDE.SubMenu Dim MenuLines As VBIDE.MenuLine Dim clickHandler As AddInClass Dim ConnectID As Long Dim thisInstance As VBIDE.Application Sub ConnectAddIn(VBInstance As VBIDE.Application) Set thisInstance = VBInstance Set clickHandler = New AddInClass Set clickHandler.thisInstance = thisInstance Set NewMenu = thisInstance.AddInMenu.MenuItems.AddMenu("&New Menu") Set MenuLines = NewMenu.MenuItems.Add("&First Option") ConnectID = MenuLines.ConnectEvents(clickHandler) End Sub Sub DisconnectAddIn(Mode As Integer) MenuLines.DisconnectEvents ConnectID NewMenu.MenuItems.Remove MenuLines thisInstance.AddInMenu.MenuItems.Remove NewMenu End Sub
You also need to add the following line to the Connector class in the ConnectAddIn method after the line in which the clickHandler variable is set:
Set clickHandler.thisInstance = thisInstance
This example just scratches the surface of how to add a form. You can change font typefaces and size. You could also add methods or properties to the form by creating a temporary file and then using the InsertFile method of the FormTemplate class.
This chapter showed you how to create add-ins for use inside Visual Basic. Starting with a single additional menu option, you progressed to two options each invoking a different class. Then after a brief tour of the Visual Basic IDE underpinnings, you
looked at how to use an add-in to create a standardized form or dialog box.
Microsoft has included the source code for an alignment add-in, as well as the code for the Data Manager add-in. Take advantage of their code to learn more about how to create your own.
In addition, don't ignore the potential profit that can be yours if you create the ultimate add-in. With a potential market of over 1.5 million programmers, even a small success can pay off big!