监听webbrowser内容改变

论坛上一位朋友发贴想实现这样功能:在webbrowser(编辑状态)中输入@,然后能捕获随后输入的几个字符。贴子见:

https://bbs.csdn.net/topics/390995682?page=1#post-403542646

 监听键盘事件有两个缺陷:

1.它只能监听到ASCII字符,如果输入汉字则不响应。
2.事件发生时,字符还未真正出现在webbrowser中。

解决方法首先是实现IHTMLChangeSink接口,这样webbrowser中内容一发生改变,我们立刻就能收到通知。

需要引用mshtml,引用该dll的方法及注意事项:

https://blog.csdn.net/drupe/article/details/45845181

主要代码:


using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
    public class Monitor : mshtml.IHTMLChangeSink
    {
        // for monitor htmleditor textchanged
        private Guid IMarkupContainer2GUID = typeof(mshtml.IMarkupContainer2).GUID;
   
        private uint cookie = 0;

        private mshtml.IMarkupContainer2 markupContainer;

      private WebBrowser webBrowser;

     // Event
        public event EventHandler HtmlEditorEvent;


       public Monitor(WebBrowser webControl)
     {
      this.webBrowser= webControl;
        }


        #region For HtmlEditor TextChanged
        
        // always monitor
        private mshtml.IMarkupContainer2 GetMarkupContainer()
        {
            object oDocument = this.webBrowser.Document.DomDocument;

            IntPtr pDocument = Marshal.GetIUnknownForObject(oDocument);

            IntPtr pMarkupContainer = IntPtr.Zero;

            // pMarkupContainer is different after a call to Navigate or designMode

            Marshal.QueryInterface(pDocument, ref IMarkupContainer2GUID, out pMarkupContainer);

            //object oMarkupContainer = Marshal.GetObjectForIUnknown(pMarkupContainer); // This does not work

            object oMarkupContainer = Marshal.GetUniqueObjectForIUnknown(pMarkupContainer);

            Marshal.Release(pDocument);

            Marshal.Release(pMarkupContainer);

            return (mshtml.IMarkupContainer2)oMarkupContainer;

        }


        // only one monitor
        private mshtml.IMarkupContainer2 GetMarkupContainer2()
        {
            return (mshtml.IMarkupContainer2)this.webBrowser.Document.DomDocument;
        }


        public void MonitorTextChangedAlways()
        {
            this.markupContainer = GetMarkupContainer();

            this.markupContainer.RegisterForDirtyRange((mshtml.IHTMLChangeSink)this, out this.cookie);
        }


        public void StopMonitorTextChanged()
        {
            if (this.markupContainer != null)
            {
                this.markupContainer.UnRegisterForDirtyRange(this.cookie);
            }
        }

        #endregion


        #region Implement Interface

        public void Notify()
        {
            //触发改变事件外界去接受
            if (this.HtmlEditorEvent != null)
            {
                this.HtmlEditorEvent(this,new EventArgs());
            }
        }

        #endregion


    }
}

 


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using mshtml;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        IHTMLDocument2 document;
        Monitor m = null;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            webBrowser1.DocumentText = string.Empty;
            webBrowser1.Document.ExecCommand("EditMode", false, null);
            webBrowser1.Document.ExecCommand("LiveResize", false, null);
            this.FormClosing += Form1_FormClosing;

            document = (IHTMLDocument2)webBrowser1.Document.DomDocument;
            m = new Monitor(webBrowser1);
            m.HtmlEditorEvent += m_HtmlEditorEvent;
            m.MonitorTextChangedAlways();
        }

        void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            m.StopMonitorTextChanged();
        }

        void m_HtmlEditorEvent(object sender, EventArgs e)
        {
            IHTMLTxtRange searchRange = (IHTMLTxtRange)document.selection.createRange();
            searchRange.collapse(true);
            searchRange.moveStart("character", -5);//长度可调整
            String t = searchRange.text;
            if (t != null)
            {
                int i = t.IndexOf('@');
                if (i >= 0)
                {
                    this.textBox1.Text = t.Substring(i + 1);
                }
            }
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值