向textview添加命令过滤器后的问题

时间:2011-12-17 10:50:41

标签: c# visual-studio vsx

我想拦截关键事件,我搜索了很多文章寻求帮助,this article启发了我。我所做的是:

  1. 创建一个新类并实现“IVsTextManagerEvents”接口来注册每个textview。

    public void OnRegisterView(IVsTextView pView)
    {
        CommandFilter filter = new CommandFilter();
        IOleCommandTarget nextCommandTarget;
        pView.AddCommandFilter(filter, out nextCommandTarget);
        filter.NextCommandTarget = nextCommandTarget;
    }
    
  2. 添加实现IOleCommandTarget的新类“CommandFilter”,我们可以从vs中拦截olecommand

    public class CommandFilter : IOleCommandTarget
    {    
    
        public IOleCommandTarget NextCommandTarget
        {
            get; 
            set;
        }
    
        public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
        {
            NextCommandTarget.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
            return VSConstants.S_OK;
        }
    
        public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            if (pguidCmdGroup == typeof(VSConstants.VSStd2KCmdID).GUID)
            {
                switch (nCmdID)
                {
                    case (uint)VSConstants.VSStd2KCmdID.RETURN:
                        MessageBox.Show("enter");
                        break;
                }
            }
    
            NextCommandTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
    
            return VSConstants.S_OK;
        }
    }
    
  3. 我们需要在Initialize

    中建议IVsTextManagerEvents
    protected override void Initialize()
    {
        base.Initialize();
    
        IConnectionPointContainer textManager = (IConnectionPointContainer)GetService(typeof(SVsTextManager));
        Guid interfaceGuid = typeof(IVsTextManagerEvents).GUID;
        textManager.FindConnectionPoint(ref interfaceGuid, out tmConnectionPoint);
        tmConnectionPoint.Advise(new TextManagerEventSink(), out tmConnectionCookie);
    }
    
  4. 经过上述准备,我们现在可以拦截关键事件。在您输入“enter”键后可以看到一个消息框。

    我的问题是,在我完成上述之后

    1. 我无法保存文件,这意味着当我抚摸ctrl + S时,什么都没发生。
    2. 当我输入单词时,你会看到明显的延迟。看来我的包裹花了很长时间来处理某些事情,但正如你在上面所看到的那样,我根本没有。

1 个答案:

答案 0 :(得分:2)

好像我找到了答案!

NextCommandTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);

return VSConstants.S_OK;

可是:

return NextCommandTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);