今天在做visio二次的开发的时候,需要给图形统一添加右键菜单,菜单添加的部分通过录制宏代码无非就是添加与修改cell 等等,添加菜单的具体程序,上代码.
1 private void Addmenu(Shape shape) 2 { 3 //shape.CellChanged -= new EShape_CellChangedEventHandler(shape_CellChanged); //目标是 在右键点击的时候触发!最好能过滤掉放入时候就触发 4 5 6 7 //清除所有相关的菜单事件 8 shape.DeleteSection((short)VisSectionIndices.visSectionAction); 9 shape.AddSection((short)VisSectionIndices.visSectionAction);10 shape.AddRow((short)VisSectionIndices.visSectionAction, (short)VisRowIndices.visRowLast, (short)VisRowTags.visTagDefault);11 12 shape.AddRow((short)VisSectionIndices.visSectionAction, 0, (short)VisRowTags.visTagDefault);13 14 shape.get_CellsSRC((short)VisSectionIndices.visSectionAction, 0, (short)VisCellIndices.visActionMenu).FormulaForceU = @"""属性""";15 16 shape.get_CellsSRC((short)VisSectionIndices.visSectionAction, 0, (short)VisCellIndices.visActionPrompt).FormulaForceU = @"""""";17 18 shape.get_CellsSRC((short)VisSectionIndices.visSectionAction, 0, (short)VisCellIndices.visActionHelp).FormulaForceU = @"""""";19 20 shape.get_CellsSRC((short)VisSectionIndices.visSectionAction, 0, (short)VisCellIndices.visActionAction).FormulaForceU = @"""""";21 22 shape.get_CellsSRC((short)VisSectionIndices.visSectionAction, 0, (short)VisCellIndices.visActionChecked).FormulaForceU = @"""""";23 24 shape.get_CellsSRC((short)VisSectionIndices.visSectionAction, 0, (short)VisCellIndices.visActionDisabled).FormulaForceU = @"""""";25 26 shape.get_CellsSRC((short)VisSectionIndices.visSectionAction, 0, (short)VisCellIndices.visActionReadOnly).FormulaForceU = "FALSE";27 28 shape.get_CellsSRC((short)VisSectionIndices.visSectionAction, 0, (short)VisCellIndices.visActionInvisible).FormulaForceU = "FALSE";29 30 shape.get_CellsSRC((short)VisSectionIndices.visSectionAction, 0, (short)VisCellIndices.visActionBeginGroup).FormulaForceU = "FALSE";31 32 shape.get_CellsSRC((short)VisSectionIndices.visSectionAction, 0, (short)VisCellIndices.visActionTagName).FormulaForceU = @"""""";33 34 shape.get_CellsSRC((short)VisSectionIndices.visSectionAction, 0, (short)VisCellIndices.visActionButtonFace).FormulaForceU = @"""""";35 36 shape.get_CellsSRC((short)VisSectionIndices.visSectionAction, 0, (short)VisCellIndices.visActionSortKey).FormulaForceU = @"""""";37 38 shape.DeleteRow((short)VisSectionIndices.visSectionAction, 1);39 40 41 42 System.Diagnostics.Debug.WriteLine("shape_CellChanged之前" );43 44 shape.CellChanged += new EShape_CellChangedEventHandler(shape_CellChanged); //目标是 在右键点击的时候触发!最好能过滤掉放入时候就触发45 46 47 //axDrawingControl1.Window.Application.EndUndoScope(undoScopeID, true);48 }
,顺便说一句,菜单触发事件,呵呵菜单触发事件,找了半天也没有见到右键菜单怎么才能触发它,图形查看宏代码,失望了,除了调用系统的外,不知道它怎么能触发自己的程序,不过从shapesheet看到右键菜单确实在Action中中写入数据了.那么我点击右键菜单他会干些什么!我找了半天也没有看出名堂,系统是用子自身的程序,我要调用我自己的winfrom窗体不能用visio内部的函数(说不定也不成功呢),那点击菜单系统总改有所改变吧!对!Shapesheet中的数据改变了.
Actions.visSSMultiState1 menu 什么的!什么check unchecked的!我又查阅了一下
系统提供了cell改变的时间事件.
,那就捕捉一个事件吧! 捕捉CellChange吧呢! 反正点击右键什么都要触发这个事件,我就用这个注册当成右键菜单的统一的处理程序,然后再过滤掉其他的,这个也容易.
只要在合适的位置注册上行,我这里是打算在图形添加到文档上后,顺便把右键才菜单的弹出程序也给注册了代码.呵呵!不错吧!
void shape_CellChanged(Cell Cell)
{
//throw new NotImplementedException();
MessageBox.Show("能弹出菜单,你修改了"+Cell.Shape.Data2 + Cell.LocalName);
if (Cell.RowName.Contains("visSSMultiState"))//1
{
string ss= Cell.Shape.get_CellsSRC((short)Microsoft.Office.Interop.Visio.VisSectionIndices.visSectionProp, 0, (short)Microsoft.Office.Interop.Visio.VisCellIndices.visCustPropsValue).FormulaU ;
System.Diagnostics.Debug.WriteLine("输入数据Cell" + Cell.LocalName);
MessageBox.Show("能弹出菜单"+Cell.LocalName);
}
}
先别慌,我总结一下,第一是注册右键显示菜单程序,第二步在注册右键弹出的菜单程序.
好了是注册右键显示菜单程序
实验一,注册右键显示菜单程序在程序加载时候.
知道上部分工作之后,要完成整个工作,下一步的工作必须是,确定在什么时候添加,先说说我做的,第一次试验是我是在加载后给页面上的所有的图形,注册每个图形注册了显示的右键菜单程序.但是结果是 当图形大一点,给所有的图形添加显示右键菜单,好你妈的,不动了,卡死了! 不是原来是假死了,奶奶的.居然要长达5分多种.这速度肯定不行,一定要减少是注册右键显示菜单程序.
实验二 是注册右键显示菜单程序在shapeAdd中也就是添加到文档上的时候.
上面的做法不妥当,因此我想起了一个好办法,我在图形添加到页面上去捕捉这个图形,这样我就化整体为部分,添加一个图形到文档,注册一个文档右键显示菜单.呵呵想法不错 !
为了达到目标,我首先要捕捉文档上添加图形的代码,呵呵简单,系统中很多事件嘛?用那个注册啊 !
axDrawingControl1.Window.Application.ActiveDocument.ShapeAdded += new EDocument_ShapeAddedEventHandler(visDocument_ShapeAdded); //
axDrawingControl1.Window.Application.ActivePage.ShapeAdded+=new EPage_ShapeAddedEventHandler(ActivePage_ShapeAdded);
visApplication.ShapeAdded+=new EApplication_ShapeAddedEventHandler(visApplication_ShapeAdded);
visWindow.Shape.ShapeAdded += new EShape_ShapeAddedEventHandler(Shape_ShapeAdded);
那么多啊 !到底用哪个啊! 看着都差不多!
, 就用第一个吧! 好像我的目标就是文档上.于是我要整个文档上添加一个事件处理程序,就是想让我添加到图形的shape能执行添加到图形的程序
这个作用是捕捉图形添加到图形上,我把这个事件让他文档已加载就注册,这样以后在添加的图形自动去执行我的注册事件.也就是下面的方法.
下面是问题,上面的代码,单步执行
1 -加载文档src
2 -注册图形添加事件
3 -人工从磨具上拖出添加一个图形试试
4 -图形添加注册事件执行,写入菜单显示程序(也就是写一堆get_Cell什么的),最后要注册右键弹出菜单事件(也就是cellchange)(我希望我注册时候cellchange不触发,当我亲自点击菜单的时候,事件触发)
5 - (我点击右键时候)执行cellchange事件(妈妈的,一个图形就算是我左右动一下它都执行好几次),好吧!在cellchange事件内,过滤掉你想捕捉的右键菜单哪个的,其他的位置变化是统统忽略.
6 -右键菜单程序执行()
什么! 添加图形的时候,cellchange也触发,也就说456 在我添加图形的一下都触发了.
我想要的是 我添加图形的时候触发4 .当后来客户点击右键菜单的时候触发和执行5 6.
不知道这个怎么忽略掉添加图形时.分开456成为4和 56.
后来我没有办法,只好把4中最后一句,注册5的去掉.子啊在窗体提单独加上一个按钮单独注册菜单弹出程序.
问题一,如何在在shapeAdd处理中注册cellchang中事件,但是cellchang太敏感了,连第一次刚添加的图形也要执行程序多次.
问题二, 上面的办法在单步调试的时候完全没有问题.
但是在系统执行的时候,shapeAdd事件 老是不执行!
试验一,在注册事件的时候延时,发现情况会好点,注册成功效率高了
for (int index = 0; index < 100000; index++)
{
for (int temp = 0; temp < 10000; temp++)
{
int aa = 32;
}
}
visDocument.ShapeAdded += new EDocument_ShapeAddedEventHandler(visDocument_ShapeAdded); //
for (int index = 0; index < 100000; index++)
{
for (int temp = 0; temp < 10000; temp++)
{
int aa = 32;
}
}
实验二: 采用时钟的异步操作,效率更高了!嘿嘿
Timer timer = new System.Windows.Forms.Timer(); //采用时钟可以 方法一
timer1.Start();
private void timer1_Tick(object sender, EventArgs e)
{
axDrawingControl1.Window.Application.ActiveDocument.ShapeAdded += new EDocument_ShapeAddedEventHandler(visDocument_ShapeAdded); //
timer1.Stop();
}
实验三: 采用时钟的异步操作,系统的回调
先写到这里!我晚上再再补充
问题补充还有几个问题
Visio出现的Com应用程序分离问题,可能原因是缓存控件没有释放Com组件引用引起的 | |||||||||
Visio调用office菜单,多个菜单,例如想从文本工具切换到添加连接点工具,txt.enable=false conne.enable=true出现Com异常 | |||||||||
添加拖入shape后事件,出现有时候能成功拖入注册,有时候不能成功注册现象,而且是单步调试能成功,推测系统运行太快,com组件来不及相应,此部分需要元Com实现异步处理 | |||||||||
Visio中如果是工作中心曾打开过,那么在图形编辑中会出现干扰问题.原因在于属于同共享一个Application,此问题最好能在模块切换的时候能够彻底关闭上一次模块(工作中心),模块完全隔离 |