|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
TWebBrowser - цвет выделенного текста, когда приложение не в фокусе
Добрый день.
Возникла такая необходимость: При выделении текста в WebBrowser он отображается корректно, но если приложение потеряет фокус, то визуально выделение становится не видно, хотя оно и остаётся. Можно ли как-то перенастроить TWebBrowser для того, чтобы выделение было как в браузере серым цветом при потере фокуса? Скриншот для большего понимания: |
#2
|
|||
|
|||
Ну, в принципе, можно попробовать "поправить" стили в загруженной таблице.
|
#3
|
|||
|
|||
Цитата:
Т.е. подключить стиль для отображения пассивного выделения, когда приложение не в фокусе? Искал эту тему в рамках JavaScript или HTML, ничего не нашёл. Такое есть в CSS или где-то ещё? |
#4
|
|||
|
|||
Да, именно CSS.
|
#5
|
|||
|
|||
Цитата:
Есть ли какие-нибудь примеры? В сети в справочниках по CSS там всего 4 свойства: color, background, background-color и text-shadow. Ничего похожего на цвет не в фокусе. https://webref.ru/css/selection |
#6
|
|||
|
|||
Вообще, я так понимаю, TWebBrowser использует IE как основу, а в IE тоже воспроизводится, что выделение вне фокуса визуально не отображается. То есть это конкретно реализация браузера так выполнена.
В других браузерах визуальное выделение без фокуса везде реализовано. Похоже, остаётся CSS, но возможно ли через него это реализовать? |
#7
|
||||
|
||||
Правильно понимаете, WebBrowser входит в состав системного IE как ActiveX контрол, и тянет за собой все "прелести" мелкомяконького обозревателя, нужно менять настройки там. Можно ещё при потере/получении фокуса менять цвет выделенного фрагмента текста средствами OleObject as IHTMLDocument посредством тега <span style=...>, попробовал такое, но это оказалось слишком гиморно, бросил
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#8
|
|||
|
|||
Цитата:
Та же идея. Полдня сегодня потратил на похожий вариант: использовать JavaScript, подменяющий выделенный фрагмент по MouseUp, точнее добавляющий по бокам нужный тег для цвета. Но всплыло сразу несколько проблем: - выделение нескольких блоков в какой-нибудь таблице не позволит себя отформатировать, потому что внутри будет начало табличных тегов, а замена прошла за его скобками, браузер просто проигнорирует такие левые теги, нарушающие порядок тегов; - нужно следить за тем, что теги уже были добавлены к выделенному тексту, не добавлять их повторно; - нужно удалять теги опять же после потери выделения, что вызывает основную головную боль. Так что да, идея реализовать через форматирование тегами (что JS, что методами TWBrowser) обречена на провал. Цитата:
Там тоже не нашёл такой надстройки. Пробовал включать/выключать ускорители или копаться в безопасности. Ничего не помогло. Похоже, Мелкомягкие попросту не подумали об этой детали на этапе архитектуры и теперь её поддержку не могут в него внести. Всё же в идеале реализовать это нужно через код - будет меньше зависимости от настроек в системе пользователя. Возможно, стоит подумать в сторону хитростей. Скажем, перевыделять выделенный текст при потере фокуса и как-то его отображать потемнее. |
#9
|
||||
|
||||
Поменять цвет фона выделения
Код:
var SelObj: IHTMLSelectionObject; SelRange: IHtmlTxtRange; begin SelObj:= (WebBrowser1.Document as IHTMLDocument2).selection; SelRange:= SelObj.CreateRange as IHtmlTxtRange; SelRange.execCommand('BackColor', false, '#FFCC00'); {Вернуть дефолтный SelRange.execCommand('BackColor', false, 'false'); } end; Я не понял Вашего вопроса, но всё же Вам на него отвечу! Последний раз редактировалось Alegun, 02.03.2017 в 07:40. |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
Droltromed (02.03.2017)
|
#10
|
|||
|
|||
Цитата:
Спасибо большое, действительно работает. В USES для него пришлось подцепить MSHTML. Повесил на ApplicationEvents.OnDeactivate - выделяет выделенный текст цветом при потере фокуса формой. Но появилась проблема - если повесить Код:
SelRange.execCommand('BackColor', false, 'false'); Но решение практически найдено. Попробую найти способ как выполнить между получением фокуса формой и обработкой клика мыши (сбрасывающий прежнее выделение текста). Если кликнуть так, чтобы выделение текста не сбросить или просто взять в фокус форму без клика, то всё идеально - текст помечается цветом при потере фокуса и теряет цвет при его получении, показывая обычное выделение текста. Спасибо, практически идеальное решение) Попытаюсь решить вопрос с получением формой фокуса, чтобы сбросить цвет до сброса выделения и отпишусь об успехе или неудаче. |
#11
|
||||
|
||||
Вот пример HTML редактора для разборки, у меня правда не пошёл, среда не та
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#12
|
|||
|
|||
Цитата:
В общем, решение завершил. Реализовал так: Эту часть запихнул в ApplicationEvents.OnDeactivate Код:
var SelObj: IHTMLSelectionObject; SelRange: IHtmlTxtRange; begin SelObj:= (WebBrowser1.Document as IHTMLDocument2).selection; SelRange:= SelObj.CreateRange as IHtmlTxtRange; SelRange.execCommand('BackColor', false, '#FFCC00'); //даём цвет выделенной части end; И эту часть запихнул в ApplicationEvents.OnMessage: Код:
var SelObj: IHTMLSelectionObject; SelRange: IHtmlTxtRange; begin if (Msg.message=WM_LBUTTONDOWN) or (Msg.message=WM_RBUTTONDOWN) then begin SelObj:= (Form13.WebBrowser1.Document as IHTMLDocument2).selection; SelRange:= SelObj.CreateRange as IHtmlTxtRange; SelRange.execCommand('BackColor', false, 'false'); //убираем цвет с выделения end; end; Как оказалось, OnActivate срабатывает уже после обработки события, через которое получен фокус назад (будь это alt+tab, клик мыши или что-то ещё), поэтому в нём бесполезно ловить выделенный текст: он будет уже потерян после клика мышью по окну браузера. А OnMessage срабатывает как раз перед всеми обработчиками, именно там и ловим нажатие мыши. Повесил проверку именно левой или правой кнопки мыши, потому что выделение из браузера снять больше нечем. Провёл небольшие тесты: ни одно из событий получения фокуса (кнопки, горячие клавиши) не снимут выделение браузера, кроме левой или правой кнопки мыши и кроме одного события: - если кликнуть на заголовок окна, то оно не засчитается в OnMessage как клик мышью. Это создало небольшую проблему. Поэтому просто берём и запихиваем в OnActivate то же самое, что и в OnDeactivate, но снимающее цвет: Код:
var SelObj: IHTMLSelectionObject; SelRange: IHtmlTxtRange; begin SelObj:= (Form13.WebBrowser1.Document as IHTMLDocument2).selection; SelRange:= SelObj.CreateRange as IHtmlTxtRange; SelRange.execCommand('BackColor', false, 'false'); //убираем цвет с выделения end; В итоге получаем: при снятии фокуса с приложения окрашивается цвет выделенного. При получении фокуса кликом цвет снимается через OnMessage. При получении фокуса кликом по заголовку в дело вступает OnActivate и тоже снимает цвет с выделения. Есть в этом небольшой минус - множество холостых срабатываний если просто кликать по окну, вызывая OnMessage или когда получаем фокус кликом (срабатывает OnMessage, а следом OnActivate, получая двойной сброс цвета). Благо предложенный код не создаёт тормоза при выполнении и не вызывает исключений, если у браузера ничего не выделено, но вызывает исключения если в браузере ничего не открыто. Поэтому если бывают случаи держать браузер пустым, то обработку можно просто завернуть в Try Except или проверять наполненность браузера. В остальном, реализация получилась именно такой, как хотелось и задумывалось. Большое спасибо за предложенный код, Alegun . |
#13
|
|||
|
|||
Вообще можно было бы оставить только OnActivate и OnDeactivate, но для этого в OnActivate вместо
Код:
SelObj:= (Form13.WebBrowser1.Document as IHTMLDocument2).selection; Но проблема в другом, как этой переменной внести не selection, а весь текст целиком? Пробовал вместо .selection что-нибудь в стиле .text, .all или вообще убирать - не принимает. Впрочем, сама переменная подразумевает получение IHTMLSelectionObject. Можно ли как-то SelRange подсунуть не IHTMLSelectionObject, а конкретно body, toString или какой-нибудь другой вид всего текста разом? UPD: нашёл решение: В ApplicationEvents.OnActivate вписываем: Код:
var SelRange: IHtmlTxtRange; begin SelRange:=((WebBrowser1.Document AS IHTMLDocument2).body AS IHTMLBodyElement).createTextRange; //получаем весь текст SelRange.execCommand('BackColor', false, 'false'); //сбрасываем цвет у всего текста end; В ApplicationEvents.OnDeactivate, соответственно, остаётся: Код:
var SelObj: IHTMLSelectionObject; SelRange: IHtmlTxtRange; begin SelObj:= (WebBrowser1.Document as IHTMLDocument2).selection; SelRange:= SelObj.CreateRange as IHtmlTxtRange; SelRange.execCommand('BackColor', false, '#FFCC00'); //устанавливаем цвет выделенной части end; Последний раз редактировалось Droltromed, 02.03.2017 в 14:14. |
Эти 2 пользователя(ей) сказали Спасибо Droltromed за это полезное сообщение: | ||
Alegun (02.03.2017),
dr. F.I.N. (03.03.2017)
|
#14
|
||||
|
||||
Оффтоп: Респект за упёртость и въедчивость, хорошо ведь, когда досконально всё прорабатывается
Мож поможет: Цитата:
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#15
|
|||
|
|||
Цитата:
Цитата:
|