2012-01-06 2 views
6

Если окно, например. Firefox, меняет название, от Firefox до Stack Overflow - Firefox, затем я хочу, чтобы мое приложение записывало, что Firefox изменил название.Название окна Измененное событие

Возможно ли это без использования крюка и петли (EnumWindows)? Если можно сделать только с помощью крючка, какой тип крючка?

+0

Вы говорите об одном браузере, а также о переадресации ..? вы искали в Request/Response и обращались к заголовкам? просто интересно, если я на той же странице, что и вы .. – MethodMan

+1

Да, требуется крючок. Довольно уверен, что я уже говорил вам о WH_SHELL. –

+1

Возможный дубликат [Регистрация всех Windows, закрытых в Windows] (http://stackoverflow.com/questions/8648386/log-all-windows-that-are-closed-in-windows) –

ответ

9

WinEvents - это путь сюда. Необходимый вам API: SetWinEventHook() - если вам интересно о конкретном окне, используйте GetWindowThreadProcessId(), чтобы получить threadId HWND, а затем прослушать события только из этого конкретного потока. Для изменений названия окна вам понадобится событие EVENT_OBJECT_NAMECHANGE.

Вы можете подключить либо «в контексте», либо «вне контекста» - последний является самым простым и означает, что событие доставляется обратно в ваш собственный процесс, поэтому вам не нужна отдельная DLL - это делает его возможно сделать все это на C#; но поток, который вызывает SetWinEventHook, должен иметь цикл сообщений (GetMessage/TranslateMessage/DispatchMessage), поскольку события доставляются с использованием формы сообщений за кулисами.

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

-

Кстати, вы можете проверить this answer для некоторых образца C# код, который использует WinEvents; он использует их для отслеживания изменений окна переднего плана во всех окнах на рабочем столе; но нужно просто сделать несколько простых изменений, описанных выше, чтобы отслеживать изменения имен в определенном окне.

+1

EVENT_OBJECT_NAMECHANGE много, он срабатывает даже при перемещении мыши на одной и той же вкладке того же окна! это связано с тем, что вы сказали «возможно, включая изменения имени дочернего окна», но как этого избежать? просто игнорируя одни и те же повторяющиеся «заголовки окон» в обратном вызове? – JohnTube

+1

Если вас интересуют только изменения в одном процессе, вы можете указать идентификатор процесса в вызове 'SetWindowEventHook', что значительно уменьшит количество наблюдаемых событий. –

+0

@BrendanMcK Я получаю заголовки при переключении окон, например. из chome> notepad> visualstudio, но не получая, как реализовать событие для изменения вкладок хрома или изменения документа в visualstudio. вы можете помочь? С уважением –

3

Вам понадобится крючок (или техника опроса, указанная в вашем вопросе).

В основном в Windows API, чтобы изменить «заголовок окна» - или, точнее, текст окна - вы отправляете WM_SETTEXT, поэтому ваш крючок должен перехватить это сообщение. Тип крюка, который вам нужен, - WH_CALLWNDPROC, и просто проверьте, является ли получаемое сообщение WM_SETTEXT, а hWnd является основным окном для приложения, которое вы ищете (чтобы вы не получали ложные срабатывания, такие как приложение, пытающееся установить текст окон детей).

Небольшое примечание здесь. Хотя это, вероятно, не так, помните, что название, которое вы видите, можно просто нарисовать там вручную, а не через обычный Windows API. Используйте Spy ++ или что-то, чтобы увидеть, что происходит, прежде чем идти слишком далеко по этому маршруту, вы можете потратить много времени.

+1

Это будет работать, но это не самый простой способ. Ловушка с крюком WH_CALLWNDPROC заключается в том, что вам понадобится отдельная библиотека C/C++ - вы не можете сделать все это на C#. (Кроме того, вам понадобятся отдельные перехватчики для 32-разрядного и 64-битного кода, если вам это интересно.) SetWinEventHook, скорее всего, будет лучше подходит здесь, так как вы можете вернуть уведомление в свой собственный процесс, избегая необходимости отдельная DLL. – BrendanMcK

+0

Вы уже отправили свой ответ, зачем беспокоиться об этом комментарии? – Blindy

+5

Чтобы потенциальный будущий SO-читатель понял, как эти два метода связаны друг с другом, или увидит это предостережение, даже если только сканирование принятого ответа; комментарий имеет лучшую пространственную локальность, чем отдельный ответ. – BrendanMcK

-7

Вам не нужны крючки. Просто используйте окна событий

+3

....... такой как? – LarsTech

+0

@fred, это не очень полезный ответ: Windows имеет много доступных функций, которые можно охарактеризовать как события. Если вы google для «Widows Events», вы получаете хит для регистрации событий Windows как первое совпадение, которое является абсолютно несвязанной технологией. По крайней мере, дайте имя API или подобное - предпочтительно со ссылкой - чтобы читатель понял, о чем вы говорите. – BrendanMcK

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