操纵形状(哭脸变笑脸)
        
我这个人比较直接,用C#控制visio就想看看效果。比如实现一个动画?哭脸变笑脸?
当然我脑海中这很简单,无非就是做一个visio图,把哭脸和笑脸摆在一起,重叠放置,然后一会儿把哭脸放在前边,一会儿把笑脸放在前边。
 
        
这个很简单吧?至少听起来很简单。这里有两件事情需要搞清楚。第一,我们知道visio里的东西都是Shape,就是形状了,似乎印象中Shape是一个对象,Shape.
BringToFront();就是放置在前边。这个解决Shape放置很容易了。第二,既然Shape是一个对象,那我们怎么知道哭脸是哪个对象,笑脸是哪个对象呢?这就存在一个Visio中的查找形状的问题。说实话这个问题真是讨厌,按照我的想法,因为Visio中每一个Shape都可以定义自己的形状数据(就是形状上按右键à数据à形状数据定义的东西),我只需要为哭脸定义一个形状数据,为笑脸定义一个形状数据,然后查找包含指定形状数据的形状,这样就可以确定了。
        
简单说来就是这样的:
        
foreach(每一个形状)
        
{
                  
如果形状.形状数据 = 指定的形状数据(例如哭脸或笑脸)
                  
{
                           
形状.BringToFront()
                           
Break;
                  
}
        
}
 
 
怎么打开visio文件?
        
恩,说了这么多,第一件事就是打开visio文件。C#操作visio需要Reference中引用Microsoft.Office.Interop.Visio;
然后在CS文件中:
using Microsoft.Office.Interop.Visio;
 
第一件事情就是初始化一个app:
ApplicationClass app = new ApplicationClass();
第二件事情就是打开文档:
Document doc;
        
doc = app.Documents.OpenEx("E://csharp//tstvisio001//test.vsd",
(short)Microsoft.Office.Interop.Visio.VisOpenSaveArgs.visOpenCopy);
 
Okay,我们初始化了app,也打开了这个test.vsd,然后呢?我把整个visio进行全屏:
app.DoCmd((short)VisUICmds.visCmdFullScreenMode);
为了让visio关闭的时候别提示要保存,咱们让visio以为已经保存了:
doc.Saved = true;
 
好了,事已至此,差不多算打开了visio文件。
 
关闭文件请:
        
doc.Close();
        
app.Quit();
 
 
怎么枚举页面中每一个形状
        
简单说来,枚举页面中每一个形状可以使用Document.Pages[x].Shapes来枚举。页面上的所有形状都是Shape,放在该Page对象的Shapes里边。
        
for(i=1;i<=doc.Pages[1].Shapes.Count;i++)
        
{
                  
Shape sp = doc.Pages[1].Shapes[i];
                  
…
}
        
注意Shape的下标是从1开始的。
 
怎么寻找定义的形状数据。
        
这个比较搞,花了一点时间才弄明白。首先是要搞明白Visio的结构。显然形状数据从属于形状。也就是说我期望Shape里有一个专门的形状数据属性,然后直接取出来就可以。后来发现Shape的属性中没有这个东西,找来找去都是什么GetRowCount,GetCellsSRC之类的东西。
        
貌似保存的形状数据也是在Row、Cell里。注意了,神秘的Row、Cell是Visio的基础。Row是一个框,什么都往里装。我看例子和帮助里都是用CellsSRC之类的东西取的Prop。CellsSRC的参数有三个:short
Section, short Row, short Column
        
Section:帮助里语焉不详的说什么visSectionProp是形状数据。
        
Row:        
许多里直接写的就是0
        
Column:   许多里也直接写的0
        
实际上我们在笑脸中定义了形状数据后,直接用Shape.
get_CellsSRC((short)VisSectionIndices.visSectionProp,(short)0,(short)0);
可以直接取得刚才定义的形状数据Cell。
 
        
看到这里我迷惑了。一开始看到参数中又是行又是列,脑海中赫然一张二维表,恩恩,有道理,可能形状数据可以定义很多吧,但后来一看,md难道每次定义的都是在第0行第0列?这不是sb了么?
        
恩恩,这个问题直到后来研究改颜色的时候才明白过味来。我一开始写的程序,就直接用的Shape.
get_CellsSRC((short)VisSectionIndices.visSectionProp, (short)0,
(short)0); 。这里可以给大家一个小提示,VisRowIndices.visRowProp
的定义就是0,VisCellIndices.visUserValue的定义也是0
,也就是说,get_CellsSRC((short)VisSectionIndices.visSectionProp,
VisRowIndices.visRowProp,      
VisCellIndices.visUserValue); 和0,0是等价的。
 
        
废话不多说,直接上程序:
 
| 
public Shape findshapebyid(string sid) { 
        
Shape sp; 
        
int i; 
        
Cell ce; 
        
short iCellExits; 
        
for (i = 1; i <= m_Doc.Pages[1].Shapes.Count; i++) 
        
{ 
                  
sp = m_Doc.Pages[1].Shapes[i]; 
                  
iCellExits =
sp.get_CellsSRCExists((short)VisSectionIndices.visSectionProp,
(short)VisRowIndices.visRowProp, 
                           
(short)VisCellIndices.visUserValue,(short)1); 
                  
if (iCellExits == 0) 
                           
continue; 
                   
                  
ce = sp.get_CellsSRC((short)VisSectionIndices.visSectionProp,
(short)VisRowIndices.visRowProp, 
                           
(short)VisCellIndices.visUserValue); 
                  
if (ce.Formula == sid) 
                           
return sp; 
        
} 
        
return null; } | 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
这个要注意一下,因为我们用的Cells.Formula,因此如果定义的是CUSTID1,那么对应的Formula的值就是带了前后引号的”CUSTID1”,因此,传入参数应当是”/”CUSTID1/””。
 
 
程序及文件
        
做了一个Visio文件,里边两个Shape
,重叠在一起,分别定义形状数据CUSTID1,CUSTID2,然后不断拿到前边,这样形成哭脸变笑脸的动画。
 
 
程序包: http://download.csdn.net/source/2251471
 
							
		 
						
		加载中,请稍候......