-
Notifications
You must be signed in to change notification settings - Fork 4
/
ScrollRTB.cs
82 lines (71 loc) · 2.83 KB
/
ScrollRTB.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
This file is part of TorqueDev.
TorqueDev is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
TorqueDev is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with TorqueDev. If not, see <http://www.gnu.org/licenses>
EXCEPTIONS TO THE GPL: TorqueDev links in a number of third party libraries,
which are exempt from the license. If you want to write closed-source
third party modules that you are going to link into TorqueDev, you may do so
without restriction. I acknowledge that this technically allows for
one to bypass the open source provisions of the GPL, but the real goal
is to keep the core of TorqueDev free and open. The rest is up to you.
*/
using System;
using System.Windows.Forms;
namespace TSDev {
/// <summary>
/// Summary description for ScrollableRichTextbox.
/// </summary>
internal class ScrollRTB : System.Windows.Forms.RichTextBox {
// constants for the message sending
const int WM_VSCROLL = 0x0115;
const int WM_LBUTTONDOWN = 0x0201;
const int WM_SETFOCUS = 0x0007;
const int WM_KILLFOCUS = 0x0008;
readonly IntPtr SB_ENDSCROLL = (IntPtr)8;
readonly IntPtr SB_BOTTOM = (IntPtr)7;
// flag we use to determine if we can scroll
bool _scrollable = true;
// locking object
object _scrollLock = new object();
public void AppendText(string text, bool scrollToEnd) {
lock(_scrollLock) {
if(IntPtr.Zero != base.Handle) {
decimal length = base.Text.Length + text.Length;
if(length >= base.MaxLength) base.Clear();
//base.Text += text;
base.AppendText(text);
if(_scrollable && scrollToEnd) {
if(IntPtr.Zero != base.Handle) {
base.SelectionStart = base.Text.Length;
Message m = Message.Create(base.Handle, WM_VSCROLL, SB_BOTTOM, IntPtr.Zero);
base.WndProc(ref m);
}
}
}
}
}
protected override void WndProc(ref Message m) {
// if we're in a scroll set the scrolling flag to false & skip the
// auto scroll
if((m.Msg == WM_LBUTTONDOWN) || m.Msg == WM_VSCROLL && m.WParam != SB_BOTTOM) {
_scrollable = false;
}
// if we are done scrolling, set the falg to true & do the scrolling
if(m.Msg == WM_VSCROLL && m.WParam == SB_ENDSCROLL) {
_scrollable = true;
}
// this keeps the user from setting the cursor in the textbox
// because that causes problems if they do
//if(m.Msg == WM_SETFOCUS && base.ReadOnly) m.Msg = WM_KILLFOCUS;
base.WndProc (ref m);
}
}
}