How to make a textbox non-selectable using C#

前端 未结 11 1860
轮回少年
轮回少年 2021-02-19 11:09

I\'m using C#/.NET for a Windows Forms application. I have a text box. How can I make the text box unselectable?

I don\'t want to disable the complete textbox.

11条回答
  •  野趣味
    野趣味 (楼主)
    2021-02-19 11:46

    The messages that cause text can be intercepted and blocked. I would have thought that EM_SETSEL would be all that is required. However, even when the mouse clicks and drags, there is no EM_SETEL message, but the text still selects. Possibly one of the messages has a pointer to a struct that contains the info.

    Note: I'm not sure if this prevents all ways to select text.

    public class TextBox2 : TextBox {
    
        private const int EM_SETSEL = 0x00B1;
        private const int WM_LBUTTONDBLCLK = 0x203;
        private const int WM_MOUSEMOVE = 0x200;
        private const int WM_KEYDOWN = 0x100;
        private const int VK_CONTROL = 0x11;
        private const int VK_SHIFT = 0x10;
    
        public TextBox2() {
            this.ShortcutsEnabled = false; // disabled right click menu
            this.Cursor = Cursors.Default;
    
        }
    
        protected override void OnGotFocus(EventArgs e) {
            base.OnGotFocus(e);
            HideCaret(this.Handle); // doesn't work from OnHandleCreated
        }
    
        [DllImport("user32.dll")]
        public static extern bool HideCaret(IntPtr hWnd);
    
        public override bool PreProcessMessage(ref Message msg) {
            // prevents the user from using the SHIFT or CTRL + arrow keys to select text
            if (msg.Msg == WM_KEYDOWN)
                return true;
    
            return base.PreProcessMessage(ref msg);
        }
    
        protected override void WndProc(ref Message m) {
            if (m.Msg == EM_SETSEL || m.Msg == WM_MOUSEMOVE || m.Msg == WM_LBUTTONDBLCLK)
                return;
    
            base.WndProc(ref m);
        }
    }
    

提交回复
热议问题