当前位置: 首页>编程语言>正文

visio运行java程序 visio可以编程吗

visio二次开发——事件编程

  1. 首先,创建一个Visio事件侦听类
    “`
    ///
    /// Visio事件侦听类
    ///
    [ComVisible(true)]
    public sealed class EventSink : IVisEventProc
    {
    private Application eventApplication; //Visio应用程序对象
    private Document eventDocument; //Visio文档对象
    private int alertResponse;
public event VisioEventHandler OnShapeAdd;      //形状添加事件
public event VisioEventHandler OnShapeClick;      //形状点击事件
public event VisioEventHandler OnShapeDelete;   //形状删除事件
public event VisioEventHandler OnMarkerEvent;   //右键菜单事件阀门开关
public event VisioEventHandler OnCellChanged;   //属性值修改事件
public event VisioEventHandler OnTextEdit;      //文本编辑事件
public event QueryCancelEventHandler OnQueryCancelSelectionDelete; //选区选择删除事件

/// <summary>
/// 默认构造函数
/// </summary>
public EventSink()
{
}

/// <summary>
/// 对文档的相关处理事件进行侦听处理
/// </summary>
/// <param name="callingApplication">应用对象</param>
/// <param name="callingDocument">文档对象</param>
[CLSCompliant(false)]
public void AddAdvise(Application callingApplication, Document callingDocument)
{
   // ArgumentValidation.CheckForNullReference(callingApplication, "callingApplication");
    //ArgumentValidation.CheckForNullReference(callingDocument, "callingDocument");

    // 保存应用程序对象,方便设置事件处理
    eventApplication = callingApplication;
    // 缓存AlertResponse 对象的值
    alertResponse = callingApplication.AlertResponse;
    // 保存文档对象,方便设置事件处理
    eventDocument = callingDocument;

    // 增加感兴趣的事件侦听处理
    setAddAdvise();

    return;
}

/// <summary>
/// 当事件被增加到事件列表后,且该事件被触发处理,那么IVisEventProc.VisEventProc 函数会被Visio进行调用
/// 事件增加通过SetAddAdvise函数进行处理。
/// </summary>
/// <param name="eventCode">触发的事件代码</param>
/// <param name="source">触发事件的源对象,该对象可能是一个Visio应用程序对象(application),也可以是文档对象(document)。</param>
/// <param name="eventId">触发的事件唯一性标识</param>
/// <param name="eventSequenceNumber">触发事件的相对顺序</param>
/// <param name="subject">发生该事件的对象应用,如对形状删除和增加的事件来说,对象就是形状本身。</param>
/// <param name="moreInfo">关于该事件的附加信息</param>
/// <returns>返回值会被忽略,除非事件是一个查询事件。如没有任何的查询事件,返回值对象是一个空值。</returns>
object IVisEventProc.VisEventProc(short eventCode, object source, int eventId,
    int eventSequenceNumber, object subject, object moreInfo)
{
    Application eventProcApplication = null;
    Document eventProcDocument = null;
    Shape eventShape = null;
    Selection subjectSelection = null;

    object result = null;

    // 获得传递过来的应用程序对象或者文档对象
    if (source is IVApplication)
    {
        eventProcApplication = (Visio.Application)source;
    }
    else if (source is IVDocument)
    {
        eventProcDocument = (Document)source;
    }

    // 检查每个事件代码是否被处理了。事件代码是对象和事件动作的联合对象。
    // 仅当事件在SetAddAdvise方法里面增加后,事件会被发送到这里进行处理。
    switch (eventCode)
    {
        // 形状新增事件
        // VisEventCodes.visEvtAdd的值不能自动转换到一个short类型,通过unchecked函数,可以实现short类型的转换。
        case (short)VisEventCodes.visEvtShape + unchecked((short)VisEventCodes.visEvtAdd):
            eventShape = (Shape)subject;
            handleShapeAdd(eventShape);
            break;

        //形状删除事件
        case (short)VisEventCodes.visEvtDel + (short)VisEventCodes.visEvtShape:
            eventShape = (Shape)subject;
            handleShapeDelete(eventShape);
            break;

        //右键菜单事件
        case (short)VisEventCodes.visEvtApp + (short)VisEventCodes.visEvtMarker:
            handleMarker(eventProcApplication);
            break;

        //常规处理
        case (short)VisEventCodes.visEvtApp + (short)VisEventCodes.visEvtNonePending:
            handleNonePending(eventProcApplication);
            break;

        //单元属性值修改事件
        case (short)VisEventCodes.visEvtCell + (short)VisEventCodes.visEvtMod:
            Visio.Cell cell = (Cell)subject;
            handleCellModify(cell);
            break;

        //形状文本编辑处理事件
        case (short)VisEventCodes.visEvtCodeShapeExitTextEdit:
            eventShape = (Shape)subject;
            handleShapeExitTextEdit(eventShape);
            break;

        //选区对象删除的事件处理
        case (short)VisEventCodes.visEvtCodeQueryCancelSelDel:
            subjectSelection = (Visio.Selection)subject;
            result = handleQueryCancelSelectionDelete(subjectSelection);
            break;
        case (short)VisEventCodes.visEvtCodeMouseDown:
            subjectSelection = (Visio.Selection)subject;
            result = handleQueryCancelSelectionDelete(subjectSelection);
            break;

        default:
            break;
    }

    return result;
}

/// <summary>
/// 该方法增加相应的事件,用来响应对应Visio的行为处理。
/// 例如,增加或删除形状的事件为了和Visio控件表格数据保持一致,需要进行相应处理。
/// Marker事件(右键事件)用来响应形状的双击操作。
/// none-pending事件则是用在空闲时间对Visio进行的相应处理。
/// </summary>
/// <remarks>如果失败,则抛出异常信息</remarks>
private void setAddAdvise()
{
    const string sink = "";
    Event newEvent = null;

    EventList applicationEvents = eventApplication.EventList;
    EventList documentEvents = eventDocument.EventList;

    // 增加shape-added形状添加事件到文档,新形状对象在该处理过程中可以使用。
    // VisEventCodes.visEvtAdd的值不能自动转换为short类型,可以通过unchecked方法进行转换为short类型。
    newEvent = documentEvents.AddAdvise(
        (unchecked((short)VisEventCodes.visEvtAdd) + (short)VisEventCodes.visEvtShape),
        (IVisEventProc)this, sink, "ShapeAdd");

    //增加对文档的before-shape-deleted(形状删除前)事件处理。
    //该事件在文档的形状删除后触发产生,删除的形状对象在处理过程中依旧是可用的
    newEvent = documentEvents.AddAdvise(
        (short)VisEventCodes.visEvtDel + (short)VisEventCodes.visEvtShape,
        (IVisEventProc)this, sink, "ShapeDelete");

    // 增加none-pending 事件处理,该事件在Visio空闲的时候触发。
    newEvent = applicationEvents.AddAdvise(
        (short)VisEventCodes.visEvtApp + (short)VisEventCodes.visEvtNonePending,
        (IVisEventProc)this, sink, "NonePending");

    //由于MarkertEvent只需执行一次事件绑定,因此先判断是否已经绑定
    //如果多次绑定,会出现多次响应的情况
    if (!IsContainEvent(applicationEvents, "MarkerEvent"))
    {
        newEvent = applicationEvents.AddAdvise(
            (short)VisEventCodes.visEvtApp + (short)VisEventCodes.visEvtMarker,
            (IVisEventProc)this, sink, "MarkerEvent");
    }

    //形状属性单元发生修改的事件
    newEvent = documentEvents.AddAdvise(
        (short)VisEventCodes.visEvtMod + (short)VisEventCodes.visEvtCell,
        (IVisEventProc)this, sink, "CellChanged");

    //形状文本退出修改的事件
    newEvent = documentEvents.AddAdvise(
       (short)VisEventCodes.visEvtCodeShapeExitTextEdit,
       (IVisEventProc)this, sink, "ShapeExitedTextEdit");

    //选区对象删除的事件
    newEvent = documentEvents.AddAdvise(
       (short)VisEventCodes.visEvtCodeQueryCancelSelDel,
       (IVisEventProc)this, sink, "QueryCancelSelectionDelete");

    return;
}

/// <summary>
/// 查看是否包含指定的事件
/// </summary>
private bool IsContainEvent(EventList eventList, string eventTargetArgs)
{
    foreach (Event oneEvent in eventList)
    {
        if (oneEvent.TargetArgs == eventTargetArgs)
        {
            return true;
        }
    }
    return false;
}

/// <summary>
/// 该方法在Visio事件全部被处理后被调用。
/// </summary>
/// <param name="idleApplication">空闲的应用程序对象</param>
private void handleNonePending(Application idleApplication)
{
}

/// <summary>
/// 该方法在形状添加后触发调用。
/// 形状对象已经存在,因此可以在后续使用进行引用处理。
/// 形状添加的实际处理过程,是在所有Visio事件处理完毕后进行。
/// </summary>
/// <param name="addedShape">待添加的形状对象</param>
private void handleShapeAdd(Shape addedShape)
{
    //在绘图过程中如果用户组存在该形状,那么添加事件将会忽略这个添加的形状对象
    //这样可以阻止OnShapeAdd事件触发,导致添加的对象被重复计算超过一次
    if (!eventApplication.get_IsInScope((short)VisUICmds.visCmdObjectGroup))
    {
        OnShapeAdd(addedShape, new EventArgs());
    }            
}

private void handleShapeClick(Shape addedShape)
{
//在绘图过程中如果用户组存在该形状,那么添加事件将会忽略这个添加的形状对象
//这样可以阻止OnShapeAdd事件触发,导致添加的对象被重复计算超过一次
if (!eventApplication.get_IsInScope((short)VisUICmds.visCmdObjectGroup))
{
OnShapeClick(addedShape, new EventArgs());
}
}
///
/// 当形状被删除时,该方法会被调用。
/// 该形状对象在此过程依旧可用,因此形状的信息可以在下面继续被读取。
/// 形状添加的实际处理过程,是在所有Visio事件处理完毕后进行。
///
/// 待删除的形状对象
private void handleShapeDelete(Shape deletedShape)
{
if (!eventApplication.get_IsInScope((short)VisUICmds.visCmdObjectGroup))
{
OnShapeDelete(deletedShape, new EventArgs());
}
}

/// <summary>
/// 该方法当Visio触发marker事件的时候进行处理。
/// 当用户在形状上双击,在形状的EventDblClick单元上将会运行QueueMarkerEvent方法,触发marker事件。
/// </summary>
/// <param name="visioApplication">触发该事件的Visio应用程序</param>
private void handleMarker(Application visioApplication)
{
    if (OnMarkerEvent != null)
    {
        string arguments = visioApplication.get_EventInfo((short)VisEventCodes.visEvtIdMostRecent);
        // 获得形状的引用
        Shape targetShape = VisioUtility.GetShapeFromArguments(visioApplication, arguments);
        OnMarkerEvent(targetShape, new MarketEventArgs(arguments));
    }
    return;
}

/// <summary>
/// 形状属性单元发生修改的事件处理
/// </summary>
/// <param name="cell">单元对象</param>
private void handleCellModify(Cell cell)
{
    if (OnCellChanged != null)
    {
        OnCellChanged(cell, new EventArgs());
    }
}

/// <summary>
/// 形状文本退出修改的事件处理
/// </summary>
/// <param name="shape">形状对象</param>
private void handleShapeExitTextEdit(Shape shape)
{
    if (OnTextEdit != null)
    {
        OnTextEdit(shape, new EventArgs());
    }
}

/// <summary>
/// 选区对象删除的事件处理
/// </summary>
/// <param name="selection">选区对象</param>
/// <returns></returns>
private bool handleQueryCancelSelectionDelete(Visio.Selection selection)
{
    bool result = false;
    if (OnQueryCancelSelectionDelete != null)
    {
        result = OnQueryCancelSelectionDelete(selection, new EventArgs());
    }
    return result;
}

}

///
/// Market事件的参数
///
public class MarketEventArgs : EventArgs
{
private string argument = string.Empty;

/// <summary>
/// 参数表达式
/// </summary>
public string Argument
{
    get { return argument; }
    set { argument = value; }
}

public MarketEventArgs() { }
public MarketEventArgs(string argument)
{
    this.argument = argument;
}

}

2. 初始化文档的事件处理类

partial class FrmConstruct
{

/// <summary>
    /// 初始化文档的事件处理
    /// </summary>
    private void InitEventSink(Visio.Application targetApplication, Document targetDocument)
    {
        try
        {
            visioEventSink = null; // 释放上一次对应的事件处理

            //创建一个事件接收器,连接事件到Visio的应用程序和文档。
            visioEventSink = new EventSink();
            visioEventSink.AddAdvise(targetApplication, targetDocument);

            //侦听添加形状的事件
            visioEventSink.OnShapeAdd += new VisioEventHandler(visioEventSink_OnShapeAdd);
            //侦听形状删除的事件
            visioEventSink.OnShapeDelete += new VisioEventHandler(visioEventSink_OnShapeDelete);
            //侦听右键菜单的marker事件,当用户双击形状的时候触发
            //visioEventSink.OnMarkerEvent += new VisioEventHandler(visioEventSink_OnMarkerEvent);
            //侦听形状单元属性修改事件
            //visioEventSink.OnCellChanged += new VisioEventHandler(visioEventSink_OnCellChanged);
            //侦听形状文本内容修改事件
            visioEventSink.OnTextEdit += new VisioEventHandler(visioEventSink_OnTextEdit);
            //侦听选区删除处理事件
            //visioEventSink.OnQueryCancelSelectionDelete += new QueryCancelEventHandler(visioEventSink_OnQueryCancelSelectionDelete);
        }
        catch (COMException error)
        {
            MessageUtil.ShowError("An unknown COM error occurred:" + error.Message);
            throw;
        }
    }

    private void visioEventSink_OnTextEdit(object sender, EventArgs e)
    {
        MessageBox.Show("文本修改");
    }

    /// <summary>
    /// 处理形状删除的事件,它将移除指定形状表格上的信息。
    /// </summary>
    /// <param name="sender">事件的触发形状对象</param>
    /// <param name="e">事件关联参数,在此被忽略使用。</param>
    private void visioEventSink_OnShapeDelete(object sender, EventArgs e)
    {
        MessageBox.Show("删除");
    }

    /// <summary>
    /// 在用户添加设备后,我们为特定的设备增加对应的右键菜单事件。
    /// 当用户双击形状的时候,触发对应的右键菜单事件(marker event)
    /// </summary>
    /// <param name="sender">用户双击的Visio形状对象 </param>
    /// <param name="e">事件关联参数,在此被忽略使用。</param>
    private void visioEventSink_OnShapeAdd(object sender, EventArgs e)
    {
        MessageBox.Show("添加");
    }
}

“`

注意:上面两个类要在同一命名空间下


https://www.xamrdz.com/lan/5kk1920562.html

相关文章: