Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » Hookproc, Dll, Rückruf zur Exe

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
13.04.2003, 16:00 Uhr
~SKARF
Gast


Ich Programmiere mit dem Visual C++ 6 Compiler für win9x / XP.
Ich habe bereits vor geraumer Zeit verzweifelt ein Programm aufgegeben
welches eigendlich anfangs recht einfach schien.
Jetzt habe ich von diesem Forum erfahren und hoffe ihr könnt mir weiterhelfen.
Dazu werde ich ziemlich weit ausholen,merkwürdige Rechtschreibung verwenden und Kommas falsch oder gar nicht setzen:

Ziel war und ist es ein Programm zu schreiben welches die Tastatur überwacht und aufgrund bestimmter Tasten bestimmte benutzerdefinierte Dinge tut.
Ein solches gehörte zum Beispiel auch zu meiner Tastatur um die dieversen "Extratasten" zu Überwachen nur leider ist dieses nicht konfigurierbar.
Aus irgendeinem Grund hatte der Programmierer keine Lust dies zu realisieren also werde ich es wohl selber machen müssen.

Das ganze lässt sich wohl am besten mit einer Hookprozedur bewerkstelligen
( mann halte mich auf wenn ich bereits hier falsch liege ).

Hiermit überwache ich alle existierenden Threads und damit auch ALLE Tastaturereignisse.

Folgender Aufruf in der EXE:
SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,dll,NULL);

WH_KEYBOARD -> wegen Tastatur Hook
KeyboardProc -> zeigt auf Hookprozedur in DLL
dll -> Handle to DLL
NULL -> alle Threads

Da ich alle Threads überwache muss sich die Hookprozedur in einer DLL befinden:
( mann halte mich auf wenn diese Behauptung falsch ist )

#define exp extern "C" __declspec(dllexport)

//Hookprozedur (Aufruf durch Explorer.exe)
exp LRESULT CALLBACK KeyboardProc(int code,WPARAM wParam,LPARAM lParam)
{

unsigned int x;
unsigned int scan;

x = lParam & 3221225472;

if(x == 0)
{

scan = lParam & 16711680;
scan >>= 16;

switch (scan)
{
case 20: //Einer der "Extratasten"

MessageBox(NULL,"Test","xxx",MB_OK);

break;
}

}

return CallNextHookEx(hook,code,wParam,lParam);
}

Soweit so gut bis hier funktioniert das ( auf Tastendruck folgt MessageBox ), ist aber auch noch recht sinnlos.
Das Problem ist jetzt, das sich der aufgrund eines Tastendrucks auszuführende Code in der EXE und nicht in der DLL befinded. Also muss ich innerhalb "KeyboardProc" irgendwie eine funktion aus der EXE aufrufen.
D.h. die Explorere.exe müsste irgendwie die Funktion in der EXE aufrufen ( über die DLL selbstverständlich ).

Versucht habe ich das mit einem Zeiger auf diese Funktion.
Diesen habe ich einer exportierten Funktion in der DLL übergeben welche ihn wiederum in einen Global definierten Zeiger kopiert.
Somit konnte ich in "KeyboardProc" über den globalen Zeiger die Funktion in der EXE aufrufen.
Das hat sogar funktioniert und es folgte abermals eine MessageBox auf Tastendruck.
Sobald aber das Fenster der EXE in irgendeiner Weise inaktiv wurde hat das nicht mehr funktioniert.
Schade Fehlschlag!


Anmerkung dazu:
Scheinbar wird beim minimieren oder bei inaktiven Fenster die betreffende Funktion in der EXE ( oder die ganze EXE ) im RAM verschoben.
Damit würde der Zeiger in der DLL irgenwo ins Leere zeigen.
Das würde normalerweise einen Absturz verursachen. Explorer.exe erkennt diesen Umstand allerdings, ignoriert den Zeiger und entläd die ganze DLL.
( vorher war die DLL von beiden Geladen: Explorer.exe und meiner EXE )
Um diese Theorie nachzuvollziehen habe statt die Funktion über den Zeiger aufzurufen mit dem Zeiger einen neuen Thread begonnen.
Jetzt hat Explorer.exe den ungültigen Zeiger nicht mehr erkannt und ist abgestürtzt!
Ich hab meine Exlorer.exe getötet! Sehr schön, muss mann auch mal gemacht haben!


Dann habe ich abermals innerhalb "KeyboardProc" mit LoadLibrary und GetProcAddress einen Zeiger auf besagte Funktion erhalten ( diesmal local ).
Hat nur bei aktiven Fenster fuktioniert.
Hier müsste ja GetProcAddress auch bei minimierten Fenster einen korrekten Zeiger liefern. Tat es nicht!
Schade Fehlschlag ! Warum nur? Ist die Funktion ausgelagert worden? oder wie? wo isse hin?


Dann habe ich versucht die EXE mittels "PostMessage" zu informieren.
Nur solange das Fenster nicht minimiert war!
Das sehe ich sogar ein aber trotzdem: Schade Fehlschlag!

Der nächste Versuch eine Nachricht zu senden war folgender:
SendNotifyMessage( HWND_BROADCAST,UINT Msg,WPARAM wParam,LPARAM lParam );
Ich habe hier eine benutzerdefinierte Nachricht gesendet da diese an alle Fenster ging.
Aufgrund des Parameters HWND_BROADCAST sollte diese Nachricht an alle existenten Fenster inclusive aller minimierten und versteckten Fenster gesendet werden. ( mann halte mich auf wenn diese Behauptung falsch ist )
Hat funktioniert solange das Fenster nicht minimiert oder versteckt war!
Schade Fehlschlag! Und das verstehe ich jetzt wirklich nicht.

