2012-01-06 24 views
6

Jeśli okno, na przykład Firefox zmienia swój tytuł z Firefox na Stack Overflow - Firefox, a następnie chcę, aby moja aplikacja zapisywała, że ​​Firefox zmienił swój tytuł.Tytuł okna Zmieniono wydarzenie

Czy jest to możliwe bez użycia haczyka i pętli (EnumWindows)? Jeśli można zrobić tylko za pomocą haka, jaki rodzaj haka?

+0

Czy mówisz o pojedynczej przeglądarce, a także przekierowaniach ...? czy wyszukiwałeś na Żądanie/Odpowiedź i uzyskiwałeś dostęp do nagłówków? po prostu ciekawa, czy jestem na tej samej stronie co ty .. – MethodMan

+1

Tak, wymagany hak. Jestem pewien, że już powiedziałem ci o WH_SHELL. –

+1

możliwy duplikat [Zaloguj wszystkie okna zamknięte w systemie Windows] (http://stackoverflow.com/questions/8648386/log-all-windows-that-are-closed-in-windows) –

Odpowiedz

9

WinEvents to sposób, aby przejść tutaj. Interfejs API, którego potrzebujesz, to SetWinEventHook() - jeśli interesuje Cię określone okno, użyj GetWindowThreadProcessId(), aby uzyskać identyfikator wątku HWND, a następnie odsłuchaj zdarzenia tylko z tego konkretnego wątku. W przypadku zmian tytułu okna będziesz potrzebować zdarzenia EVENT_OBJECT_NAMECHANGE.

Możesz przechwycić "w kontekście" lub "poza kontekstem" - ta ostatnia jest najprostsza i oznacza, że ​​zdarzenie zostanie dostarczone z powrotem do twojego własnego procesu, więc nie potrzebujesz osobnej biblioteki DLL - co sprawia, że możliwe zrobić to wszystko w języku C#; ale wątek, który wywołuje SetWinEventHook musi mieć pętlę komunikatów (GetMessage/TranslateMessage/DispatchMessage), ponieważ zdarzenia są dostarczane za pomocą postaci wiadomości za kulisami.

W twoim zgłoszeniu zwrotnym WinEvent, musisz sprawdzić, czy HWND jest tym, na którym Ci zależy, ponieważ dostaniesz zmiany nazw dla dowolnego interfejsu użytkownika w tym docelowym wątku, prawdopodobnie włączając zmiany nazwy okna podrzędnego lub inne rzeczy nie obchodzi cię to.

-

Nawiasem mówiąc, można sprawdzić this answer przez jakiś przykładowy kod C#, który używa WinEvents; używa ich do śledzenia zmian pierwszoplanowych okien we wszystkich oknach na pulpicie; ale wystarczy wykonać kilka prostych modyfikacji opisanych powyżej, aby śledzić zmiany nazw w określonym oknie.

+1

EVENT_OBJECT_NAMECHANGE występuje bardzo często, jest wyzwalany nawet po przesunięciu myszy na tę samą kartę w tym samym oknie! czy jest to związane z tym, co powiedziałeś "prawdopodobnie włączając zmiany nazwy okna dziecka", ale jak tego uniknąć? po prostu ignorując te same powtarzające się "tytuły okien" w wywołaniu zwrotnym? – JohnTube

+1

Jeśli interesują Cię tylko zmiany w jednym procesie, możesz określić identyfikator procesu w wywołaniu "SetWindowEventHook", co znacznie zmniejszy liczbę obserwowanych zdarzeń. –

+0

@BrendanMcK Otrzymuję tytuły po przełączeniu okien, np. z chome> notepad> visualstudio, ale nie wiadomo, jak zaimplementować zdarzenie do zmiany tabulatora w chrome lub zmiany dokumentu w visualstudio. czy możesz pomóc? pozdrowienia –

3

Będziesz potrzebował haka (lub techniki głosowania, o której wspomniałeś w swoim pytaniu).

Zasadniczo w Windows API, aby zmienić "podpis okna" - lub dokładniej tekst okna - wysyłasz WM_SETTEXT, więc twój hak musi przechwycić tę wiadomość. Wymagany typ haka to WH_CALLWNDPROC i po prostu sprawdź, czy otrzymujesz wiadomość: WM_SETTEXT, ajest głównym oknem dla aplikacji, której szukasz, więc nie otrzymasz fałszywych alarmów, takich jak aplikacja próbująca ustawić tekst okien dzieci).

Mała uwaga tutaj: chociaż prawdopodobnie tak nie jest, należy pamiętać, że tytuł, który widzisz, może być po prostu narysowany ręcznie, a nie zwykłym interfejsem API systemu Windows. Użyj Spy ++ lub czegoś, aby zobaczyć, co się dzieje, zanim pójdziesz za daleko w tę stronę, możesz spędzić dużo czasu za darmo.

+1

To zadziała, ale nie jest to najprostszy sposób. Połów z hakiem WH_CALLWNDPROC jest taki, że potrzebujesz osobnej biblioteki DLL C/C++ - nie możesz tego zrobić w C#. (Poza tym potrzebujesz osobnych zaczepów dla kodu 32- i 64-bitowego, jeśli Ci na tym zależy). SetWinEventHook będzie prawdopodobnie lepiej pasował, ponieważ możesz otrzymać powiadomienie z powrotem do swojego własnego procesu, unikając potrzeby osobna biblioteka DLL. – BrendanMcK

+0

Już opublikowałeś swoją odpowiedź, po co zawracać sobie głowę tym komentarzem? – Blindy

+5

Aby potencjalny przyszły czytnik SO zrozumiał, w jaki sposób te dwie techniki odnoszą się do siebie nawzajem, lub zobaczy to zastrzeżenie, nawet jeśli tylko zeskanuje zaakceptowaną odpowiedź; komentarz ma lepszą lokalizację przestrzenną niż osobna odpowiedź. – BrendanMcK

-7

Nie potrzebujesz żadnych haczyków. Wystarczy użyć zdarzeń Windows

+3

....... takich jak? – LarsTech

+0

@fred, to nie jest bardzo pomocna odpowiedź: system Windows ma wiele dostępnych funkcji, które można opisać jako zdarzenia. Jeśli korzystasz z google "Widows Events", otrzymujesz hit do logowania zdarzeń systemu Windows jako pierwszy mecz, który jest całkowicie niezwiązaną technologią. Przynajmniej podaj nazwę API lub podobną - najlepiej z łączem - aby czytelnik zrozumiał, o czym mówisz. – BrendanMcK