Im Hintergrund Mausklicks zählen



  • Hallo,
    ich will ein Programm schreiben, das die Mausklicks zählt, während es im Hintergrund läuft.
    Wenn das Fenster geöffnet ist und ich darauf klicke funktioniert das wunderbar, aber wie kann ich die klicks zählen, wenn das Fenster nur im Hintergrund läuft?

    MfG
    Burger



  • Mit einem Mouse-Hook in einer DLL...



  • Hier ein Beispiel für die Tastatur... Ist aber leicht auf Mäuse übertragbar 😃 ...

    Du brauchst auch wieder SetWindowsHookEx mit dem Flag WH_MOUSE.



  • danke erstmals für den hinweis

    ich benutze Dev-C++ und habe dazu hier ein Tutorial zu Mousehooks gefunden:
    http://elearning.tutorials.de/flashpaper/c_c++/c-Mouse-Systemhook.swf

    Es wird beschrieben, wie man ein "Pipetten"-Programm schreibt, das Farben auf dem Bildschrim erkennen kann.
    Darin stehen folgende Codes:

    1. die Header-Datei der DLL (dll.h):

    #ifndef _DLL_H_
    #define _DLL_H_
    
    #include <windows.h>
    
    #if BUILDING_DLL
    # define DLLIMPORT __declspec (dllexport)
    #else /* Not BUILDING_DLL */
    # define DLLIMPORT __declspec (dllimport)
    #endif /* Not BUILDING_DLL */
    
    #define SHARED __attribute__((section(".shr"), shared)) 
    
    DLLIMPORT BOOL InstallHook(); 
    DLLIMPORT BOOL UninstallHook(); 
    
    LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam);
    
    #endif /* _DLL_H_ */
    

    hier hatte ich zuerst Probleme, weil auf der Seite das letzte #endif angeschnitten war, konnte ich aber noch leicht korrigieren

    2. der main-coder der DLL (dllmail.c):

    /* Replace "dll.h" with the name of your header */ 
    #include "dll.h" 
    
    // Globale Variablen 
    HHOOK g_hMouseHook SHARED = NULL; // Handle unseres Hooks (als "shared" Deklariert) 
    HINSTANCE g_hInst SHARED = NULL;     // Handle der DLL selbst 
    
    BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ , 
                           DWORD reason        /* Reason this function is being called. */ , 
                           LPVOID reserved     /* Not used. */ ) 
    { 
      g_hInst = hInst; 
      return TRUE; 
    }
    DLLIMPORT BOOL InstallHook() 
    { 
      if(g_hMouseHook != NULL) 
        return TRUE; 
      g_hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc, g_hInst, 0); 
      if(g_hMouseHook == NULL) 
        return FALSE; 
      return TRUE; 
    } 
    DLLIMPORT BOOL UninstallHook() 
    { 
      if(g_hMouseHook != NULL) 
      { 
        UnhookWindowsHookEx(g_hMouseHook); 
        g_hMouseHook = NULL; 
      }
      return TRUE;  
    }
    
    LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) 
    { 
      if (nCode < 0) 
        return CallNextHookEx(g_hMouseHook, nCode, wParam, lParam); 
      if(nCode == HC_ACTION) 
      { 
        if ( (wParam == WM_LBUTTONDOWN)||(wParam == WM_NCLBUTTONDOWN) ) 
        { 
          MOUSEHOOKSTRUCT *mhs = (MOUSEHOOKSTRUCT*)lParam; 
          HWND caller = FindWindow("Pipette", NULL); 
          if(caller != NULL) 
            PostMessage(caller, WM_USER+123, 0, MAKELPARAM(mhs->pt.x, mhs->pt.y)); 
        } 
        return CallNextHookEx(g_hMouseHook, nCode, wParam, lParam); 
      }
    }
    

    3. die Headerdatei vom Pipetten-Programm (main.h)

    #include <windows.h> 
    #include <stdio.h> 
    
    /* DEFINES */ 
    
    #define WINDOW_WIDTH 310 
    #define WINDOW_HEIGHT 200 
    
    #ifndef GET_X_LPARAM 
    #define GET_X_LPARAM(lp)   ((int)(short)LOWORD(lp)) 
    #endif 
    #ifndef GET_Y_LPARAM 
    #define GET_Y_LPARAM(lp)   ((int)(short)HIWORD(lp)) 
    #endif 
    
    typedef bool (CALLBACK *MYFUNC)(void); 
    
    /* Prototypen */ 
    
    void Init(); 
    void DrawColor(POINT &p, HWND &mainWindow); 
    void DrawDialog(HWND &parent, HINSTANCE &inst); 
    void ToHTML(); 
    void ToRGB(); 
    bool IsPointInApp(POINT &p, HWND &mainWindow); 
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); 
    
    /* Globale Variablen */ 
    
    MYFUNC InstallHook; 
    MYFUNC UninstallHook;
    
    HWND hInstallHookBtn; 
    HWND hUninstallHookBtn; 
    HWND hEditRGB; 
    HWND hEditHTML; 
    HWND hStaticFrame; 
    
    COLORREF col; 
    RECT ColorRect; 
    
    char szClassName[ ] = "Pipette";
    

    4. der main-code vom Programm (main.cpp):

    #include "main.h" 
    
    int WINAPI WinMain (HINSTANCE hThisInstance, 
    HINSTANCE hPrevInstance, 
    LPSTR lpszArgument, 
    int nFunsterStil) 
    
    { 
      HWND hwnd;               /* This is the handle for our window */ 
      MSG messages;            /* Here messages to the application are saved */ 
      WNDCLASSEX wincl;        /* Data structure for the windowclass */
      Init(); 
      /* The Window structure */ 
      wincl.hInstance = hThisInstance; 
      wincl.lpszClassName = szClassName; 
      wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */ 
      wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */ 
      wincl.cbSize = sizeof (WNDCLASSEX); 
      /* Use default icon and mouse-pointer */ 
      wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); 
      wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); 
      wincl.hCursor = LoadCursor (NULL, IDC_ARROW); 
      wincl.lpszMenuName = NULL;                 /* No menu */ 
      wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */ 
      wincl.cbWndExtra = 0;                      /* structure or the window instance */ 
      /* Use Windows's default color as the background of the window */ 
      wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; 
      /* Register the window class, and if it fails quit the program */ 
      if (!RegisterClassEx (&wincl)) 
        return 0; 
      /* The class is registered, let's create the program*/ 
      hwnd = CreateWindowEx ( 0,                   /* Extended possibilites for variation */ 
                              szClassName,         /* Classname */ 
                              "Pipette",           /* Title Text */ 
                              WS_SYSMENU|WS_MINIMIZEBOX, /* default window */ 
                              CW_USEDEFAULT,       /* Windows decides the position */ 
                              CW_USEDEFAULT, /* where the window ends up on the screen */ 
                              WINDOW_WIDTH,                 /* The programs width */                
                              WINDOW_HEIGHT,                 /* and height in pixels */             
                              HWND_DESKTOP,        /* The window is a child-window to desktop */ 
                              NULL,                /* No menu */ 
                              hThisInstance,       /* Program Instance handler */ 
                              NULL                 /* No Window Creation data */ 
                            ); 
      DrawDialog(hwnd, hThisInstance); 
      /* Make the window visible on the screen */ 
      ShowWindow (hwnd, nFunsterStil); 
      HINSTANCE hDLL = LoadLibrary("mousehook.dll"); 
    
      if(hDLL == NULL) 
      { 
        MessageBox(NULL, "Fehler beim Laden der DLL: mousehook.dll", "Fehler", MB_OK); 
        return FALSE; 
      } 
      InstallHook = (MYFUNC) GetProcAddress(hDLL, "InstallHook"); 
      if(InstallHook == NULL) 
      { 
        MessageBox(NULL, "Fehler: InstallHook nicht gefunden in: mousehook.dll", "Fehler", MB_OK);
        return FALSE; 
      } 
      UninstallHook = (MYFUNC) GetProcAddress(hDLL, "UninstallHook"); 
      if(UninstallHook == NULL) 
      { 
        MessageBox(NULL, "Fehler: UninstallHook nicht gefunden in: mousehook.dll", "Fehler", MB_OK); 
        return FALSE; 
      } 
      /* Run the message loop. It will run until GetMessage() returns 0 */ 
      while (GetMessage (&messages, NULL, 0, 0)) 
      { 
        /* Translate virtual-key messages into character messages */ 
        TranslateMessage(&messages); 
        /* Send message to WindowProcedure */ 
        DispatchMessage(&messages); 
      } 
      /* The program return-value is 0 - The value that PostQuitMessage() gave */ 
      FreeLibrary(hDLL); 
      return messages.wParam; 
    } 
    
    void Init() 
    { 
      InstallHook = NULL; 
      UninstallHook = NULL; 
      hInstallHookBtn = NULL; 
      hUninstallHookBtn = NULL; 
      hEditRGB = NULL; 
      hEditHTML = NULL; 
      hStaticFrame = NULL; 
      col = RGB(0,0,0); 
      ColorRect.left = 10; 
      ColorRect.top = 120; 
      ColorRect.right = 290; 
      ColorRect.bottom = 160; 
    }
    
    void DrawDialog(HWND &parent, HINSTANCE &inst) 
    { 
      hInstallHookBtn = CreateWindow("BUTTON", 0, WS_CHILD|WS_VISIBLE, 10, 10, 120, 30, parent, 0, inst, 0);
      SetWindowText(hInstallHookBtn, "Install Hook"); 
      hUninstallHookBtn = CreateWindow("BUTTON", 0, WS_CHILD|WS_VISIBLE, 170, 10, 120, 30, parent, 0, inst, 0); 
      SetWindowText(hUninstallHookBtn, "Uninstall Hook"); 
      HWND tmp; 
      tmp = CreateWindow("STATIC", 0, WS_CHILD|WS_VISIBLE, 10, 60, 100, 18, parent, 0, inst, 0); 
      SetWindowText(tmp, "RGB Farbe:"); 
      tmp = CreateWindow("STATIC", 0, WS_CHILD|WS_VISIBLE, 10, 90, 100, 18, parent, 0, inst, 0); 
      SetWindowText(tmp, "HTML Farbe:"); 
      hEditRGB = CreateWindow("EDIT", 0, WS_BORDER|WS_CHILD|WS_VISIBLE|ES_READONLY, 120, 59, 100, 20, parent, 0, inst, 0); 
      hEditHTML = CreateWindow("EDIT", 0, WS_BORDER|WS_CHILD|WS_VISIBLE|ES_READONLY, 120, 89, 100, 20, parent, 0, inst, 0); 
      //hStaticFrame = CreateWindow("STATIC", 0, WS_BORDER|WS_CHILD|WS_VISIBLE, 10, 120, 280, 40, parent, 0, inst, 0); 
    } 
    
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
    { 
      HWND hBut; 
      static HBRUSH brush; 
      switch (message)                  /* handle the messages */ 
      { 
        case WM_COMMAND: 
          if(HIWORD(wParam) == BN_CLICKED) 
          { 
            hBut = (HWND)lParam; 
            if(hBut == hInstallHookBtn) 
            { 
              BOOL ret = InstallHook(); 
              if(ret == FALSE) 
                MessageBox(NULL, "InstallHook fehlgeschlagen", "Fehler", MB_OK); 
              else
                SetWindowPos(hwnd,  HWND_TOPMOST , 0, 0, 0, 0, SWP_NOSIZE |SWP_SHOWWINDOW); 
            } 
            else if(hBut == hUninstallHookBtn) 
            { 
              if(UninstallHook() == FALSE) 
                MessageBox(NULL, "UninstallHook fehlgeschlagen", "Fehler", MB_OK); 
            } 
          } 
          break; 
    
        case WM_USER+123: 
          POINT p; 
          p.x = GET_X_LPARAM(lParam); 
          p.y = GET_Y_LPARAM(lParam); 
          DrawColor(p, hwnd); 
          break;
    
        case WM_PAINT: 
          PAINTSTRUCT ps; 
          brush = CreateSolidBrush(col); 
          HDC dc; 
          dc = NULL; 
          dc = BeginPaint(hwnd, &ps); 
          SelectObject(dc, brush); 
          FillRect(dc, &ColorRect, brush);
          EndPaint(hwnd, &ps); 
          return 0; 
    
        case WM_DESTROY: 
          DeleteObject(brush); 
          if(!UninstallHook()) 
            MessageBox(NULL, "UninstallHook fehlgeschlagen", "Fehler", MB_OK); 
          PostQuitMessage (0);       /* send a WM_QUIT to the message queue */ 
          break; 
    
        default:                      /* for messages that we don't deal with */ 
          return DefWindowProc (hwnd, message, wParam, lParam); 
      } 
      return 0; 
    } 
    
    void DrawColor(POINT &p, HWND &mainWindow) 
    { 
      HWND owner = WindowFromPoint(p); 
      if(owner) 
      { 
        HDC ownerDC = GetDC(owner); 
        if(ownerDC && !IsPointInApp(p, mainWindow)) 
        {
          ScreenToClient(owner, &p); 
          col = GetPixel(ownerDC, p.x, p.y); 
          ToHTML(); 
          ToRGB(); 
          InvalidateRect(mainWindow, &ColorRect, TRUE); 
        } 
      } 
    } 
    
    void ToHTML() 
    { 
      char sHtml[8]; sHtml[0] = 0; 
      sprintf(sHtml, "#%.2X%.2X%.2X", GetRValue(col), 
      GetGValue(col), 
      GetBValue(col)); 
      SetWindowText(hEditHTML, sHtml); 
    } 
    
    void ToRGB() 
    { 
      char sRGB[12]; sRGB[0] = 0; 
      sprintf(sRGB, "%d,%d,%d", GetRValue(col), 
      GetGValue(col), 
      GetBValue(col)); 
      SetWindowText(hEditRGB, sRGB); 
    } 
    
    bool IsPointInApp(POINT &p, HWND &mainWindow) 
    { 
      RECT rect; 
      GetWindowRect(mainWindow, &rect); 
      if(p.x >= rect.left && 
         p.x <= rect.right && 
         p.y >= rect.top && 
         p.y <= rect.bottom) 
      { 
        return true; 
      } 
      else 
        return false; 
    }
    

    Jetzt aber zu meinem Problem:
    ich kann dieses Programm problemlos kompilieren, allerdings kommt dann vo Programm die Meldung "Fehler: InstallHook nicht gefunden in: mousehook.dll". Dann hab ich die DLL mit dem Dependency Walker von Microsoft Visual C++ geöffnet und gesehen, dass es die Fuktionen "InstallHook" und "UninstallHook" nicht gibt, sondern nur "_Z11InstallHookv" und "Z_13UninstallHookv".
    Also hab ich sie im Code ersetzt:

    HINSTANCE hDLL = LoadLibrary("mousehook.dll"); 
    
      if(hDLL == NULL) 
      { 
        MessageBox(NULL, "Fehler beim Laden der DLL: mousehook.dll", "Fehler", MB_OK); 
        return FALSE; 
      } 
      InstallHook = (MYFUNC) GetProcAddress(hDLL, "_Z11InstallHookv"); 
      if(InstallHook == NULL) 
      { 
        MessageBox(NULL, "Fehler: InstallHook nicht gefunden in: mousehook.dll", "Fehler", MB_OK);
        return FALSE; 
      } 
      UninstallHook = (MYFUNC) GetProcAddress(hDLL, "_Z13UninstallHookv"); 
      if(UninstallHook == NULL) 
      { 
        MessageBox(NULL, "Fehler: UninstallHook nicht gefunden in: mousehook.dll", "Fehler", MB_OK); 
        return FALSE; 
      }
    

    Danach schien das Programm zu laufen, aber sobals ich auf "installHook" klicke, erscheint die Meldung "InstallHook fehlgeschlagen", welche so zustande kommt:

    case WM_COMMAND: 
          if(HIWORD(wParam) == BN_CLICKED) 
          { 
            hBut = (HWND)lParam; 
            if(hBut == hInstallHookBtn) 
            { 
              BOOL ret = InstallHook(); 
              if(ret == FALSE) 
                MessageBox(NULL, "InstallHook fehlgeschlagen", "Fehler", MB_OK); 
              else
                SetWindowPos(hwnd,  HWND_TOPMOST , 0, 0, 0, 0, SWP_NOSIZE |SWP_SHOWWINDOW); 
            } 
            else if(hBut == hUninstallHookBtn) 
            { 
              if(UninstallHook() == FALSE) 
                MessageBox(NULL, "UninstallHook fehlgeschlagen", "Fehler", MB_OK); 
            } 
          } 
          break;
    

    Aber wo liegt nun der Fehler? Kann mir jemand dabei helfen?
    Danke im vorraus

    Burger



  • extern C Block verwenden, siehe google.


Log in to reply