How to Hide ScrollBar of RichtextBox
-
Dear CPians, I want to hide RichtextBox's ScrollBar or set its width = 0, since I am scrolling the RichtextBox programetically in runtime using
API
methods (SetScrollPos
,GetScrollPos
,PostMessageA
). How to achieve this? Thanks in advance, Regards, Jay. -
Dear CPians, I want to hide RichtextBox's ScrollBar or set its width = 0, since I am scrolling the RichtextBox programetically in runtime using
API
methods (SetScrollPos
,GetScrollPos
,PostMessageA
). How to achieve this? Thanks in advance, Regards, Jay. -
This would not solve my purpose. Actually I want to syncronise the scrolling of two
RichTextBoxes
, sayRichTextBox1
andRichTextBox2
I am overridingWndProc
method ofRichTextBox1
and sendingSystem.Windows.Forms.Message m
toRichTextBox2
by raising anevent
and passingm.WParam
,m.LParam
. If I setRichTextBox2.ScrollBars
=None
, the above would not work. -
This would not solve my purpose. Actually I want to syncronise the scrolling of two
RichTextBoxes
, sayRichTextBox1
andRichTextBox2
I am overridingWndProc
method ofRichTextBox1
and sendingSystem.Windows.Forms.Message m
toRichTextBox2
by raising anevent
and passingm.WParam
,m.LParam
. If I setRichTextBox2.ScrollBars
=None
, the above would not work.What does synchronization have to do with "How to Hide ScrollBar of RichtextBox", which is what your subject says? The first reply answered your subject. You don't pass a
Message
toWndProc
. TheRichTextBox
encapsulates the Rich Edit common control, which manages the scroll bars itself. You only need to P/InvokeSendMessage
(orSetScrollPos
, as you asked about before) and set the scroll position. This results in the scroll messages being sent and the scroll bars adjusted automatically, all something done by the Rich edit control. The only reason to overrideWndProc
is to handle theWM_HSCROLL
(0x0114) andWM_VSCROLL
(0x0115) messages. As documented in the Platform SDK, the high-order word is the actual position, where the low-order word is the scrolling request. You should read the documentation for these two messages (though they are alike) in the Platform SDK on MSDN[^]. What you then do is call the P/Invoke'dSendMessage
(see pinvoke.net[^] if you need help with the signature) with the same message (WM_HSCROLL
orWM_VSCROLL
) and the same parameters. Do not callWndProc
directly.SendMessage
(or usePostMessage
for asynchronous operations, which should work in most cases) does this.Microsoft MVP, Visual C# My Articles
-
What does synchronization have to do with "How to Hide ScrollBar of RichtextBox", which is what your subject says? The first reply answered your subject. You don't pass a
Message
toWndProc
. TheRichTextBox
encapsulates the Rich Edit common control, which manages the scroll bars itself. You only need to P/InvokeSendMessage
(orSetScrollPos
, as you asked about before) and set the scroll position. This results in the scroll messages being sent and the scroll bars adjusted automatically, all something done by the Rich edit control. The only reason to overrideWndProc
is to handle theWM_HSCROLL
(0x0114) andWM_VSCROLL
(0x0115) messages. As documented in the Platform SDK, the high-order word is the actual position, where the low-order word is the scrolling request. You should read the documentation for these two messages (though they are alike) in the Platform SDK on MSDN[^]. What you then do is call the P/Invoke'dSendMessage
(see pinvoke.net[^] if you need help with the signature) with the same message (WM_HSCROLL
orWM_VSCROLL
) and the same parameters. Do not callWndProc
directly.SendMessage
(or usePostMessage
for asynchronous operations, which should work in most cases) does this.Microsoft MVP, Visual C# My Articles
Dear Heath, I am doing the same. Please refer to the code below:
protected override void WndProc(ref System.Windows.Forms.Message m) { if(m.Msg == WM_MOUSEWHEEL) //WM_MOUSEWHEEL 0x020a { if(Control.ModifierKeys != Keys.Control) { MouseWheelRollingEventArgs e = new MouseWheelRollingEventArgs(m.WParam, m.LParam); MouseWheelRolling(this, e); base.WndProc(ref m); } else { return; } } else if( m.Msg == WM_VSCROLL ) { //process similarly for scroll, below //..... //..... base.WndProc (ref m); } else { base.WndProc (ref m); } }
private void rtb_MouseWheelRolling(object sender, TextEditor.MouseWheelRollingEventArgs e) { //note : lineSrNo is the other richTextBox I am syncronising const int WM_MOUSEWHELL = 0x020a; PostMessageA((int)lineSrNo.Handle,WM_MOUSEWHELL, (int) e.wp, (int) e.lp); }
rtb
andlineSrNo
are the tworichTextBoxes
, I want to syncronise.lineSrNo richTextBox
contains the lineNumbers ofrtb richTextBox
. When ever user scrolls thertb richTextBox
(usingMouseWheel rolling
orScrollBar
) correspondinglylineSrNo richTextBox
should also get scrolled. Line numbers are added in thelineSrNo richTextBox
when ever user enters any line inrtb richTextBox
.lineSrNo richTextBox
Locked
property is set toTrue
and I am scrolling it programetically. I am able to acheive the target, but I do not wantscrollBar
inlineSrNo richTextBox
That is the reason, I am asking the way out to hide the scrollBar of the richTextBox or set its width to 0. Regards, Jay -
Dear Heath, I am doing the same. Please refer to the code below:
protected override void WndProc(ref System.Windows.Forms.Message m) { if(m.Msg == WM_MOUSEWHEEL) //WM_MOUSEWHEEL 0x020a { if(Control.ModifierKeys != Keys.Control) { MouseWheelRollingEventArgs e = new MouseWheelRollingEventArgs(m.WParam, m.LParam); MouseWheelRolling(this, e); base.WndProc(ref m); } else { return; } } else if( m.Msg == WM_VSCROLL ) { //process similarly for scroll, below //..... //..... base.WndProc (ref m); } else { base.WndProc (ref m); } }
private void rtb_MouseWheelRolling(object sender, TextEditor.MouseWheelRollingEventArgs e) { //note : lineSrNo is the other richTextBox I am syncronising const int WM_MOUSEWHELL = 0x020a; PostMessageA((int)lineSrNo.Handle,WM_MOUSEWHELL, (int) e.wp, (int) e.lp); }
rtb
andlineSrNo
are the tworichTextBoxes
, I want to syncronise.lineSrNo richTextBox
contains the lineNumbers ofrtb richTextBox
. When ever user scrolls thertb richTextBox
(usingMouseWheel rolling
orScrollBar
) correspondinglylineSrNo richTextBox
should also get scrolled. Line numbers are added in thelineSrNo richTextBox
when ever user enters any line inrtb richTextBox
.lineSrNo richTextBox
Locked
property is set toTrue
and I am scrolling it programetically. I am able to acheive the target, but I do not wantscrollBar
inlineSrNo richTextBox
That is the reason, I am asking the way out to hide the scrollBar of the richTextBox or set its width to 0. Regards, JayHave you tried getting the handle to the scroll bars (use
FindWindowEx
, or some controls actually define a message to return the scrollbar handle) and simply P/InvokingSetWindowsLongPtr
passing~WS_VISIBLE
OR'ed with the previous style? That would literally hide the scrollbars but should still respond to scroll messages.Microsoft MVP, Visual C# My Articles
-
Have you tried getting the handle to the scroll bars (use
FindWindowEx
, or some controls actually define a message to return the scrollbar handle) and simply P/InvokingSetWindowsLongPtr
passing~WS_VISIBLE
OR'ed with the previous style? That would literally hide the scrollbars but should still respond to scroll messages.Microsoft MVP, Visual C# My Articles
I tried getting the
Handle
ofrichTextBox's
scrollBar
using the following code, but could not succeed. Can you please point out where am I going wrong?public class ScrollBarHiddenRTB : System.Windows.Forms.RichTextBox { [System.Runtime.InteropServices.DllImport("user32.dll")] public static extern IntPtr FindWindowEx(IntPtr parent, IntPtr next, string sClassName, IntPtr sWindowTitle); [System.Runtime.InteropServices.DllImport("user32.dll")] public static extern int SetWindowLongPtr( IntPtr hWnd, int nIndex, int dwNewLong); private const int WS_VISIBLE = 0x10000000; public ScrollBarHiddenRTB() : base() { this.HandleCreated += new EventHandler(CreateRTBHandle); } private void CreateRTBHandle(object sender, EventArgs e) { ScrollBarHiddenRTB self = sender as ScrollBarHiddenRTB; System.Diagnostics.Debug.Assert(self != null); IntPtr scrollHandle = FindWindowEx(self.Handle, IntPtr.Zero, "ScrollBar", IntPtr.Zero); if(scrollHandle != IntPtr.Zero) { MessageBox.Show(scrollHandle.ToString()); } } }
Regards, Jay.
-
I tried getting the
Handle
ofrichTextBox's
scrollBar
using the following code, but could not succeed. Can you please point out where am I going wrong?public class ScrollBarHiddenRTB : System.Windows.Forms.RichTextBox { [System.Runtime.InteropServices.DllImport("user32.dll")] public static extern IntPtr FindWindowEx(IntPtr parent, IntPtr next, string sClassName, IntPtr sWindowTitle); [System.Runtime.InteropServices.DllImport("user32.dll")] public static extern int SetWindowLongPtr( IntPtr hWnd, int nIndex, int dwNewLong); private const int WS_VISIBLE = 0x10000000; public ScrollBarHiddenRTB() : base() { this.HandleCreated += new EventHandler(CreateRTBHandle); } private void CreateRTBHandle(object sender, EventArgs e) { ScrollBarHiddenRTB self = sender as ScrollBarHiddenRTB; System.Diagnostics.Debug.Assert(self != null); IntPtr scrollHandle = FindWindowEx(self.Handle, IntPtr.Zero, "ScrollBar", IntPtr.Zero); if(scrollHandle != IntPtr.Zero) { MessageBox.Show(scrollHandle.ToString()); } } }
Regards, Jay.
A few tips, first: don't use
<code>
within a<pre>
tag. The former is for in-line code, and the latter is for block code. Also, don't handle events for the control class you're extending. It is much faster and you have more control by overridingOnHandleCreated
, or any of theOn_EventName_
handlers defined by the base class. This lets you callbase.OnHandleCreated
if you want (in this case you should, but there are times you might not want to when overridingWndProc
, for example). It's also much faster code. To invoke a delegate, many, many IL instructions are required. To call a virtual function it's one:callvirt
. The Rich Edit control doesn't expose its scroll bars in the same way as other controls. If you look at the message documentation for the Rich Edit control like I mentioned before you might notice anEM_SHOWSCROLLBAR
message you can send by P/InvokingSendMessage
like so:[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hWnd, int msg, ScrollBar sb, bool show);
private enum ScrollBar
{
Horizontal,
Vertical
}Please note that this signature is not 64-bit compatible, however. In such a case, both return value and the last two params should be
IntPtr
s, which is a system-dependent bit width. Then, just sendEM_SHOWSCROLLBAR
(0x0460) with the params you require.Microsoft MVP, Visual C# My Articles
-
A few tips, first: don't use
<code>
within a<pre>
tag. The former is for in-line code, and the latter is for block code. Also, don't handle events for the control class you're extending. It is much faster and you have more control by overridingOnHandleCreated
, or any of theOn_EventName_
handlers defined by the base class. This lets you callbase.OnHandleCreated
if you want (in this case you should, but there are times you might not want to when overridingWndProc
, for example). It's also much faster code. To invoke a delegate, many, many IL instructions are required. To call a virtual function it's one:callvirt
. The Rich Edit control doesn't expose its scroll bars in the same way as other controls. If you look at the message documentation for the Rich Edit control like I mentioned before you might notice anEM_SHOWSCROLLBAR
message you can send by P/InvokingSendMessage
like so:[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hWnd, int msg, ScrollBar sb, bool show);
private enum ScrollBar
{
Horizontal,
Vertical
}Please note that this signature is not 64-bit compatible, however. In such a case, both return value and the last two params should be
IntPtr
s, which is a system-dependent bit width. Then, just sendEM_SHOWSCROLLBAR
(0x0460) with the params you require.Microsoft MVP, Visual C# My Articles
Dear Heath, Thanks for the tips. I will keep in mind for future postings. I tried sending
EM_SHOWSCROLLBAR
message by P/InvokingSendMessage
, But It did not work in my case. However, I could solve the problem by P/InvokingGetSystemMetrics
,CreateRectRgn
,SetWindowRgn
. I am pasting the code for future reference.private const int SM_CXVSCROLL = 2;
//
[System.Runtime.InteropServices.DllImport("user32")]
public static extern int GetSystemMetrics(int nIndex);
//[System.Runtime.InteropServices.DllImport("gdi32")]
public static extern int CreateRectRgn(int X1, int Y1, int X2, int Y2) ;
//[System.Runtime.InteropServices.DllImport("user32")]
public static extern int SetWindowRgn(int hwnd, int hRgn, bool bRedraw);public void HideVerticalScrollBar(RichTextBox rtb)
{
//get scroll bar width
int scrollbarWidth = WinApi.GetSystemMetrics(SM_CXVSCROLL);
// handle of the region
int handleRgn = WinApi.CreateRectRgn(0, 0, rtb.Width , rtb.Height);
//change the width of the rtb
rtb.Width += scrollbarWidth;
//set window region
WinApi.SetWindowRgn(rtb.Handle.ToInt32(), handleRgn, true);
}Regards, Jay.