我想连接到正在运行的excel,或启动excel,并在运行时在根/主功能区/菜单栏上添加一个选项卡。当我使用interop连接到excel应用程序对象时,我看到一个动态对象菜单栏。它在运行时解析为我无法解析的.com对象。
我可以迭代到每个菜单,看到menu.name,ID和菜单项。它看起来像我正在运行的功能区中的功能区项目,但我不能在运行时添加或删除或影响项目。菜单,菜单,menuitem都是Microsoft私有的。我缺少什么来解决和添加/操作/删除我自己的运行时菜单项?我不想编写和编译静态或运行时xml(还)。我看到其他供应商这样做了。我失踪了什么集会或包括?这是我从纯粹的黑客行为中得到的。
using System;
using System . Collections . Generic;
using System . Linq;
using System . Text;
using System . Threading . Tasks;
using Microsoft.Office.Core;
using System . Linq . Expressions;
using Microsoft . Office . Interop . Outlook;
using Microsoft . Office . Interop . Excel;
using System .Diagnostics;
using System . Runtime . InteropServices;
using System . Runtime . InteropServices . ComTypes;
using System . Diagnostics . Contracts;
using System . Windows . Controls . Ribbon;
using Microsoft . Office . Tools . Excel;
using Microsoft . Office . Tools . Ribbon;
using System . ComponentModel . Design;
using System . Reflection;
using Microsoft . Office . Interop . Access;
private static void ExcelChops ( )
{
Process [ ] Running = Process . GetProcessesByName ( "Excel" );
if ( Running . Count()==0 )
{
return;
}
Microsoft . Office . Interop . Excel . Application ExcelApplication = ( Microsoft . Office . Interop . Excel . Application ) Marshal . GetActiveObject ( "Excel.Application" );
if ( ExcelApplication == null )
{
return;
}
string ActiveExcelApplicationCaption = ExcelApplication . Caption;
Windows ExcelWindows = ExcelApplication . Windows;
int ExcelWindowCount = ExcelWindows . Count;
XlWindowState WindowState = ExcelApplication . WindowState;
Window ExcelWindow = ExcelApplication . Windows [ 1 ];
String ExcelWindoWindowCaption = ExcelWindow . Caption;
System . Diagnostics . Debug . WriteLine ( String . Format ( "\nExcel Application Caption {0} " , ActiveExcelApplicationCaption ) );
System . Diagnostics . Debug . WriteLine ( String . Format ( "\nExcel Window Caption {0} " , ExcelWindoWindowCaption ) );
System . Diagnostics . Debug . WriteLine ( String . Format ( "Excel Window Count {0} " , ExcelWindowCount ) );
System . Diagnostics . Debug . WriteLine ( String . Format ( "Excel Window State {0} " , WindowState ) );
//Microsoft.Office.Interop.Excel.Panes panes = ExcelWindow . Panes;
//IteratePanes ( panes );
Microsoft.Office.Interop.Excel.MenuBar aMB = ExcelApplication . ActiveMenuBar;
IterateMenus ( aMB , 0 );
System . Diagnostics . Debug . WriteLine ( String . Format ( "{0} {1} " , "Completed" , ( ( ( System . Environment . StackTrace ) . Split ( '\n' ) ) [ 2 ] . Trim ( ) ) ) );
}
private static void IterateMenus ( MenuBar aMB , int v )
{
string caption = aMB . Caption;
int ndx = aMB . Index;
dynamic parent = aMB . Parent;
Menus menus = aMB . Menus;
int menusCount = aMB . Menus . Count;
for ( int i = 1 ; i <= menusCount ; i++ )
{
Menu a = menus [ i ];
int b = a . Index;
string c = a . Caption;
System . Diagnostics . Debug . WriteLine ( String . Format ( "{0} {1} " , b , c ) );
IterateMenus ( a , v + 1 );
}
}
private static void IterateMenus ( Menu A , int v )
{
string caption = A . Caption;
int ndx = A . Index;
MenuItems items = A . MenuItems;
int itemsCount = items . Count;
for ( int i = 1 ; i <= itemsCount ; i++ )
{
dynamic a = items [ i ];
Type t = a.GetType ( );
object o = a as object;
Type to = o . GetType ( );
String oo = to . ToString ( );
var occ = to . Name;
var ooc = to . TypeHandle;
System . Diagnostics . Debug . WriteLine ( String . Format ( "menu item {0} of {1} {2} {3} " , i , itemsCount, occ, caption) );
}
}
功能区无法按照您希望的方式进行编程控制。
在功能区之前,Office应用程序可以访问MenuBar
(未记录为Excel)和CommandBar
对象。 MenuBar
是经典的菜单类型(文件,编辑,视图,窗口,帮助等)。 CommandBar
是经典的工具栏类型(菜单下方的按钮行)。使用这些对象,您可以直接操作这些旧的UI功能。
功能区完全不同。使用功能区,您无法随意操纵它。这旨在保护一个加载项与另一个加载项。要使用功能区,您必须具有加载项以提供描述要应用的功能区配置的XML。有几种方法可以创建Excel加载项:
除此之外,我建议你谷歌搜索“excel addin ribbon”,了解如何在你的插件中使用功能区的各种文档。
MenuBar
和CommandBar
对象和属性仍然用于遗留和非功能目的(例如,显示右键单击菜单)。如果您在具有功能区的Excel版本中创建新的应用程序级CommandBars,则会毫不客气地将新的CommandBars转储到通用选项卡中,其中所有加载项的CommandBars最终都会出现。调整内置CommandBars不会影响内置功能区。