make richtextbox not respond to mouse events - c#

I am developing an application and in one of its forms i have placed a richtextbox that has some text that the user will be typing,I have set richtextbox's ReadOnly property to true, form's keypreview to true and I have handled forms keypress event to apply blue color to the correct keypress and red color to the wrong keypress to current character in the richtextbox. now i need to restrict the users to only typing the text, they should not be able to select richtextbox text using mouse caz that way they can mess with my application.
tnx in advance

You need to subclass RichTextBox and disable processing of mouse events.
public class DisabledRichTextBox : System.Windows.Forms.RichTextBox
{
// See: http://wiki.winehq.org/List_Of_Windows_Messages
private const int WM_SETFOCUS = 0x07;
private const int WM_ENABLE = 0x0A;
private const int WM_SETCURSOR = 0x20;
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if (!(m.Msg == WM_SETFOCUS || m.Msg == WM_ENABLE || m.Msg == WM_SETCURSOR))
base.WndProc(ref m);
}
}
It will act like a label, preventing focus, user input, cursor change, without being actually disabled.
You also need to keep ReadOnly = true to disable editing.

Related

Capturing key presses in datagridview cells in c#

I'm trying to develop a results box that pops when I start to type in cell in the datagridview, something similar to what Chrome does when you type in the address bar.
I've done most of it, the main problem I'm having is trying to capture and handle arrow key presses (up and down).
I've caste the cell control to a textbox so I can grab key presses and pass them to the result box so it know what results to display.
tx.PreviewKeyDown += new PreviewKeyDownEventHandler(tx_PreviewKeyDown);
tx.KeyDown += new KeyEventHandler(tx_KeyDown);
tx.KeyPress += new KeyPressEventHandler(tx_KeyPress);
that works all fine, the problem is, when I press the arrow key down, the tx_PreviewKeyDown captures it, then it disappears until its caught in the datagridview_KeyUp event, by then, its too late and the datagridview has shifted the active cell downwards.
I can handle the event in the tx_PreviewKeyDown and pass that down to move the highlighted value in the result box fine, but what I need to do is prevent it from shifting the active cell downwards into the new row.
I need to be able to cancel the keypress, but the PreviewKeyDown doesn't have a e.Handle flag, either that I need to find what KeyDown event is fired after the tx_PreviewKeyDown but before datagridview_KeyUp event. Something handles that arrow key, but what?!
You can always extend the DataGridView and use the WndProc method:
class exDataGridView : DataGridView
{
private const int WM_KEYDOWN = 0x100;
private const int WM_KEYUP = 0x101;
private const int KEYUP = 38;
private const int KEYDOWN = 40;
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_KEYDOWN:
if (m.WParam == (IntPtr)KEYDOWN)
{
// Do key down stuff...
return;
}
else if (m.WParam == (IntPtr)KEYUP)
{
// Do key up stuff...
return;
}
break;
}
base.WndProc(ref m);
}
}
Try to use the ff. events
CellBeginEdit - this event will fire when you start typing in the cell,
CellEndEdit - when you lost focus in the cell,
DataError - if error occur during data input

how to disable System's caps-lock notification on textbox password field

In Winforms Textbox, I have defined new ToolTip and configured it. I have set the PasswordChar to '*'. However, when caps lock is on, two tooltip is shown. One of them is mine the other one is system's default tooltip notification. I only want to show my tooltip. I want to disable system's tooltip. How can I disable it?
One way is to derive your own textbox control from the existing one and handle the EM_SHOWBALLOONTIP message. Then just drag this control onto your form instead of the regular textbox control.
public partial class PasswordTextBox : TextBox
{
private const int EM_SHOWBALLOONTIP = 0x1503;
protected override void WndProc(ref Message m)
{
if (m.Msg == EM_SHOWBALLOONTIP)
{
m.Result = (IntPtr)0;
return;
}
base.WndProc(ref m);
}
public PasswordTextBox()
{
InitializeComponent();
}
}

WM_MOUSEWHEEL message does not propagate to parent

