Creating a Team Folders Wizard Extension

[Previous] [Next]

In addition to creating a template for the Team Folders Wizard, you can extend the wizard interface itself. Extending the wizard interface allows users to further customize your applications before the wizard deploys them. The Team Folders Wizard extensions are registered individually for each template. Therefore, to add an extension to all templates, you need to register the extension with each template. You'll see how to register an extension later in this chapter.

Interfaces of the Team Folders Wizard Extension

A Team Folders extension is an ActiveX DLL that implements specific interfaces required by the Team Folders Wizard. The wizard uses these interfaces to inform an extension of specific events, such as when the user enters the portion of the wizard that implements the extension. This occurs after the user has selected the permissions for the Team Folders application but before the wizard displays the last screen.

When creating your ActiveX DLL, you should implement a similar interface to that of the Team Folders Wizard. This means implementing Back, Next, and Cancel buttons directly on your form. Plus, you need to make sure that you code the extension correctly so that if a user returns to it after clicking the Next button, the extension can correctly return to the appropriate screen. You don't want your extension to repeat any unnecessary steps.

Creating an extension is quite easy. This book's companion CD contains a sample extension for the Account Tracking template. This extension allows the user creating an application from the Account Tracking template to specify whether to automatically add the folder to her Favorites folder as well as to add a shortcut on the Outlook bar. Figure 9-22 shows the extension's user interface.

click to view at full size.

Figure 9-22. The user interface of the Account Tracking extension.

Now, you need to add some references to your Microsoft Visual Basic project in order to determine which extension interfaces to implement in your ActiveX DLL. First, you need to add a reference to the file tfexten.dll (ITeamFoldersExtension typelib). Next, add the Microsoft Scripting Runtime reference. Figure 9-23 shows how to add these references.

click to view at full size.

Figure 9-23. Adding Visual Basic references to the necessary files to create a Team Folders extension.

Once you've added these references, you need to type Implements ITeamFolderExtension in your Visual Basic code. In the drop-down lists, you'll see three interfaces that you need to implement: ExtExec, ExtUndo, and ExtCancel.

The wizard calls the ExtExec function when the user enters your extension by clicking on Next in the wizard. Here is a stub for this function:

Private Function ITeamFoldersExtension_ExtExec( _ ByVal UserPerms As Scripting.IDictionary, _ ByVal TempDirectory As String, ByVal CurrentStep As Integer, _ ByVal TotalSteps As Integer) As Long End Function

The Team Folders Wizard passes you a number of parameters for this interface. The first parameter is a Dictionary object called UserPerms that contains the permissions list for the application. The second parameter, TempDirectory, specifies the path to the temporary directory where the folder home page files for the application are located before being deployed. You have Write permissions to these files in the temporary directory. The Account Tracking extension uses this location to modify the files to specify the preferences of the user. The third parameter, CurrentStep, specifies the number of steps of the wizard that the user already has been through. When you combine CurrentStep with the next parameter, TotalSteps, you can display the progress bar showing the progress of your wizard's extension.

Your extension should return a value of Long data type, which tells the wizard whether the user clicked Next, Back, or Cancel, or if the extension didn't work. The specific literals for this return value appear in the following code for the Account Tracking extension's ExtExec function that shows the user interface:

Private Function ITeamFoldersExtension_ExtExec( _ ByVal UserPerms As Scripting.IDictionary, _ ByVal TempDirectory As String, ByVal CurrentStep As Integer, _ ByVal TotalSteps As Integer) As Long 'Shows user interface 'Returns Success = 0 ' Failure = -1 ' Back = 1 ' Cancel = 2 'This extension needs to know only where the working directory is so that 'it can modify the HTML file Debug.Print "in ITeamFolderExt" gWizardStep = CurrentStep + 1 gWizardSteps = TotalSteps gTempDirectory = TempDirectory Debug.Print gTempDirectory & gWizardSteps frmAppOptions.Show vbModal 'as modal so that it doesn't 'return too early ITeamFoldersExtension_ExtExec = gRetValue End Function

As the code shows, the extension retrieves the values for the step counters, gets the temporary directory, and then displays its Visual Basic form as a modal form. Once the user leaves the form, the extension returns the correct value as determined by the user's actions in the form.

