Хост IDeskBand в форме Windows - PullRequest
       27

Хост IDeskBand в форме Windows

12 голосов
/ 05 ноября 2011

Я пытаюсь отобразить панель инструментов адреса из панели задач Windows в моей собственной WinForm. Я могу получить CLSID адреса toobar ({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, но панель инструментов Address не является элементом управления ActiveX. Я пытался позвонить

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

или

(deskband as IDockingWindow).ShowDW(true);

а также различные другие интерфейсы и их методы, но ничто из того, что я делаю, кажется, никуда меня не приведет. Я был бы очень рад, если бы мог видеть, что эта панель инструментов появляется где угодно. Но я не могу устранить разрыв между ссылкой IDeskBand и подключением ее к форме Windows.

Кто-нибудь пытался сделать это раньше и продвинулся дальше, чем я?

1 Ответ

1 голос
/ 02 декабря 2011

Я не думаю, что это поддерживается, так как DeskBand должен быть размещен в Проводнике, но вот пример кода формы, который демонстрирует, как это сделать, и должен помочь вам начать работу.

Идея в том, что вам нужно быть "Сайтом", а не Проводником. Если вы посмотрите документацию здесь Создание пользовательских панелей обозревателя, панелей инструментов и рабочих столов , вам необходимо убедиться, что ваш код ведет себя так же, как ведет себя проводник. Итак, первое, что нужно сделать, это предоставить реализацию «Site» объекту десктопа, и первым интерфейсом, который должна обеспечить эта реализация, является IOleWindow. Объект рабочего стола спросит ваш «Сайт», каков дескриптор родительского окна. Просто дайте дескриптор формы (например), и рабочий стол будет отображаться как дочерний элемент формы:

enter image description here

ПРИМЕЧАНИЕ. Вы не можете использовать какой-либо класс 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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...