visio二次开发___事件篇___事件编程

Visio二次开发的事件编程主要分为四个步骤:

首先,需要创建visio事件代理和visio事件处理类,并添加需要处理的事件;

其次,对需要处理的事件向对象进行注册,即添加到对象的EventList事件列表中,并同时指定visio事件处理类。这样,当对象触发了相应的事件后,能够向事件处理类发出通知;

再次,需要实现事件处理类的事件处理方法,以便当接到通知后,能够做出相应的处理;

最后,根据接收到的事件通知,判断其事件代码、事件源、作用对象、事件ID等参数,来触发相应的需要处理的事件。

下面结合源码给予说明:

1.       创建visio事件代理和visio事件处理类,并添加需要处理的事件

/// <summary>

    /// 是一个用于处理visio事件的visio事件代理

    /// </summary>

    /// <param name="sender">引发事件的visio对象</param>

    /// <param name="e">与事件相关的参数</param>

    public delegate void VisioEventHandler(object sender, EventArgs e);

 

    /// <summary>

    /// 这是一个visio事件处理类,继承IVisEventProc

    /// 所有的注册了的visio事件发出通知后,都会调用VisEventProc()过程;

    /// </summary>

public sealed class EventSink : IVisEventProc{}

/// <summary>

        /// 图形添加事件

        /// </summary>

        public event VisioEventHandler OnShapeAdd;

        /// <summary>

        /// 图形删除事件

        /// </summary>

        public event VisioEventHandler OnShapeDelete;

        /// <summary>

        /// 定义图形双击事件

        /// </summary>

public event VisioEventHandler OnShapeDoubleClick;

2.向对象注册事件,可以接收注册事件的对象有:ApplicationDocument。就是将事件分为处于应用层的事件(和应用相关的事件),还有文档层的事件(只和文档相关的事件)。那么哪一些事件和Application相关?哪一些事件和Document相关呢?可以参考前一篇文章“visio二次开发_事件篇_事件分类”。这里和Application相关的事件与和Document相关的事件有点区别,关于这方面的内容,在后续的文章会有介绍。

向对象注册事件,其实就是调用对象的EventListAddAdvise()方法:

假设有Application对象visApplicationDocument对象visDocument

EventList applicationEvents = visApplication.EventList;

EventList documentEvents = visDocument.EventList;

Event newEvent = null;

    // visDocument注册该文档的图形添加事件

                newEvent = documentEvents.AddAdvise(

                        (unchecked((short)VisEventCodes.visEvtAdd) +

                        (short)VisEventCodes.visEvtShape),

                        (IVisEventProc)this, sink, targetArgs);

                // visDocument注册该文档的图形删除事件

                newEvent = documentEvents.AddAdvise(

                    (short)VisEventCodes.visEvtDel +

                    (short)VisEventCodes.visEvtShape,

                    (IVisEventProc)this, sink, targetArgs);

                // visApplication注册该应用的标签事件

                newEvent = applicationEvents.AddAdvise(

                    (short)VisEventCodes.visEvtApp +

                    (short)VisEventCodes.visEvtMarker,

                (IVisEventProc)this, sink, targetArgs);

3.实现事件处理类的事件处理方法,根据 eventCode判断是什么样的事件,这里需要注意的是要将VisEventCodes强制转变为short类型。关于标签事件在后续的文章中会介绍:

object IVisEventProc.VisEventProc(short eventCode, object source,

            int eventId,

            int eventSequenceNumber,

            object subject,

        object moreInfo)

switch (eventCode)

            {

                // 根据 VisEventCodes判断是什么样的事件;

                // 注意要将VisEventCodes强制转变为short类型

                //判断是否为图形添加事件;

                case (short)VisEventCodes.visEvtShape +

                unchecked((short)VisEventCodes.visEvtAdd):

                    // 调用handleShapeAdd()去抛出图形添加事件

                    eventShape = (Shape)subject;

                    handleShapeAdd(eventShape);

                    break;

                //判断是否为图形删除事件;

                case (short)VisEventCodes.visEvtDel +

                (short)VisEventCodes.visEvtShape:

                    // 调用handleShapeDelete()去抛出图形删除事件

                    eventShape = (Shape)subject;

                    handleShapeDelete(eventShape);

                    break;

                //判断是否为应用的标记事件;

                case (short)VisEventCodes.visEvtApp +

                (short)VisEventCodes.visEvtMarker:

                    // 调用handleMarker()去抛出标签事件

                    handleMarker(eventApplication);

                    break;

}

