在Windows窗体中托管IDeskBand

12

我试图在自己的WinForm中显示Windows任务栏中的地址工具栏。 我可以获取地址工具栏的CLSID({01E04581-4EEE-11d0-BFE9-00AA005B4383}),并且可以获得一个对其的IDeskBand引用。但是...接下来该怎么做呢?

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

我尝试使用AxHost来托管它,但地址工具栏不是一个ActiveX控件。我尝试调用

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

或者

(deskband as IDockingWindow).ShowDW(true);

除了各种其他接口和它们的方法之外,我似乎无论做什么都没有进展。如果我能看到那个工具栏出现在任何地方,我会非常高兴。但是我似乎无法将IDeskBand引用插入到我的Windows窗体中。

有人以前尝试过这样做,并比我取得了更多进展吗?


你能提供更多关于地址工具栏桌面带的功能需求信息吗?这个接口在Windows 7中已经被弃用,所以在未来的Windows版本中可能不会得到支持。 - Kevin McCormick
我想要能够将地址桌面栏、链接或者其他自定义的桌面栏放入我的WinForm中,并且让它们显示出与任务栏相同的效果。 - deanis
也许我不想实现 IDeskBand。我相当确定地址和链接工具栏是 DeskBand COM 对象,这就是为什么我转向了 IDeskBand。所以我真正想做的是查询目标 COM 对象,我可以通过查询匹配的 GUID 来实现,然后使用 Activator.CreateInstance 实例化它。但是当我尝试在我的 WinForm 中托管 COM 对象时,事情就出问题了。 - deanis
1个回答

1

我认为这不被支持,因为 DeskBand 应该由 Explorer 托管,但是这里有一个示例表单代码,演示了如何实现它,并应该帮助您入门。

关键在于您需要成为“站点”,而不是 Explorer。如果您查看此处的文档 Creating Custom Explorer Bars, Tool Bands, and Desk Bands,您需要确保您的代码的行为类似于 Explorer 的行为。因此,要做的第一件事是为桌面绑定对象提供“站点”实现,而此实现需要提供的第一个接口是 IOleWindow。桌面绑定对象将询问您的“站点”父窗口句柄是什么。只需提供表单的句柄(例如),桌面绑定将显示为表单的子级:

enter image description here

注意:您不能使用任何表单或控件类作为IOleWindow实现者,因为它已经在幕后实现了(Winforms实现),而且这个实现非常特定,因此您需要一个自定义站点,如此处所示。

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! - deanis
有人知道如何调整这个工具栏的大小吗?我尝试了很多不同的调用,但都没有成功。 - deanis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接