2013-12-09 4 views
1

У меня есть приложение VCL, которое я тестирую, но не имею исходного кода. Мне нужно проверить, какой текст был нарисован на ярлыках на экране, но метки не являются окном, поэтому я создаю крючок для функции drawtext, и я могу получить текст, который был нарисован на экране.Получить местоположение элемента управления после подключения к функции Drawtext

Но я не могу проверить, где на экране был нарисован текст, так как функция получает hdc и точку, где нужно нарисовать текст в контексте. Мне нужно определить, где на экране находится hdc, и убедиться, что метка верна.

Есть ли способ сделать это? Управляемая неуправляемая доза не имеет значения для меня.

ответ

1

Я думаю, что вам нужно будет сделать что-то вроде этого:

  1. вызов WindowFromDC узнать окно, на котором размещается ярлык. Как вы знаете, метка Delphi не окончена, и элемент управления фактически рисует в своем родительском окне. Это может завершиться неудачно, если родительский буфер с двойной буферизацией. В этом случае у вас нет надежды получить дескриптор окна из контекста устройства, поскольку все, что у вас есть, - это контекст устройства растрового изображения.
  2. Теперь, когда у вас есть окно, на котором нанесен ярлык, вам нужно узнать расположение метки в окне. VCL вызывает SetWindowOrgEx, чтобы установить, что контекст устройства имеет логические координаты 0,0 в левом верхнем углу метки. Поэтому вы можете позвонить GetWindowOrgEx, чтобы узнать расположение метки относительно родителя.
  3. Теперь вы знаете расположение метки относительно родителя и дескриптор окна родителя, вы можете определить, где текст нарисован на экране с помощью ClientToScreen.

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

+0

Тогда у меня нет надежды. – ealbert

+0

Есть еще надежда. Вам просто нужно определить, как битмап-буфер в конечном итоге нарисован на экране. Вы можете проверить, что текст написан в нужном месте в растровом изображении, поэтому, если вы можете проверить, что растровое изображение выведено в нужное место на экране, вы закончите. Альтернативой может быть просто сравнение последнего изображения на экране с хорошо известным изображением. –

+0

У вас есть идея, как проверить, где рисуется растровое изображение? – ealbert

1

Вы можете создать DLL в Delphi и вставить эту DLL в целевой процесс. Поскольку вы счастливо подключаете Win32 APis, я полагаю, у вас не будет проблем с этим.

В этой DLL вы можете найти (используя API Win32) HWND, который является «родителем» метки.

С этим HWND вы можете найти связанные TWinControl. Для этого вы должны погрузиться в исходный код VCL.

Для Delphi 4 (да, я знаю, это старый) вам нужно построить Atom-строку, используйте GlobalFindAtom, а затем GetProp. Результатом является указатель на TWinControl.

Для Delphi7 (старый тоже) вы должны использовать RegisterWindowMessage со строкой, составленной из «ControlOfs», за которой следует ручка модуля и идентификатор потока. Затем LRESULTSendMessage является указателем на TWinControl.

Извините, я не знаю других версий Delphi, но все они должны быть найдены в источниках VCL.

После того как вы TWinControl указателя, вы можете перечислить ребенок как TComponent, и получить их Name «с (как они появляются в исходном коде у вас нет ...), их ClassName» с, и так на, вы получаете идею.

+0

Я попробую это решение, если все остальное не удастся. Мне нужно будет сделать это несколько раз для разных версий delphi. Также я надеялся на решение, которое будет охватывать и другие языки. – ealbert

+0

Я нацелился на общий случай, не забудьте UIAutomation. Но, imho, нет серебряной пули. – manuell

+0

UIAutomation здесь не поможет, потому что это не оконный элемент управления, а VCL не реализует интерфейсы автоматизации помимо того, что поставляется бесплатно со стандартными элементами управления Win32. –

Смежные вопросы