Отправляет email-рассылки с помощью сервиса Sendsay

Программирование. Форум !!!

Delphi чтение текста WINAPI

Это всё правильно. Но: переведённая мною цитата из MSND - "приложения
посылают сообщение WM_GETTEXTLENGTH для определения длины текста,
ассоциированного с окном, в символах". Если окно является обычным окном, то
ассоциированным текстом является его заголовок, если стандартным контролом,
то им является текст в этом окне, в зависимости от типа контрола: кнопки
возвращают текст на себе (OK или Cancel, например), списки возвращают текст
"подсвеченно" элемента итп. То же относится и к функции GetWindowText().
Описанная тобой ситуация похожа на то, что у тебя собственные, созданные
тобой дочерние окна, которые обслуживаются не ОС, а твоим приложением, и при

этом не имеющие заголовков. Если ты намеревался таким образом получить
текст, отображаемый в окне, как например отображает набранный в документе
текст MS Word, то вынужден огорчить: ничего не получится. ОС не запоминает,
что приложение рисует в своём окне. Этот текст НЕ СТАНОВИТСЯ ассоциированным

с окном, хотя бы потому, что там кроме текста могут быть ещё и изображения.
Вместо этого она посылает приложению сообщение о необходимости перерисовать
такое-то окно (WM_PAINT), и приложение само должно это сделать. Это сделано
из соображений экономии системных ресурсов: проще приложению сохранять
состояние своего окна наиэкономнейшим способом (например, программист может
просто запоминать текст в массиве строк, чтобы по запросу вновь его
перерисовать какими-нибудь DrawText()-ами), вместо того чтобы ОС запоминала
целый битовый образ окна, временно "затираемого" другими окнами. Это ещё и
быстрее на порядок будет, если программист не ламер последний, конечно. Это
всё азбука Windows-программирования, но если ты используешь что-нибудь типа
VCL, то ты вполне может этого и не знать, ибо эта библиотека сама заботится
обо всех подобных нюансах (точнее, заботятся её канвы - Canvas), если только

ты явно не программируешь иным образом.
Чтобы решить эту проблему, тебе нужно будет или самому обрабатывать
сообщения WM_GETTEXTLENGTH и WM_GETTEXT в своих дочерних окнах, или
использовать собственные сообщения, из разряда WM_USER, что лучше, ибо в
этом случае они не будут пересекаться со стандартными WM_GETTEXTLENGTH и
WM_GETTEXT, предназначенными вообще-то для других и вполне определённых
целей.
Кстати, "по настояшему" профессиональные программисты на Builder-е и Delphi
редко используют канвы на полную катушку из сображений экономии системных
ресурсов. Канва ведь всё равно в общем случае не может сохранить свой
констекст иначе, как битовое изображение. Представь, если MS Word будет
сохранять 200-страничный документ в виде Bitmap-а, да ещё с "принтерным"
разрешением 600 dpi, а не 96 или 120, как на большинстве мониторов.

--
С уважением, boroda
mailto:boroden***@s*****.ru

Номер выпуска : 4138
Возраст листа : 540 (дней)
Количество подписчиков : 527
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/332780
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