4. 触发相应的需要处理的事件。由于篇幅原因,这里只给出图形添加的例子。需要注意的事情是,为了提高效率,往往会使用队列来处理这些图形添加事件,就是暂时将添加的图形放到队列中去,等到空闲的时候,再出队处理(即抛出事件):

private void handleShapeAdd(Shape addedShape)

  {

if (OnShapeAdd != null)

          OnShapeAdd(addedShape, new EventArgs());

}

 

当然要进行事件编程,到这里并没有结束。需要进行事件编程的组件还要向这个visio事件处理类的实例对象注册事件处理方法:  

EventSink visioEventSink = new EventSink();

//注册图形添加处理事件;

    visioEventSink. OnShapeAdd += new VisioEventHandler(visioEventSink_OnShapeDoubleClick);

    //注册图形删除处理事件;

    visioEventSink. OnShapeDelete +=

               new VisioEventHandler(visioEventSink_OnSelectTheSameFloorShape);

 其实本文主要介绍了如何注册事件,相应事件通知,再分别抛出事件等过程。抛砖引玉,希望大家提出自己的高见。

下面是完整的源码:

 

Code
using System;
using System.Diagnostics;

using Microsoft.Office.Interop.Visio;

namespace IndoorDistribut
{
/// <summary>
/// 是一个用于处理visio事件的visio事件代理
/// </summary>
/// <param name="sender">引发事件的visio对象</param>
/// <param name="e">与事件相关的参数</param>
public delegate void VisioEventHandler(object sender, EventArgs e);

/// <summary>
/// 这是一个visio事件处理类,继承IVisEventProc。
/// 所有的注册了的visio事件发出通知后,都会调用VisEventProc()过程;
///
/// </summary>
public sealed class EventSink : IVisEventProc
{
/// <summary>Visio.Application 对象.</summary>
private Microsoft.Office.Interop.Visio.Application
eventApplication
= null;

/// <summary>Visio.Document 对象.</summary>
private Document eventDocument = null;

/// <summary>Visio Application.AlertResponse value.</summary>
private int alertResponse = 0;

/// <summary>Two FIFO queues are used to store added and deleted
/// shape information while Visio events are being processed.</summary>
private System.Collections.Queue shapeAddedQueue = null;
private System.Collections.Queue shapeDeletedQueue = null;

/// <summary>
/// 图形添加事件
/// </summary>
public event VisioEventHandler OnShapeAdd;

/// <summary>
/// 图形删除事件
/// </summary>
public event VisioEventHandler OnShapeDelete;

/// <summary>
/// 定义图形双击事件
/// </summary>
public event VisioEventHandler OnShapeDoubleClick;

public EventSink()
{

// 创建图形添加和删除的事件队列
shapeAddedQueue = new System.Collections.Queue();
shapeDeletedQueue
= new System.Collections.Queue();
}

/// <summary>
/// 当然这首先要通过AddAdvise()添加需要侦测的事件。
/// 也就是需要用AddAdvise()向visio注册事件;
/// summary>

[CLSCompliant(
false)]
public void AddAdvise(
Microsoft.Office.Interop.Visio.Application callingApplication,
Document callingDocument)
{

if (callingApplication == null)
{

throw new ArgumentNullException("callingApplication","");
}

if (callingDocument == null)
{

throw new ArgumentNullException("callingDocument","");
}

eventApplication
= callingApplication;

alertResponse
= callingApplication.AlertResponse;

eventDocument
= callingDocument;

setAddAdvise();

return;
}

object IVisEventProc.VisEventProc(short eventCode,
object source,
int eventId,
int eventSequenceNumber,
object subject,
object moreInfo)
{

Microsoft.Office.Interop.Visio.Application eventApplication
= null;
Document eventDocument
= null;
Shape eventShape
= null;

if (source is IVApplication)
{

eventApplication
=
(Microsoft.Office.Interop.Visio.Application)source;
}
else if (source is IVDocument)
{

eventDocument
= (Document)source;
}

switch (eventCode)
{

// 根据 VisEventCodes判断是什么样的事件;
// 注意要将VisEventCodes强制转变为short类型
//判断是否为图形添加事件;
case (short)VisEventCodes.visEvtShape +
unchecked((short)VisEventCodes.visEvtAdd):

// 调用handleShapeAdd()去抛出图形添加事件
eventShape = (Shape)subject;
handleShapeAdd(eventShape);
break;
//判断是否为图形删除事件;
case (short)VisEventCodes.visEvtDel +
(
short)VisEventCodes.visEvtShape:

// 调用handleShapeDelete()去抛出图形删除事件
eventShape = (Shape)subject;
handleShapeDelete(eventShape);
break;
//判断是否为应用的标记事件;
case (short)VisEventCodes.visEvtApp +
(
short)VisEventCodes.visEvtMarker:

// 调用handleMarker()去抛出标签事件
handleMarker(eventApplication);
break;

case (short)VisEventCodes.visEvtApp +
(
short)VisEventCodes.visEvtNonePending:

handleNonePending(eventApplication);
break;

default:
break;
}

return null;
}

private void setAddAdvise()
{

const string sink = "";
const string targetArgs = "";

Event newEvent
= null;

EventList applicationEvents
= eventApplication.EventList;
EventList documentEvents
= eventDocument.EventList;
try
{
// 向visDocument注册该文档的图形添加事件
newEvent = documentEvents.AddAdvise(
(
unchecked((short)VisEventCodes.visEvtAdd) +
(
short)VisEventCodes.visEvtShape),
(IVisEventProc)
this, sink, targetArgs);

// 向visDocument注册该文档的图形删除事件
newEvent = documentEvents.AddAdvise(
(
short)VisEventCodes.visEvtDel +
(
short)VisEventCodes.visEvtShape,
(IVisEventProc)
this, sink, targetArgs);

// 向visApplication注册该应用的标签事件
newEvent = applicationEvents.AddAdvise(
(
short)VisEventCodes.visEvtApp +
(
short)VisEventCodes.visEvtMarker,
(IVisEventProc)
this, sink, targetArgs);

newEvent
= applicationEvents.AddAdvise(
(
short)VisEventCodes.visEvtApp +
(
short)VisEventCodes.visEvtNonePending,
(IVisEventProc)
this, sink, targetArgs);
}
catch (Exception e)
{
;
}

return;
}

/// visio空闲时,需做的处理
private void handleNonePending(
Microsoft.Office.Interop.Visio.Application idleApplication)
{

// 处理添加图形事件队列
if (OnShapeAdd != null)
{

while (shapeAddedQueue.Count > 0)
{
OnShapeAdd(shapeAddedQueue.Dequeue(),
new EventArgs());
}
}

else
{
shapeAddedQueue.Clear();
}

// 处理添加图形事件队列
if (OnShapeDelete != null)
{
while (shapeDeletedQueue.Count > 0)
{

OnShapeDelete(shapeDeletedQueue.Dequeue(),
new EventArgs());
}
}

else
{
shapeDeletedQueue.Clear();
}

return;
}

private void handleShapeAdd(Shape addedShape)
{

shapeAddedQueue.Enqueue(addedShape);
return;
}

private void handleShapeDelete(Shape deletedShape)
{

shapeDeletedQueue.Enqueue(productId);
return;
}

}
}

