RichTextBox + API

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
hardhouse
Начинающий
Начинающий
 
Сообщения: 10
Зарегистрирован: 22.01.2005 (Сб) 17:33

RichTextBox + API

Сообщение hardhouse » 22.01.2005 (Сб) 17:40

Проблема: добавление текста в вышеназваный контролл так, чтобы при фокусе на нем не было автоматического скроллирования.
Поясню: есть RichTextBox, в нем есть некое кол-во текста, форматированного. Чтобы форматирование не исчезало при добавлении текста, обычно ставят каретку ввода на самый конец файла (SelStart=len(text)). Однако при этом ричтекстбокс непременно будет скроллироваться вниз, что крайне нежелательно.
Есть способ с помощью АПИ: EM_EXSETSEL (выделяю текст), затем EM_REPLACESEL ("вставляю" текст) и даю команду ричэдиту на форматирование (например, SelColor=vbRed). Отлично, код работает! Однако, если я в это время переведу фокус на ричэдит, то в нем появляется каретка ввода и при выделении EM_EXSETSEL окно опять скроллируется вниз... а ведь при всем при этом нужна возможность спокойно копировать текст из окна в то время, как другой текст вставлялся бы в конец и форматировался под некие требования. Как решить эту проблему?
На данный момент была осуществлена попытка создать сабклассинг и ловля сообщения WM_VSCROLL. Упрощенный алгоритм: запоминание позиции ползунка скролла, потом вставка нужного текста, форматирование, и снова возврат ползунка на исходную позицию. Однако вот беда: в wRaram содержится позиция бегунка только когда я его мышкой непосредственно передвину! А если я пользуюсь "стрелочками" на полосе прокрутки? Или, скажем, с помощью скролла мыши? Как быть?
И еще вопрос вдогонку: как вставить туда картинку так, чтобы ее нельзя было ресайзить мышкой? Аналог - клиент ICQ, там сделано как раз так, как мне нужно, т.е. картинка не ресайзится, и можно спокойно вводить текст, редактировать и т.д. Как они так сделали?
Заранее благодарен.

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 22.01.2005 (Сб) 17:50

1) Не знаю, поможет ли это, но попробуй мой класс для форматирования RTF:
http://bbs.vbstreets.ru/viewtopic.php?t=11986&postdays=0&postorder=asc&start=15
2) Изображения вставляются как OLE-объекты (коллекция OLEObjects RichTextBox'а), верно? Значит, можно создать свой объект для загрузки изображений. Только не спрашивай меня, как это сделать :) Я этим детально не занимался :)
Моду создают модоки, а распространяют модозвоны.

hardhouse
Начинающий
Начинающий
 
Сообщения: 10
Зарегистрирован: 22.01.2005 (Сб) 17:33

Сообщение hardhouse » 22.01.2005 (Сб) 18:33

1. Интересно, а чем мне твой класс поможет? Ты же используешь те же АПИ для выделения и редактирования, что и я. Проблема же не в том, как выделить, а в том, как избежать обязательного скроллирования ричтекстбокса.
2. Совершенно согласен:) Однако, именно благодаря тому, что объект будет как OLE, он позаимствует все его свойства, в т.ч. и ресайз. Скажу наперед - через буфер обмена тоже не пойдет, так же будет существовать возможность ресайза.

SergeySV2
Новичок
Новичок
 
Сообщения: 33
Зарегистрирован: 06.01.2005 (Чт) 22:06

Сообщение SergeySV2 » 22.01.2005 (Сб) 20:41

Насчет скролинга, ты прав, там одним WM_VSCROLL не обойдешься - хорошая глава на эту темку у Петзольда есть, там он в примере все возможные события по скролингу расмматривает: и через мышку и через клаву........ ща книги нет, на работе в элект. виде осталась, так что если заинтересуешься и не найдешь в инете, то пиши, выложу

Qubicz
Обычный пользователь
Обычный пользователь
 
Сообщения: 87
Зарегистрирован: 16.10.2004 (Сб) 20:21
Откуда: Санкт-Петербург

Сообщение Qubicz » 22.01.2005 (Сб) 20:49

