{"id":40,"date":"2009-10-09T09:32:00","date_gmt":"2009-10-09T08:32:00","guid":{"rendered":"http:\/\/blog.kalmbach-software.de\/de\/2009\/10\/09\/getwindowtext-und-wm_gettext\/"},"modified":"2009-10-11T14:07:04","modified_gmt":"2009-10-11T13:07:04","slug":"getwindowtext-und-wm_gettext","status":"publish","type":"post","link":"http:\/\/blog.kalmbach-software.de\/de\/2009\/10\/09\/getwindowtext-und-wm_gettext\/","title":{"rendered":"GetWindowText und WM_GETTEXT"},"content":{"rendered":"<p>Es soll ja tats\u00e4chlich Leute geben, die den Unterschied der beiden Funktionsweisen noch nicht kennen. Liest man die MSDN-Dokumentation, so kann man erkennen, dass <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms633520\">GetWindowText<\/a> nur zuverl\u00e4ssig f\u00fcr den eigenen Prozess funktioniert. Die Begr\u00fcndung findet man dann bei &#8220;<a href=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2003\/08\/21\/54675.aspx\">The Old New Thing<\/a>&#8220;.<\/p>\n<p>Und damit es jeder auch selber nachvollziehen kann, dass <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms633520\">GetWindowText<\/a> wirklicht nicht <strong>zuverl\u00e4ssig<\/strong> f\u00fcr andere Prozesse geht, hab ich hier ein kleines Beispielprogramm:<br \/>\n<a href=\"http:\/\/blog.kalmbachnet.de\/files\/GetWindowText.zip\">http:\/\/blog.kalmbachnet.de\/files\/GetWindowText.zip<\/a><\/p>\n<p>Wie man aus dem verwiesenen Blog-Eintrag erkennen kann, verwendet intern &#8220;GetWindowText&#8221; nur <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms632627\">WM_GETTEXT<\/a>, wenn es ein Fenster im eigenen Prozess ist. Sonst wird ein &#8220;secret-buffer&#8221; verwendet. Ein <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms632627\">WM_GETTEXT<\/a> wird nicht gesendet!<\/p>\n<p>Die ZIP-Datei besteht aus zwei Projekten (Release-EXEn liegen auch drin, damit man es nicht mal mehr selber \u00fcbersetzen muss).<br \/>\n1. TargetApp: Dieses Wizard erzeugte Fenster-Programm verarbeitet selber die WM_GETTEXT Message und gibt als String &#8220;Booga!&#8221; zur\u00fcck. Durch Aufruf von &#8220;Help|About&#8230;&#8221; kann man nachweisen, dass &#8220;GetWindowText&#8221; hier den String &#8220;Booga!&#8221; zur\u00fcck gibt. Es verwendet also WM_GETTEXT um den Text zu erhalten.<\/p>\n<p>2. SpyApp: Dieses Wizard erzeugte Fenster-Programm mach nach Aufruf von &#8220;Help|About&#8230;&#8221;: Es ermittelt das Fenster-Handle des TargetApp durch den Klassennamen (TARGETAPP).  Dann kommt der eigentlich Aufruf zu &#8220;GetWindowText&#8221;. Der zur\u00fcckgegebene Text wird dann in einer MessageBox angezeigt.<\/p>\n<p>Und dreimal d\u00fcrft Ihr Raten, was das f\u00fcr ein Text ist \ud83d\ude09 (nein, es ist nicht &#8220;Booga!&#8221;).<\/p>\n<p>PS: Auch durch den Aufruf von diversen anderen Funktionen wie AttachThreadInput und GetFocus \u00e4ndert sich an dem verhalten nichts, dass GetWindowText nicht WM_GETTEXT verwendet.<\/p>\n<p>PPS: Wer sich f\u00fcr den Ausl\u00f6ser dieses Posting interessiert, der kann es hier nachlesen:<br \/>\n<a href=\"http:\/\/groups.google.de\/group\/microsoft.public.de.german.entwickler.dotnet.csharp\/msg\/90f0b3105ce866e3\">aktives Control ermitteln<\/a><br \/>\nDort behauptet der Poster, dass &#8220;GetWindowText&#8221; intern WM_GETTEXT sendet. Und das stimmt nat\u00fcrlich nur f\u00fcr den eigenen Prozess, nicht aber f\u00fcr externe (in diesem Thread geht es nur um externe Prozesse).<\/p>\n<p>[ADD: 2009-10-11]<br \/>\nPPPS: Wer sich wundert, warum im Source-Code der SpyApp sowas komisches wie &#8220;AttachThreadInput&#8221; aufgerufen wird, der sollte einfach nur den obigen Thread lesen&#8230; dieser Aufruf ist einfach sinnlos und kann getrost entfernt werden; ein anderer behauptet in dem Thread, dass es &#8220;<a href=\"http:\/\/groups.google.de\/group\/microsoft.public.de.german.entwickler.dotnet.csharp\/msg\/4abf4a5da607529d\">unbedingt notwendig<\/a>&#8221; ist, damit das &#8220;GetWindowText&#8221; intern ein WM_GETTEXT verwendet (was es ja f\u00fcr externe Prozesse nicht tut, wie das Beispiel ja sch\u00f6n zeigt).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Es soll ja tats\u00e4chlich Leute geben, die den Unterschied der beiden Funktionsweisen noch nicht kennen. Liest man die MSDN-Dokumentation, so kann man erkennen, dass GetWindowText nur zuverl\u00e4ssig f\u00fcr den eigenen Prozess funktioniert. Die Begr\u00fcndung findet man dann bei &#8220;The Old New Thing&#8220;. Und damit es jeder auch selber nachvollziehen kann, dass GetWindowText wirklicht nicht zuverl\u00e4ssig [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-40","post","type-post","status-publish","format-standard","hentry","category-alles-uber-die-echte-windowsprogrammierung"],"_links":{"self":[{"href":"http:\/\/blog.kalmbach-software.de\/de\/wp-json\/wp\/v2\/posts\/40","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.kalmbach-software.de\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.kalmbach-software.de\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.kalmbach-software.de\/de\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.kalmbach-software.de\/de\/wp-json\/wp\/v2\/comments?post=40"}],"version-history":[{"count":0,"href":"http:\/\/blog.kalmbach-software.de\/de\/wp-json\/wp\/v2\/posts\/40\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.kalmbach-software.de\/de\/wp-json\/wp\/v2\/media?parent=40"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.kalmbach-software.de\/de\/wp-json\/wp\/v2\/categories?post=40"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.kalmbach-software.de\/de\/wp-json\/wp\/v2\/tags?post=40"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}