Reputation: 639
In C# WinForms, I have a custom RichTextBox where I handle middle-mouse scrolling by myself. When it's done, I want to show my own cursor. I switch to this cursor in the MouseDown event, when the middle button is pressed.
void richText_MouseDown(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Middle) {
Cursor.Current = MainForm.cursors["hand_NS"];
}
}
However, the text box then instantly switches to the Windows "arrow" cursor. This seems to be part of the RichTextBox autom. behavior, either in MouseDown or in MouseMove. I can override this by constantly showing my cursor in MouseMove, but it looks flickery, as the two cursors fight each other. Can I block this automatic switch to the "arrow" cursor somehow?
EDIT: Tried setting the Cursor property:
void richText_MouseDown(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Middle) {
richText.Cursor = MainForm.cursors["hand_NS"];
//Cursor.Current = MainForm.cursors["hand_NS"];
}
}
Restoring the I-beam cursor:
void richText_MouseUp(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Middle) {
richText.Cursor = Cursors.IBeam;
//Cursor.Current = Cursors.IBeam;
}
}
Upvotes: 2
Views: 404
Reputation: 639
Finally got it to work decently (virtually no flicker) by throwing at it all the artillery I could find. What's done in MouseMove (below) is also done in MouseDown.
public const uint LVM_SETHOTCURSOR = 4158;
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
void richText_MouseMove(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Middle) {
this.TopLevelControl.Cursor = Cursors.PanNorth;
richText.Cursor = Cursors.PanNorth;
SendMessage(richText.Handle, LVM_SETHOTCURSOR, IntPtr.Zero, Cursors.PanNorth.Handle);
Cursor.Current = Cursors.PanNorth;
}
}
Overriding the SETCURSOR message in the RTB control:
[DllImport("user32.dll")]
public static extern int SetCursor(IntPtr cursor);
private const int WM_SETCURSOR = 0x20;
protected override void WndProc(ref System.Windows.Forms.Message m) {
if (m.Msg == WM_SETCURSOR) {
SetCursor(Cursors.PanNorth.Handle);
m.Result = new IntPtr(1);
return;
}
base.WndProc(ref m);
}
Sources:
ListView Cursor changing & flickering
Mouse cursor flickers over selected text - how to prevent this?
Upvotes: 0