在 Windows 窗体中托管 IDeskBand

发布于 2024-12-14 01:49:00 字数 764 浏览 0 评论 0原文

我正在尝试在我自己的 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 窗体之间的差距。

以前有人尝试过这个,并且比我走得更远吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

掩耳倾听 2024-12-21 01:49:00

我不认为这是受支持的,因为 DeskBand 应该由 Explorer 托管,但这里有一个示例表单代码,演示了如何执行此操作,并且应该帮助您入门。

这个想法是你需要成为“站点”,而不是资源管理器。如果您查看此处的文档 创建自定义资源管理器栏、工具带和桌面带,您需要确保代码的行为类似于资源管理器的行为。因此,首先要做的就是为桌带对象提供一个“Site”实现,该实现需要提供的第一个接口是IOleWindow。桌面带对象将询问您的“站点”父窗口句柄是什么。只需提供表单的句柄(例如),桌面带就会将其自身显示为表单的子项:

在此处输入图像描述

注意:您不能使用任何 Form 或 Control 类作为 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);
    }
}

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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文