GetWindowText und WM_GETTEXT

Es soll ja tatsächlich Leute geben, die den Unterschied der beiden Funktionsweisen noch nicht kennen. Liest man die MSDN-Dokumentation, so kann man erkennen, dass GetWindowText nur zuverlässig für den eigenen Prozess funktioniert. Die Begründung findet man dann bei “The Old New Thing“.

Und damit es jeder auch selber nachvollziehen kann, dass GetWindowText wirklicht nicht zuverlässig für andere Prozesse geht, hab ich hier ein kleines Beispielprogramm:
http://blog.kalmbachnet.de/files/GetWindowText.zip

Wie man aus dem verwiesenen Blog-Eintrag erkennen kann, verwendet intern “GetWindowText” nur WM_GETTEXT, wenn es ein Fenster im eigenen Prozess ist. Sonst wird ein “secret-buffer” verwendet. Ein WM_GETTEXT wird nicht gesendet!

Die ZIP-Datei besteht aus zwei Projekten (Release-EXEn liegen auch drin, damit man es nicht mal mehr selber übersetzen muss).
1. TargetApp: Dieses Wizard erzeugte Fenster-Programm verarbeitet selber die WM_GETTEXT Message und gibt als String “Booga!” zurück. Durch Aufruf von “Help|About…” kann man nachweisen, dass “GetWindowText” hier den String “Booga!” zurück gibt. Es verwendet also WM_GETTEXT um den Text zu erhalten.

2. SpyApp: Dieses Wizard erzeugte Fenster-Programm mach nach Aufruf von “Help|About…”: Es ermittelt das Fenster-Handle des TargetApp durch den Klassennamen (TARGETAPP). Dann kommt der eigentlich Aufruf zu “GetWindowText”. Der zurückgegebene Text wird dann in einer MessageBox angezeigt.

Und dreimal dürft Ihr Raten, was das für ein Text ist 😉 (nein, es ist nicht “Booga!”).

PS: Auch durch den Aufruf von diversen anderen Funktionen wie AttachThreadInput und GetFocus ändert sich an dem verhalten nichts, dass GetWindowText nicht WM_GETTEXT verwendet.

PPS: Wer sich für den Auslöser dieses Posting interessiert, der kann es hier nachlesen:
aktives Control ermitteln
Dort behauptet der Poster, dass “GetWindowText” intern WM_GETTEXT sendet. Und das stimmt natürlich nur für den eigenen Prozess, nicht aber für externe (in diesem Thread geht es nur um externe Prozesse).

[ADD: 2009-10-11]
PPPS: Wer sich wundert, warum im Source-Code der SpyApp sowas komisches wie “AttachThreadInput” aufgerufen wird, der sollte einfach nur den obigen Thread lesen… dieser Aufruf ist einfach sinnlos und kann getrost entfernt werden; ein anderer behauptet in dem Thread, dass es “unbedingt notwendig” ist, damit das “GetWindowText” intern ein WM_GETTEXT verwendet (was es ja für externe Prozesse nicht tut, wie das Beispiel ja schön zeigt).