Масштабирование TextBox

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

Масштабирование TextBox

Сообщение RNG21 » 09.12.2021 (Чт) 0:17

Возможно ли в VB6 каким-то образом выполнить масштабирование стандартного контрола TextBox?
Требуется укрупнить его отображение на форме (и, соответственно, укрупнить размер отображающихся в нем символов) без изменения размера используемого в нем шрифта в пунктах.
Или как вариант - укрупнить (уменьшить) отображение на экране всей формы со всеми контролами без изменения номинальных размеров шрифтов (чтобы размер шрифта в текстбоксах продолжал оставаться, например, 10)?

[Хакер] :: Перенесено из раздела «Кирпичный завод» в раздел «Visual Basic 1—6». Предупреждаю: раздел «Кирпичный завод» не предназначен для вопросов, а предназначен для совершенно другого.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Масштабирование TextBox

Сообщение Хакер » 09.12.2021 (Чт) 11:49

Это что-то из разряда:
  • Как взлететь в небо, не отрывая ног от земли?
  • Как зарабатывать больше без увеличения зарплаты?
  • Как сбросить лишний вес, не теряя килограммы?

Чем не подходит простое увеличение размера контрола и пропорциональное увеличение размера (кегля) шрифта? Или требуется увеличить контрол по принципу экранной лупы, чтобы вся пикселизация вылезла наружу?
pixelart_of_control.png
pixelart_of_control.png (1.13 Кб) Просмотров: 2000
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

RNG21
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: 08.12.2021 (Ср) 23:06

Масштабирование TextBox

Сообщение RNG21 » 09.12.2021 (Чт) 22:50

Извиняюсь за то, что изначально неправильно разместил тему - писал уже в два ночи, случайно нажал кнопку "создать тему" не в том разделе. Как исправить - не нашел, насколько я понял, это может сделать только модератор, спасибо что перенесли.

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

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Масштабирование TextBox

Сообщение Хакер » 12.12.2021 (Вс) 17:49

А для какой цели используется TextBox? Только для отображения или для редактирования?

Простейшим способ избежать переменчивости мест разбиения текста на строчки и не уходить от стандартного TextBox-контрола будет расставить в тексте символы vbNewLine в тех местах, где они должны быть. По какому алгоритмы определять места правильного переноса строки — отдельный вопрос, и ответ на него не такой однозначный, раз пропорциональное изменение размера TextBox-а и шрифта даёт «прыгающую» картину мест переноса строки.

Другой вариант: это писать собственную реализацию подобного контрола, которая будет гарантировать однозначный принцип разбиения текста на строчки. Если контрол требуется не для редактирования, а только для отображения, это вообще легко. Хотя, если подумать, BiDi и прочие прелести юникода — это кроличья нора, из которой иной раз сложно вынырнуть.

Третий вариант с «экранной лупой»: создаём UserControl, назвав его, например, ScalableTextBox. Внутри этого UserControl-а лежит TextBox с Visiable=False. При создании UserControl создаёт совместимый DC (CreateCompatibleDC) с экраном, выбирает в нём правильный битмап, чтобы задать правильные аттрибуты. Затем, оконные сообщения от UserControl-а транслируются почти без изменений оригинальному TextBox-у, за исключением сообщения WM_PAINT.

WM_PAINT обрабатывает по особому: скрытому TextBox-у шлётся WM_PRINT или WM_PRINTCLIENT с указанием in-memory DC, который мы создали. Затем растр из in-memory DC переносится с уменьшеним на экранный DC юзерконтрола вызовом функции StretchBlt. Чтобы графика не выглядела суперотстойно, рекомендую невидимый TextBox иметь в том размере, который предполагается максимальным для масштабируемого контрола, а то и в два раза больше (т.е. использовать оверсэмплинг) — таким образом StretchBlt должен всегда сжимать растр, но никогда не растягивать. А во-вторых, включить антиалиасинг при стретчинге вызовом SetStretchBltMode.

Единственное, что в рамках этого подхода надо что-то изобретать с отображением каретки.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

RNG21
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: 08.12.2021 (Ср) 23:06

Re: Масштабирование TextBox

Сообщение RNG21 » 12.12.2021 (Вс) 23:31

TextBox, разумеется, нужен для редактирования, если бы только для отображения, я бы и вопрос задавать не стал.

Расставить в тексте символы vbNewLine в тех местах, где они должны быть - конечно, я думаю об этом варианте. Но этот способ вызывает большие проблемы при редактировании и получается очень ресурсозатратным ("алгоритмом" определения места правильного переноса строки может быть только другой, невидимый текстбокс нужного размера и с нужным шрифтом, в котором будет размещаться второй экземпляр редактируемого текста и из которого после посылки сообщения EM_FMTLINES будут браться места "мягких" разрывов, соответственно в процессе редактирования при каждом нажатии клавиши, вставке и т.п. необходима сложная синхронизация текста между редактируемым и "форматирующим" контролами). Во всяком случае, с этим вариантом все более-менее понятно и помощь с ним мне вряд ли потребуется.

Вариант написания собственного контрола не подходит в принципе, так как программа пишется не "с нуля", имеется куча старых данных, которые расчтаны на отображение только в текстбоксах с заданными параметрами с их алгоритмом разбиения текста (а его подробности мне неизвестны).

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

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Масштабирование TextBox

Сообщение Хакер » 16.12.2021 (Чт) 2:42

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


Ну вот, например. Набросал по быстрому. Самый-самый-самый минимум, но каретка не отображается — это тебе домашнее задание.
rng_scalable.zip
(7.44 Кб) Скачиваний: 122


Можно выделять текст, можно редактировать текст — дописывать, переписывать выделенное, удалять (правда каретку не видно). Для масштабирования нужно крутить колесо мышки, можно с зажатым Ctrl для более тонкого масштабирования.
Изображение
У контрола, естественно, нет большинства типичных для этого свойств или событий. Даже свойства Texf нет, изменить текст можно только зайдя в сам UserControl и поменяв свойство Text у вложенного TextBox-а.

Сдеано только событие MouseWheel, чтобы со стороны кода формы сделать обработчик, который меняет размер контрола. Изменение размера ограничено рамками от ×0.1 до x1: как я уже говорил, для хорошего качества лучше чтобы «оригинальный размер» контрола никогда не был меньше, чем фактический/рабочий, т.е. чтобы масштабирование всегда работало на уменьшение картинки, а не на растягивание. Хотя самому контролу глубоко плевать: он может и на увеличение масштабировать, и вообще: менять масштаб по вертикали и горизонтали с разными пропорциями.

Свойства OriginalWIdth/OriginalHeight задают размер TextBox-а такой, какой бы он имел без масштабирования — причём всегда в твипах, а вот свойства Width/Height задают реальный размер контрола (с учётом масштбирования), причём единциами измерения может быть что угодно.

Просьба никуда не выкладывать модули cwmsgflt.cls (CUniWindowMsgFilter) и mwmsgflt.bas (MUniWindowMsgFilter) — я их выдрал из одного из своих проектов, они в очень многих моих проектах фигурируют в слегка видоизменённом каждый раз состоянии. Я их планирую оформить как кирпич, но в данном случае это шибко урезанные и далёкие от цели варианты модулей.

Код вообще не откомментирован, поэтому вопросу по коду приветствуются.
Вложения
demo_anim.gif
(2.19 МиБ) Скачиваний: 415
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

RNG21
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: 08.12.2021 (Ср) 23:06

Re: Масштабирование TextBox

Сообщение RNG21 » 16.12.2021 (Чт) 22:58

Спасибо, разбираюсь.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Масштабирование TextBox

Сообщение Хакер » 16.12.2021 (Чт) 23:37

Хакер писал(а): И конечно, каретка нужна, в стандартной экранной лупе ведь отображается и выделение, и она, значит этого добиться можно?

Экранная лупа отображает окно, которое уже и так отрисовано на экране: она просто берёт растр, который уже есть в буфере устройства «дисплей», и копирует его.

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

Вторая сложность в том, что потока не может существовать одновременно два окна, создавшего себе каретку. Поэтому мало будет просто для своего контрола-враппера создавать каретку, надо ещё внутреннему (оборачиваемому) контролу не давать создавать свою каретку. Плюс синхронизировать положение своей каретки с положением его каретки.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

RNG21
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: 08.12.2021 (Ср) 23:06

Re: Масштабирование TextBox

Сообщение RNG21 » 31.12.2021 (Пт) 0:26

С кареткой вроде разобрался, но возникла еще одна проблема - невидимый текстбокс неправильно отвечает на некоторые сообщения, в частности, EM_GETFIRSTVISIBLELINE. Похоже, все-таки придется его делать видимым, прятать под picturebox и вывод направлять в этот picturebox.
Вложения
ScalableTextBox.zip
(11.36 Кб) Скачиваний: 126

RNG21
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: 08.12.2021 (Ср) 23:06

Re: Масштабирование TextBox

Сообщение RNG21 » 18.01.2022 (Вт) 23:03

Вариант с видимым текстбоксом под picturebox-ом. От "настоящей" каретки все-таки пришлось отказаться, больше проблем, чем удобств, проще рисовать ее через BitBlt. Добавил режим прямого отображения: если при масштабировании контрола его величина становится близкой к размеру текстбокса, picturebox становится невидимым, а текстбокс видимым и доступным, работа идет непосредственно с ним. Ну и постарался уменьшить количество перерисовок при работе.
Вложения
STB_pb.zip
(15.96 Кб) Скачиваний: 109


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

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

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

    TopList