VBProjectsEvents在哪里? [英] Where are the VBProjectsEvents?

查看:164
本文介绍了VBProjectsEvents在哪里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#中使用 Microsoft.Vbe.Interop ,我可以访问 CommandBarEvents ReferencesEvents 通过 VBE.Events



然而,有用的 MSDN 文档似乎表明有一个 VBProjectsEvents ,我可以使用它来通知我的加载项,当一个项目被添加到/从VBE删除...这正是我要在这里实现的。



我可以在对象浏览器中看到 _VBProjectsEvents 接口,但没有实现相对于 _CommandBarControlsEvents 接口,它由 CommandBarEventsClass 实现),使用ReSharper的执行功能。



是否在任何地方实现了 _VBProjectsEvents 如果没有,那么关于从IDE中删除的VBProject的通知如何呢?

解决方案

你需要创建一个



实现 _dispVBProjectsEvents dispatch接口 - 这是一个实现,通过调用常规托管的.net事件来响应这些事件,有效地包装$ code> VBProjects 事件:

  public class VBProjectsEventsSink:_dispVBProjectsEvents 
{
public event EventHandler< DispatcherEventArgs< VBProject>> ProjectAdded;
public void ItemAdded(VBProject VBProject)
{
if(VBProject.Protection == vbext_ProjectProtection.vbext_pp_none)
{
OnDispatch(ProjectAdded,VBProject);
}
}

public event EventHandler& DispatcherEventArgs< VBProject>> ProjectRemoved;
public void ItemRemoved(VBProject VBProject)
{
if(VBProject.Protection == vbext_ProjectProtection.vbext_pp_none)
{
OnDispatch(ProjectRemoved,VBProject);
}
}

public event EventHandler< DispatcherRenamedEventArgs< VBProject>> ProjectRenamed;
public void ItemRenamed(VBProject VBProject,string OldName)
{
var handler = ProjectRenamed;
if(handler!= null&& VBProject.Protection == vbext_ProjectProtection.vbext_pp_none)
{
handler.Invoke(this,new DispatcherRenamedEventArgs< VBProject>(VBProject,OldName));
}
}

public event EventHandler& DispatcherEventArgs< VBProject>> ProjectActivated;
public void ItemActivated(VBProject VBProject)
{
if(VBProject.Protection == vbext_ProjectProtection.vbext_pp_none)
{
OnDispatch(ProjectActivated,VBProject);
}
}

private void OnDispatch(EventHandler< DispatcherEventArgs< VBProject>> dispatched,VBProject项目)
{
var handler = dispatched;
if(handler!= null)
{
handler.Invoke(this,new DispatcherEventArgs< VBProject>(project));
}
}
}

DispatcherEventArgs 类只是一个方便的方式来公开事件涉及的 VBProject 项目,它可以重用于其他接收器:

  public class DispatcherEventArgs< T> :EventArgs 
其中T:class
{
private readonly T _item;

public DispatcherEventArgs(T item)
{
_item = item;
}

public T Item {get {return _item; }}
}

客户端代码需要注册接收器 - 为此您需要保持一个 IConnectionPoint 字段及其 int cookie:

  private readonly IConnectionPoint _projectsEventsConnectionPoint; 
private readonly int _projectsEventsCookie;

VBProjects 集合实现 IConnectionPointContainer 接口,您需要使用它来查找连接点:

  var sink = new VBProjectsEventsSink(); 
var connectionPointContainer =(IConnectionPointContainer)_vbe.VBProjects;
var interfaceId = typeof(_dispVBProjectsEvents).GUID;
connectionPointContainer.FindConnectionPoint(ref interfaceId,out _projectsEventsConnectionPoint);

一旦您有 IConnectionPoint ,请使用建议方法来连接您的接收器并检索 cookie

  _projectsEventsConnectionPoint.Advise(sink,out _projectsEventsCookie); 

然后,您可以像任何正常.net事件一样处理接收器事件: p>

  sink.ProjectAdded + = sink_ProjectAdded; 
sink.ProjectRemoved + = sink_ProjectRemoved;
sink.ProjectActivated + = sink_ProjectActivated;
sink.ProjectRenamed + = sink_ProjectRenamed;

当你想断开你的接收器时,你将 cookie 传递给 Unadvise 方法 IConnectionPoint 实例:

  _projectsEventsConnectionPoint.Unadvise(_projectsEventsCookie); 

