项目中要实现一个功能,就是qq的@功能,在获取文本上遇到一些问题,希望各位恩那个帮忙给些思路:下面是qq的效果:
技术背景:
这是一个WinForm客户端项目
输入框是使用WebBrowser,直接让wb控件处于编辑状态然后进行编辑,然后当用户输入@的时候弹出一个用户列表控件,我现在需要对用户列表进行模糊搜索,需要得到用户在输入@之后用户输入的文本内容。本人不才遇到以下问题:
不知如何能获取当用户输入@之后的文本内容,而且可能完成了一个@之后还有@其他人的情况
wb控件里面直接编辑得到的html大概是<font>文本内容</font> 并没有标签id之类的内容
上面忘记说我是在wb控件的PreviewKeyDown事件里面处理的
想请教下各位大侠,我如何在获得@之后输入的内容呢,不管是用win32的钩子还是html js之类的方案都可以接受,
如上图,如果只有一个@ 基本没有问题,我是直接获取整个wb控件的所有内容,然后去掉html标签与@文字但如图如果已经存在了文本 我再输入@然后使用上图的方法获取文本就不对了
大家帮帮忙给点建议,我需要获取wb控件中每次输入@之后紧跟着的文本内容
谢谢
技术背景:
这是一个WinForm客户端项目
输入框是使用WebBrowser,直接让wb控件处于编辑状态然后进行编辑,然后当用户输入@的时候弹出一个用户列表控件,我现在需要对用户列表进行模糊搜索,需要得到用户在输入@之后用户输入的文本内容。本人不才遇到以下问题:
不知如何能获取当用户输入@之后的文本内容,而且可能完成了一个@之后还有@其他人的情况
wb控件里面直接编辑得到的html大概是<font>文本内容</font> 并没有标签id之类的内容
上面忘记说我是在wb控件的PreviewKeyDown事件里面处理的
想请教下各位大侠,我如何在获得@之后输入的内容呢,不管是用win32的钩子还是html js之类的方案都可以接受,
如上图,如果只有一个@ 基本没有问题,我是直接获取整个wb控件的所有内容,然后去掉html标签与@文字但如图如果已经存在了文本 我再输入@然后使用上图的方法获取文本就不对了
大家帮帮忙给点建议,我需要获取wb控件中每次输入@之后紧跟着的文本内容
谢谢
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 upContainer; 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.upContainer = GetMarkupContainer(); this.upContainer.RegisterForDirtyRange((mshtml.IHTMLChangeSink)this, out this.cookie);
}
public void StopMonitorTextChanged()
{
if (this.upContainer != null)
{
this.upContainer.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);
}
}
}
}
}在任何情况下,只要你输入的字符跟在@后面,立刻就能显示出来。剩下的就好办了吧。