C #.Excel Addin.Невозможно переместить плавающую пользовательскую панель задач - PullRequest
3 голосов
/ 02 августа 2011

При создании настраиваемой области задач ( _CustomTaskPane MSDN ) и установке ее DockPosition в плавающее состояние, я хочу указать Top и Left свойства окна появились. Поскольку API-интерфейсы Office COM не предоставляют прямой возможности сделать это, люди советуют изменить значения соответствующих свойств CommandBar:

var application = (_Application)_nativeTaskPane.Application;
application.CommandBars["Task Pane Title"].Top = top;
application.CommandBars["Task Pane Title"].Left = left;

В приведенном выше коде я предполагаю, что

1) _nativeTaskPane - это мой экземпляр, реализующий _CustomTaskPane (на самом деле это Microsoft.Office.Core.CustomTaskPane)

2) _Application is Microsoft.Office.Interop.Excel._Application

Конечно, я делаю это после установки Visible = true . Даже подписался на VisibleStateChange панели задач, чтобы быть более уверенным. Однако я получаю COMException с HRESULT E_FAILED.

Дело в том, что я могу прочитать эти свойства (сверху и слева) при отладке, однако их установка вызывает исключение.

Похоже, проблема всплывала в Интернете по крайней мере несколько раз:

1) http://www.add -in-express.com / forum / read.php? FID = 1 & TID = 5595

2) [http://aritrasaha.wordpress.com/2009/05/19/programatically-position-office-2007-floating-custom-task-pane/]

3) [http://www.visualstudiodev.com/visual-studio-tools-for-office/need-location-of-custom-task-pane-45822.shtml]

Обходной путь - использование Windows API. Однако кто-нибудь может объяснить, что может быть не так с использованием CommandBar-подхода? Может быть, я смогу «перенастроить» что-то, чтобы этот Top / Left-setter работал без исключений.

Ответы [ 4 ]

1 голос
/ 26 июня 2013

Это должно сработать, и есть интересный комментарий MVP Синди Мейстер относительно этой ошибки здесь (она проверила, что она работает, прежде чем ответить на этот вопрос на форуме) - http://social.msdn.microsoft.com/Forums/vstudio/en-US/2df0e430-4d93-416e-89a0-56f8ad5dc988/seting-position-of-a-floating-custome-task-pane?prof=required

В ней она говорит, что использование неверной переменной для получения объекта приложения приводит к ошибке, а именно:

Globals.MyAddIn.Application -> this will ultimately cause an exception   
Globals.ThisAddin.Application -> this will ultimately work

Где мы предполагаем, что оба возвращают один и тот же объект Application.

Если вы думаете, что это странно, значит, вы в хорошей компании.

Я добавил комментарий к вопросу, который спрашивает, почему имя переменной, используемой для доступа к объекту Application, имеет какое-либо значение - несомненно, это тот же самый объект Application, который используется.

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

1 голос
/ 06 сентября 2013

это решение, которое я использую в своих программах:

    /// <summary>
    /// Set a custom panes position in the undocked state.
    /// </summary>
    /// <param name="customTaskPane">The custom task pane.</param>
    /// <param name="x">The new X position.</param>
    /// <param name="y">The new Y position.</param>
    private void SetCustomPanePositionWhenFloating(CustomTaskPane customTaskPane, int x, int y)
    {
        var oldDockPosition = customTaskPane.DockPosition;
        var oldVisibleState = customTaskPane.Visible;

        customTaskPane.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionFloating;
        customTaskPane.Visible = true; //The task pane must be visible to set its position

        var window = FindWindowW("MsoCommandBar", customTaskPane.Title); //MLHIDE
        if (window == null) return;

        WinApi.MoveWindow(window, x, y, customTaskPane.Width, customTaskPane.Height, true);

        customTaskPane.Visible = oldVisibleState;
        customTaskPane.DockPosition = oldDockPosition;
    }

    [DllImport("user32.dll", EntryPoint = "FindWindowW")]
    public static extern System.IntPtr FindWindowW([System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string lpClassName, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string lpWindowName);

    [DllImport("user32.dll", EntryPoint = "MoveWindow")]
    [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
    public static extern bool MoveWindow([System.Runtime.InteropServices.InAttribute()] System.IntPtr hWnd, int X, int Y, int nWidth, int nHeight, [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] bool bRepaint);



    /// <summary>
    /// Set a custom panes size in the undocked state.
    /// </summary>
    /// <param name="customTaskPane">The custom task pane.</param>
    /// <param name="width">The new width.</param>
    /// <param name="height">The new height.</param>
    private void SetCustomPaneSizeWhenFloating(CustomTaskPane customTaskPane, int width, int height)
    {
        var oldDockPosition = customTaskPane.DockPosition;

        customTaskPane.DockPosition = Microsoft.Office.Core.MsoCTPDockPosition.msoCTPDockPositionFloating;
        customTaskPane.Width = width;
        customTaskPane.Height = height;

        customTaskPane.DockPosition = oldDockPosition;
    }

Не стесняйтесь использовать его ...: -)

С уважением, Йорг

0 голосов
/ 12 августа 2014

Панель команд, на которую вы должны ссылаться, это «Панель задач», которая является стандартной панелью команд в коллекции CommandBars.Вы получили сообщение HRESULT, потому что CommandBar «Заголовок панели задач» не найден в коллекции CommandBars.

0 голосов
/ 04 августа 2011

Я думаю, что когда пользовательская панель установлена ​​на floating, вы не можете изменять ее верхние / левые свойства по определению.что именно вы хотите достичь?Вы хотите расположить панель на определенной позиции?если да, сделайте это, прежде чем установить для свойства visible значение true

...