Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#。Excel Addin。Can';t重新定位浮动自定义任务窗格_C#_Excel_Add In_Excel Addins_Customtaskpane - Fatal编程技术网

C#。Excel Addin。Can';t重新定位浮动自定义任务窗格

C#。Excel Addin。Can';t重新定位浮动自定义任务窗格,c#,excel,add-in,excel-addins,customtaskpane,C#,Excel,Add In,Excel Addins,Customtaskpane,创建自定义任务窗格()并将其DockPosition设置为floating时,我想指定窗口的Top和Left属性。由于Office COM API不能直接实现这一点,因此人们建议更改CommandBar相应属性的值: var application = (_Application)_nativeTaskPane.Application; application.CommandBars["Task Pane Title"].Top = top; application.CommandBars["T

创建自定义任务窗格()并将其DockPosition设置为floating时,我想指定窗口的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) _应用程序是Microsoft.Office.Interop.Excel。_应用程序

当然,我是在设置Visible=true之后才这样做的。更确切地说,甚至订阅了任务窗格的VisibleStateChange。然而,我对HRESULT E_失败感到意外

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

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

(一)

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

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


解决方法是使用Windows API。然而,有人能解释一下使用CommandBar方法会有什么问题吗?也许我可以“重新配置”smth,使这个顶部/左侧设置器能够正常工作。

我认为,一旦自定义窗格设置为浮动,您就无法根据定义更改其顶部/左侧属性。你到底想要实现什么?是否要将窗格定位到特定位置?如果是,请在将
visible
属性设置为true之前执行此操作,它应该可以工作,MVP Cindy Meister对此错误给出了有趣的评论(她在回答此论坛问题之前测试了它是否可以工作)——

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

Globals.MyAddIn.Application -> this will ultimately cause an exception   
Globals.ThisAddin.Application -> this will ultimately work
我们假设两者都返回相同的应用程序对象

如果你觉得这很奇怪,那你就有好朋友了

我在问题中添加了一条注释,询问为什么用于访问应用程序对象的变量的名称会有任何区别——当然,它是使用的同一个应用程序对象


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

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

    /// <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;
    }
//
///将自定义窗格位置设置为未锁定状态。
/// 
///自定义任务窗格。
///新的X位置。
///新的Y位置。
私有无效设置CustomPanePositionWhenfloating(CustomTaskPane CustomTaskPane,int x,int y)
{
var oldDockPosition=customTaskPane.DockPosition;
var oldVisibleState=customTaskPane.Visible;
customTaskPane.DockPosition=Microsoft.Office.Core.MsoCTPDockPosition.MsoCTPDockPosition浮动;
customTaskPane.Visible=true;//任务窗格必须可见才能设置其位置
var window=FindWindowW(“MsoCommandBar”,customTaskPane.Title);//MLHIDE
if(window==null)返回;
移动窗口(窗口,x,y,customTaskPane.Width,customTaskPane.Height,true);
customTaskPane.Visible=oldVisibleState;
customTaskPane.DockPosition=旧DockPosition;
}
[DllImport(“user32.dll”,EntryPoint=“FindWindowW”)]
public static extern System.IntPtr FindWindowW([System.Runtime.InteropServices.InAttribute()][System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)]字符串lpClassName,[System.Runtime.InteropServices.InAttribute()][System.Runtime.InteropServices.MarshalAsAttribute](System.Runtime.InteropServices.UnmanagedType.LPWStr)]字符串(lpWindowName);
[DllImport(“user32.dll”,EntryPoint=“MoveWindow”)]
[返回:System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
公共静态外部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);
/// 
///在未固定状态下设置自定义窗格大小。
/// 
///自定义任务窗格。
///新的宽度。
///新高度。
私有void设置CustomPaneSizeWhenFloating(CustomTaskPane CustomTaskPane,整型宽度,整型高度)
{
var oldDockPosition=customTaskPane.DockPosition;
customTaskPane.DockPosition=Microsoft.Office.Core.MsoCTPDockPosition.MsoCTPDockPosition浮动;
customTaskPane.Width=宽度;
customTaskPane.Height=高度;
customTaskPane.DockPosition=旧DockPosition;
}
请随意使用它…:-)

问候,,
Jörg

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

此外,您提供的“变通”链接不适用于多个监视器。在我的机器上,只要将窗口移动到给定的坐标,它就会显示在显示器上,而我的office程序甚至没有显示