Thread: Windows Hooks for global mouse detection

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    102

    Windows Hooks for global mouse detection

    Hey all, I'm looking to set up a program that can detect all mouse events. I think the solution is in the windows hooks functions, however I can't find any examples on how to use these. Is there anyone who knows where I can find an example of using windows hooks to track mouse events or keyboard events?

    Basically I need my program to be able to keep track of mouse coordinates once it's clicked during a certain time period. I need my program to be able to know about them and record them, even if I'm clicking in a completely different application. Hope thiks helps

    Thanks in advance.
    Last edited by JJFMJR; 08-10-2008 at 03:40 PM.
    My Favorite Programming Line:
    Code:
    #define true ((rand() % 2) ? true : false)

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You can capture the mouse, so that you receive its events even if the mouse leaves the window. I think it's MouseCapture or CaptureMouse or something similar. And you can read the position in a WM_MOUSEMOVE event.

    Edit: Right, you can look at all the mouse stuff here.

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    102
    Thanks, I'll look into it now .
    My Favorite Programming Line:
    Code:
    #define true ((rand() % 2) ? true : false)

  4. #4
    Registered User
    Join Date
    Apr 2007
    Posts
    102
    Quote Originally Posted by tabstop View Post
    You can capture the mouse, so that you receive its events even if the mouse leaves the window. I think it's MouseCapture or CaptureMouse or something similar. And you can read the position in a WM_MOUSEMOVE event.

    Edit: Right, you can look at all the mouse stuff here.

    Hmm.. thanks it looked promising, however it seems as though the GetCapture method works only for windows in your thread. My goal is to get the mouse information from a completely different thread entirely and pass it to my thread.
    My Favorite Programming Line:
    Code:
    #define true ((rand() % 2) ? true : false)

  5. #5
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Is there anyone who knows where I can find an example of using windows hooks to track mouse events or keyboard events?
    Code:
    #define _WIN32_WINNT 0x0400
    #pragma comment( lib, "user32.lib" )
    
    #include <windows.h>
    #include <stdio.h>
    
    HHOOK hMouseHook;
    
    __declspec(dllexport) LRESULT CALLBACK KeyboardEvent (int nCode, WPARAM wParam, LPARAM lParam)
    {
        MOUSEHOOKSTRUCT * pMouseStruct = (MOUSEHOOKSTRUCT *)lParam;
        if (pMouseStruct != NULL)
            printf("Mouse position X = %d  Mouse Position Y = %d\n", pMouseStruct->pt.x,pMouseStruct->pt.y);
        return CallNextHookEx(hMouseHook,
            nCode,wParam,lParam);
    }
    
    void MessageLoop()
    {
        MSG message;
        while (GetMessage(&message,NULL,0,0)) {
            TranslateMessage( &message );
            DispatchMessage( &message );
        }
    }
    
    DWORD WINAPI MyMouseLogger(LPVOID lpParm)
    {
        HINSTANCE hInstance = GetModuleHandle(NULL);
        if (!hInstance) hInstance = LoadLibrary((LPCSTR) lpParm); 
        if (!hInstance) return 1;
    
        hMouseHook = SetWindowsHookEx (  
            WH_MOUSE_LL,
            (HOOKPROC) KeyboardEvent,  
            hInstance,                 
            NULL                       
            );
        MessageLoop();
        UnhookWindowsHookEx(hMouseHook);
        return 0;
    }
    
    int main(int argc, char** argv)
    {
        HANDLE hThread;
        DWORD dwThread;
    
        hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)
            MyMouseLogger, (LPVOID) argv[0], NULL, &dwThread);
        if (hThread)
            return WaitForSingleObject(hThread,INFINITE);
        else return 1;
    
    }

  6. #6
    Registered User
    Join Date
    Apr 2007
    Posts
    102
    Bob, thanks abunch, your the man, that's exactly the kind of thing I was looking for. Thanks
    My Favorite Programming Line:
    Code:
    #define true ((rand() % 2) ? true : false)

  7. #7
    Registered User
    Join Date
    Apr 2007
    Posts
    102
    Alright, I've now tried swapping the FilterFunction to a dll file, I got it to run just to test it and it still did the exact same thing :/. So I went back to the old version. The problem is that the program for some reason seems to stop executing the code at a certain point. As soon as I set the hook to work, and hit the GetMessage line, it exits out of the loop and I can't get it back in, even by unsetting the hook. Here's the code:

    main.cpp

    Code:
    
    #define _WIN32_WINNT 0x0400
    #pragma comment( lib, "user32.lib" )
    
    #include <windows.h>
    #include <stdio.h>
    #include <iostream>
    
    #include "Grid.h"
    
    using namespace std;
    
    HHOOK hMouseHook;
    HINSTANCE hInstance;
    
    int mouseX = -1;     //Keeps track of where the mouse was released at
    int mouseY = -1;     //Keeps track of where the mouse was released at
    
    int maxClicks = 0;
    
    __declspec(dllexport) LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
        MOUSEHOOKSTRUCT * pMouseStruct = (MOUSEHOOKSTRUCT *)lParam;
        static int numClicks = 0;
    
        if (pMouseStruct != NULL)
            if(wParam == WM_LBUTTONDOWN)
            {
                numClicks++;
                mouseX = pMouseStruct->pt.x;
                mouseY = pMouseStruct->pt.y;
    
                cout << mouseX;
                cout << mouseY;
    
            }
    
        if(numClicks >= maxClicks)
        {
            numClicks = 0;
            UnhookWindowsHookEx(hMouseHook);
            cout << "Calling unhook";
            return 0;
        }
    
        return CallNextHookEx(hMouseHook,
            nCode,wParam,lParam);
    }
    
    void wait ( int seconds )
    {
      clock_t endwait;
      endwait = clock () + seconds * CLOCKS_PER_SEC ;
      while (clock() < endwait) {}
    }
    
    
    void MainLoop()
    {
        bool exiting = false;
    
        GridPlots* ResourceArea;
        GridPlots* ReturnPath;
    
        while(!exiting)
        {
            string input;
            bool getInput = true;
    
            bool mouseListener = false;
    
            if(getInput)
            {
                cout << "Enter command or /c for a list of commands. >> ";
                cin >> input;
            }
    
            if(input == "/c")
            {
                cout << "\nCommands: \n1) Set: The next mouse position clicked will set the grid at 0.0 to that point.\n";
                cout << "\n2) SetGrid: All the next positions clicked on will be added to the grid in sets of 2 until Esc is pressed.\n";
                cout << "\n3) SetReturn: Sets the return path until Esc is pressed.\n";
    
                getInput = true;
    
                if(mouseListener == true)
                    UnhookWindowsHookEx(hMouseHook);
    
                mouseListener = false;
            }
            else if(input == "Set")
            {
                cout << "\nYou have 10 seconds to switch to browser.\n";
    
                for(int l = 5; l >= 1; --l)
                {
                    cout << "\n" << l << "...";
                    wait(1);
                }
    
                hMouseHook = SetWindowsHookEx (WH_MOUSE_LL,(HOOKPROC) MouseProc,hInstance,0);
                mouseListener = true;
                maxClicks = 1;
    
                //Set the center grid spot
                if(mouseX != -1 && mouseY != -1)
                {
                    cout << "\nCenter point set at " << mouseX << " " << mouseY;
    
                    if(ResourceArea == 0)
                    {
                        ResourceArea = new GridPlots(mouseX, mouseY, 0);
                        getInput = true;
                    }
                }
                else
                    getInput = false;
    
            }
            else if(input == "SetGrid")
            {
                cout << "\nYou have 10 seconds to switch to browser.\n";
    
                for(int l = 5; l >= 1; --l)
                {
                    cout << "\n" << l << "...";
                    wait(1);
                }
    
                hMouseHook = SetWindowsHookEx (WH_MOUSE_LL,(HOOKPROC) MouseProc,hInstance,0);
                mouseListener = true;
    
                //Set the grid for the next few spots
                getInput = false;
    
            }
            else if(input == "SetReturn")
            {
                cout << "\nYou have 10 seconds to switch to browser.\n";
    
                for(int l = 5; l >= 1; --l)
                {
                    cout << "\n" << l << "...";
                    wait(1);
                }
    
                hMouseHook = SetWindowsHookEx (WH_MOUSE_LL,(HOOKPROC) MouseProc,hInstance,0);
                mouseListener = true;
    
                //Set the return path for the next few spots
                getInput = false;
            }
            else
            {
                getInput = true;
                UnhookWindowsHookEx(hMouseHook);
                mouseListener = false;
    
                cout << "\nInvalid Entry.\n";
            }
    
            if(mouseListener == true)
            {
                MSG message;
    
                /*********************************************************
    
                        ERROR IN HERE SOMEWHERE!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
                **********************************************************/
    
                BOOL bRet;
                cout << "??";
    
                while( (bRet = GetMessage( &message, NULL, 0, 0 )) != 0)
                {
    
                    if (bRet == -1)
                    {
                        // handle the error and possibly exit
                    }
                    else
                    {
                        TranslateMessage(&message);
                        DispatchMessage(&message);
                    }
    
                }
    
            }
        }
    }
    
    DWORD WINAPI MyMouseLogger(LPVOID lpParm)
    {
        hInstance = GetModuleHandle(NULL);
        if (!hInstance) hInstance = LoadLibrary((LPCSTR) lpParm);
        if (!hInstance) return 1;
    
        MainLoop();
    
        return 0;
    }
    
    int main(int argc, char** argv)
    {
        HANDLE hThread;
        DWORD dwThread;
    
        hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)
            MyMouseLogger, (LPVOID) argv[0], 0, &dwThread);
        if (hThread)
            return WaitForSingleObject(hThread,INFINITE);
        else return 1;
    
    }
    BTW: I have tried setting the mouseListener boolean to global, and setting it false in the filter function, but that didn't work lol.

    Now, at once you type in Set , the program does a 5 second countdown, then turns on the hook. That works fine, then I wait for a single click globally. I record that information and then try to exit the hook listening process, however once I do exit (or don't idk) I don't know where the program execution is, it's still running, but not where I expect. I expected it to come back right into my main while(!exiting) loop. However it doesn't seem to do that. I have no idea where it is running at !! Please if anyone can help me to get the execution back on line after that point, I'd be soooo grateful. Thanks in advance!
    Last edited by JJFMJR; 08-11-2008 at 01:38 PM. Reason: Tested
    My Favorite Programming Line:
    Code:
    #define true ((rand() % 2) ? true : false)

  8. #8
    Registered User
    Join Date
    Apr 2007
    Posts
    137
    Quote Originally Posted by JJFMJR View Post
    however I can't find any examples on how to use these. Is there anyone who knows where I can find an example of using windows hooks to track mouse events or keyboard events?
    Are you joking ?!
    There are plenty of complete samples in MSDN, KB, PSDK...
    for all types of hooks !

  9. #9
    Registered User
    Join Date
    Apr 2007
    Posts
    102
    Quote Originally Posted by Alex31 View Post
    Are you joking ?!
    There are plenty of complete samples in MSDN, KB, PSDK...
    for all types of hooks !
    Lol, keep reading, that was resolved much earlier, but the problem I have is the post above yours . I just thought since it was on the same topic, it should be put in this thread instead of a new one.
    My Favorite Programming Line:
    Code:
    #define true ((rand() % 2) ? true : false)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. (Windows) Send keyboard and mouse to another program?
    By Chrisname in forum Windows Programming
    Replies: 4
    Last Post: 06-13-2009, 06:13 PM
  2. Game Design Topic #2 - Keyboard or Mouse?
    By TechWins in forum Game Programming
    Replies: 4
    Last Post: 10-08-2002, 03:34 PM
  3. OpenGL and Windows
    By sean345 in forum Game Programming
    Replies: 5
    Last Post: 06-24-2002, 10:14 PM
  4. Windows Hooks Q?
    By SyntaxBubble in forum Windows Programming
    Replies: 3
    Last Post: 03-03-2002, 10:20 AM
  5. Mouse in 800x600 24Bit Mode?
    By Unregistered in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 11-11-2001, 01:38 AM