Friday, September 30, 2005

Creating a Domino Navigation System - Part 2

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...
  • 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.

Thursday, September 29, 2005

Creating a Domino Navigation System - Part 1

Introduction
In this tutorial, I'll be attempting to show you one way that you could make a menu/navigation system for your company (I'm hesitating to use the word portal), without resorting to either Workplace or WebSphere.

I think we're all familiar with the welcome screen, which is nice for individual users, but really isnt much good for a corporation, especially not one with lots of databases.

I originally built a navigation system for my company using Navigators, they were the only things available at the time. This resolved some problems I had with the workspace, namely how to put new databases on the desktop, and control where they went.

Unfortunately, the problem with this approach is that when you want to make changes, you have to do so using designer. I wanted to come up with a more flexible navigator which would allow things to be easily moved around.

Note that the proposed navigator is a Notes-based, rather than web-based system.



The Basic Building Blocks
I'm going to assume a little familiarity with domino designer here...

Outlines
Create an outline to use for the left hand panel navigation system - I'd suggest that it should include things like My Mail, and the main departments/divisions in your company.

Pages
Create a Page for the Navigator Controls (down the left hand side of the screen), and embed the outline onto it.

Create a second page for the main body of the navigator - we're actually going to use views for most of the work in the navigator, but a page is really nice to start on. This gives us a bit of scope for graphics. You might want to embed some frequently used views from other databases onto this page. I added our room booking system and business contacts, speed dials and staff phone list. I also added some graphical icons below and put two views (back into the navigation system itself) at the top (I'll provide more information on these later).

I created a page for the Top banner and a page for the version number (bottom left hand corner), these pages don't do much, so you might want to ignore them.

Forms
I have two forms in my database, one is a Navigator Entry, and the other is a Reminder. The reminder is essentially the same as the navigator entry except that it has time and scheduling fields to make its entries appear only on days for which it is relevant. The data from the reminder form appears on the top view of the navigator.

I'm mainly going to be concerned with the navigator entry form. This form should have, at the very least, an Item Title (text field), possibly a LinkType (dialog list) and a LinkData field (text).
I've called these fields TXTTitle, KEYLinkType and TXTLinkData respectively. You should also consider having a Categories (Dialog List) field, so that you can decide which views an entry should be in. My categories field was called KEYCategories.

Views
Finally, create a view which displays the TXTTitle from the Navigator Entry form. You can place a restriction on the view if you like, In my case, I restrict to only those Navigator Entries which have @Contains(KEYCategories ; "STAFF_FAVORITES"). You should update your page to embed this view on it.

You should create one or two more copies of this view, with different KEYCategories restrictions, including at least one view with no restrictions. You should link some of your outline entries to these views, (to open the views in the pane currently occupied by the main body page.

Framesets
Create a frameset to tie all of these elements together and set the database to open the frameset. Make the navigation controls page, and the main body page the default settings for the navigator, and set the database to open the navigator automatically when it is opened.


Next Time: I'll give you the code required to execute items when they are double-clicked in views.

Wednesday, September 28, 2005

Copyright and Other Disclaimers (Important)

I'm not a "legal" person, and I know that most people don't bother reading legal things, so I'm writing this in plain English. Ideally that shouldn't affect the legal potency of this work...

Ownership of Material
Technically I am the owner of all material posted on this blog, however I grant everyone the right to use it in any way they want to (except to bring legal action, abuse or other horrible stuff down onto me). It would be nice if you were to acknowledge the source, but I know that in the connected world, this isn't always possible, so I won't hold you to it.

You can copy it, send it around, change words (on your copy, not on mine) etc...

Insulting Statements etc.
I will be trying hard not to insult people or companies or make libellous statements, but sometimes you do these things without thinking. If I offend anyone, please let me know (I think there's some sort of email link on this blog somewhere), and I will remove the offending entry post-haste. Don't sue me or take any form of legal action (I hate that sort of thing), just let me know, I'll apologise and remove the offending entry and all will be sweet (I hope).

Disclaimer
I'm something of a programmer, though not really what you'd call a terribly good one. There will be source code posted here, as well as other statements. You can use it to your heart's content (see the first paragraph - duh..) but... assume that I'm an idiot...

Don't place any faith in any statement, or any code that I post. Be man (or woman) enough to check it out for yourself. I'm disclaiming responsibility as far as I possibly can, for anything posted here. Use at your own risk

Of course, if you do find something wrong... let me know the right answer and I'll fix it.

Gavin.

Welcome (Introduction to the Blog)

Hi, and welcome to my Computing and Lotus Domino blog... I was originally going to mix computing family and movies all into my other blog, but then I thought about the audience... If you want to read about one topic, you don't want other topics interfering.

The main things that will be on this blog will be;
  • General Articles on Computing
    Future Directions, Home PC Security etc. I don't expect anything here to be life-changing, but I'll try to pitch this at a consistent level.
  • Real-life Computing problems and Answers
    I'm an IT Manager and have a lot to do with LANs, Security etc). I'll talk about my problems with Systems Implementation, Management issues etc.
  • Lotus Domino /Lotus Notes (and maybe Workplace)
    I have a long association with this product, and there already a lot of sites out there that are either too light, or too technical, I'm going to try to walk a middle road.

I will try to keep these things separate and will usually attempt to describe the topic neatly in the heading.

Enjoy reading.

Gavin.