转载于:https://www.cnblogs.com/sjkjsandy/archive/2008/11/20/1337979.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
cn_visio_professional_2016是一款由微软公司开发的专业流程图和业务图解软件,在2016年发布的版本中进行了多项改进和优化。 cn_visio_professional_2016具有用户友好的界面,使用户能够轻松地创建、编辑和共享各种类型的图表和图解。该软件提供了丰富的图表模板和形状库,用户可以根据自己的需要选择合适的模板和形状,快速绘制出清晰、美观的图表。 cn_visio_professional_2016支持多种数据连接方式,用户可以将外部数据直接导入图表,实现动态更新和实时展示。此外,该软件还支持与其他Office应用程序(如Excel、Word和PowerPoint)的无缝集成,方便用户在不同应用之间进行数据共享和协作。 在cn_visio_professional_2016中,用户可以通过智能和自动化的工具来提高工作效率。例如,该软件提供了智能图形识别功能,能够自动将手绘的图形转换为矢量图形,大大节省了时间和精力。另外,用户还可以通过一键生成的功能,快速创建复杂的流程图和组织结构图。 cn_visio_professional_2016还具有强大的协作功能。用户可以通过内置的在线共享功能,将图表和图解与团队成员实时共享,实现多人协作和编辑。同时,该软件还支持导出为多种格式,如PDF、PNG和JPEG等,方便用户在不同场合和设备上进行展示和分享。 总的来说,cn_visio_professional_2016是一款功能强大、易于使用和高效的流程图和业务图解软件,可以帮助用户快速、准确地表达和展示复杂的业务过程和组织结构。无论是在商业、教育还是其他领域,该软件都能为用户带来便利和便捷。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值