Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# Windows Forms
Войти
Регистрация
Восстановить пароль
 
micron
1 / 1 / 2
Регистрация: 16.04.2014
Сообщений: 19
#1

Свой VScrollBar для TextBox

26.05.2015, 14:58. Просмотров 330. Ответов 0
Метки нет (Все метки)

Добрый день!
Требуется TextBox с вертикальным скроллбаром нестандартного вида. Начал создавать свою библиотеку компонентов, сам VScrollBar требуемого вида и функционала сделал, TextBox использую стандартный.
Теперь требуется связать их между собой.

Скроллинг TextBox'а посредством своего скроллбара сделал без проблем используя сообщение EM_LINESCROLL:
C#
1
2
3
4
5
const int EM_LINESCROLL = 0x00B6;
[DllImport("user32.dll")]
static extern int SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
...
SendMessage(textBox1.Handle, EM_LINESCROLL, 0, VScrollBar1.Value);
Но помимо "прямого" скролинга есть и "обратный", когда скролл должен менять свое положение в зависимости от перемещения курсора по TextBox'у.
С горем пополам кое-как справился с навигацией по тексту обычными стрелочками вверх/вниз/влево/вправо. Для этого искал номер строки, на которой стоит курсор
C#
1
textBox1.GetLineFromCharIndex(textBox1.GetFirstCharIndexOfCurrentLine())
Но вот при обработке PageUp/PageDown полный финиш... При нажатии этих клавиш прокрутка TextBox'а происходит, а вот номер строки, на которой расположен курсор, может вообще не измениться. Естественно, вся моя тактика отслеживания курсора пошла коту под хвост.

Вопрос:
1. Можно ли как-то определить номер строки, на которой расположен курсор, но с отсчетом не от самой первой строки текста, а от первой отображаемой в TextBox'е строки?
2. Есть ли какое-нибудь сообщение, отправляемое в случае скролла компонента? Я бы его ловил, и решил этим вообще все свои проблемы "обратного" скрола.
3. Сейчас я обрабатываю события нажатия навигационных клавиш через PreviewKeyDown, что по понятным причинам неправильно. Есть ли событие, которое происходит после действия, назначенного клавише, но при этом до ее отпускания? Ведь пользователь может зажать PageDown и удерживать его, и мне необходимо будет "поймать" каждое действие, которое произойдет.
3.1. Может опять же есть какое-нибудь сообщение, на базе которого я могу создать свое событие?
4. Может быть есть более элегантный выход?

Добавлено через 21 час 41 минуту
Сам себе отвечаю, может пригодится кому...

Для реализации функционала "обратного" скролинга необходимо иметь возможность получить текущее значение скрола компонента.

Сперва я хотел использовать для этого функцию GetScrollPos из user32.dll, но оказалось, что она выдает значение стандартного скрола (который появляется справа от компонента, если текста много). Если этот стандартный скрол скрыт (а он скрыт, я же свой пристроил), то GetScrollPos всегда будет выдавать 0.
Другой выход - получить значение скрола прямо из текстового поля, используя сообщение EM_GETSCROLLPOS. Но TextBox не обрабатывает это сообщение, поэтому единственным выходом оказалось использовать RichTextBox. Но и тут геморрой не закончился.

Во-первых, мне нужно работать с Plain-текстом, поэтому пришлось отлавливать нажатия CTRL+X, CTRL+C, CTRL+V и редактировать содержимое буфера, выбрасывая оттуда RTF-форматирование.
Во-вторых, мне по-прежнему требовалось обрабатывать PageUp/PageDown именно после произведенных ими действий. Эту проблему я решил написав обертку на компонент RichTextBox, где переопределил WndProc и на сообщения WM_VSCROLL, WM_MOUSEWHEEL, WM_KEYDOWN создал новое событие, которое отвечало всем моим требованиям.

Вот как-то так... 2 дня ушло на казалось бы простую задачу...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.05.2015, 14:58
Ответы с готовыми решениями:

Как сделать свой обработчик события для нескольких TextBox
У меня есть метод, который не позволяет писать в textBox'ы ничего кроме цифр. public static int...

Свой компонент от ListBox. Не могу задать свой тип для Items
День добрый господа. Нуждаюсь в вашей помощи. Суть такова, что я желаю создать свой компонент на...

Как сделать свой стиль выделения в TextBox
Поясню вопрос, если непонятен: Обычно текст выделяется так: Но вот как сделать вот так?=) ...

как связать vScrollBar и textbox?
Как сделать чтобы vScrollBar прокручивал текст в textbox?

HSrollBar и VScrollBar
Необходимо с помощью HScrollBar и VScrollBar изменять положение кнопки на форме

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.05.2015, 14:58

Событие ReadOnlyChanged в TextBox Одно для нескольких TextBox-ов
Здравствуйте! Дамы и Господа, подскажите как сделать одно событие ReadOnlyChanged для нескольких...

Привязка VScrollBar'a к TreeView
Подскажите, пожалуйста как привязать VScrollBar к TreeView. С ScrollBar сталкиваюсь впервые....

Как связать Chekedlistbox и VScrollBar?
У меня есть такой chekedlistbox, как мне сделать прокрутку(так как данных м.б. больше). И можно ли...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru