Пользовательское текстовое поле: выделение и выделение

Я опубликовал вопрос, подобный этому ранее, однако, подумав об этом и проверив ответы, я считаю, что неправильно истолковал ответы, и ответчик (ответчики) неправильно истолковал меня. Исходный вопрос здесь. Я думаю, люди поверили, что я просто хотел выделить строки, я не указал свою точную цель. Итак, я сейчас:

В последнее время я пытался создать текстовое поле на 100% с нуля в C++ CLR с использованием GDI+. Я столкнулся с проблемой размещения курсора, когда пользователь щелкает текстовое поле. Выполняя простую математику (где они щелкнули, деленное на ширину линии), я могу выяснить, на какую строку они щелкнули. Но для того, чтобы щелкнуть символ, мне нужно (если нет лучших способов) сравнить ограничивающие прямоугольники всех символов в строке и поместить курсор перед тем, в который вписывается мышь. Для этого мне нужно получить точные границы каждого отдельного символа, а не всей строки.

Я уже пробовал несколько вещей, ни одна из которых не работала:

  • Graphics::MeasureString не рекомендуется никому, и это не дает того, что я хочу
  • TextRenderer::MeasureText больше точен, но для этого недостаточно точен
  • Graphics::MeasureCharacterRanges содержит 32 символа. cap, и я ожидаю, что строки в некоторых случаях будут длиннее 32 символов

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


person smoth190    schedule 22.02.2012    source источник
comment
Я не вижу в вашей ссылке Graphics::MeasureCharacterRanges ничего, что указывает на ограничение в 32 символа.   -  person Mark Ransom    schedule 22.02.2012
comment
@MarkRansom Я где-то это читал, и, конечно же, я получаю исключение OverflowException, когда набираю 32+ символа.   -  person smoth190    schedule 23.02.2012


Ответы (1)


Из-за способа кернинга и сглаживания текста граница символа зависит от всех символов слева от него. Однако вам не нужно знать каждую границу символа, а только те, которые находятся по обе стороны от точки щелчка. Вы можете найти их с помощью бинарного поиска — разделите строку пополам, измерьте ее (используя TextRenderer::MeasureText) и определите, находится ли она слева или справа от точки щелчка. Продолжайте сужать размер строки, пока не останется только одна возможность.

person Mark Ransom    schedule 22.02.2012
comment
Хорошо, если это решит проблему кликов, что произойдет, когда я доберусь до проблемы выделения? Измерения, которые я получаю выше, по-прежнему не решат мою проблему с этим. - person smoth190; 23.02.2012
comment
@smoth190, это еще проще. Просто сделайте одно измерение символов перед выделением и еще одно со всем до выделения включительно. - person Mark Ransom; 23.02.2012
comment
Хорошо, я думаю, это кажется логичным. Спасибо за помощь, почти все заработало. - person smoth190; 28.02.2012