SetTimer war auch noch so eine Idee.
Wenn der Aufruf in der DLL stattfindet und die übergebene Callbackfunktion in der EXE ist hätte mann einen zwar umständlichen aber funktionierenden Funktionsaufruf. Solange der SetTimer Aufruf bei aktiven Fenster stattfand hat das funktioniert.
Der Timer und damit die Callbackfunktion wurde dann auch bei minimierten oder versteckten Fenster korrect ausgelöst.
SetTimer bei bereits minimierten Fenster hat gar nichts bewirkt!
Warscheinlich weil der übergebene Zeiger zu den Zeitpunkt ungültig ist.


Mittlerweile an einem ganz anderen Programm arbeitend habe ich mich mit der KlasseCAsyncSocket beschäftigt um über ein LAN Netzwerk zu kommunizieren.
Dabei ist sind mir in Zusammenhang mit meinen Problemprogramm ganz merkwürdigeGedanken gekommen die mit dem Servernamen "loopback" zu tun haben.
Aber das währe dann wohl irgendwie von hinten durch die Brust ins Auge.


Nachdem sämmtliche Kommunikationsversuche zwischen DLL und EXE gescheitert sindhabe ich mich entschlossen den gesammten für die Tastenreaktionen erforderlichenCode in die DLL zu packen, und die EXE nur noch zum laden der DLL zu benutzen.

In dem Zusammenhang kann mir mal einer sagen wie genau sich eine Globale Variable in einer DLL laut ANSI-Standart zu verhalten hat?
Global ist sie ja insofern das sich der Compiler nicht beschwert wenn mann in verschiedenen Funktionen bezug darauf nimmt.
Darüber hinaus sollte mann ja über eine solche Variable auch Werte zwischen den Funktionen austauschen können.
Kann mann auch Werte zwischen Programmen austauschen?
Eigendlich ja, das hat in meinem Problemprogramm ja auch funktioniert solange der Zeiger noch gültig war.
Trotzdem ist mir bei dem Versuch die notwendigen Programmteile in die DLL zu packen aufgefallen, das einige unbedingt erforderliche Globale Variablen
in der DLL zugewiesene Werte einfach vergessen haben!
Damit war der ganze Code nicht mehr lauffähig.

Über diesen Umstand habe ich dann nicht weiter nachgedacht und das Programm aufgegeben.

Das währen dann also die Kernfragen:
Wie hat sich eine Globale Variable in einer DLL zu verhalten?
Wie kann ich eine Funktion in einer EXE von einer anderen EXE oder DLL aus aufrufen?

Gruß an Christian der mir mit der SysTray Sache weitergeholfen hat ( es funktioniert! ).
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
13.04.2003, 22:25 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Bevor ich mir hier alles durchlese, lade dir das KeyboardHook-Programm aus dem Downloadbereich runter, der sendet alle globalen Tastatureingaben als WM-Nachricht an das Programm ...
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
13.04.2003, 22:38 Uhr
Christian
C/C++ Master
(Operator)


Hi!

Okay, ich habe jetzt nur dein erstes Problem durchgelesen. Versuche es mal mit Memory Mapped Dateien in Verbindung mit Ereignisobjekten. Ich hoffe, dass man diese auch aus DLLs heraus verwenden kann, aber warum eigentlich nicht.

Link wegen den MemorymappedDateien:

http://cplus.kompf.de/memmap.html


MSDN Stichwort wegen den Ereignisobjekten:

CreateEvent(..)
OpenEvent(..)
...

Ich hoffe, das hilft dir!


Grüße, Christian
--
Grüße, Christian
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
15.04.2003, 17:27 Uhr
~SKARF
Gast


Ok das KeyboardHook-Programm hat mir weitergeholfen.
Die Vorgehenweise ist nahezu identisch mit meiner eigenen.
Der einzige nennenswerte Unterschied war gleichzeitig auch das Problem:

Kann mir jemand sagen was die volgenden pragma - Aufrufe
zu bedeuten haben?

#pragma data_seg(".HOOKDATA")
HHOOK hook = NULL;
HWND hwnd = NULL;
char ClassN[100];
char WTitle[100];
#pragma data_seg()

#pragma comment(linker, "/SECTION:.HOOKDATA,RWS")
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
29.12.2005, 01:43 Uhr
~gast
Gast



Zitat von ~SKARF:
Ich Programmiere mit dem Visual C++ 6 Compiler für win9x / XP.
.


hallo

wo bekommt mann den denn her ?


grüße

björn
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
29.12.2005, 01:45 Uhr
~Gast
Gast



Zitat von ~gast:
Ich Programmiere mit dem Visual C++ 6 Compiler für win9x / XP.


hallo

wo bekommt mann den denn her ?


grüße

björn




meine e-mail adresse bjoern_meyer@gmx.de
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
29.12.2005, 12:19 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


kaufen! oder den 2005er Express (365Tage version) von microsoft runterladen.

Falls du ihn dir kaufen willst, kauf dir den 2003er, der ist noch nicht abhängig vom .NET Framework.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: