e-requisites: XP- development machine with the .net framework installed ( I am running 1.1 ), Visual Studio 2003 (for C#) and Visual Object ( I am running 2.7b ).
There are many things we can do today that can help preparing us for the near future. To me it’s clear that the future of desktop development lies in .NET.
All of the popular development environments, tools and libraries are working on or already have .NET versions and the Win32 API is clearly frozen.
We are beginning to see features emerging that are only available as .NET components, and certainly a lot of demo’s and examples are available on this appealing platform. So when targeting for an XP environment it is not so bad to assume or require the .NET framework present on a client machine. If you concur with this, this article might be for you; I am presenting an example of how to use a .NET component from within VO applications. I was triggered by a question on the public VO newsgroup regarding the cool popup messages you get from Outlook 2003 and Windows (and MSN) messenger clients. They are called Toast pop-ups.
When I did my research on the topic ( Google rules! ) I quickly found references to messenger but unfortunately the object model is hardly documented and although I was able to generate the OLE-wrapper in VO I did not see any objects nor methods that suggested I could make toast with the messenger object. So I researched a bit further and stumbled upon a sample written by Prateek Kaul on CodeProject.com (http://www.codeproject.com/dialog/statusbarmsgwnd.asp).
Prateek wrote a great class in C# that produces Toast forms pretty much the same as messenger and the good part is, all of the source code is there so it is pretty easy to change bitmaps to give them your personal or company look and feel.
So far so good, we found some code to work with. This combined with the fact that in theory every .NET assembly can be used as a com-component we should be on the right track here.
What is needed to produce a type library for the class is easy, all you have to add in Visual Studio is add an attribute and you can tell the IDE to generate the typelib and register the component on your development machine. Now you know where the VO- devteam got their inspiration from ;-).
What I actually did was create a new project in Visual Studio based on the C#, class Library template project. I deleted Class1 and replaced it with Prateek’s Taskbarnotifier class. Next I added the ClassInterfaceAttribute:
[ClassInterface(ClassInterfaceType.AutoDual)]
public class TaskbarNotifier : System.Windows.Forms.Form
………
The only other thing required is a project property setting, in Project Configuration Properties, set Register for COM Interop to True:

Now build the release build and in the projects’ release folder the DLL and TLB show up.

At the same time the component is registered by Visual Studio so when you start the Automation Server Tool from the VO IDE you will see it listed immediately. The name is generated based on the Class name, so you can find it there as TaskbarNotify. The ProgId will be the Namespace followed by the class name so in this case CustomUIControls.TaskbarNotify. Even without generating code in VO you are able to use a component like this late bound, this would be the code for a quick demo:
METHOD Test1( ) CLASS MainDialog
LOCAL o AS Object
o := OleAutoObject{“CustomUIControls.TaskbarNotify”}
o:CloseClickable := TRUE
///
/// Displays the popup for a certain amount of time
///
/// <param name="strTitle">The string which will be shown as the title of the popupparam>
/// <param name="strContent">The string which will be shown as the content of the popupparam>
/// <param name="nTimeToShow">Duration of the showing animation (in milliseconds)</param>
/// <param name="nTimeToStay">Duration of the visible state before collapsing (in milliseconds)</param>
/// <param name="nTimeToHide">Duration of the hiding animation (in milliseconds)</param>
/// Nothing
o:Show_2("Popup from VO","VO and .NET Rule!",500,3000,500)
Why Show_2 you wonder? Well, since the TaskbarNotify class inherits from System.Windows.Forms.Form all of the public methods that this class implements are also available in the generated Type Library. And since the class does have a show method, but with different parameters (C# supports method overloading) Visual Studio made sure all of the different ways to call show are available to you, be it with different names.
There one problem left however, when we look at the Demo project Prateek supplied in his sample we see that the component actually needs a bit more configuration he’s made it so that the calling application can set the bitmaps and size of the pop-up windows, have a look at this C# code from the demo:
taskbarNotifier2.SetBackgroundBitmap(new Bitmap(GetType(),"skin2.bmp"),Color.FromArgb(255,0,255));
taskbarNotifier2.SetCloseBitmap(new Bitmap(GetType(),"close2.bmp"),Color.FromArgb(255,0,255),new Point(300,74));
taskbarNotifier2.TitleRectangle=new Rectangle(123,80,176,16);
taskbarNotifier2.ContentRectangle=new Rectangle(116,97,197,22);
Now, it’s not going to be easy creating these objects on the VO side, so we either need methods on the components to generate them, or we just let the component take care of this itself. I choose this last option. I decided to move this code to the constructor of the TaskbarNotifier class and be done with it. This also calls for the default bitmaps to be included in the TaskbarNotifier DLL. So, I copied the bitmap files to the new project and set their property Build Action to Embedded Resource. This made the dll grow from 28Kb to 365Kb, but with hard drives these days who cares? The next thing to do is to move the above code to the constructor method which presented the next challenge, how to create a bitmap object from an embedded resource. Again Google to the rescue!
This is the constructor in C# I ended up with:
public TaskbarNotifier()
{
// Window Style
FormBorderStyle = FormBorderStyle.None;
WindowState = FormWindowState.Minimized;
base.Show();
base.Hide();
WindowState = FormWindowState.Normal;
ShowInTaskbar = false;
TopMost = true;
MaximizeBox = false;
MinimizeBox = false;
ControlBox = false;
//
Assembly asm = Assembly.GetExecutingAssembly();
Bitmap bmpSkin = new Bitmap
(
asm.GetManifestResourceStream(asm.GetName().Name +
".skin.bmp")
);
this.SetBackgroundBitmap(bmpSkin,Color.FromArgb(255,0,255));
bmpSkin = new Bitmap
(
asm.GetManifestResourceStream(asm.GetName().Name +
".close.bmp")
);
this.SetCloseBitmap(bmpSkin,Color.FromArgb(255,0,255),new Point(127,8));
this.TitleRectangle=new Rectangle(40,9,70,25);
this.ContentRectangle=new Rectangle(8,41,133,68);
//
timer.Enabled = true;
timer.Tick += new EventHandler(OnTimer);
}
Now I am finally able to make Toast using Visual Objects (and from any other COM-client by the way, which might come in handy from an occasional Outlook or Word Macro).
What a cool way to do some work in a new environment and reap the benefits in existing VO applications.
Many thanks to Prateek Kaul for sharing the code with us on Codeproject.com!
Ed Richard (Ed@wss-ed.nl)
Download Source code
Download Sample