It's in there somewhere
It's funny how the mind works. I was recently asked whether the software I've been variously working on for the last few years could be extended so its documents - in this case video clip names - could be displayed on a web page. Easy. However, they wanted to be able to make them hyperlinks so the users could click on them and the application would start, load the video clip, and wind to a specific frame in the video. If they had this feature in the application, they could publish a webpage on their company intranet that had a list of selected highlights in sports games videos - goals, penalties etc. The application already has a high level of desktop integration using shortcuts, so the (leap of faith) thinking was it would be a natural addition to this. Not so easy.
If that wasn't enough, they also wanted this custom hyperlink behaviour to work on all their office applications - Word, Excel, and so on. My initial reaction was no way. But after a coffee and a sit down, something was ringing in the back of my tiny brain. I vaguely remembered articles about res: protocol and asynchronous pluggable protocols. Time to investigate...
Asynchronous pluggable protocols - eh?
Microsoft's asynchronous pluggable protocols allow developers to create pluggable protocol handlers, MIME filters, and namespace handlers that work with IE. Applications can use them to handle a custom URL protocol scheme. The ability to handle a custom URL protocol scheme using a pluggable protocol handler allows developers to implement custom protocol schemes for IE and for applications that use URL monikers. The default pluggable protocol handler included with Internet Explorer handles existing protocol schemes such as HTTP, FTP and Mailto.
Now, as it turns outs, there is a huge amount of useful information on MSDN about this, and it it took a while to fathom what it was all about. However, what was clear was I was in for a bumpy ride and I couldn't quite see how I could make the custom URLs work in Word and Excel. How could I get my custom protocol implementation plugged into them?
Buried deep in the documentation, I found a couple of gems that meant, with a few registry settings, a bit code, and some lateral thinking, I could provide a neat solution and I didn't need to implement a full pluggable protocol handler. Importantly, pluggable protocols aren't implemented in Office products. It appears to be hard coded for chosen protocols (HTTP, FTP, File, Mailto etc.), but this solution gets around this issue.
Registering an application to a URL protocol
With a few registry keys, it's possible to register an application to respond to a custom protocol and pass parameters to it on the command line. It this case, I've devised a protocol called 'vip' (very important protocol) and registered it with the APPTest application.
HKEY_CLASSES_ROOT
vip
(Default) = "URL:vip Protocol"
URL Protocol= ""
DefaultIcon
(Default) = "c:\somepath\APPTest.exe"
shell
open
command
(Default) = "c:\somepath\APPTest.exe" "%1"
This is much like associating an application with a file extension. Obviously, in the real world, c:\somepath needs to be a real path where the application is installed. By adding these settings to the registry, running "vip:wibble" on the command line would attempt to launch APPTest.exe and pass wibble on the command line.
The APPtest application and the protocol
I want to keep this article short and explain the technique. So rather than build a full blown application and associated protocol behaviour, I'm going to take a very simple example and let you decide how you want to use it. I'll use the video clip problem described to demonstrate the principles.
So let's decide on a very simple protocol. When someone needs to display the video clip name, they need an ID (maybe it's held on a central database), a key frame (frame offset from the start of the clip), and a name for the key frame.
id-clipname-frame-framename
E.g., 123-MonacoGP-19279-Senna
The APPText code simply needs to process the command line parameters (in this case, it will be the protocol represented as a string), parse out what it needs, and do something with it. In this case, it will just display the parsed out details in a dialog, but you can do what you want.
Here's the very simple parsing code that's not exactly robust, but will be OK for this example.
void CAPPTestDlg::SetClip(CString strClip)
{
char *pStr = strClip.GetBuffer();
pStr = strtok (pStr, ":");
pStr = strtok(NULL, "-");
m_strId = pStr;
pStr = strtok(NULL, "-");
m_strClipname = pStr;
pStr = strtok(NULL, "-");
m_strFrame = pStr;
pStr = strtok(NULL, "-");
m_strFramename = pStr;
strClip.ReleaseBuffer();
}
To make all this work, you'll need to set the protocol registry keys. You could do this in your MSI installer, but I've chosen to put it in the APPTest code so when it runs the first time with no parameters, the necessary registry keys are set.
To check everything is working, run APPTest with no parameters and you'll get a message telling you everything is registered. Now, go to a command line and type:
vip:123-MonacoGP-19279-Senna
You should get a dialog showing the parsed out string, like this:
So how do I get this to work when I click a hyperlink?
With the protocol registered on the PC and the APPTest application installed, we need to find a way to invoke it from a hyperlink. Some magic? No, just a bit of lateral thinking. We can take advantage of the existing hyperlink behaviour in Explorer, Word, Excel etc., and hook up our new protocol to be triggered on the back of it. A regular link on an HTML page consists of an anchor and a destination. The link starts at the "source" anchor, and points to the "destination" anchor, which may be any Web resource (e.g., an image, a video clip, a sound bit, a program, an HTML document, an element within an HTML document, etc.). Typically:
<a href="http:\\www.dashnet.co.uk">An excellent consultancy</a>
Applications like IE, Word, Excel are written so they parse out HTML expressions like this, display them as clickable hyperlinks, and execute the protocol when they are clicked. If we use our own protocol within a standard anchor, and hijack the protocol and destination, not only will the application display the link as a standard clickable link, it will execute our protocol when it's clicked. So, change the anchor to look like this:
<a href="vip:123-MonacoGP-19279-Senna">Senna wins at Monaco</a>
and the magic happens.
Building and testing the sample code
Build the solution and run the application with no parameters. This will register the vip: protocol on your PC, and you'll get a confirmation dialog. Now, open either the test HTML (APPTest.htm) page or the Word document (APPTest.doc), and click the hyperlinks. You'll see the protocol being executed by the APPTest application, and it will display the parsed out details like this: