文本框不可点击但可编辑

roa*_*ter 0 c# textbox winforms

我有一个带有10个文本框的小表单,我将它们设置在右边的Tab顺序中,目前我希望它们以Tab To的方式.我想知道是否有办法设置文本框,因此除非它们被选中,否则无法选择它们进行编辑.ie ...我不希望最终用户能够点击文本框来编辑它们,我只希望它们可以通过Tabbing进行编辑.

Sri*_*vel 6

这应该可以解决问题

public partial class PoorTextBox : TextBox
{
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == (int) WM.LBUTTONDOWN)
        {
            return;//Eat mouse down events 
        }
        base.WndProc(ref m);
    }
}
Run Code Online (Sandbox Code Playgroud)

可以在此处找到窗口消息枚举.


没有继承怎么做TextBox:

class EatMouseDown : NativeWindow
{
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == (int)WM.LBUTTONDOWN)
        {
            return;
        }
        base.WndProc(ref m);
    }
}

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    new EatMouseDown().AssignHandle(textBox1.Handle);//Subclass a Handle
}
Run Code Online (Sandbox Code Playgroud)


如何做到没有任何继承:

清理部分省略,这也很重要.这可能是错误的但是有效.推荐的方法是使用继承.从.net fw src中提取所需的方法.

class EatMouseDown
{
    public delegate IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

    #region External methods...

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr SetWindowLong(HandleRef hWnd, int nIndex, WndProc wndproc);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr SetWindowLongPtr(HandleRef hWnd, int nIndex, WndProc wndproc);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr GetWindowLong(HandleRef hWnd, int nIndex);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr GetWindowLongPtr(HandleRef hWnd, int nIndex);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr DefWindowProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr CallWindowProc(IntPtr wndProc, IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

    #endregion

    private const int GWLP_WNDPROC = -4;
    private IntPtr handle;
    private IntPtr originalWndProc;
    private IntPtr currentWndProc;

    public static IntPtr SetWindowLongHelper(HandleRef hWnd, int nIndex, WndProc wndProc)
    {
        return IntPtr.Size == 4
            ? SetWindowLong(hWnd, nIndex, wndProc)
            : SetWindowLongPtr(hWnd, nIndex, wndProc);
    }

    public static IntPtr GetWindowLongHelper(HandleRef hWnd, int nIndex)
    {
        return IntPtr.Size == 4
            ? GetWindowLong(hWnd, nIndex)
            : GetWindowLongPtr(hWnd, nIndex);
    }

    internal void SubclassHandle(IntPtr handle)
    {
        this.handle = handle;
        this.originalWndProc = GetWindowLongHelper(new HandleRef(this, handle), GWLP_WNDPROC);
        SetWindowLongHelper(new HandleRef(this, handle), GWLP_WNDPROC, new WndProc(this.Callback));
        this.currentWndProc = GetWindowLongHelper(new HandleRef(this, handle), GWLP_WNDPROC);
    }

    private IntPtr Callback(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam)
    {
        var m = Message.Create(hwnd, msg, wparam, lparam);
        if (m.Msg == (int)WM.LBUTTONDOWN)
        {
            return IntPtr.Zero;
        }
        return CallWindowProc(originalWndProc, hwnd, msg, wparam, lparam);
    }
}

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    new EatMouseDown().SubclassHandle(textBox1.Handle);//Subclass a Handle
}
Run Code Online (Sandbox Code Playgroud)

  • @MatinLotfaliee - 当他有多个文本框时,你的路线不是那么漂亮或简单.至少在这条路线上,您可以创建控件,然后再也不用担心它的外观. (4认同)