3

创建自定义任务窗格(_CustomTaskPane MSDN)并将其DockPosition设置为浮动时,我想指定出现的窗口的TopLeft属性。由于 Office COM API 不提供直接执行此操作的可能性,因此人们建议更改 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 是 Microsoft.Office.Interop.Excel._Application

当然,我是在设置Visible = true之后这样做的。甚至订阅了任务窗格的VisibleStateChange以更加确定。但是,我收到了带有 HRESULT E_FAILED 的 COMException。

问题是我可以在调试时读取这些属性(顶部和左侧),但是设置它们会引发异常。

看起来这个问题至少在互联网上出现了好几次:

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

4 回答 4

1

这是我在程序中使用的解决方案:

    /// <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;
    }

随意使用它... :-)

问候,约尔格

于 2013-09-06T08:31:24.090 回答
1

它应该可以工作,并且 MVP Cindy Meister 在这里对此错误发表了有趣的评论(她在回答此论坛问题之前测试了它是否有效) - http://social.msdn.microsoft.com/Forums/vstudio/en-US/ 2df0e430-4d93-416e-89a0-56f8ad5dc988/设置浮动自定义任务窗格的位置?教授=必需

在其中,她说使用错误的变量来获取应用程序对象会导致错误,即:

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

我们假设两者都返回相同的 Application 对象。

如果您认为这很奇怪,那么您的陪伴很好。

我在这个问题中添加了一条评论,询问为什么用于访问 Application 对象的变量的名称会产生任何影响 - 当然它与所使用的 Application 对象相同。

我怀疑这是由其他一些内部因素强加的一些可怕的内部、类似反射的限制。但是无辜的开发人员并没有受到这种非常奇怪的情况的保护。

于 2013-06-26T03:48:31.417 回答
0

我认为一旦将自定义窗格设置为floating您就无法根据定义更改其顶部/左侧属性。你到底想达到什么目的?您想将窗格定位在特定位置吗?如果是,请在将visible属性设置为 true之前执行此操作

于 2011-08-04T11:09:08.997 回答
0

您应该引用的命令栏是“任务窗格”,它是命令栏集合中的标准命令栏。您收到 HRESULT 消息,因为在 CommandBars 集合中找不到“任务窗格标题”CommandBar。

于 2014-08-12T17:05:11.527 回答