c# - 将命令过滤器添加到 textview 后出现问题

标签 c# visual-studio vsx

想拦截vs中的关键事件,找了很多文章求助,this article启发了我。我所做的是:

  1. 创建一个新类并实现“IVsTextManagerEvents”接口(interface)来注册每个 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);
    }
    

经过上面的准备,我们现在可以拦截关键事件了。按下“enter”键后,您会看到一个消息框。

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

  1. 我无法保存文档,这意味着当我按下 ctrl+S 时,没有任何反应。
  2. 当我输入文字时,你可以看到明显的延迟。看来我的包裹需要很长时间才能处理一些东西,但正如您在上面看到的,我根本没有。

最佳答案

看来我找到了答案!

不是:

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

return VSConstants.S_OK;

但是:

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

关于c# - 将命令过滤器添加到 textview 后出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8544203/

相关文章:

c# - 如何使用维基百科中的超链接以编程方式制作 html 文本?

c# - 如何使用 Expression 使用 Where 和 OR 构建动态查询

c# - 如何使自动版本号在 Visual Studio 中工作

visual-studio-2012 - VSIX 扩展使用第 3 方 DLL 无法加载依赖项之一

wpf - VSX 2010 包加载 - Markup.xaml 解析找不到程序集

c# - 在 MVC 3 中实现 Controller 创建策略的最佳方式

c# - 为什么未加载ScriptableObject Assets 中的嵌套资源引用?

visual-studio - Visual Studio 监 window 口中的问号 (???) 表示什么?

visual-studio - Visual Studio 2017 中没有针对新 C# 文件的智能感知

visual-studio-2010 - 设计 Visual Studio 2010 集成包