I have a RichTextBox with ScrollBars set to None. According to MSDN
The DefWindowProc function propagates the message to the window's
parent. There should be no internal forwarding of the message, since
DefWindowProc propagates it up the parent chain until it finds a
window that processes it.
I interpret this as, I should not need to hook into the message pump (IMessageFilter) and manually forward WM_MOUSEWHEEL events to the parent Form containing the richtextbox. When I am inside of RichTextBox and perform a mouse scroll, the Form does not scroll. Why not? How can I get the Form to scroll?
Keep in mind that scrollbars are set to none for RichTextBox and enabled for the Form. So why isn't the form getting the scroll event?
public partial class Form4 : Form
{
public Form4()
{
InitializeComponent();
this.AutoScroll = true;
richTextBox1.ScrollBars = RichTextBoxScrollBars.None;
}
}
For my derived TextBox, rather than ignore the mouse wheel as the above does, I instead wanted to pass it on up to my Parent control... which is what the TextBox SHOULD do in any case, in my opinion. Here's what I put in my derived TextBox's WndProc:
switch (m.Msg)
{
case 0x020A: // WM_MOUSEWHEEL
case 0x020E: // WM_MOUSEHWHEEL
if (this.ScrollBars == ScrollBars.None && this.Parent != null)
m.HWnd = this.Parent.Handle; // forward this to your parent
base.WndProc(ref m);
break;
default:
base.WndProc(ref m);
break;
}
The form doesn't scroll because the RichTextBox handles the WM_MOUSEWHEEL itself and doesn't call DefWindowProc to forward it to its parent. Apparently that doesn't change when disabling the scroll bars.
So you either need to implement an IMessageFilter or create a subclass of RichTextEdit that will forward the WM_MOUSEWHEEL as shown here:
public class NoScrollRichTextBox : RichTextBox
{
const int WM_MOUSEWHEEL = 0x020A;
protected override void WndProc(ref Message m)
{
// This will completely ignore the mouse wheel, which will disable zooming as well
if (m.Msg != WM_MOUSEWHEEL)
base.WndProc(ref m);
}
}

Activate a form and process button click at the same time?

I'm using Windows Forms in C#.
I have a main form with a couple of toolbars that contain toolStripButtons. After working with another form that contains data, the main form loses focus and clicking on a toolStripButton does not trigger OnClick event: the first click activates the main form, and only the second click actually pushes the button. I need the user to click a button only once to trigger a Click event, any ideas on how to do that? Thanks.
Notes:
I was using MDI and there were no problems clicking on the parent's form buttons. But now the paramount is to have forms freely floating across multiple displays.
The worker forms have the main form as the Owner property, this way they stay on top of the main form.
When I click on the button of an inactive form, none of MouseHover, MouseEnter, MouseDown nor MouseUp fires. It's just main form's Activate event that fires.
There is a treeView (inside a tabControl, inside a splitContainer, inside a panel), on the main form. Its items are selected upon a first mouse click, even if the main form is inactive. I guess not all controls are equal!
What you need to do is create a class that inherits ToolStrip and handles the WndProc. This is one way to do it. There are others.
private class MyToolStrip : ToolStrip
{
private const uint WM_LBUTTONDOWN = 0x201;
private const uint WM_LBUTTONUP = 0x202;
private static bool down = false;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_LBUTTONUP && !down)
{
m.Msg = (int)WM_LBUTTONDOWN;
base.WndProc(ref m);
m.Msg = (int)WM_LBUTTONUP;
}
if (m.Msg == WM_LBUTTONDOWN) down = true;
if (m.Msg == WM_LBUTTONUP) down = false;
base.WndProc(ref m);
}
}
I've also seen this solution:
protected override void WndProc(ref Message m)
{
// WM_MOUSEACTIVATE = 0x21
if (m.Msg == WM_MOUSEACTIVATE && this.CanFocus && !this.Focused)
this.Focus();
base.WndProc(ref m);
}
I ran into this at the last place I worked, I think the solution I came up with worked more like the latter, but I don't have access to the exact code I used.
if u have Form without borders, so this logic was working for you built in :)
form.FormBorderStyle = FormBorderStyle.None

RichTextBox & Disabling Mouse Scrolling

I want to use the mouse middle button to clear a RichTextBox, but it also activates a mouse scrolling functionality similar to what you find in web broswers. When the vertical scrollbar is visible (there's enough data) and you press the middle button in the mouse a scrolling cursor appears and you can scroll up or down by moving the cursor up or down. How do I disable the mouse scrolling?
Mouse scrolling seems to be a Windows (or mouse driver) feature, so how can I stop the MouseDown event (if the mouse middle button is pressed) from reaching whatever routine is responsible for the mouse scrolling?
Check for 0x207 and 0x208, middle button down and up:
using System;
using System.Windows.Forms;
class MyRtb : RichTextBox {
protected override void WndProc(ref Message m) {
if (m.Msg == 0x207) this.Clear();
else if (m.Msg != 0x208) base.WndProc(ref m);
}
}
No scrolling RichTextBox, just Inherit from RichTextBox and you done.
public class NoScrollRichTextBox : RichTextBox
{
const int WM_MOUSEWHEEL = 0x020A;
protected override void WndProc(ref Message m)
{
// This will completely ignore the mouse wheel, which will disable zooming as well
if (m.Msg != WM_MOUSEWHEEL)
base.WndProc(ref m);
}
}

Categories

Resources