Код: Выделить всё
Private Declare Function GetScrollPos Lib "user32" Alias "GetScrollPos" (ByVal hwnd As Long, ByVal nBar As Long) As Long
Private Declare Function SetScrollPos Lib "user32" Alias "SetScrollPos" (ByVal hwnd As Long, ByVal nBar As Long, ByVal nPos As Long, ByVal bRedraw As Long) As Long

Может оно?

hardhouse
Начинающий
Начинающий
 
Сообщения: 10
Зарегистрирован: 22.01.2005 (Сб) 17:33

Сообщение hardhouse » 23.01.2005 (Вс) 7:59

SergeySV2 спасибо, лучше если бы выложил... процесс пойдет быстрее (хотя вряд ли я что новое там узнаю).
Qubicz Не подходит. GetScrollPos возвратит 32 битные значения, а wParam - 16битные значения, и эти значения никак не сопоставить.
Второе. SetScrollPos не скроллирует контент! Только ползунок.

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Re: RichTextBox + API

Сообщение Eugenio » 23.01.2005 (Вс) 9:10

hardhouse писал(а):нужна возможность спокойно копировать текст из окна в то время, как другой текст вставлялся бы в конец и форматировался под некие требования. Как решить эту проблему?
На данный момент была осуществлена попытка создать сабклассинг и ловля сообщения WM_VSCROLL. Упрощенный алгоритм: запоминание позиции ползунка скролла, потом вставка нужного текста, форматирование, и снова возврат ползунка на исходную позицию..

Я может, глупый щас вопрос задам, но я не понял:
Почему не запоминать позицию курсора, а не ползунка (EM_EXGETSEL, потом после вставки всего, что надо и куда надо - EM_EXSETSEL, где и первый и последний симв. - те, что получены в lParam через EM_EXGETSEL)?
Последний раз редактировалось Eugenio 23.01.2005 (Вс) 10:42, всего редактировалось 1 раз.
Есть ли у меня вопрос? У меня всегда есть вопрос

Eugenio
Постоялец
Постоялец
 
Сообщения: 393
Зарегистрирован: 08.05.2004 (Сб) 13:27
Откуда: Ekaterinburg

Сообщение Eugenio » 23.01.2005 (Вс) 9:17

SergeySV2 писал(а):хорошая глава на эту темку у Петзольда есть, там он в примере все возможные события по скролингу расмматривает: и через мышку и через клаву........ ща книги нет, на работе в элект. виде осталась, так что если заинтересуешься и не найдешь в инете, то пиши, выложу

А..Э.. Не будет ли любезен уважаемый сэр.. Короче, тоже буду очень благодарен, если!
(мой email есть в личных сведениях)
Есть ли у меня вопрос? У меня всегда есть вопрос

hardhouse
Начинающий
Начинающий
 
Сообщения: 10
Зарегистрирован: 22.01.2005 (Сб) 17:33

Сообщение hardhouse » 23.01.2005 (Вс) 11:02

Eugenio На самом деле позиция курсора не есть хорошо:
1. Курсор будет "занят" выделением текста мышкой (скажем, в середине), поэтому его нельзя трогать ни при каких обстоятельствах. Его скачки неизбежны и это будет только нервировать юзера.
2. Позиция, скажем в середине, при прокрутке "назад" станет уже первой (логично?).
3. Не спорю, с помощощью АПИ можнно всегда вычислить позицию первого символа первой видимой строки.
4. И, наконец, главное, почему нельзя использовать в качестве отправной точки каретку: если я сдвину текст так, чтобы видна была только нижняя половина первой видимой строки, то при вставке каретки текст тут же выровняется, и текст первой видимой строки станет станет полностью видимым. Т.е. будут опять скачки контента.
В общем, каретка - это тупиковый путь...

hardhouse
Начинающий
Начинающий
 
Сообщения: 10
Зарегистрирован: 22.01.2005 (Сб) 17:33

Сообщение hardhouse » 23.01.2005 (Вс) 13:43

