Question

I'm trying to create a little app that will detect when the mouse cursor moves to the edge of the screen and will move it to the opposite edge, to create a continuous desktop effect, if that makes sense.

Below is some code from someone else (the mouse hook part) I adapted by added the SetCursorPos to move the mouse to a fixed position for now. When I run it, SetCursorPos returns true, which I assume means the call succeeded, but the mouse does not move. I read somewhere something about security constraints in later Windows version preventing stuff like this, which would make sense, but the source was unclear to how true this is. Does anyone know why this would not work?

Thanks, code below:

#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)
    {
        if (pMouseStruct->pt.x < -1900)
        {
            BOOL r = SetCursorPos(
                500,
                500
            );

            printf("Trigger %d.  Response %d", pMouseStruct->pt.x, r);
        }
    }

    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;
}
Was it helpful?

Solution

This appears to be a problem with calling SetCursorPos inside your hook proceedure. I guess this is explicitly prohibted in Vista/Windows 7, but I couldn't find any documentation to confirm that. I modified your code slightly to post a thread message when it wants to move the cursor, and do the actual SetCursorPos inside your message proceedure. It works fine once this is done.

In your hook procedure:

if (pMouseStruct->pt.x < -1900)
    {
        PostThreadMessage( GetCurrentThreadId(), WM_USER, 0, 0 );
        printf("Trigger %d.  Response %d", pMouseStruct->pt.x, r);
    }

In your message loop:

while (GetMessage(&message,NULL,0,0)) {
    if( message.hwnd == NULL ) {
        if( message.message == WM_USER ) {
            SetWindowPos( 500, 500 );
        }
     } else {
         TranslateMessage( &message );
         DispatchMessage( &message );
     }
}

(Note this is just a demonstration, not an actual fix.)

That being said, there are numerous, serious problems with your code. I don't think it's appropriate to go into all of them here, but I recommend you post it on https://codereview.stackexchange.com/.

OTHER TIPS

Looks like you need to translate coordinates. as per docs you need to call ClientToScreen or ScreenToClient to translate the point. I don't know which Window is the reference. You need to pass that window handle as point (as out parameter) as parameter. and then use the altered point with SetCursorPos

check example

If you want the Screen You need to do GetDC(NULL) and pass the returned handle to ClientToScreen

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top