The wizard calls the ExtUndo function when the user reenters your extension after he has already left. This can happen if the user clicks the Back button on one of your subsequent extension pages or on the wizard's final page to return to a specific extension. This function receives the same parameters as the ExtExec function and returns a Long value that means the same as each value in the ExtExec function. For example, returning a value of 0 indicates success. The code for this function follows:

Private Function ITeamFoldersExtension_ExtUndo( _ ByVal UserPerms As Scripting.IDictionary, _ ByVal TempDirectory As String, ByVal CurrentStep As Integer, _ ByVal TotalSteps As Integer) As Long Should show user interface from last step in extension 'Returns Success = 0 ' Failure = -1 ' Back = 1 ' Cancel = 2 gWizardStep = CurrentStep - 1 gWizardSteps = TotalSteps gTempDirectory = TempDirectory frmAppOptions.Show vbModal ITeamFoldersExtension_ExtUndo = gRetValue End Function

As you can see, the ExtExec and ExtUndo functions are very similar. The function sets the progress bar for the extension to the correct value. It then displays the Visual Basic form as a modal form, and after the user is finished interacting with the form, the function returns the correct return value. Depending on what your extension does, you might need to implement more functionality.

The ExtCancel function is called when the user clicks the Cancel button elsewhere in the wizard. In this function, place any cleanup code that your extension requires. This function passes you the same parameters as the ExtUndo and ExtExec functions; however, the return value for ExtCancel is a bit different than that of the previous two functions. The ExtCancel function can return one of only two values rather than four. Since the user has clicked Cancel, she won't care about moving backward or forward in the wizard. Therefore, the return value needs to indicate only success or failure. Here is the code for this function:

Private Function ITeamFoldersExtension_ExtCancel( _ ByVal UserPerms As Scripting.IDictionary, _ ByVal TempDirectory As String, ByVal CurrentStep As Integer, _ ByVal TotalSteps As Integer) As Long 'Should show no user interface 'Returns Success = 0 ' Failure = -1 gTempDirectory = TempDirectory 'MsgBox " Implement Cancel functionality for extension here" ITeamFoldersExtension_ExtCancel = eSuccess End Function

Visual Basic Form for the Account Tracking Extension

Besides implementing the extension interfaces, the Visual Basic project for the Account Tracking extension includes the actual Visual Basic form shown to the user as part of the application. This form contains all the logic for the extension as well as the navigation for the user. The code for the form follows:

