OK, I admit it. The shim control is a mess. If you don’t know what the shim control is, it is an sample (AKA unsupported) ActiveX control that hosts .NET user controls for use in ActiveX control containers. The reason for its miserable existence is in how .NET user controls are run as ActiveX controls (actually the failure of that). At one time, early in the development of the .NET Frameworks, user controls were to act and behave like ActiveX controls when in an ActiveX control container. However, there were enough differences between .NET and ActiveX that the decision was made to now allow user controls to be hosted as ActiveX controls except in two cases, when the container either is Internet Explorer or MFC (I think MFC was added with the 1.1 release of .NET).


This was bad for the Visual Studio automation model because using the method Windows.CreateToolWindow, you can host an ActiveX control on a tool window just like any other tool window in VS. But since .NET user controls could not be hosted as an ActiveX control, we needed a more creative solution and the shim control was born. The shim control (an ActiveX control written using ATL) has a method that you can call to tell it to host a .NET user control. It does this by first spinning up an instance of the Framework, then, using interop, creating an instance of the desired user control, grabbing the HWND of that control, and using the HWND parenting the control to the ActiveX control.


Great idea, right? In theory, yes, in practice, no. The first problem is distribution. Currently everybody has to modify the controls’s GUIDs and ProgID before shipping otherwise they could mess up other Add-ins that use that control. The way I should have fixed it: create a merge module and distribute the merge module. By the time I realized this was broken, it was already in the wild and too many people were using it. The second problem: accelerators. We have always had problems with tool windows, ActiveX controls, and accelerators. Since VB5 (where some of VS gets its code), we have had this problem. I fixed some of the problems in subsequent versions, but the shim control compounds them since it does not redirect accelerator to the correct place. This was partially fixed in a later version of the control (which was never very widely distributed), but it was not fixed completely and some special case code was needed.


Will this get better? Yes. In the next version of VS we will have a new method, CreateToolWindow2, which takes as it’s arguments an assembly and a class name. We will then host the control without the shim. Not only that, but we will host the window more like VS does and not the way they were hosted in prior versions. When a tool window is created using CreateToolWindow we host the control using the ActiveX control containment interfaces. However, tool windows that are built into VS are handled differently. CreateToolWindow2 will use this other method, which uses less code and requires less negotiation between the container and the control to be displayed.