Решил было сделать все с нуля, создал объект класса EDIT через
CreateWindowEx(WS_EX_STATICEDGE Or WS_EX_TRANSPARENT, "edit", "", WS_CHILD Or ES_NOHIDESEL Or ES_MULTILINE Or WS_VSCROLL, 0, 0, 300, 100, Me.hwnd, 0, App.hInstance, ByVal 0&), да вот только текст-то все равно скроллится при добавлении текста:((((
В общем, уже и не знаю, что предпринять.. но ведь как-то же делают, взять любой браузер.. там без специального скрипта ползунок и не подумает сдвинуться с места, между тем как страничка подгружается (например, потоковый чат) и я могу спокойно при этом копировать, редактировать и т.д.
У кого есть идеи? Если не в лоб, то хитростью...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 23.01.2005 (Вс) 14:04

Применительно к TextBox подобная проблема обсуждалась на http://groups.google.ru/groups?hl=ru&lr ... corbina.ru

Может, это и к RTB подойдёт?
Изображение

hardhouse
Начинающий
Начинающий
 
Сообщения: 10
Зарегистрирован: 22.01.2005 (Сб) 17:33

Сообщение hardhouse » 23.01.2005 (Вс) 14:51

tyomitch Вы вообще поняли о чем идет речь? Читайте внимательно... скролл как раз-таки нежелателен

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 23.01.2005 (Вс) 15:37

Там цель была отскроллить в конец, здесь - оставить в начале... Разницы-то вроде нет, вверх или вниз скроллить?
Изображение

hardhouse
Начинающий
Начинающий
 
Сообщения: 10
Зарегистрирован: 22.01.2005 (Сб) 17:33

Сообщение hardhouse » 23.01.2005 (Вс) 16:56

Не в начале, а на том же самом месте, где в последний раз велась работа. Повторяю еще раз - манипуляции с кареткой - это ошибочный путь.

hardhouse
Начинающий
Начинающий
 
Сообщения: 10
Зарегистрирован: 22.01.2005 (Сб) 17:33

Сообщение hardhouse » 23.01.2005 (Вс) 17:38

Кажется, до меня дошло, как реализовать задуманное... На примере ричтекстбокса (хотя можно и для обычного текстового контрола, однако он почему-то дико мигает, причем это мигание я никак не смог побороть).
Итак, берем ричтекстбокс. При добавлении текста динамически увеличиваем его высоту. В конечном итоге он когда-то выйдет за пределы формы, но нам это и нужно. Чтобы эмулировать скролл, я создаю его через ShowScrollBar (хотя можно сразу SetScrollInfo), потом ставлю сабклассинг (к сожалению, без него никак) и ловлю сообщения... затем с помощью GetScrollInfo получаю необходимые 32-битные значения и применяю их к свойству Top ричтекстбокса. Таким образом, я совершенно не завишу от каретки (объем текста целиком помещается в нам контейнер), и в то же время я могу спокойно скроллировать текст, точнее эмулировать его:) А для сохранения выделения можно использовать все те же ф-ии EM_EXSETSEL и EM_REPLACESEL.
Идея была взята с http://www.mvps.org/vbvision/_samples/Scrollbars_(Windows)_Demo.zip, осталось только обтесать под мои нужды и продумать код для использования эмуляции скролла в нескольких ричэдитах.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 23.01.2005 (Вс) 20:47

hardhouse писал(а):Не в начале, а на том же самом месте, где в последний раз велась работа. Повторяю еще раз - манипуляции с кареткой - это ошибочный путь.

В том примере как раз велась работа не с кареткой, а со скроллбаром (слался EM_LINESCROLL).

Но если проблема уже решена, тогда ладно :-)
Изображение

hardhouse
Начинающий
Начинающий
 
Сообщения: 10
Зарегистрирован: 22.01.2005 (Сб) 17:33

Сообщение hardhouse » 24.01.2005 (Пн) 20:12

Так, а вот рано я обрадовался... оказывается, высоту контролов нельзя выставить больше, чем 245745.. а в моем случае это очень и очень мало... как быть?

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 24.01.2005 (Пн) 20:27

Уверен, что не хочешь делать EM_GETFIRSTVISIBLELINE перед добавлением текста, и EM_LINESCROLL на ту же строку - после?
Изображение

hardhouse
Начинающий
Начинающий
 
Сообщения: 10
Зарегистрирован: 22.01.2005 (Сб) 17:33

Сообщение hardhouse » 24.01.2005 (Пн) 23:19

конечно уверен, я ж с этого начал и давно уже аргументировал это решение.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 25.01.2005 (Вт) 12:11

Ты вообще-то про каретку говорил и аругментировал. Я не нашёл в топике места, где бы ты хоть слово сказал о EM_LINESCROLL. Покажешь?
Изображение


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 15

    TopList