Как добавить скроллбары в кастомный RichTextBox?

230
21 мая 2018, 17:10

Создаю свою компоненту richtextbox. Не могу понять как добавить вертикальный скроллбар?

 class ViewOnlyRichTextBox : RichTextBox
    {
        const int WM_SETFOCUS = 0x0007;
        const int WM_KILLFOCUS = 0x0008;
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_SETFOCUS) m.Msg = WM_KILLFOCUS;
            base.WndProc(ref m);
        }
    }
Answer 1

Встроенными средствами Windows Forms этого сделать нельзя. Однако WinAPI (поверх которого и построен WF) позволяет добавить полосу прокрутки к элементу управления без вмешательства в его содержимое и даже создания экземпляра ScrollBar.

Дело в том, что в WinAPI каждое окно и каждый элемент управления уже имеют вертикальную и горизонтальную полосы прокрутки, и надо просто попросить операционную систему их показать. Делается это с помощью задания флагов оконного стиля WS_HSCROLL и WS_VSCROLL для горизонтальной и вертикальной полос прокрутки соответственно.

Эти стили задаются через свойство CreateParams. Так как оно доступно только для чтения, переопределим его (благо, оно виртуальное):

class ViewOnlyRichTextBox : RichTextBox
{
    // ...
    const int WS_HSCROLL = 0x00100000;
    const int WS_VSCROLL = 0x00200000;
    const int WM_HSCROLL = 0x0114;
    const int WM_VSCROLL = 0x0115;
    const int SB_HORZ    = 0;
    const int SB_VERT    = 1;
    [DllImport("user32.dll")]
    private static extern int GetScrollPos(IntPtr hwnd, int nBar);
    protected override CreateParams CreateParams {
        get {
            CreateParams cp = base.CreateParams;
            cp.Style |= WS_VSCROLL;
            return cp;
        }
    }
}

Эти полосы прокрутки генерируют WndProc-сообщения WM_HSCROLL и WM_VSCROLL при любой горизонтальной и вертикальной прокрутке соответственно. Конкретное положение ползунков можно получить при помощи GetScrollPos(this.Handle, ...), где вместо многоточия надо подставить либо SB_HORZ, либо SB_VERT для указания на интересующую нас полосу.

READ ALSO
Не работает привязка DataGridComboBoxColumn ItemSource к списку

Не работает привязка DataGridComboBoxColumn ItemSource к списку

К Datagrid подключается коллекция с одним элементомОтображается только ячейка с датой

215
Программно создать RadioButton на TabControl c# [требует правки]

Программно создать RadioButton на TabControl c# [требует правки]

Как создать RadioButton на определенной вкладке TabPage, с определенными параметрами и события checked

166
Ошибка при загрузке страницы входа на сайте

Ошибка при загрузке страницы входа на сайте

Пытаемся получить корректный ответ от веб-сервера:

219
Вывод каталогов и файлов в один DataGrid

Вывод каталогов и файлов в один DataGrid

Суть такова, есть DataGrid и 2 списка с типом FileInfo и DirectoryInfo

196