简单!


Using Microsoft.Vbe.Interop in C#, I can access CommandBarEvents and ReferencesEvents via VBE.Events.

However the ever-so helpful MSDN documentation seems to indicate that there's a VBProjectsEvents that I could use to notify my add-in when a project is added or removed to/from the VBE... which is exactly what I'm trying to achieve here.

I can see that _VBProjectsEvents interface in the object browser, but no implementation for it (as opposed to the _CommandBarControlsEvents interface, which is implemented by the CommandBarEventsClass), using ReSharper's go to implementation feature.

Is there an implementation of the _VBProjectsEvents interface anywhere? If not, then how does one go about being notified of a VBProject being removed from the IDE?

解决方案

You need to create a sink for these events.

Implement the _dispVBProjectsEvents dispatch interface - here's an implementation that responds to these events by invoking regular managed .net events, effectively "wrapping" the VBProjects events:

public class VBProjectsEventsSink : _dispVBProjectsEvents
{
    public event EventHandler<DispatcherEventArgs<VBProject>> ProjectAdded;
    public void ItemAdded(VBProject VBProject)
    {
        if (VBProject.Protection == vbext_ProjectProtection.vbext_pp_none)
        {
            OnDispatch(ProjectAdded, VBProject);
        }
    }

    public event EventHandler<DispatcherEventArgs<VBProject>> ProjectRemoved;
    public void ItemRemoved(VBProject VBProject)
    {
        if (VBProject.Protection == vbext_ProjectProtection.vbext_pp_none)
        {
            OnDispatch(ProjectRemoved, VBProject);
        }
    }

    public event EventHandler<DispatcherRenamedEventArgs<VBProject>> ProjectRenamed;
    public void ItemRenamed(VBProject VBProject, string OldName)
    {
        var handler = ProjectRenamed;
        if (handler != null && VBProject.Protection == vbext_ProjectProtection.vbext_pp_none)
        {
            handler.Invoke(this, new DispatcherRenamedEventArgs<VBProject>(VBProject, OldName));
        }
    }

    public event EventHandler<DispatcherEventArgs<VBProject>> ProjectActivated;
    public void ItemActivated(VBProject VBProject)
    {
        if (VBProject.Protection == vbext_ProjectProtection.vbext_pp_none)
        {
            OnDispatch(ProjectActivated, VBProject);
        }
    }

    private void OnDispatch(EventHandler<DispatcherEventArgs<VBProject>> dispatched, VBProject project)
    {
        var handler = dispatched;
        if (handler != null)
        {
            handler.Invoke(this, new DispatcherEventArgs<VBProject>(project));
        }
    }
}

The DispatcherEventArgs class is just a convenient way to expose the VBProject item involved with the event, and it can be reused for other sinks:

public class DispatcherEventArgs<T> : EventArgs 
    where T : class
{
    private readonly T _item;

    public DispatcherEventArgs(T item)
    {
        _item = item;
    }

    public T Item { get { return _item; } }
}

The client code needs to register the sink - and for that you need to keep an IConnectionPoint field and its int cookie:

private readonly IConnectionPoint _projectsEventsConnectionPoint;
private readonly int _projectsEventsCookie;

The VBProjects collection implements the IConnectionPointContainer interface, which you need to use to find the connection point:

var sink = new VBProjectsEventsSink();
var connectionPointContainer = (IConnectionPointContainer)_vbe.VBProjects;
var interfaceId = typeof (_dispVBProjectsEvents).GUID;
connectionPointContainer.FindConnectionPoint(ref interfaceId, out _projectsEventsConnectionPoint);

Once you have the IConnectionPoint, use the Advise method to "connect" your sink and retrieve a cookie:

_projectsEventsConnectionPoint.Advise(sink, out _projectsEventsCookie);

And then you can handle the sink events as you would any "normal" .net events:

sink.ProjectAdded += sink_ProjectAdded;
sink.ProjectRemoved += sink_ProjectRemoved;
sink.ProjectActivated += sink_ProjectActivated;
sink.ProjectRenamed += sink_ProjectRenamed;

When you want to disconnect your sink, you pass the cookie to the Unadvise method of the IConnectionPoint instance:

_projectsEventsConnectionPoint.Unadvise(_projectsEventsCookie);

"Simple as that!"

这篇关于VBProjectsEvents在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