作者:xenogear
http://www.cnblogs.com/xenogear/
还有一个很好的方法,就是直接发送命令
#region 向Visio工作区发送Visio命令
[StructLayout(LayoutKind.Sequential)]
public struct OLECMDTEXT
{
public UInt32 cmdtextf;
public UInt32 cwActual;
public UInt32 cwBuf;
public char rgwz;
}
[StructLayout(LayoutKind.Sequential)]
public struct OLECMD
{
public UInt32 cmdID;
public UInt64 cmdf;
}
[ComImport(), Guid("B722BCCB-4E68-101B-A2BC-00AA00404770"), InterfaceType
(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleCommandTarget
{
[PreserveSig()]
int QueryStatus([In, MarshalAs(UnmanagedType.Struct)] ref Guid pguidCmdGroup, [MarshalAs
(UnmanagedType.U4)] int cCmds, [In, Out] IntPtr prgCmds, [In, Out] IntPtr pCmdText);
[PreserveSig()]
int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdExecOpt, object[] pvaIn, [In, Out,
MarshalAs(UnmanagedType.LPArray)] object[] pvaOut);
}
/// <summary>
/// 发送OLE命令
/// </summary>
/// <param ></param>
private void SendCommand(UInt32 command)
{
IOleCommandTarget commandTarget =
(IOleCommandTarget)visDrawing.GetOcx();
try
{
Guid CLSID_Application = new Guid("{0x00021A20, 0x0000, 0x0000, {0xC0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x46}}");
commandTarget.Exec(ref CLSID_Application, command, 0, null, null);
}
catch(System.Runtime.InteropServices.COMException ex)
{
MessageBox.Show(ex.ToString());
}
}
#endregion
这个是从msdn online中的一篇文章学来的。
比如想显示标尺和网格配置的对话框出来
public void RulesAndGrid(TulipMenuItem item)
{
this.SendCommand((UInt32)Visio.VisUICmds.visCmdRulerGridDlg);
}
那个对话框就出来了。:D
页面设置
public void PageSetup(TulipMenuItem item)
{
this.SendCommand((UInt32)Visio.VisUICmds.visCmdPageMeasureUnitsDlg);
}
还有好多好多的对话框可以用发命令方式出来
很多快捷键一样可以用,比如Ctrl+F,F3什么的
如果掌握了前面我写的东西,应该开发一个像样的东西就不是很难了。主要是要和自己的业务逻辑挂钩起来。
关于Drawing Control的文章很少,在msdn online上有几篇文章,可以看看,很不错的,有一个例子带了一个VisioUtility.cs的类,有一些用处的。
要解决一些棘手的问题,靠VBA是一个很好的方式。
下面说一些问题:
1、如果你用到这个control的form是mdichild。就要注意,当你第一次打开,没有问题,但是当你关闭了这个子form,再开一个的时候,就会出现异常。如果保留第一个打开的子form不动,打开第二个就没事。这个问题是因为什么一直不知道,最后我的解决方法是主窗体一开就建立一个隐藏的子form
FormWorkspace formHide = new FormWorkspace(new BusinessProcessResource(), FormMain.userID, "", false, "");
2、带有这个control的form在打开的时候,偶尔会出现异常,那个异常的id根本哪里都查不到。我只能这样做:
MessageBox.Show(this, "发生未处理的错误,请关闭后重新打开 n" + ex.Message, "异常错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
3、有时候,这个控件里发生异常的时候,异常并不抛出,用try catch根本没有办法得到,会被生生吃了,什么反应没有,这个只能慢慢的去找。
4、有些事件有问题,比如我想抓住Ctrl+Z,也就是Undo的执行,我用Keyup来抓,结果是有时候能抓到,有时抓不到。
5、ShapeSheet的UI在控件中是显示不出来的
6、只能是单窗体运行
7、不能嵌到其他ActivX control中(其他Activex control也一样)
8、不能放到Infopath form中(好像Infopath sp1可以了)
9、不包含VBA
好了,我知道的也就差不多了。当然有很多很多的细节没有说。如果这些没有条理的所谓文章能对大家有帮助,那也是大家的理解能力好,这么乱的东西我自己也看不懂了。:D