12

I'm trying to display the Address toolbar from the Windows Taskbar in my own WinForm. I can get the CLSID of the Address toobar ({01E04581-4EEE-11d0-BFE9-00AA005B4383}), and I can get an IDeskBand reference to it. But... then what?

Guid bandCLSID = new Guid("{01E04581-4EEE-11d0-BFE9-00AA005B4383}");
Type bandType = Type.GetTypeFromCLSID(bandCLSID);
IDeskBand deskband = (IDeskBand)Activator.CreateInstance(bandType);

I've tried hosting it in an AxHost, but the Address toolbar is not an ActiveX control. I've tried calling

(deskband as IOleObjectWithSite).SetSite(various interfaces);

or

(deskband as IDockingWindow).ShowDW(true);

as well as various other interfaces and their methods, but nothing I do seems to get me anywhere. I'd be overjoyed if I could actually see that toolbar appear anywhere. But I can't seem to bridge the gap between having the IDeskBand reference and plugging it into my Windows Form.

Has anybody attempted this before, and gotten further than I have?

casperOne
  • 70,959
  • 17
  • 175
  • 239
deanis
  • 465
  • 3
  • 9
  • Can you provide more information on what functionality you need from the Address Toolbar DeskBand? This interface was deprecated as of Windows 7, so it may not be supported in future versions of Windows anyway. – Kevin McCormick Nov 08 '11 at 17:59
  • I want to be able to put the Address deskband, and other deskbands like Links or even custom ones, into my WinForm, and have them appear as they do on the Taskbar. – deanis Nov 09 '11 at 02:42
  • So maybe it's not an `IDeskBand` that I want to implement. I'm pretty sure that the Address and Links toolbars are DeskBand COM objects, which is why I made the jump to `IDeskBand`. So what I'm really trying to do is query the target COM object, which I can do to get the matching Guid, the instantiate it, which I do with `Activator.CreateInstance`. Where things are falling apart for me is when I try to make the jump to hosting the COM object in my WinForm. – deanis Nov 10 '11 at 03:24

1 Answers1

1

I don't think this is supported, as a DeskBand is supposed to be hosted by Explorer, but here is a sample Form code that demonstrates how to do it and should help to get you started.

The idea is you need to be the "Site", instead of Explorer. If you look at the documentation here Creating Custom Explorer Bars, Tool Bands, and Desk Bands, you need to ensure your code behave like Explorer behaves. So, the fist thing to do is to give a "Site" implementation to the desk band object, and the first interface this implementation needs to provide is IOleWindow. The desk band object will ask your "Site" what is the parent windows handle. Just give the form's handle (for example) and the desk band will display itself as a Form's child:

enter image description here

NOTE: You can't use any Form or Control class as the IOleWindow implementer because it's already implementing it behind the scene (Winforms implementation), and this implementation is very specific, so you'll need a custom site as demonstrated here.

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private IObjectWithSite _band = (IObjectWithSite)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("{01E04581-4EEE-11d0-BFE9-00AA005B4383}")));
        private BandSite _site;

        public Form1()
        {
            InitializeComponent();
        }

        protected override void CreateHandle()
        {
            base.CreateHandle();
            if (_site == null)
            {
                _site = new BandSite(Handle);
                _band.SetSite(_site);
            }
        }

        private class BandSite : IOleWindow
        {
            private IntPtr _hwnd;

            public BandSite(IntPtr hwnd)
            {
                _hwnd = hwnd;
            }

            void IOleWindow.GetWindow(out IntPtr hwnd)
            {
                hwnd = _hwnd;
            }

            void IOleWindow.ContextSensitiveHelp(int fEnterMode)
            {
                throw new NotImplementedException();
            }
        }
    }

    [ComImport, Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IObjectWithSite
    {
        void SetSite([MarshalAs(UnmanagedType.IUnknown)] object pUnkSite);

        [return: MarshalAs(UnmanagedType.IUnknown)]
        object GetSite(ref Guid riid);
    }

    [ComImport, Guid("00000114-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IOleWindow
    {
        void GetWindow(out IntPtr hwnd);
        void ContextSensitiveHelp(int fEnterMode);
    }
}
Simon Mourier
  • 117,251
  • 17
  • 221
  • 269
  • Well holy smokes, that worked! I just hosted the Address toolbar, and then the Tablet PC Input Panel toolbar. For some reason, Links isn't working for me. If you have any idea why that is, I'd take any tips. I also have to figure out how to resize these controls, but at least I can see them now. Thanks Simon! – deanis Dec 07 '11 at 16:29
  • Anyone have any idea how I would resize this toolbar? I've tried a bunch of different calls, but haven't had any luck. – deanis Dec 20 '11 at 15:05