Dim strText Dim oCreatedFile As Scripting.File Dim fs As Scripting.FileSystemObject Dim iFavorites Dim iAddShortcut Private Sub btnBack_Click() gRetValue = eStepBack 'Function returns 1 'indicating extension Undo frmAppOptions.Hide End Sub Private Sub btnHelp_Click() MsgBox "Insert Your Help Routines Here" End Sub Private Sub btnNext_Click() 'Need to set return value for function and exit function 'OLTFWizardExt returns 0 if successful Dim fsResult Dim oFile As Scripting.File Dim oBUFile As Scripting.File Dim oTextStream As Scripting.TextStream 'Open the HTML file and set some global variables 'storing the user's selections Set oFile = fs.GetFile(strBrowseAddress) If oFile Is Nothing Then MsgBox "Error opening acctext.htm" Else 'Before writing to the file, make a clean backup 'Make sure not to overwrite if already there! On Error Resume Next oFile.Copy gTempDirectory & "\webview\acctext2.htm", False On Error GoTo 0 Set oBUFile = fs.GetFile(gTempDirectory & "\webview\acctext2.htm") 'Overwrite the backup over the original oBUFile.Copy strBrowseAddress, True Debug.Print "made copy" 'Reset oFile Set oFile = fs.GetFile(strBrowseAddress) Set oTextStream = oFile.OpenAsTextStream(ForAppending, _ TristateUseDefault) With oTextStream .WriteLine "<Script Language = vbscript>" .WriteLine "boolAddtoFavorites = " & _ checkAddtoFavorites.Value .WriteLine "boolAddShortcut = " & checkAddShortcut.Value .WriteLine "</Script>" End With oTextStream.Close End If Debug.Print "creating file" 'Create a new file in the temporary address to mark down the values Set oCompleted = fs.CreateTextFile(gTempDirectory _ & "\complete.txt", True) ' Remember user selections oCompleted.WriteLine checkAddtoFavorites.Value oCompleted.WriteLine checkAddShortcut.Value oCompleted.Close Set fs = Nothing gWizardStep = gWizardStep + 1 gRetValue = eSuccess ' Extension finished; return 0 success code Me.Hide End Sub Private Sub btnCancel_Click() 'Insert your cancel functionality here and then set the 'OLTFWizardExt return value to 2 (Cancel) gRetValue = eCancelWiz Me.Hide End Sub Private Sub Form_Activate() progBar.Max = gWizardSteps progBar.Value = gWizardStep Set fs = New FileSystemObject Dim oTS As Scripting.TextStream Set oCreatedFile = Nothing Debug.Print "in Activate" 'Check to see whether a file called complete.txt already exists On Error Resume Next Set oCreatedFile = fs.GetFile(gTempDirectory & "\complete.txt") On Error GoTo 0 If Not (oCreatedFile Is Nothing) Then Debug.Print "File exists" 'Pull the values from the file Set oTS = oCreatedFile.OpenAsTextStream(ForReading) iFavorites = oTS.ReadLine iAddShortcut = oTS.ReadLine If iFavorites = 1 Then checkAddtoFavorites.Value = vbChecked Else checkAddtoFavorites.Value = vbUnchecked End If If iAddShortcut = 1 Then checkAddShortcut.Value = vbChecked Else checkAddShortcut.Value = vbUnchecked End If End If End Sub Private Sub Form_Load() 'Load form strings strText = "" 'Need to load all strings here Debug.Print "Form Load: " & gTempDirectory If gTempDirectory <> "" Then strBrowseAddress = gTempDirectory & "\webview\acctext.htm" Else MsgBox "Error - no browsable address found" End If End Sub

The interesting aspects of the code lie in the btn_Next and Activate subroutines. The Activate subroutine sets the progress bar for the form that shows the user the wizard's progress based on the number of steps already performed. This subroutine also checks to see whether a file named complete.txt exists in the temporary directory created by the Team Folders Wizard. This file stores the user's preferences, as you'll see in the btn_Next subroutine. I use a text file to be absolutely sure that the preferences are stored—just in case the user clicks Back or Next, possibly several times, to move between the extension and the built-in Team Folders Wizard pages. If the text file doesn't exist, the application creates it. If it does exists, the application loads the values from the text file and makes them the default for the form controls.

The application calls the btn_Next subroutine when the user clicks the Next button on the extension's form. In this subroutine, the extension needs to set some variables so that the folder home page knows what the user selected from the extension. If no backup exists, the subroutine first makes a backup copy of the original folder home page file so that if the user unselects something in the user interface, the extension doesn't have to parse and delete text from the HTML file. Instead, the extension can overwrite the existing file with the clean backup and add the necessary information to it.

Once the backup is completed or verified, the subroutine writes the necessary values to the file. Then, the subroutine creates the complete.txt file using the FileSystemObject of the scripting runtime. If complete.txt already exists, the extension overwrites it.

Folder Home Page for the Account Tracking Extension

Now that we've seen what the extension can do, let's see how the folder home page implements the preferences set in the extension. The folder home page included with the extension template is a slightly modified version of the Account Tracking template you saw earlier. The key changes are the ability of the extension to check for preferences set by the user, to implement those preferences, and to make sure those preferences are implemented only once. The code for this functionality follows:

