C# 在C中使用自定义滚动条处理RichTextBox#

C# 在C中使用自定义滚动条处理RichTextBox#,c#,scrollbar,controls,richtextbox,C#,Scrollbar,Controls,Richtextbox,最近我在做一个带有自定义GUI的表单项目。(MetroFrameWork)它有自己的文本框组件,但我更喜欢RichTextBox。问题是,如果我将其设置为可见,它将使用windows传统滚动条。我不想用这个。幸运的是,框架有自己的滚动条组件和我想要的皮肤。我可以设置没有滚动条的RichTextBox(ScrollBars属性设置为NONE),并将停靠在RichTextBox右侧的独立自定义滚动条设置为RichTextBox。我没有找到任何好的解决方案,如何将自定义滚动条控件派生或附加到我的遗留R

最近我在做一个带有自定义GUI的表单项目。(MetroFrameWork)它有自己的文本框组件,但我更喜欢RichTextBox。问题是,如果我将其设置为可见,它将使用windows传统滚动条。我不想用这个。幸运的是,框架有自己的滚动条组件和我想要的皮肤。我可以设置没有滚动条的RichTextBox(ScrollBars属性设置为NONE),并将停靠在RichTextBox右侧的独立自定义滚动条设置为RichTextBox。我没有找到任何好的解决方案,如何将自定义滚动条控件派生或附加到我的遗留RichTextBox,就好像它的行为与RTB的内置滚动条一样。所以我试着用手来做。当填充RTB时,我可以计算自定义滚动条的最小值、最大值、SmallChange、LargeChange属性,这样它就可以设置滚动条的拇指大小。我实现了用cathich custom scrollbar的滚动事件模拟滚动方法,然后可以使用互操作服务(user32.dll)垂直滚动RTB的文本内容(只需要垂直滚动):

但这仅在滚动或鼠标滚轮滚动时发生。当您使用键盘箭头滚动时不会

你们能告诉我一个方法我怎么能做到这一点吗?或者我的方法完全错误,也许有办法,我可以从自定义滚动条的控件派生/继承遗留RTB控件,这样我就可以在RTB的滚动条属性设置为“无”时将自定义滚动条完全附加到richtextbox。(如此内置的滚动条不可见)


很抱歉,我解释得太长了,我到处搜索解决方案,好几天都没有成功…

您尝试过捕获密钥点吗?按鼠标滚轮上的上下键并调整滚动条位置按键盘上的箭头键不会发送
WM_*SCROLL
消息。您必须处理按键输入消息,如
WM\u KEYDOWN
。当RichTextBox包含100%的即时滚动支持时,你会奇怪为什么要完成所有这些工作。不需要代码。@Cody不需要。不需要。当滚动条不可见时,RichTextBox通常不提供任何滚动信息。我想知道如何模仿它。如何在客户端区域更改时获取滚动信息。(文本向上或向下)嗯,是的,如果没有滚动条,你就不需要它来滚动。你试过捕获密钥点吗?按鼠标滚轮上的上下键并调整滚动条位置按键盘上的箭头键不会发送
WM_*SCROLL
消息。您必须处理按键输入消息,如
WM\u KEYDOWN
。当RichTextBox包含100%的即时滚动支持时,你会奇怪为什么要完成所有这些工作。不需要代码。@Cody不需要。不需要。当滚动条不可见时,RichTextBox通常不提供任何滚动信息。我想知道如何模仿它。如何在客户端区域更改时获取滚动信息。(文本向上或向下)是的,如果没有滚动条,你就不需要它来滚动。
private void metroScrollBarRichTextBoxMain_Scroll(object sender, ScrollEventArgs e)
{
    uint nPos = (uint)metroScrollBarRichTextBoxMain.Value * (uint)Math.Round((decimal)richTextBoxMain.Font.GetHeight(), 1, MidpointRounding.AwayFromZero);
    uint wParam = (uint)WindowMessageConstants.ScrollBarCommands.SB_THUMBPOSITION | nPos << 16;
    SendMessage(richTextBoxMain.Handle, WindowMessageConstants.WM_VSCROLL, (IntPtr)wParam, IntPtr.Zero);
}
protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);

    if (m.Msg == WindowMessageConstants.WM_VSCROLL || m.Msg == WindowMessageConstants.WM_HSCROLL ||
            m.Msg == WindowMessageConstants.WM_MOUSEWHEEL)
    {
         ...do something here
    }
}