|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
Опции темы | Поиск в этой теме |
14.06.2009, 18:01 | #1 |
Регистрация: 07.06.2009
Сообщений: 5
|
CreateCompatibleDC(NULL) - для какого HDC создаётся compatible DC
Когда я вызываю CreateCompatibleDC(NULL), то данный вызов, как я понимаю, эквивалентен вызову CreateCompatibleDC(hdc) для некоторого ненулевого hdc. Как узнать, для какого именно?
Вот, что сказано в MSDN по поводу данного вызова "If this parameter is NULL, the function creates a memory DC compatible with the application's current screen". Если это так, то как получить HDC для "application's current screen"? Дело вот в чём. Некоторые словари, напрмер, Lingvo >=12, используют технику API hooking для перевода текста, над которым находится указатель мыши. В моём случае, нужно обрабатывать текст, который принадлежит определённым окнам. Первоначально, моей идеей было - перехватывать функции типа DrawText, TextOut и др., получать передаваемый в них hdc и при помощи WindowFromDC определять в каком окне происходит отображение текста. Однако выяснилось, что некоторые приложения перед тем как отобразить текст создают контекст в памяти при помощи CreateCompatibleDC(NULL), в котором происходит весь текстовый вывод. Я просто думал перехватить вызов CreateCompatibleDC(NULL), определить реальный hdc, а по реальному hdc при помощи WindowFromDC определить дескриптор окна. Возможно, данный способ не очень красивый (а возможно и принципиально неправильный из-за моего непонимания). Но другого пока я не придумал. Последний раз редактировалось butterflight; 14.06.2009 в 21:32. Причина: уточнение вопроса |
14.06.2009, 21:02 | #2 |
Форумчанин
Регистрация: 05.12.2007
Сообщений: 236
|
Что-то я вопроса не понял, но посоветую GetDC, если имелось в виду именно это.
|
14.06.2009, 21:35 | #3 |
Регистрация: 07.06.2009
Сообщений: 5
|
GetDC требует дескриптор окна, который мне не известен. В действительности меня интересует именно дескриптор окна, который я собирался определить при помощи WindowFromDC(hdc).
|
15.06.2009, 00:13 | #4 |
Форумчанин
Регистрация: 05.12.2007
Сообщений: 236
|
Можно по фокусу определить дескриптор окна, можно по имени окна, смотря что вам известно? Если собираешься перехватывать в определенных окнах, значит должно быть известно имя окна. Либо просмотреть все окна, определить процесс, а потом имя исполняемого файла, если отбор идет по имени запущенных программ
|
15.06.2009, 14:31 | #5 |
Регистрация: 07.06.2009
Сообщений: 5
|
Попытаюсь объяснить. Есть анализируемая программа, допустим, Internet Explorer 5.0 (исходников к ней, понятно, нет), которая имеет несколько окон (в случае IE, в каждом окне отображается соответствующая страница). Необходимо написать программу-анализатор, которая анализирует текстовое содержимое каждого из окон. Скажем, если в тексте, отображаемом в окне IE, присутствует слово sex, то необходимо закрыть данное окно (лишь одно окно, где есть sex, но ни в коем случае не все окна процесса).
Спрашивается, на каких идеях строить подобный анализатор. Первое, что пришло в голову перехватывать вызовы DrawText, TextOut, etc. при помощи техники API hooking и, исходя из передаваемого данным функциям в качестве параметра текста, делать дальнейший анализ. В этом случае код программы будет состоять из 2 частей: 1) - перехватчик функций DrawText, TextOut и т.д.; 2) - парсер, который получает текст от перехватчика и принимает решение о закрытии окна приложения. При этом возникает проблема: как определить, в каком из окон IE будет отображён перехваченный текст с ключевым словом? Ведь в функциях DrawText, TextOut, etc. дескриптор окна (HWND) не передаётся, передаётся лишь декскриптор контекста устройства (HDC). Как связать HDC и HWND? Я знаю только один способ - WindowFromDC. Оказалось, однако, что очень часто создаётся контекст в памяти при помощи CreateCompatibleDC(NULL), который и передаётся в DrawText, TextOut, etc. Вызов WindowFromDC для контекста в памяти даёт NULL информации об окне, то бишь ничего не даёт. В любом случае связывание контекста в памяти с контекстом окна рано или поздно должно произойти (иначе текст просто не будет отображён). Это может произойти или при создании контекста в памяти при помощи CreateCompatibleDC(NULL) - с каким контекстом связывает система создаваемый контекст (если вообще с каким-то связывает)? (Это и был мой первоначальный вопрос. Мне казалось, что функция CreateCompatibleDC(NULL) внутри себя определяет действительный hdc нужного окна и создаёт совместимый контекст именно для действительного hdc.) Либо это может произойти на более позднем этапе, когда контекст в памяти уже содержит полностью подготовленное изображение. В этом случае, как я понимаю, должны вызываться BitBlt или StretchBlt? Данные функции копируют изображение из одного контекста hdcSrc в другой - hdcDest. К сожалению, по непонятным для меня причинам перехват BitBlt и StretchBlt ничего не дал - вызовы BitBlt, StretchBlt, в которых контекст, созданный при помощи createCompatibleDC(NULL), передавался бы в качестве hdcSrc попросту отсутствуют. Если у кого-то есть соображения почему они могут отсутствовать - с удовольствием выслушаю. В конечном итоге, задача состоит в определении связи между контекстом в памяти и окном в которое этот контекст в конечном итоге будет отображён. Любые идеи приветствуются. По поводу определения активного окна. Страница с ключевым словом может загружаться и не будучи активной, текст в ней будет перехвачен, передан парсеру, а парсер закроет другое окно. Это не совсем то, как мне кажется. По крайней мере, я пытался это делать при помощи функции GetGUIThreadInfo. Определялось другое окно. Последний раз редактировалось butterflight; 15.06.2009 в 14:38. |
15.06.2009, 14:41 | #6 |
Белик Виталий :)
Старожил
Регистрация: 23.07.2007
Сообщений: 57,097
|
Уй-юй-юй... А чего бы просто не написать проксисервер и не анализировать им?
Или в крайнем слечае подсоединиться к IE как к СОМ серверу?
I'm learning to live...
|
15.06.2009, 15:49 | #7 | |
Регистрация: 07.06.2009
Сообщений: 5
|
Цитата:
Тем более, что определённая часть кода по внедрению DLL и перехвату API у меня уже написана. Неужели связывание контекстов с окнами операционной системой настолько сложный и малопонятный механизм, что в него нельзя внедриться, перехватив пару-тройку API? По поводу подсоединения как к COM-серверу - я не очень силён в деталях реализации этого метода. Насколько это универсально? Все ли браузеры обязаны поддерживать его? Например, здесь: http://nibuthomas.com/2008/08/15/cap...-mouse-cursor/ приведён пример прграммы определения текста, находящегося в "чужом" приложении под курсором мыши. Могу сказать, что у меня данная программа работает не со всеми приложениями, с которыми работает API hooking. |
|
15.06.2009, 16:23 | #8 |
Пользователь Подтвердите свой е-майл
Регистрация: 21.06.2008
Сообщений: 12
|
butterflight!
У меня проблема, как у тебя, кажется, один к одному. Вот только исследуемые проги разные. И опыта у меня поменьше. Ты пишешь: "В любом случае связывание контекста в памяти с контекстом окна рано или поздно должно произойти" Вот именно. Это предполагает исследование программы. Тяжело это. Ещё смотри. У тебя, видать, существует какой-нибудь аналог BitBlt. Но! Если ты думаешь, что перехватишь этот аналог и почерпнёшь информацию о соответствии контекста памяти контексту окна, то ошибаешься. (Рад буду, если это не так) Я, например, могу перехватывать BitBlt в тех и только тех случаях, когда дескриптор целевого DC есть дескриптор некоторого определённого нужного мне окна (Я к чему это? Просто рано или поздно ты найдёшь аналог BitBlt, но много ли он даст?) Вот такой код выполняется у меня вместо BitBlt Код:
Но правильно ты говоришь- в какой момент было такое соответствие определено? Просто из перехвата не понять. Тут исследовать программу надо. Так. Теперь по хэндлу нужного мне окна. В данной задаче предпочитаю находить не программмно, а с помощью некоторого приложения. Могу дать ссылку. Наводишь курсор на окно и видишь хэндл. Потом ещё поразмышляю. А вот к тебе вопрос- я перехватываю CreateCompatibleDC, но параметр, переданный в неё почему-то не ноль. То есть я понимаю, что это какое-то заданное устройство и CreateCompatibleDC вернёт дескриптор контекста устройства, котрое с этим устройством совместимо. В общем, наговорил-наговорил, аж сам не понял. Если речь идёт об окне- передаём в CreateCompatibleDC хэндл окна, что ли? Последний раз редактировалось rpy3uH; 15.06.2009 в 17:41. |
15.06.2009, 22:22 | #9 | |
Регистрация: 07.06.2009
Сообщений: 5
|
Цитата:
Почему BitBlt не принимает в качестве параметра hdcSrc созданный в памяти контекст, я не знаю. Графическая информация, подготовленная через контекст в памяти, отображается в окне при помощи BitBlt. Другой вопрос, что дескриптор контекста, передаваемый BitBlt, не совпадает с дескриптором, созданным CreateCompatibleDC. |
|
16.06.2009, 21:19 | #10 | |
Пользователь Подтвердите свой е-майл
Регистрация: 21.06.2008
Сообщений: 12
|
Цитата:
А потом из этого промежуточного дескриптора с помощью BitBlt прописывается в контекст устройства, который соответствует окну. (Предпоследний найден, предполагаю с помощью GetDC) Вот, посмотри эту тему, в частности сообщение N 4. Как раз об этом http://www.wasm.ru/forum/viewtopic.php?id=33082 Ну и от себя. Я читал где-то в инете, что промежуточные усройства вот для чего используются: если, допустим с помощью TextOut рислвать текст не в промежуточном устройстве, а сразу в окне, то после прорисовки каждой стоки будет происходить мигание окна. Надеюсь, помог в прояснении. |
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
operator= для NULL | Selebro | Общие вопросы C/C++ | 2 | 14.12.2008 16:29 |
Обработка значения Null в sql запросе | KeyDok | БД в Delphi | 6 | 13.07.2008 12:03 |
delete where fields=null??? | Geddar | SQL, базы данных | 1 | 02.06.2008 16:57 |
Delphi 2007 и NULL | nemaster21 | Общие вопросы Delphi | 14 | 23.04.2008 16:59 |
вопрос time(NULL) | Ceprey | Общие вопросы C/C++ | 5 | 07.03.2008 11:30 |