Ответить   Шматко А.А. Mon, 14 Mar 2005 11:03:07 +0300 (#332780)

 

Ответы:

Здравствуйте, Шматко.

Вы писали 14 марта 2005 г., 14:03:07:

Все это мне известно.

Даже текст из блокнота?
Именно его я использую для тестирования

Ответить   Tue, 15 Mar 2005 20:13:39 +0600 (#333271)

 

Как раз он-то обрабатывает эти сообщения. Поэтому с ним WM_GETTEXTLENGTH,
WM_SETTEXT, WM_GETTEXT будут работать. Но программисты из Microsoft
специально позаботились об этом, когда его писали. У тебя же, судя по всему,

дочернее окно не обрабатывает WM_GETTEXTLENGTH и WM_GETTEXT, просто
передавая их обработку в DefWindowProc(), которая ведёт себя именно, как
указано в MSDN. Хотя возможно, что и перехватывает, но почему-то намеренно
ведёт себя так, как ты наблюдаешь. При этом почему-то обрабатывает
WM_SETTEXT ожидаемым тобой способом.
Это твоё окно или "компонентское"? Исходники его есть? В отладчике
протрассируй, если так.

--
С уважением, boroda
mailto:boroden***@s*****.ru

Номер выпуска : 4141
Возраст листа : 542 (дней)
Количество подписчиков : 526
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/333739
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

Ответить   Шматко А.А. Wed, 16 Mar 2005 08:47:05 +0300 (#333739)

 

Здравствуйте, Шматко.

Вы писали 16 марта 2005 г., 11:47:05:

Я тестирую прогу на Блокноте! И не работает!

Ответить   Wed, 16 Mar 2005 20:08:08 +0600 (#334130)

 

Что ж ты сразу не сказал, что лезешь к дочерним окнам ДРУГОГО приложения!
Счас протестировал на Блокноте. WinXP Pro SP2 RUS.

WM_SETTEXT, WM_GETTEXTLENGTH, WM_GETTEXT.
Непосредственно Блокноту - всё работает. Но влияет на ЗАГОЛОВОК окна.
Если отыскать его дочернее окно, в котором собственно текст отображается
(если кто не знает, область редактирования в Блокноте - это обычный
стандартный многострочный Edit-control), и посылать сообщения ему, то тоже
всё работает. Текст появляется в области редактирования и читается оттуда.

SetWindowText(), GetWindowTextLength(), GetWindowText().
Непосредственно Блокноту - аналогично. Влияет на ЗАГОЛОВОК окна.
Дочернему окну - ни хрена не работает. Читаем MSDN: "GetWindowText не может
вернуть текст контрола ДРУГОГО приложения"; "GetWindowTextLength не может
вернуть длину текста edit-контрола ДРУГОГО приложения"; "SetWindowText не
может изменить текст контрола ДРУГОГО приложения".

Кстати, для работы с ...box-контролами имеются также специализированные
сообщения. Смотри по LB_xxx для listbox-ов, CB_xxx для combobox-ов.

--
С уважением, boroda
mailto:boroden***@s*****.ru

Номер выпуска : 4146
Возраст листа : 543 (дней)
Количество подписчиков : 526
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/334560
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

Ответить   Шматко А.А. Thu, 17 Mar 2005 08:59:25 +0300 (#334560)

 

Здравствуйте !


Стоп, еще раз, и медленно, пожалуйста...
Есть твоя прога. Так ?
Ты открываешь блокнот. Да ?
Получаешь дескриптор одного из его окон (того, в котором текст),
подсовываешь его в _своей_ проге в SendMessage(handle, WM_GETTEXTLENGTH, ...

Или как ?

Просто, если процессы разные (если до меня правильно дошло... что
ты не из окна своего процесса пытаешься взять текст), то да - тебе
текст не вернется.

Так, все таки, все так как выше описано ?

--
С уважением, Вахтуров Виктор.

Номер выпуска : 4153
Возраст листа : 545 (дней)
Количество подписчиков : 525
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/336396
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

Ответить   Sat, 19 Mar 2005 23:13:16 +0300 (#336396)

 

Здравствуйте, Victor.

Вы писали 20 марта 2005 г., 2:13:16:



Да, именно так... Процессы разные

Ответить   Sun, 20 Mar 2005 09:02:07 +0600 (#336491)

 

Занятно. Читаю это обсуждение, вроде бы все сказано, даже цитаты
из документации приведены, а все не разберемся :)

Во-первых, согласно MSDN, если бы использовались функции
GetWindowText/GetWindowTextLength, текст окна из другого
процесса действительно не удалось бы взять. Для окна своего
процесса они используют WM_GETTEXT*, а для окон
других процессов явно дают заголовок, если он есть.

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

Не сработало WM_GETTEXT для Блокнота скорее всего
потому, что приведенный код нашел не окно
редактора, а какое-то другое:

Надо бы устроить цикл с вызовом GetClassName.

Упоминания об ограничениях на размер буфера сообщения
при вызове между процессами что-то не нашел...

Номер выпуска : 4157
Возраст листа : 546 (дней)
Количество подписчиков : 528
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/336579
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

Ответить   Sun, 20 Mar 2005 12:17:35 +0300 (#336579)

 

Хаю ду ю ду Емельянов Алексей?

Смотрю и вижу, как ты печатаешь умные вещи и дай-ка, думаю,
тоже что-нибудь напечатаю:

PostMessage

Ответить   Sun, 20 Mar 2005 23:27:09 +0500 (#336807)