start activeX out of Squeak possible?

John R. Pierce john at pierce.name
Wed Jul 7 14:43:23 UTC 2004


Now on to wrapping a COM object and automating it in Squeak.  For this
demonstration I will choose a rather boring COM object because I know it
generally is installed on any Windows machine.  We will automate the Windows
Script Host objects, an instance of the WshShell class in particular.  

First, we have to get the COM object wrapped with .NET wrappers before this will
be useful.  You must open a command prompt and ensure you are in the
Microsoft.NET\SDK\v1.1\bin folder (generally under c:\Program Files) or you have
a path setup to this folder.  We want to run tlbimp.exe (in this folder).  This
is the Type Library to Assembly Converter program from the Microsoft .NET SDK. 
It basically adapts the COM interface to a .NET one.  As a matter of definition,
.NET DLLs are called "assemblies" (not entirely correct, but good enough for
this discussion).

Now that you are in the right folder let's create the .NET wrapper for the WSH
COM objects.  Depending on your computer your WSH DLL may be in a different
location, but on my Windows XP computer it is the following file:
C:\WINDOWS\System32\wshom.ocx

So I will run the following command:

  tlbimp c:\windows\system32\wshom.ocx

This will generate a file called "IWshRuntimeLibrary.dll" in the current folder.
 Move this file to your squeak default folder for ease of use.  That's all we
needed the Microsoft .NET SDK for at this point.

If you browse the Microsoft SDK documentation you will see that there is a
WshShell class.  To access this class in Squeak we first need to load this new
assembly we just created.  In a workspace do the following:

  DotNet Assembly loadFrom: 'IWshRuntimeLibrary.dll'.

NOTE: You will get warnings about unknown selectors when using the .NET bridge
because  nearly everything in this bridge is implemented via the magic of DNU. 
With nearly 1600 classes in the .NET framework we took this short cut.  Just
proceed through the warnings.

Now this .NET wrapper is loaded in the .NET execution environment.  Next we
instantiate an instance of the WshShell class as follows:

shell := DotNet WshShellClass new.

Why not just WshShell?  WshShell is the interface and WshShellClass is the class
that implements this interface.  This is a common idiom when using wrapped COM
objects via .NET (not a Squeak .NET bridge idiom).

Now that we have an instance of COM object "WScript.WshShell" in hand, let's
send it the Popup message to get a messagebox on the screen.  Here's the
signature of that message from the MSDN documentation:

  intButton = object.Popup(strText,[nSecondsToWait],[strTitle],[nType])

So in Smalltalk we say:

  buttonPressed := shell popup: 'Hello from Squeak' secToWait: 5 title: '.NET
Bridge Demo' type: 0.

As you will notice, with the Squeak / .NET Bridge you have to invent keywords
for each argument.  Here, I used explaining keywords, but you can write this as:

  shell popup: with: with: with:

if you like.  It really doesn't matter what you make your keywords, just get the
function name correct up front.  Additionally, the .NET bridge in Squeak is case
insensitive, so it doesn't matter if you call POPUP, popup, or Popup.  Lastly,
you may notice the signature of Popup had optional arguments.  Well, guess what?
 .NET does not support this notion of COM and IDispatch so you must provide all
arguments.  (Again -- not a Squeak / .NET bridge issue).

If you need more examples and/or more info on using the bridge go to our wiki on
this technology at: http://www.saltypickle.com/squeakDotNet or write me.

Regards,

John

PS - To make discovery of the .NET wrapper interface easier we find using
Reflector on any .NET assembly a real time save.  You can get a copy of
reflector at: http://www.aisto.com/roeder/dotnet/.  It is like OleView, but for
.NET assemblies (not COM DLLs).



More information about the Squeak-dev mailing list