Last time we got the views, forms, framesets etc up and running. This time we're going to look at execution.
Create a VB Script Library called NAVScripts
The first thing we need to do is add the RunShellExecute API to our Project.
In the Declarations section of your application, add the following;
Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (Byval hwnd As Long, Byval lpOperation As String, Byval lpFile As String, Byval lpParameters As String, Byval lpDirectory As String, Byval nShowCmd As Long) As Long
Note that the there are only two lines here (The second group has a few word-wraps in it).
Next, add the following code, which makes it a little easier to use the shellexecute function. It also allows us to pass multiple things to it separated by double hashes ## (this is useful if you want to specify a specific action, as specified in the comments at the beginning of the routine).
Sub RunShellExecute(sTopic As String, sFile As Variant, sParams As Variant, sDirectory As Variant, nShowCmd As Long)
'EXAMPLE: Play wav file with associated app RunShellExecute "Play", "c:\windows\media\Notify.wav", 0&, 0&, SW_SHOWNORMAL
'EXAMPLE: Play avi file with associated app RunShellExecute "Play", "E:\VB Graphics\avi\Cogs.avi", 0&, 0&, SW_SHOWNORMAL
'EXAMPLE: Open txt file with associated app RunShellExecute "Open", "c:\My Documents\rundll.txt", 0&, 0&, SW_SHOWNORMAL
'EXAMPLE: Open txt file with notepad RunShellExecute "Play", "C:\windows\notepad.exe", "c:\My Documents\rundll.txt", 0&, SW_SHOWNORMAL
Dim hWndDesk As Long
Dim success As Long
Const SE_ERR_NOASSOC = &H31
Const vbTextCompare = 1
Dim HashPos As Integer
HashPos = Instr(1, sFile, "##" , vbTextCompare)
If HashPos > 0 Then
sTopic = Left(sFile, HashPos -1 )
sFile = Right(sFile, (Len(sFile) - (HashPos+1)))
End If
'The desktop will be the default for error messages
hWndDesk = GetDesktopWindow()
Print "RunShellExecute: " + "Topic=[" + sTopic + "]" + " File=[" + sFile + "]"
'Execute the passed operation
success = ShellExecute(hWndDesk, sTopic, sFile, sParams, sDirectory, nShowCmd)
End Sub
I've also got a couple of other useful subs which we should include (or the code wont work).
The first of these subs allows us to replace specific parts of variables, very similar to the replace function in Visual BASIC. (Actually, this was what we used before there was a replace function). Using this allows you to interpret command lines on the fly (eg: Substitute %USERNAME% with the current user name).
Function ReplaceSubstring(BigString As String, ReplaceString As String, WithString As String, CaseSensitive As Boolean) As String
Dim CaseSelector As Integer
Dim ReplaceLength As Integer, Position As Integer
Dim LeftString As String, RightString As String
If CaseSensitive = True Then CaseSelector = 0 Else CaseSelector = 1
Position = Instr(1,BigString,ReplaceString, CaseSelector)
If Position <> 0 Then
ReplaceLength = Len(ReplaceString)
LeftString = Left$(Bigstring,Position-1)
RightString = Mid$(BigString,Position+ReplaceLength)
ReplaceSubstring = LeftString + WithString + RightString
Else
ReplaceSubstring = BigString
End If
End Function
Now that we have actual "execution" routines, we need to create a function to read the values from the form and execute them.
Sub QueryODCentral(Source As Notesuiview, Continue As Variant)
Dim session As New NotesSession
Dim db As NotesDatabase
Dim docs As NotesDocumentCollection
Dim doc As NotesDocument
Set db = session.CurrentDatabase
Set docs = Source.Documents
Set doc = docs.GetFirstDocument()
Dim CommandLine As String
Dim LinkType As String
Dim LinkData As String
Dim DocInfo As String
Dim ReminderTitle As String
Dim DatabaseURL As String
DatabaseURL = db.NotesURL
DocInfo = doc.TXTTitle(0)
ReminderTitle = doc.Subject(0)
LinkType = doc.KeyLinkType(0)
LinkData = doc.TXTLinkData(0)
If DocInfo = "" Then DocInfo = ReminderTitle
Select Case Ucase$(Trim$(LinkType))
Case "LAUNCH"
If LinkData <> "" Then
If Instr(1, Ucase$(LinkData), "%NOTESSERVER%",1) > 0 Then
LinkData = ReplaceSubstring(LinkData, "%NOTESSERVER%", NotesServer, 0)
End If
If Instr(1, Ucase$(LinkData), "%CURRENTYEAR%",1) > 0 Then
LinkData = ReplaceSubstring(LinkData, "%CURRENTYEAR%", Trim$(Format$(Now, "YYYY")), 0)
End If
RunShellExecute "Open", LinkData, 0&, 0&, 1
Print "LAUNCH: " + DocInfo
Else
Print "LAUNCH ERROR: There was no document specified"
End If
Case "MESSAGE"
Msgbox LinkData,64,DocInfo
Print "MESSAGE: " + LinkData
Case Else
Msgbox "Unknown Link Type - Unable to Launch",48,"Error"
End Select
Continue = False
End Sub
You will notice that in this code, there are two possible linktypes: Message and Launch. We can easily add more, though as yet, I havent found the need... Eventually though, I may add an opendocument type - I'll explain the use of Notes URLs a bit later, so you can see that this wont necessarily be required.
Finally, we need to make some modifications to the views... Remember to leave at least one view "untouched" (and call this view Edit Mode - or something similar).
In the Options for the View, include the phrase
Use "NAVScripts"
In the QueryOpenDocument part of the view, include the following;
Sub Queryopendocument(Source As Notesuiview, Continue As Variant)
QueryODCentral Source , Continue
End Sub
That's it... now you can start to create some Navigator Entries.
Ideally when you double-click them, they will launch.
The theory is that you could create an entry with a sensible display title (TXTTitle), set the link type (KEYLinkType) to LAUNCH, and then Set the Link Data (TXTLinkData) to almost anything;
examples:
http://www.google.com.au
notes://%NOTESSERVER%/names.nsf
C:\temp\mytextfile.txt
C:\windows\system32\calc.exe
The other terribly exciting thing that this navigator has over my old Navigator is that because these things are documents in views, I can full text search for anything I can't find.
Final Thoughts...
The full version of my navigator also includes...
Create a VB Script Library called NAVScripts
The first thing we need to do is add the RunShellExecute API to our Project.
In the Declarations section of your application, add the following;
Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (Byval hwnd As Long, Byval lpOperation As String, Byval lpFile As String, Byval lpParameters As String, Byval lpDirectory As String, Byval nShowCmd As Long) As Long
Note that the there are only two lines here (The second group has a few word-wraps in it).
Next, add the following code, which makes it a little easier to use the shellexecute function. It also allows us to pass multiple things to it separated by double hashes ## (this is useful if you want to specify a specific action, as specified in the comments at the beginning of the routine).
Sub RunShellExecute(sTopic As String, sFile As Variant, sParams As Variant, sDirectory As Variant, nShowCmd As Long)
'EXAMPLE: Play wav file with associated app RunShellExecute "Play", "c:\windows\media\Notify.wav", 0&, 0&, SW_SHOWNORMAL
'EXAMPLE: Play avi file with associated app RunShellExecute "Play", "E:\VB Graphics\avi\Cogs.avi", 0&, 0&, SW_SHOWNORMAL
'EXAMPLE: Open txt file with associated app RunShellExecute "Open", "c:\My Documents\rundll.txt", 0&, 0&, SW_SHOWNORMAL
'EXAMPLE: Open txt file with notepad RunShellExecute "Play", "C:\windows\notepad.exe", "c:\My Documents\rundll.txt", 0&, SW_SHOWNORMAL
Dim hWndDesk As Long
Dim success As Long
Const SE_ERR_NOASSOC = &H31
Const vbTextCompare = 1
Dim HashPos As Integer
HashPos = Instr(1, sFile, "##" , vbTextCompare)
If HashPos > 0 Then
sTopic = Left(sFile, HashPos -1 )
sFile = Right(sFile, (Len(sFile) - (HashPos+1)))
End If
'The desktop will be the default for error messages
hWndDesk = GetDesktopWindow()
Print "RunShellExecute: " + "Topic=[" + sTopic + "]" + " File=[" + sFile + "]"
'Execute the passed operation
success = ShellExecute(hWndDesk, sTopic, sFile, sParams, sDirectory, nShowCmd)
End Sub
I've also got a couple of other useful subs which we should include (or the code wont work).
The first of these subs allows us to replace specific parts of variables, very similar to the replace function in Visual BASIC. (Actually, this was what we used before there was a replace function). Using this allows you to interpret command lines on the fly (eg: Substitute %USERNAME% with the current user name).
Function ReplaceSubstring(BigString As String, ReplaceString As String, WithString As String, CaseSensitive As Boolean) As String
Dim CaseSelector As Integer
Dim ReplaceLength As Integer, Position As Integer
Dim LeftString As String, RightString As String
If CaseSensitive = True Then CaseSelector = 0 Else CaseSelector = 1
Position = Instr(1,BigString,ReplaceString, CaseSelector)
If Position <> 0 Then
ReplaceLength = Len(ReplaceString)
LeftString = Left$(Bigstring,Position-1)
RightString = Mid$(BigString,Position+ReplaceLength)
ReplaceSubstring = LeftString + WithString + RightString
Else
ReplaceSubstring = BigString
End If
End Function
Now that we have actual "execution" routines, we need to create a function to read the values from the form and execute them.
Sub QueryODCentral(Source As Notesuiview, Continue As Variant)
Dim session As New NotesSession
Dim db As NotesDatabase
Dim docs As NotesDocumentCollection
Dim doc As NotesDocument
Set db = session.CurrentDatabase
Set docs = Source.Documents
Set doc = docs.GetFirstDocument()
Dim CommandLine As String
Dim LinkType As String
Dim LinkData As String
Dim DocInfo As String
Dim ReminderTitle As String
Dim DatabaseURL As String
DatabaseURL = db.NotesURL
DocInfo = doc.TXTTitle(0)
ReminderTitle = doc.Subject(0)
LinkType = doc.KeyLinkType(0)
LinkData = doc.TXTLinkData(0)
If DocInfo = "" Then DocInfo = ReminderTitle
Select Case Ucase$(Trim$(LinkType))
Case "LAUNCH"
If LinkData <> "" Then
If Instr(1, Ucase$(LinkData), "%NOTESSERVER%",1) > 0 Then
LinkData = ReplaceSubstring(LinkData, "%NOTESSERVER%", NotesServer, 0)
End If
If Instr(1, Ucase$(LinkData), "%CURRENTYEAR%",1) > 0 Then
LinkData = ReplaceSubstring(LinkData, "%CURRENTYEAR%", Trim$(Format$(Now, "YYYY")), 0)
End If
RunShellExecute "Open", LinkData, 0&, 0&, 1
Print "LAUNCH: " + DocInfo
Else
Print "LAUNCH ERROR: There was no document specified"
End If
Case "MESSAGE"
Msgbox LinkData,64,DocInfo
Print "MESSAGE: " + LinkData
Case Else
Msgbox "Unknown Link Type - Unable to Launch",48,"Error"
End Select
Continue = False
End Sub
You will notice that in this code, there are two possible linktypes: Message and Launch. We can easily add more, though as yet, I havent found the need... Eventually though, I may add an opendocument type - I'll explain the use of Notes URLs a bit later, so you can see that this wont necessarily be required.
Finally, we need to make some modifications to the views... Remember to leave at least one view "untouched" (and call this view Edit Mode - or something similar).
In the Options for the View, include the phrase
Use "NAVScripts"
In the QueryOpenDocument part of the view, include the following;
Sub Queryopendocument(Source As Notesuiview, Continue As Variant)
QueryODCentral Source , Continue
End Sub
That's it... now you can start to create some Navigator Entries.
Ideally when you double-click them, they will launch.
The theory is that you could create an entry with a sensible display title (TXTTitle), set the link type (KEYLinkType) to LAUNCH, and then Set the Link Data (TXTLinkData) to almost anything;
examples:
http://www.google.com.au
notes://%NOTESSERVER%/names.nsf
C:\temp\mytextfile.txt
C:\windows\system32\calc.exe
The other terribly exciting thing that this navigator has over my old Navigator is that because these things are documents in views, I can full text search for anything I can't find.
Final Thoughts...
The full version of my navigator also includes...
- Keywords for Department Names (so that certain things only appear for certain departments)
- Keywords for Importance Levels etc... to assist in the sorting of items in views.
- A calendar entry form which is similar to the navigator entry, which causes specific items to appear on specific days only. (and they're still launchable).
I apologise for getting so technical early on on this blog... I'll try to vary the technical levels of my entries. If anyone has any questions, let me know and I'll provide you with a template.
Gavin.
Comments