David Stone's Blog

I'm open to suggestions for a subtitle here! (Really!)

June 2003 - Posts

IL Editor

Does anybody know of an IL editor? I mean, there must be one right? But I've searched google high and low for an IL editor and I can't find one at all. Better yet, why doesn't VS.NET have support for IL editing? Doesn't that make sense? I mean, don't get me wrong, I like ILDASM and Reflector and all that, but it would be nice to have IDE support for IL. Instead, there's nothing...nada, zip, zero, zilch.

Ad Aware

Since I installed FeedDemon I have now to fight against spyware.

I already found with Ad_Aware from Lavasoft 70 kind of spyware :-(.


[heLP .Net Blog]

Seems that Paschal is having a problem with Spyware. This is why I recommend that everybody go to LavaSoft's website and buy Ad Aware Pro. It has real time scanning, that way you don't have to wait for spyware to get onto your system...it never gets a chance in the first place.

Dead Wrong

Here's another quote: "Please, whatever you do, stay away from .NET. It is nothing but more proprietary lock-in from the biggest proprietary software company in the world. If you are working at a company that is considering using .NET, do everything you can to keep away them from it."

Hey, all you .NET webloggers, wanna have fun with this one?

[The Scobleizer Weblog]

Hmmm...have they ever heard of Rotor? ECMA? Mono? Portable.NET? XML? SOAP?

Getting back in the swing of things

Yikes...I need to get back to blogging. One thing that's really going to help me do this is the new FeedDemon release (thanks to Thomas Freudenberg). The NewsBin thing is just waay too cool.

But one thing that I did want to point out was that my good friend Marc Clifton over on CodeProject has released another article in his Application Automation Layer series:

The Application Automation Layer - Using XML To Dynamically Generate GUI Elements--Forms And Controls

These articles are an essential read. Quite awesome coding going on there. Marc is one of those brilliant guys I aspire to be like someday. I highly recommend checking out the other AAL articles too.

WordBandit...or SharpWord...or Wordirella

Want to read RSS in Word? Here ya go. 

Some cool stuff

First of all, this article came across the CodeProject RSS feed yesterday:

SharpPrivacy - OpenPGP for C#

SharpPrivacy is an OpenPGP implementation in C#. It can be used to encrypt and sign data, created OpenPGP compatible keys, and a lot more. This article explains how to use the library in your own .NET application or webpage to encrypt, sign, decrypt or verify OpenPGP messages. 

Second, I wanted to direct you to the blog of my good friend leppie:

http://leppie.blogspot.com/

He's been doing work with AsmL trying to create a full CodeDomParser for C#. He's doing some way cool stuff...and AsmL is very different. No RSS feed yet...but he'd like to move here once the Beta sign comes down. :)

Back!

Wow, I've been gone for a long time, mostly due to my school schedule, but I should be back for a while now. :)

Anyway, I haven't just been doing school while I've been gone. I've been working on the CodeProject VS.NET Addin competition as well. I just wanted to say to everybody that does COM Interop on a regular basis: I salute you. It amazes me the type of things that I've had to do to get this to work...especially since I usually just stay within the .NET Sandbox.

One of the snags I ran into involved WinForms UserControls. In my addin, I wanted what VS.NET calls a ToolWindow for the main UI. Well, I also wanted my UserControl to reside on this ToolWindow. Microsoft recommends that you use the VSUserControlHost project to host a UserControl on top of an ATL ActiveX control which then fits on the ToolWindow. However, a little digging yielded this article by Chris Sells showing one way to host a UserControl on a ToolWindow without using this VSUserControlHost "shim". After careful examination of the code that he presents, I thought about it a bit and decided that there had to be a better way. 

So I started searching in the System.Runtime.InteropServices namespace and couldn't really figure out what I really wanted to do from there. So I took a look at what VS.NET was expecting. In the Exec method of the Connect class that VS.NET creates for you when you say you want to create an addin, I was doing this:

public void Exec(string commandName, EnvDTE.vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
{
    handled = false
;
    if
(executeOption == EnvDTE.vsCommandExecOption.vsCommandExecOptionDoDefault)
    {
        if
(commandName == "DocHelper.Connect.DocHelper")
        {
            
//This has to be null, otherwise the window will be loaded twice...and we don't want that
            
if(toolWindow == null
)
           {
                int
counter = 0;
                object temp = null
;
            TryAgain:
//We're defining this label because we use it for the goto 
                
try
                
{
                    toolWindow = applicationObject.Windows.CreateToolWindow(addinInstance,"MyAddinCtrl", "My Addin", "{89171DAB-243C-47d1-B8D7-9AA23482BEFF}", ref
temp);
                    docHelperControl = (DocHelperControl)temp;
                    docHelperControl.DTE = this
.applicationObject;
                    this.toolWindow.Visible = true
;
                    AddToIDE(toolWindow);
                }
                catch
(Exception ex)
                {
                    counter++;
                    
// If we've tried more than once, get out of the loop
                    
if
(counter == 2)System.Diagnostics.Debug.WriteLine("Addin failed to load: " + ex.Message);
                    else goto
TryAgain;
                    
/*We're using the goto block here because, without fail, the addin fails to load the first time.
                    * The only error message the IDE returns is "Not Implemented" which I take to mean that InteropServices
                    * hasn't prepared the CCW for the UserControl yet. The addin will always load the second time, so I use the
                    * goto statment to branch control back up to the TryAgain label. The goto statement was recommended by
                    * Tom Archer in Inside C#, 2nd Edition, Ch. 12, Section "Retrying Code". And I figured, hey, if Tom isn't afraid
                    * to use a goto statement, then I shouldn't be afraid to use a goto statement. :) 
                    */
                
}
                handled = true
;
                return
;
            }
            
else
            
{
                
//If the addin has already been loaded, show it now
                
toolWindow.Activate();
            }
        }
    }
}

Anyway, it would always error out on the red line. So what I did was took a look at the arguments. There's one for the progID of the control, and there's a ProgId attribute in the InteropService namespace. Also, I figured out that I needed to take control of the Interface type that the UserControl exposed in the COM Callable Wrapper. So what I wound up doing is decorating my UserControl with the following attributes:

[ProgId("MyAddinCtrl"), ClassInterface(ClassInterfaceType.AutoDual), Guid("89171DAB-243C-47d1-B8D7-9AA23482BEFF")]

After some more wrangling around and getting vague errors like "Not Implemented" or "Unspecified Error" from VS.NET, I found out that I had to include the curly brackets in the GUID in my method call, but not in the GuidAttribute constructor.

Once I got that ironed out, I figured out that the addin failed to load the first time, every single time. So I have discovered the one and only use for the goto statement. Basically, I just need to get back out of the catch block the first time in order to do the try block all over again. If anybody can suggest a better way of doing this, then I'd be very grateful...the goto looks unnatural. :)

Anyway, I just wanted to share my adventure with VS.NET and getting UserControls hosted as ActiveX controls in a COM Control Host other than IE. Also, because there was really not a whole lot of documentation on this, I hope my experience can serve as a reference for others looking to do the same thing.

More Posts