Autor Beitrag
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Sa 22.03.08 22:16 
Hallo, liebe Delphianer!

Mein nächstes Problem scheint schon wieder derart subtil zu sein, daß ich dazu in keinem Forum eine befriedigende Antwort fand.

Es geht um die Enumeration aller ChildWindows in einem ParentWindow, die im Prinzip ja so abläuft (und auch bei mir durchaus funktioniert):

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
var a:array[1..30of word;

function EnumChildProc(Wnd:hWnd;LParam:Longint):Bool;stdcall;
  begin
  Result:=Wnd<>0;
  if result then
    begin
    if a[1]=1 then {irgendein Code}
    EnumChildWindows(Wnd,@EnumChildProc,0)//Rekursiver Aufruf
    end
  end;

EnumChildWindows(ParentWindowHandle,@EnumChildProc,0);//Erstaufruf


Die EnumChildProc-Funktion wird mit Hilfe des @-Zeichen als/per Zeiger übergeben, aufgerufen, adressiert (?), jedenfalls las ich das so in etwa mal irgendwo. Und das scheint auch die Ursache meines Problems zu sein (obwohl der Compiler nicht meckert): Ich bekomme keinen Zugriff auf globale Variablen (hier am Beispiel des a-Arrays): Mal stimmen die Werte nicht, mal gibt es Programmabstürze als Exeptions oder anderweitige (access violation u.ä.). Ohne solche Zugriffsversuche auf globale bzw. externe Variablen, also wenn die Funktion ihr eigenes Süppchen kochen kann, kann ich die Funktion bestimmungsgemäß und unproblematisch einsetzen.

Weiß jemand, wie man innerhalb "gezeigerten" Funktion "EnumChildProc" auf globale Variablen oder wenigstens auf Variablen, die nicht in dieser (wiederholt rekursiv aufgerufenen) Funktion definiert wurden, sicher und unproblematisch lesend zugreifen kann? Oder gibt es einen anderen Weg gibt, zusätzliche Informationen (jedenfalls mehr, als Microsoft definierte) in diese Funktion zu schleusen? Mir würde es schon reichen, wenn ich diese Werte innerhalb dieser Funktion auslesen könnte, einen Bedarf, die globalen Werte dort auch zu ändern, sehe ich momentan nicht.

Versucht habe ich auch schon einiges in Richtung der Zeiger aus der guten alten Turbo-Pascal-Zeit (mit dem ^-Zeichen), jedoch alles erfolglos.

Besten Dank für Eure Aufmerksamkeit und Euer Bemühen!

Netter Gruß

Delphi-Laie

Postscriptum: Die Showmessagefunktion funktioniert in der Funktion EnumChildProc übrigens auch nicht.


Zuletzt bearbeitet von Delphi-Laie am Mo 31.03.08 23:26, insgesamt 2-mal bearbeitet
Logikmensch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 390

Win XP
Delphi 2007 Prof., XE2, XE5
BeitragVerfasst: Do 27.03.08 06:56 
Solange Du innerhalb der Enum-Funktionen das Array a nicht veränderst, sollte der Zugriff eigentlich funktionieren, vorausgesetzt, a ist ordentlich initialisiert, bevor EnumChildWindows erstmals ausgeführt wird (z.B. mit FillChar). Falls Du a aber innerhalb der Enum-Funktionen veränderst, bedenke, dass rekursiv ausgeführte Prozeduren/Funktionen grundsätzlich Probleme mit globalen Variablen haben, die sie selbst beeinflussen.
Vielleicht hilft es, wenn Du mal sagst, was mit dem a-Array eigentlich gemacht wird...

_________________
Es gibt keine Probleme - nur Lösungen!
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 27.03.08 10:22 
Auch wäre interessant, ob a statisch oder dynamisch ist.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Delphi-Laie Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Fr 28.03.08 16:07 
Vielen, herzlichen Dank Euch beiden! Mit einer Antwort rechnete ich gar nicht mehr.

Etwas detaillierter und aktualisierter schilderte ich das Problem in:www.delphipraxis.net...ebergebfunktion.html (ja, ich bin fremdgegangen, ich gebe es zu). Dort leider noch ohne Reaktion.

Natürlich verändere ich a in der/den rekursiv aufgerufenen Funktion(en) nicht. Mir würde der korrekte lesende Zugriff auf a schon völlig reichen (man wird mit den Mißerfolgen eben bescheidener).

Es kommt ja eigentlich noch schlimmer. Selbst in der Hookprozedur (HookProc), die ich hier der Einfachheit halber gar nicht mit in meinen beispielhaften Quelltext eingebunden habe und die "nur" als Argument (aber eben nicht explizit) aufgerufen wird (dieser Aufruf funktioniert merkwürdigerweise sowohl gezgeigert (@HookProc) als auch ungezeigert) ist ein sauberer, also fehlerfreier Zugriff auf a unmöglich (der Zugriff führt nicht zum Programmabbruch, aber die übergebenen Werte stimmen nicht).

a ist statisch. Alles so einach wie möglich. Ich arbeite aus gutem Grunde mit Delphi3 (obwohl mir durchaus aktuellere Delphis auch zur Verfügung stehen und auch installiert sind - benutze ich i.d.R. aber nur probeweise und bei Bedarf).

Initialisiert? Ist mir nicht bekannt, daß man das mit statischen Variablen tun muß. Seit wann denn das? Und wie soll das vonstatten gehen? (Meine Güte, was gibt es denn noch alles zu beachten und zu lernen....) Aber vielleicht haben DLLs ja noch mehr eigene Gesetze. Also, ich schleuse ein array in die DLL über die Übergabeschnittstellen der DLL-Funktionen, die vom Hauptprogramm aufgerufen werden, in die DLL ein (war das verständlich?). Innerhalb dieser aufgerufenen Funktionen ist das übergebene array nur lokal, deshalb lasse ich das an a dort in der aufgerufenen Funktion übergeben. a steht mir dann auch - nachgeprüft! - in anderen, nicht per Argument aufgerufenen Funktionen der DLL zur Verfügung, ist dort also global (wurde ja auch so definiert), nur nicht in der per Argument aufgerufenen HookProc und auch nicht in der oben beispielhaft angegebenen Funktion.

FillChar? Kenne ich nicht, und auch aus der Delphihilfe werde ich nicht so recht schlau. a ist aber zum Zeitpunkt des Zugriffs definitiv mit den richtigen Werten belegt (wie ich in anderen Funktionen feststellen konnte).

EumChildProc und EnumChildWindows habe ich entfernt (ging zur Not auch ohne). Momentan lasse ich in die Funktion HookProc die Werte über Dateizugriff einlesen/einschleusen. Nicht optimal und macht mich deshalb nicht glücklich, es funktioniert aber wenigstens.

Scheint also, als müsse ich noch viel lernen. Delphi-Laie auf Ewigkeit....

Nochmals den besten Dank an Euch beide, das hat mir schon ein wenig weitergeholfen!

Netter Gruß

Delphi-Laie


Zuletzt bearbeitet von Delphi-Laie am Fr 28.03.08 17:23, insgesamt 1-mal bearbeitet
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Fr 28.03.08 16:52 
Der Einfachheit halber zu unterschlagen, dass es sich um eine HookDLL handelt könnte in diesem Falle dein Genickbruch gewesen sein.

Denn der Code von DLLs befindet sich zwar nur ein einziges Mal im Speicher aber in jeder Anwendung, hat die DLL einen eigenen Datenbereich. Mit anderen Worten du hast eine Integervariable in der DLL die du in Anwendung 1 setzt. Wenn jetzt gleichzeitig Anwendung 2 die DLL benutzt, dann bekommt sie einen ganz anderen Wert, da sie auch eine eigenständige Variable hat.

Wie man diese Daten aber sinnvoll zwischen den Anwendungen verteilt weiß ich nicht. Aber es gibt irgendwie die Möglichkeit Speicher so erstellen zu lassen, dass dieser von mehreren Anwendungen gleichzeit benutzt werden kann. Aber wie? Keine Ahnung. Und wie du diese in die DLL bekommst ist auch wieder etwas Anderes. Denn Hook DLLs werden automatisch von Windows in die anderen Anwendungen eingeklingt.

PS: Man lernt nie aus. Wer was anderes behauptet ist ignorant und/oder lügt. Allerdings sind Hooks und deren Eigenarten auch alles andere als ein Anfängerthema. Es gibts zu viel was man verkehrt machen kann und worauf man achten muss.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
Delphi-Laie Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Fr 28.03.08 17:10 
Und ich hatte gerade noch versucht, vereinfachte Versionen von Hauptprogramm und Library zu basteln (die den Effekt zeigen sollten), um diese dann hier vorzustellen.

Meine böse Absicht war das nicht, ich erachtete, daß die DLL über einen Hook aufgerufen wird, als nicht so relevant. Anscheinend ist das alles noch viel komplizierter. DLL-Programmierung im allgemeinen und Hook-Programmierung im spezielllen scheinen ja oberätzend zu sein. Ich mußte mich mit dem Thema DLL notgedrungen auseinandersetzen, weil Hookprogrammierung nur über Exe für mich defnitiv (noch?) eine Nummer zu groß ist (auch MS widerspricht sich da m.E., ob DLL wirklich nötig ist oder nicht). Erst einmal soll das Ganze funktionieren.

Momentan, wie gesagt, bekomme ich das über Dateizugriff wenigstens funktionell hin (die Hooks funktionieren übrigens inzwischen hervorragend). Wenn es eben wegen des Hooks nicht möglich ist, dann kann ich damit auch leben.

Meine nächste Version von "AutoSetColumnSize" wird auch recht bald fertig sein (aus dem "Säugling" wird allmählich ein "Kind") - werde ich dann wieder vorstellen - vielleicht kann sich ja dann doch jemand dafür erwärmen (ich finde das Programm oberpraktisch).

Vielen, allerherzlichsten Dank!

Netter Gruß

Delphi-Laie
Delphi-Laie Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Mo 31.03.08 23:38 
Lossy eX, Deine Erläuterung erklärt auch, warum die aus der hookinitiierten Funktion heraus aufgerufene relative Pfadangabe (GetDir) nicht sauber in dem von mir bezweckten Sinne funktioniert: Sie liefert zwar Ergebnisse, die aber nicht immer den Standort der DLL (wie ich es eigentlich gern gehabt hätte) enthalten.
Frankieboy
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 65



BeitragVerfasst: Mi 02.04.08 16:37 
Genau das gleiche Problem habe ich mit der Win-API Funktion EnumThreadWindows...

Obwohl ich ein Beispiel auf einfachste Weise in eine Delphi-App übernommen habe, bekomme ich jedesmal beim Aufruf eine Access Violation.
EnumThreadWindows braucht auch eine Callback-Funktion.
Und dabei bräuchte ich die Funktion sehr dringend :evil: :evil: :evil:

Frankie