c#.Excel外接程序.不能重新定位浮动自定义任务窗格
本文关键字:定位 自定义 任务 Excel 程序 不能 新定位 | 更新日期: 2023-09-27 18:04:12
当创建自定义任务窗格(_CustomTaskPane MSDN)并将其DockPosition设置为浮动时,我想指定出现窗口的Top和Left属性。由于Office COM api不提供这样做的直接可能性,人们建议更改命令栏的相应属性的值:
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来更确定。然而,我得到一个COMException与HRESULT E_FAILED.
我可以读取这些属性(Top &左),但是设置它们会抛出异常。
看起来这个问题在网上至少出现了几次:
1) http://www.add-in-express.com/forum/read.php?FID=1& TID = 5595
2) [http://aritrasaha.wordpress.com/2009/05/19/programatically -职位-办公室- 2007 -浮-自定义-任务- pane/]
3) [http://www.visualstudiodev.com/visual工作室-工具- office/need位置- -自定义任务窗格- 45822. - shtml]
解决方法是使用Windows API。然而,有人能解释使用命令栏方法有什么问题吗?也许我可以"重新配置"smth,使这个Top/Left-setters工作,没有例外。
这是我在我的程序中使用的解决方案:
/// <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;
}
请随意使用…: -)
问候,Jorg
它应该工作,并且有MVP Cindy Meister关于此错误的有趣评论(她在回答此论坛问题之前测试了它的工作)- 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对象。
我怀疑这是一些可怕的内部,反射一样的限制强加给其他内部。但是,无辜的开发人员并没有受到这种非常奇怪的情况的保护。
我认为一旦自定义窗格被设置为floating
,你就不能通过定义改变它的顶部/左侧属性。你到底想达到什么目标?您想将窗格放置在特定位置上吗?如果是,请在将visible
属性设置为true之前执行
您应该引用的命令栏是"任务窗格",它是命令栏集合中的标准命令栏。您得到了HRESULT消息,因为在CommandBars集合中没有找到"任务窗格标题"命令栏。