Guybrush Threepwood Geschrieben 16. Dezember 2003 Geschrieben 16. Dezember 2003 Hi, ich steh gerade irgendwie voll auf dem Schlauch:( Ich hab in einer DLL eine Funktion die die Tastatureingabe lesen und in einem Array speichern soll. Die Funktion bekommt das Windowhandle übergeben, aber irgendwas funktioniert nicht, da nur 2 von ca 148 Zeichen gelesen werden.:confused: Hier mal die entsprechende Schleife in der DLL: while(true) { if (GetMessage(&Msg,hWnd,WM_KEYDOWN,WM_KEYDOWN)) { TranslateMessage(&Msg); u++; if (u>30) { SetLastError(1460); return 0; } if(Msg.wParam==27) { SetLastError(1223); return 0; } else if (Msg.wParam > 0 && Msg.wParam < 127) { karte[i] = Msg.wParam; if(++i>iIndex) break; u=0; } else Sleep(1000); } } [/PHP] Gruß Guybrush Zitieren
Klotzkopp Geschrieben 16. Dezember 2003 Geschrieben 16. Dezember 2003 Was ist denn mit der eigentlichen Nachrichtenschleife des Fensters? Hast du die angehalten? Zitieren
Guybrush Threepwood Geschrieben 16. Dezember 2003 Autor Geschrieben 16. Dezember 2003 Ne, da komm ich nicht dran, da ich die DLL für andere Entwickeln soll. Aber ich hatte auch schon den Verdacht das es damit etwas zu tun haben könnte. Hast du irgendeine Idee? Zitieren
Klotzkopp Geschrieben 16. Dezember 2003 Geschrieben 16. Dezember 2003 Warum benutzt du keinen Hook? Zitieren
Guybrush Threepwood Geschrieben 16. Dezember 2003 Autor Geschrieben 16. Dezember 2003 Original geschrieben von Klotzkopp Warum benutzt du keinen Hook? Hab leider noch nie etwas mit nem Hook gemacht habe und stehe etwas unter Zeitdruck... Zitieren
Guybrush Threepwood Geschrieben 16. Dezember 2003 Autor Geschrieben 16. Dezember 2003 Ich hab`s jetzt doch mal mit nem Hook probiert, allerdings hab ich noch ein paar Probleme. Also den Hook zu installieren, klappt, aber er macht nicht das was er soll. Eigentlich sollte er 20 Zeichen einlesen, sich dann beenden und die Zeichen in einer MessageBox ausgeben. Allerdings beendet er sich immer nach 12 Zeichen und zeogt eine leere Messagebox an:confused: Hier mal ein Teil des DLL Codes: // khookdll.cpp : Definiert den Einsprungpunkt für die DLL-Anwendung. // #include "stdafx.h" #include "khookdll.h" #pragma data_seg(".SHARDAT") static HHOOK hkb=NULL; static char karte[200]; static int i=0; #pragma data_seg() LRESULT __declspec(dllexport)__stdcall CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam) { if (nCode == HC_ACTION) { i++; if (i==20) { karte[i] = 0; UnHook(); } BYTE ks[256]; GetKeyboardState(ks); WORD w; UINT scan; scan=0; ToAscii(wParam,scan,ks,&w,0); karte[i] = char(w); } LRESULT RetVal = CallNextHookEx( hkb, nCode, wParam, lParam ); return RetVal; } [/PHP] Zitieren
Guybrush Threepwood Geschrieben 16. Dezember 2003 Autor Geschrieben 16. Dezember 2003 Ich habe komischer Weise festgestellt, dass wenn ich w in einer MessageBox ausgebe, das richtige Zeichen drinsteht. Wenn ich i ausgebe steht auch die richtige Zahl drin, nur das Array Karte bleibt irgendwie leer.:confused: Achso das er nach dem 12. mal aufgehört hat lag daran das er pro Tastendruck immer 2 mal aufgerufen wurde, das kann man aber mit lParam abfangen. Zitieren
Guybrush Threepwood Geschrieben 16. Dezember 2003 Autor Geschrieben 16. Dezember 2003 Oh man, ich sollte echt nach Hause gehen:rolleyes: Das er mir mit dem Array immer ne leere Messagebox ausgegeben hat, lag daran das ich i direkt am Anfang um 1 erhöht habe und bestimmt immer ein Nullzeichen an erster Stelle stand. Ich erhöhe i jetzt am Ende der Funktion und es klappt Jetzt muss ich es nur noch irgendwie hinbekommen das die Funktion die den Hook setzt erst returned wenn der Hook sich beendet hat. Wäre also für Ideen dankbar, aber ich geh jetzt erstmal heim:) Zitieren
Klotzkopp Geschrieben 16. Dezember 2003 Geschrieben 16. Dezember 2003 Original geschrieben von Guybrush Threepwood Jetzt muss ich es nur noch irgendwie hinbekommen das die Funktion die den Hook setzt erst returned wenn der Hook sich beendet hat. Wäre also für Ideen dankbar, aber ich geh jetzt erstmal heim:) Wie wär's mit Events? Stichworte: CreateEvent WaitForSingleObject SetEvent CloseHandle Zitieren
Guybrush Threepwood Geschrieben 16. Dezember 2003 Autor Geschrieben 16. Dezember 2003 Hab mir das gerade mal angesehen und damit sollte es eigentlich klappen. Danke:) Zitieren
Guybrush Threepwood Geschrieben 17. Dezember 2003 Autor Geschrieben 17. Dezember 2003 Irgendwie klappt das noch nicht so ganz wie es soll. Hier mal der DLL Code: #pragma data_seg(".SHARDAT") static HHOOK hkb=NULL; static char karte[200]; static int i=0; bool start=true; static char* lpFeld=NULL; #pragma data_seg() static HANDLE hEvent=NULL; LRESULT __declspec(dllexport)__stdcall CALLBACK KeyboardProc(int nCode, WPARAM wParam,LPARAM lParam) { if (((DWORD)lParam & 0x40000000) &&(HC_ACTION==nCode)) { if (start) { MessageBox(0,"ok","ht",MB_OK); start=false; } if (i>=10) { MessageBox(0,"gößer","d1",MB_OK); karte[i] = 0; UnHook(); } else { BYTE ks[256]; GetKeyboardState(ks); WORD w; UINT scan; scan=0; ToAscii(wParam,scan,ks,&w,0); karte[i] = char(w); karte[i+1]='\0'; MessageBox(0,karte,"d1",MB_OK); i++; } } LRESULT RetVal = CallNextHookEx( hkb, nCode, wParam, lParam ); return RetVal; } BOOL InstallHook() { char t[20]; hkb=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,AfxGetInstanceHandle(),0); if (hkb == NULL) { itoa(GetLastError(),t,10); MessageBox(0,t,"ht",MB_OK); } return TRUE; } BOOL UnHook() { char t[20]; BOOL unhooked = UnhookWindowsHookEx(hkb); hEvent = OpenEvent(EVENT_ALL_ACCESS,FALSE,"PS2Kartenleser"); if (!SetEvent(hEvent)) { itoa(GetLastError(),t,10); MessageBox(0,t,"ht",MB_OK); } else { MessageBox(0,karte,"ht",MB_OK); strcpy(lpFeld,karte); } return unhooked; } HANDLE __stdcall Start(char *z) { lpFeld = z; hEvent = CreateEvent(NULL,TRUE,FALSE,"PS2Kartenleser"); if (hEvent == NULL) { MessageBox(0,"dfgbn","bnsvu",MB_OK); return false; } InstallHook(); return hEvent; } [/PHP] Wenn ich aus meiner Exe Start() aufrufe übergebe ich der Funktion einen Zeiger auf ein char Feld. Warum wird das Feld nicht in der Unhook Funktion gefüllt? Zitieren
Klotzkopp Geschrieben 17. Dezember 2003 Geschrieben 17. Dezember 2003 Vermutlich, weil das char-Feld nicht im Shared-Segment der DLL liegt. Zitieren
Guybrush Threepwood Geschrieben 17. Dezember 2003 Autor Geschrieben 17. Dezember 2003 Hmm...dann muss ich wohl den Umweg über eine Datei gehen. Zitieren
Klotzkopp Geschrieben 18. Dezember 2003 Geschrieben 18. Dezember 2003 Du könntest auch ein Feld im Shared-Segment anlegen und bei Aufruf einer DLL-Funktion dessen Inhalt in einen übergebenen Puffer kopieren. Zitieren
Guybrush Threepwood Geschrieben 29. Dezember 2003 Autor Geschrieben 29. Dezember 2003 So ich hatte endlich mal wieder Zeit daran weiterzumachen und mache es jetzt doch so wie du es zuerst gesagt hast: ich halte die Hauptnachrichtenschleife an. Allerdings bekomme ich während des Ausführens immer folgende Fehlermeldung: --------------------------- Microsoft Visual C++ Debug Library --------------------------- Debug Error! Program: C:\QUELLCODE\VISUAL C++\khookexe\Debug\khookexe.exe Module: File: i386\chkesp.c Line: 42 The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention. (Press Retry to debug the application) --------------------------- Abbrechen Wiederholen Ignorieren --------------------------- Wenn ich auf Ignorieren klicke klappt alles wunderbar, die Meldung kommt aber trotzdem immer:confused: Zitieren
Klotzkopp Geschrieben 29. Dezember 2003 Geschrieben 29. Dezember 2003 Original geschrieben von Guybrush Threepwood The value of ESP was not properly saved across a function call Dieser Fehler bedeutet, dass der Stackpointer nach einem Funktionsaufruf nicht mehr dorthin zeigt, wo er vor dem Aufruf hinzeigte. Das kann gravierende Folgen haben. Die mit Abstand häufigste Ursache dafür ist, dass eine Funktion (z.B. in einer DLL) mit einer anderen Calling Convention aufgerufen wird, als sie kompiliert wurde. Die Calling Convention legt - grob gesagt - fest, wie beim Aufruf die Argumente übergeben werden, und wer hinterher den Stack wieder aufräumt. Eine bestimmte Calling Convention ist in jedem VC-Projekt per Default festgelegt. Wenn die DLL einen anderen Standard benutzt als die benutzende EXE, kann es zu diesem Fehler kommen. Meist reicht es, die Calling Convention der exportierten Funktion einfach festzulegen, indem man __stdcall oder __cdecl zwischen Rückgabetyp und Name schreibt. Siehe auch: http://msdn.microsoft.com/library/en-us/vccelng/htm/msmod_5.asp Zitieren
Guybrush Threepwood Geschrieben 30. Dezember 2003 Autor Geschrieben 30. Dezember 2003 Jup das hat das Problem gelöst:) Danke:uli Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.