Операции с выделенным текстом
1.Определение типа активного окна:если не редактируемое текстовое поле,то выход,иначе шаг 2.Как?
2.Копирование текста.Поле должно поддерживать Unicode,иначе выход.Как узнать?
3.Модификация текста(в буфере обмена,как я понял).Хотелось бы знать последовательность
4.Вставка текста в то же окно.Тут вроде проще некуда
Окно может быть любого процесса
проверяйте первые символы.
а от чего вы не верите таки системным компонентам?
Оно вам это надо? :)
В смысле?Там же не будет признака юникодовых символов(яю или что-то в этом роде)
Оно вам это надо? :)
Т.е. не верю?:)
Просто мне туда надо будет вставлять юникодовые символы,и если компонент окажется ANSIшным…думаю,понятно (=
Дык не надо было бы–стал бы я форум своим тварьчеством марать?:)
Просто мне туда надо будет вставлять юникодовые символы,и если компонент окажется ANSIшным…думаю,понятно
Windows NT от рождения Юникодный, это просто быдлопрограммеры до сих пор за каким-то фигом пользуются однобайтными кодировками.
Юникодный символ занимает минимум 2 байта в памяти. Делай выводы ;)
И что?Отсюда никаких выводов не следует(хотя если я так туг,то подскажи,пожалуйста:)).Вот из твоего предыдущего поста вполне можно кое-что изъять
Следовательно,минимум 1 проблема ушла
буфер обмена просто самое легкое решение, для передачи текста между разными приложениями...Т.к. весь процесс обработки занимает 1 секунду, пользователь ничего не заметит...чем не вариант? (надо просто позаботиться об сохранении содержимого буфера) :)
[QUOTE=MSDN]If the target window is owned by another process and has a caption, GetWindowText retrieves the window caption text. If the window does not have a caption, the return value is a null string...To retrieve the text of a control in another process, send a WM_GETTEXT message directly instead of calling GetWindowText.[/QUOTE]
а вот рассмотреть SendMessage+WM_GETTEXT - это интересный вариант, надо будет попробовать...
Точно:)
Спасибо за интересные замечания,по поводу буфера обмена вы наверняка правы чуть менее,чем полностью
Но если брать текст(хоть GetWindowText'ом,хоть сообщением),то ведь придётся самому туда символы вставлять,что не есть просто.К тому же,надо получить не весь текст,а именно выделенный
И да,GetActiveWindow,НЯЗ,возвращает дескриптор высокоуровнего окна.А как получить окно,которое в фокусе,и узнать,что оно является текстовым полем(вообще)?
3.11 давно уже не встречал, а вот с 95-ой попадаются клиенты.
Для получения выделенной части - EM_GETSEL. Есть апи - GetFocus().
Текстовое поле - это класс "EDIT" - GetClassName(мое окно, ...)
Я бы реализовал все это сл. образом
1. получить окно с фокусом hwnd = GetFocus()
2. получить класс окна и если оно текстовое, выполняем сл. опер.
3. получить текст и выделение
4. произвести свои преобразования с полченным текстом (левая часть + вставка + правая часть)
5. передать текст окну и сделать выделение всавки.
Буфер обмена служит для обмена инф. между приложениями через ПОЛЬЗОВАТЕЛЯ, как следствие - нелзя его игнорировать (пользователь занес в буфер необходимую ему инф., и после ваших манипуляций, он просто может их потерять, к пр. 1000$)
не понимаю, где вы увидели запрет на использование буфера программно? зачем тогда в дотнете существует класс System.Windows.Forms.Clipboard? "щоб було"? :)
если единственная боязнь, это
то может просто сто́ит потратить дополнительно немножко времени и гарантировать сохранность содержимого буфера после использования?
основное преимущество использования именно буфера, на мой взгляд: если введен огромный текст, а требуется "подредактировать" (т.е. выделен) маленький кусочек, то мы будем работать именно с этим кусочком, а не со всем текстом.
p.s.
такой боязни ни у кого нет? ;)
System.Windows.Forms.Clipboard нужен для возможности занесения в него данных (и чтения) из собственных контролов. Примером такового контрола может быть текстовый редактор в SharpDevelop.
Это равноценно тому, что не использовать его вовсе: в буфере может быть вообще картинка, когда же используется спец программа для работы с буфером (Ditto, рекомендую очень) это может привести к интересным побочным эффектам.
хм...вот именно, это пример, я бы сказал что он "не только" для этого нужен.
а̶ ̶в̶о̶т̶ ̶с̶п̶е̶ц̶.̶ ̶п̶р̶о̶г̶р̶а̶м̶м̶ы̶ ̶-̶ ̶э̶т̶о̶ ̶с̶о̶г̶л̶а̶с̶е̶н̶,̶ п̶р̶о̶б̶л̶е̶м̶а̶ ̶d̶e̶t̶e̶c̶t̶e̶d̶. :)
Хм. Ну раз так... Но таки это больше похоже на багу Ditto (у него их хватает :().
Скорее всего получится использовать EM_GETSEL (null,null) и WM_GETTTEXT/WM_SETTEXT (GetWindowText() не подходит для стороннего приложения). Узнать unicode ли окно - IsWindowUnicode(). GetFocus() также не подойдет для стороннего приложения, можно попробовать GetGUIThreadInfo().
Вообще было бы хорошо суперклассить EDIT в своей DLL-ке и регистрировать как системный класс...
тестил я некий ClipMatе. если запустить те же действия ("сохранил буфер - поиспользовал его - восстановил"), то ClipMate говорит, что "пытаются скопировать данные, которые уже находятся в буфере, и поэтому изменений в буфере не происходит". Если же после каждого этапа сделать задержку, например вставить вывод MessageBox'a, то ClipMate успевает отреагировать на действия моей программы - на три изменения в буфере обмена.
возможно, в этих двух утилитах, которые я пробовал, стоит слишком большой интервал на таймере проверки изменения содержимого буфера и, возможно, если интервал уменьшить, то моя программа и будет отлавливаться ими, но...но этого ж не произошло :)
Разьве? А по-моему как раз GetWindowText получает тнест из чужого окна, а вот WM_GETTEXT вернёт строку в адресное пространство процесса чьё окно. Везде где я видел его использование приходится заботиться о выделении области памяти в чужом процесса, а затем копировании данных оттуда. Проще использовать GetWindowText. И не все окна EDIT, поэтому ориентироваться только на них не надо. Однако EM_GETCURSL и прочие поддерживаются далеко не только EDIT'ами, но и прочими редакторами.
Вообще говоря:
Так что память ты выделяешь у себя в процессе сам.
Даже больше:
GetWindowText
This function causes a WM_GETTEXT message to be sent to the specified window or control.
Так что память ты выделяешь у себя в процессе сам.
KIV говорит не совсем об этом. Дело в том что некоторые оконные сообщения (например common controls) работают исключительно в рамках процесса своего окна. Но сразу скажу что WM_GETTEXT (и SET) весьма нетривиальное и не подчиняющееся этим ограничениям сообщение - оно по особому обрабатывается внутри Windows. За интересностями можете погуглить его + GetWindowsText (где-то была статья на англ.).
ТС: еще есть интересная функция InternalGetWindowText(), в описание не вчитывался но похоже она куда строже и все что надо умеет.