// Displays sending with a connected socket
// using the overload that takes a buffer, message size, and socket flags. public static int SendReceiveTest3(Socket server)
{
byte[] msg = Encoding.UTF8.GetBytes("This is a test");
byte[] bytes = new byte[256];
try {
// Blocks until send returns.
int i = server.Send(msg, msg.Length, SocketFlags.None); Console.WriteLine("Sent {0} bytes.", i);
// Get reply from the server.
int byteCount = server.Receive(bytes, server.Available, SocketFlags.None); if (byteCount > 0)
Console.WriteLine(Encoding.UTF8.GetString(bytes));
}
catch (SocketException e)
{
Console.WriteLine("{0} Error code: {1}.", e.Message, e.ErrorCode);
return (e.ErrorCode);
}
return 0; }
文本比较的核心就是比较两个给定的文本(可以是字节流等)之间的差异。目前,主流的比较文本之间的差异主要有两大类。一类是基于编辑距离(Edit Distance)的,例如LD算法。一类是基于最长公共子串的(Longest Common Subsequence),例如Needleman/Wunsch算法等。
下面是LD算法的代码,用的是VB2005。代码格式修正于2012年1月6日。Public Class clsLD Private Shared mA() As Char Private Shared mB() As Char
Public Shared Function LD(ByVal A As String, ByVal B As String) As Integer
mA = A.ToCharArray mB = B.ToCharArray
Dim L(A.Length, B.Length) As Integer Dim i As Integer, j As Integer
For i = 1 To A.Length L(i, 0) = i Next For j = 1 To B.Length L(0, j) = j Next
For i = 1 To A.Length For j = 1 To B.Length If mA(i – 1) = mB(j – 1) Then L(i, j) = L(i – 1, j – 1) Else L(i, j) = Min(L(i – 1, j – 1), L(i – 1, j), L(i, j – 1)) + 1 End If Next Next
Return L(A.Length, B.Length) End Function
Public Shared Function Min(ByVal A As Integer, ByVal B As Integer, ByVal C As Integer) As Integer Dim I As Integer = A If I > B Then I = B If I > C Then I = C Return I End Function End Class
首先,我们定义一个委托 public delegate void SendMessage(Message poMsg); 光有委托不行,我们还得定义一个事件 public event SendMessage SendMessageEvent;
以上做好之后,我们还需要重载WndProc方法。 protected override void WndProc(ref Message m) { if ( m.Msg == WM_VSCROLL) { if (SendMessageEvent != null) { SendMessageEvent(m); } } base.WndProc(ref m); }
//如果拖动滚动条是垂直方向(因为这里只让行号滚动,所以只有垂直方向),就触发消息。 定义一个滚动方法。 public void Scroll(Message poMsg) { if (this.Handle != null) { poMsg.HWnd = this.Handle; WndProc(ref poMsg); } } 这样,我们的行号随滚动条滚动的功能就基本上实现了。下面是完整代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms;
namespace AdaEniac { public delegate void SendMessage(Message poMsg); public partial class adaLineIdTxt : RichTextBox { private int WM_HSCROLL = 0x0114; private int WM_VSCROLL = 0x0115; public event SendMessage SendMessageEvent; public adaLineIdTxt() { InitializeComponent(); } protected override void WndProc(ref Message m) { if ( m.Msg == WM_VSCROLL) { if (SendMessageEvent != null) { SendMessageEvent(m); } } base.WndProc(ref m); } public void Scroll(Message poMsg) { if (this.Handle != null) { poMsg.HWnd = this.Handle; WndProc(ref poMsg); } } } }
需要说明的是,我前天写的“RichTextBox知识–为RichTextBox添加行号”需要做部分修改。将“_LineId”换成“adaLineIdTxt ” 类型。然后,还需要在“AdaScrollRichTextBox ”里增加一个方法 public void LineIdScroll(Message poMsg) { if (poMsg.Msg == (int)wm.WM_VSCROLL) { _LineId.Scroll(poMsg); } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices;
namespace AdaWinControls { public partial class adScrollRichTextBox : System.Windows.Forms.RichTextBox { public event SendMessage SendMessageEvent; private bool _AutoLineId = true; public bool AutoLineId { set { _AutoLineId = value; } get { return _AutoLineId; } } private adLineIdTxt _LineId; public adLineIdTxt LineId { get { return _LineId; } } private bool _IsChecked = false; public bool IsChecked { get { return _IsChecked; } set { _IsChecked = value; } } public adScrollRichTextBox() { InitializeComponent(); InitializeLineId(); } private void InitializeLineId() { _LineId = new adLineIdTxt(); _LineId.Name = “LineId”; _LineId.Text = “1”; _LineId.Width = 40; _LineId.Dock = DockStyle.Left; _LineId.Font = this.Font; _LineId.ForeColor = Color.Green; _LineId.ReadOnly = true; _LineId.BackColor = Color.White; _LineId.TabStop = false; _LineId.BorderStyle = BorderStyle.None; _LineId.ScrollBars = RichTextBoxScrollBars.None; _LineId.Cursor = Cursors.Arrow; this.SelectionIndent = 40; this.Controls.Add(_LineId); } protected override void WndProc(ref Message m) { if (m.Msg == (int)ApiVariable.WM_HSCROLL || m.Msg == (int)ApiVariable.WM_VSCROLL || m.Msg == (int)ApiVariable.WM_MOUSEWHEEL || m.Msg == (int)ApiVariable.EM_SCROLL || m.Msg == (int)ApiVariable.BM_CLICK) { if (SendMessageEvent != null) { SendMessageEvent(m); } } base.WndProc(ref m); } public void Scroll(Message poMsg) { if (this.Handle != null) { poMsg.HWnd = this.Handle; WndProc(ref poMsg); } } public void LineIdScroll(Message poMsg) { if (poMsg.Msg == (int)ApiVariable.WM_VSCROLL) { _LineId.Scroll(poMsg); } } public void NewLine(string pcLineNo, string pcLine, Color poLineColor) { NewLine(pcLineNo, pcLine, poLineColor, Color.White); } public void NewLine(string pcLineNo, string pcLine, Color poLineColor, Color poBackColor) { this.SelectionIndent = 40; this.SelectionColor = poLineColor; this.SelectionBackColor = poBackColor; this.AppendText(pcLine + “\r\n”); this._LineId.NewLineNo(pcLineNo); } public void SetValue(string pcAllLine) { this.SelectionIndent = 40; this.Text = pcAllLine; this._LineId.Clear(); for (int i = 1; i <= this.Lines.Length; i++) { this._LineId.NewLineNo(i.ToString()); } } protected override void OnSizeChanged(EventArgs e) { _LineId.Top–; base.OnSizeChanged(e); } protected override void OnTextChanged(EventArgs e) { this.SelectionIndent = 40; this.SelectionHangingIndent = 40; if (_AutoLineId) { this._LineId.Clear(); for (int i = 0; i < this.Lines.Length; i++) { this._LineId.NewLineNo(i.ToString()); } } base.OnTextChanged(e); } #region RichTextBox_ScrollVariable private int _VPrePosition = 0; private int _HPrePosition = 0; // =================================================================== // for NativeWindow and PostMessageA private const int WM_HSCROLL = 0x114; private const int WM_VSCROLL = 0x115; private const int WM_MOUSEWHEEL = 0x20A; private const int WM_COMMAND = 0x111; // =================================================================== // for GetScroll and PostMessageA private const int WM_USER = 0x400; private const int SBS_HORZ = 0; private const int SBS_VERT = 1; // =================================================================== // for SubClassing private const int SB_THUMBPOSITION = 4; // =================================================================== // API Function: GetScrollPos() [DllImport(“user32.dll”)] private static extern int GetScrollPos(IntPtr hWnd, int nBar); // =================================================================== // API Function: PostMessageA() [DllImport(“user32.dll”)] private static extern bool PostMessageA(IntPtr hwnd, int wMsg, int wParam, int lParam); #endregion protected override void OnVScroll(EventArgs e) { VerticalScrollNew(this, this._LineId); base.OnVScroll(e); } private void VerticalScrollNew(RichTextBox sender, RichTextBox receiver) { int liPosition = GetScrollPos(sender.Handle, SBS_VERT); if (liPosition != _VPrePosition) { this._VPrePosition = liPosition; PostMessageA(receiver.Handle, WM_VSCROLL, SB_THUMBPOSITION + 0x10000 * liPosition, 0); } } } }