0

我一直在尝试制作一个自定义 TextBox 组件,该组件允许我在 TextBox 的输入字段中包含一段静态文本,因此不允许用户更改它。

我发现我必须操纵/挂钩键输入事件(包括 WndProc)。

具体来说,我的目标是防止用户粘贴替换、剪切、删除可以“停靠”(或不停靠)到 TextBox 开头或结尾的静态文本。

我尝试了很多事情,但我一直面临的问题是我无法推断出选择的结束位置。

我目前拥有的(启发/基于TNumEditBox):

public class LibraryComboBox : HybridComboBox //Ignore the parent class' name; it is basically a ComboBox that supports the ReadOnly attribute
{
    public LibraryComboBox()
        : base()
    { }

    public String SelectedLibrary { get; set; } //Static text
    public TextPosition TextPosition = TextPosition.None; //"Docking" position

    private const int WM_CHAR = 0x0102;
    private const int WM_CUT = 0x0300;
    private const int WM_COPY = 0x0301;
    private const int WM_PASTE = 0x0302;
    private const int WM_CLEAR = 0x0303;

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_PASTE)
        {
            //TODO: Prevent overwriting the static part
        }
        else if (m.Msg == WM_CUT)
        {
            //TODO: Prevent cutting over the static part
        }
        else if (m.Msg == WM_CLEAR)
        {
            base.OnTextChanged(EventArgs.Empty);
        }
        else
        {
            base.WndProc(ref m);
        }
    }

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (keyData == (Keys)Shortcut.CtrlV)
        {

            string text = Clipboard.GetText();

            for (int k = 0; k < text.Length; k++)
            {
                SendCharKey(text[k]);
            }
            return true;
        }
        else if (keyData == (Keys)Shortcut.CtrlC)
        {
            Clipboard.SetText(this.SelectedText);
            return true;
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);

        if (!this.ReadOnly)
        {
            if (e.KeyData == Keys.Delete || e.KeyData == Keys.Back)
            {
                //TODO: Remove corresponding characters
                e.SuppressKeyPress = true;  // does not transform event to KeyPress, but to KeyUp
            }
        }
    }

    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        base.OnKeyPress(e);

        if (this.ReadOnly)
        {
            return;
        }

        //TODO: Prevent any unauthorized changes to the library path

        if (this.SelectionStart < this.Text.IndexOf(this.SelectedLibrary))
            e.Handled = true;
    }

    private void SendCharKey(char c)
    {
        Message msg = new Message();

        msg.HWnd = this.Handle;
        msg.Msg = WM_CHAR;
        msg.WParam = (IntPtr)c;
        msg.LParam = IntPtr.Zero;

        base.WndProc(ref msg);
    }
}

public enum TextPosition
{
    None = 0,
    Left = 1,
    Right = 2
}
4

0 回答 0