PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Veränderung im Fenster registrieren


JessicaLampe
2005-09-09, 18:41:36
Hallo, ich habe die folgende Frage:

Ich möchte mit MFC ermitteln, ob sich ein beliebiges Fenster (z. Bsp. ein Internetfenster) zur Laufzeit verändert hat.

Dafür kann ich das Fenster auf dem Desktop lokalisieren und die Kindelemente durchgehen.

Nun bräuchte ich einen geeigneten Lösungsansatz, wie ich vorgehen könnte um auf eine Veränderung im Fenster zu reagieren. Mir sind auf Anhieb 2 Möglichkeiten eingefallen, die aber wahrscheinlich beide nicht so 100%-ig funktionieren:

1. Ich könnte das Fenster suchen, mit ::SendMessage(HWND_Fensterelement, WM_GETTEXT, sizeof(Text), (LPARAM)Text); den Text ermitteln, alle Zeichenketten in einem Array speichern und nach einer vorgegebenen Zeit das Fenster erneut suchen und überprüfen, ob sich die Werte gegenüber dem Array verändert haben.

2. Ich könnte einen Screenshot erstellen und mit einer geeigneten Methode (über die Größe der Screenshotdatei ???) überprüfen, ob sich etwas verändert hat.

Ich denke aber, diese beiden Varianten sind nicht das Non-Plus-Ultra um auf eine tatsächliche Veränderung im Fenster zu reagieren.

Wie kann ich vorgehen um auf eine Änderung im Fenster zu registrieren? :confused:

Xmas
2005-09-09, 21:51:08
Welche Arten von Veränderung meinst du? Geht es nur um die Texte in Edit-Boxen, Focus-Veränderung, grafische Veränderungen, etc.?

Das einfachste wäre, die Steuerelemente des Fensters selbst dazu zu bringen, sich bei einer Veränderung zu melden. Dazu müsstest du deren Nachrichtenprozedur (WndProc) mit einer eigenen kapseln.

muhkuh_rs
2005-09-10, 01:40:33
Was genau meinst Du damit, dass sich ein Fenster verändert hat? Bei einigen kannst du mit WM_GETTEXT den Inhalt abfragen. Bei anderen wird das schweirig zu unterscheiden, ob es sich nur um einen normalen Redraw handelt oder ob sich der Fensterinhalt verändert hat.

Bei der Geschichte mit WM_GETTEXT würde es funktionieren, dir mit EnumWindows alle möglichen Fenster und mit EnumChildWIndows alle Kindfenster zurückgeben zulassen, allerdings müsstest du dann pollen. WM_GETTEXT funktioniert aber z.B. nicht bei Passworteingabefeldern aus einer anderen Anwendung heraus.

Wenn Du nicht pollen willst, müsstest Du Hooks installieren mit SetWindowsHookEx, was allergings bei allen Fenstern ziemlich nervig und eventuell auch recht langsam sein dürfte.

JessicaLampe
2005-09-10, 15:54:25
Hallo Xmas und muhkuh_rs,

als eine Veränderung in einem Fenster definiere ich, dass auf das Beispiel einer Internetseite bezogen, beispielsweise ein Forenbeitrag hinzugekommen, ein neuer Text/Button/Bild aufgetaucht ist etc.

Eine Focusveränderung etc. will ich nicht berücksichtigen, da ich selbst für den Refresh des jeweiligen Fensters verantwortlich bin und dazu den Focus selbst neu setze.

Wie ich sämtliche Fenster-/elemente enumeriere, weiß ich.
Wäre es ausreichend, wenn ich alle Elemente ermittle, sie in einem Array speichere (die Antwort von WM_GETTEXT) und dann nach dem Refresh mit den alten Inhalten vergleiche?

Was ist das Pollen, das du angesprochen hast?

Wenn ich mit einem Hook arbeiten würde, welchen Hook müsste ich einsetzen um die gewünschten Veränderungen zu registrieren? :confused:

muhkuh_rs
2005-09-11, 01:08:31
Pollen bedeutet, in bestimmten Abständen abzufragen, ob sich etwas verändert hat. Bei Hooks wäre es nicht so, sondern du könntest alle möglichen Nachrichten, die das Fenster bekommt, abfangen (z.B. WM_SETTEXT ).

Wenn Du selber für für den Redraw des Fensters verantwortlich bist, dann kannst Du Dir Hooks sparen. Alle Child Windows und deren Fenstertext zu speichern und bei einem Redraw mit dem neuen zu vergleichen könnte klappen. Theoretisch kann das Browserfenster nach einem Refresh aber auch neue Child Windows erzeugt und einige gelöscht haben. Außerdem ist sicher nicht jede Textänderung relevant und ich weiß auch nicht, ob alle Dich interessierenden Elemente, mit denen Text auf der Website gerendert wird, Standard-Windowscontrols sind, die auf WM_GETTEXT reagieren. Einen Versucht ist es aber wert.