Saturday, January 28, 2006

The PInvoke Live Template

Live Templates in Delphi 2006 are a pretty cool feature. The idea is that you can extend the Code Template mechanism (Ctrl+J since, well, a long time) - by including your snippets of code, and even add functionality to the IDE beyond simple code replacements. For instance, typing in "if" and hitting the space bar immediately brings up a series of things in the IDE that look like this:

You can type in a condition and hit [tab] : the cursor will move to the next line for you to continue. Awesome stuff, and more importantly, it's all extensible! Check out the set of files in your ObjRepos directory, by default at C:\Program Files\Borland\BDS\4.0\Objrepos\code_templates\delphi.

The XML files are a little complicated, but you will find Deborah Pate's detailed explanation of these files very helpful to start. Also you can refer to the Wiki for Live Templates, containing more helpful information.

From the XML file, you can call "script" functions that will make Delphi automatically declare a variable, or Invoke Code Completion or call some other functions. But, and this is very interesting, you can extend this script. What this means is, a live template can call YOUR custom function when a user invokes it. For instance, a template could brings up a message saying "How disgusting." when a user types "GOTO", and then proceed to erase the GOTO.

Sparky's blog post tells you how to extend this script schema. The extension involves writing a package with a new "script engine" and then calling that script engine from the live template XML file. The post contains a very good example of how to paste clipboard text wrapped around a try/finally block, by just typing clippy in the code and hitting TAB.

This got me thinking. Can we call external applications using live templates? "Of course you can.", is the right answer. And I'm not the first one to get there or blog about it - Daniel Wischnewski has written an article about a web search live template script that invokes your browser from the IDE.

I wrote something too. It's called a "PInvoke extension" for Delphi and C#. You need to do the following:

1) Download the source code from
2) compile/install the package in the IDE.
3) Copy the .xml files over to your ObjRepos folder (appropriate sub folder) or to the User Folder (by default: c:\Documents and Settings\[USERNAME]\Local Settings\Application Data\Borland\BDS\4.0\code_templates)

Then in a new Delphi unit type: pinvd and you'll see this:
I typed in PeekMessage and I got:

(Click to enlarge)

You can use pinvc in a C# file as well, and the result is the C# code for the Win32 call. I've used both Adam Nathan's site and John Kaster's BabelCode C# to Delphi for .NET converter.

(The site only gave me C# definitions. I used that and sent it over to BabelCode for the Delphi translation of the same C# code.)

What? No Stock Quotes?

And in the spirit of a true web service programmer, you will also need to get Stock Quotes when you are in the IDE. Which means you can type squote and hit TAB, and you'll get:

and if you type BORL and [enter] you get:

Can't live without it.

Anyhow, all source is available, so feel free to dig in, and tell me what you think.