'Check to see whether there is a hidden message 'in the user's Inbox that corresponds to our application. 'If not, do the action and create the hidden message. 'If there is, skip this section. set oInbox = oSession.Inbox set oHidden = oInbox.HiddenMessages 'Clear out any filters oHidden.Filter = Nothing Set oFilter = oHidden.Filter oFilter.Fields.Add "strEntryID", 8, strEntryID 'If count is 1, then we don't want to do anything 'since we performed this action for the user already If oHidden.count > 1 then MsgBox "Error! Too many items meet the criteria!" ElseIf oHidden.count = 0 then 'Check to see whether we need to add to Favorites If boolAddtoFavorites = 1 Then AddToFavorites End If If boolAddShortcut = 1 Then AddOutlookShortcut End If 'Create a hidden message stating that we already 'did all the work for this user so that next time 'they come in, we don't do it again! 'Assume everything was done. CreateHiddenMessage Else 'MsgBox "Hidden message already exists" End If End Sub Function CheckOfflineStatus() On Error Resume Next If oInfoStore.Fields(&H6632000B).Value = True Then CheckOfflineStatus = True 'MsgBox "Offline" Else CheckOfflineStatus = False 'MsgBox "online" End If End Function Sub AddToFavorites 'Check to see whether we're in the private store or a .pst file. 'Check to see whether we're working offline. 'If we are, don't try to add to Favorites 'since the folder should already be in the Favorites 'folder. 'Get the Favorites folder EntryID. 'MsgBox "Adding to Favorites" Set oInfoStores = oSession.InfoStores For Each otmpInfoStore In oInfoStores Set oInfoStore = otmpInfoStore boolPFStore = CheckForPFStore If boolPFStore = True Then 'We found the Public Folder infostore 'MsgBox "Found PF" Exit For End If Next boolOffline = CheckOfflineStatus strFavEntryID = oInfoStore.Fields(ActMsgPR_IPM_FAVORITES_ENTRYID).Value Set oFavFolder = oSession.GetFolder(strFavEntryID, Null) 'MsgBox oFavFolder.Name If (boolPFStore = True And boolOffline = False) Then 'Add to Favorites On Error Resume Next oViewControl.AddToPFFavorites Else 'MsgBox "not adding to favorites" End If End Sub Function CheckForPFStore() On Error Resume Next Err.Clear lMask = oInfoStore.Fields.Item(ActMsgPR_STORE_SUPPORT_MASK) If lMask And ActMsgSTORE_PUBLIC_FOLDERS Then 'It's a Public Folder store 'MsgBox "PF" CheckForPFStore = True Else 'MsgBox "not a PF" CheckForPFStore = False End If End Function Sub AddOutlookShortcut() Set oPane = oExplorer.Panes("OutlookBar") Set oOLBarStorage = oPane.Contents Set oOLBarGroups = oOLBarStorage.Groups Set oNewOLGroup = oOLBarGroups.Add("Account Tracking (ext)", _ oOLBarGroups.Count + 1) Set oNewOLShortcuts = oNewOLGroup.Shortcuts oNewOLShortcuts.Add oAccountFolder, "Account Tracking (ext)" End Sub Sub CreateHiddenMessage() On Error Resume Next 'MsgBox "Creating Hidden Message" Set oInbox = oSession.Inbox Set oHidden = oInbox.HiddenMessages Set oNewMsg = oHidden.Add("Acct Ext: " & oFolder.Name, _ "", "IPM.Post.AcctExt") oNewMsg.Fields.Add "strEntryID", 8, strEntryID oNewMsg.Update End Sub

The code checks in the user's Inbox for the existence of a hidden message that matches the ID of the current folder. If the code finds that message, it doesn't attempt to add the folder to the user's Favorites folder or the Outlook bar. However, if the code doesn't find that message, it checks the values put into the global variables that the Team Folders extension added.

If the user is online and has indicated to the extension to add the folder to the user's Favorites folder, the code uses the AddtoPFFavorites method of the View control to do so. You check online and offline status in your code by using a property on the InfoStore object. Since the application must be in the Favorites folder to be accessible offline, the code does not attempt to add the folder to Favorites folder if the user is working offline.

The code then adds the folder to the Outlook shortcut bar by using the OutlookBarShortcuts collection of the Outlook object model. Next, the code uses the HiddenMessages collection of CDO in the user's Inbox to create a new item. This item will prevent future hits on the folder home page that would cause these actions to recur. This is a good way to store user customization or completion information because you know the Inbox will roam with the user no matter what computer he logs on from. As long as the user logs on to Exchange Server, you can access his Inbox and retrieve your hidden message.



Programming Microsoft Outlook and Microsoft Exchange
Programming Microsoft Outlook and Microsoft Exchange, Second Edition (DV-MPS Programming)
ISBN: 0735610193
EAN: 2147483647
Year: 2000
Pages: 184

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net