3

私は、マウスカーソルが画面の端に移動したことを検出し、反対側の端に移動して、意味がある場合は継続的なデスクトップ効果を作成する小さなアプリを作成しようとしています。

以下は、他の誰か(マウスフック部分)からのコードです。今のところ、マウスを固定位置に移動するためにSetCursorPosを追加して調整しました。実行すると、SetCursorPosはtrueを返します。これは、呼び出しが成功したことを意味すると思いますが、マウスは移動しません。私は、このようなものを防ぐ後のWindowsバージョンのセキュリティ制約についてどこかで読んだことがありますが、これは理にかなっていますが、ソースはこれがどれほど真実であるかについて不明でした。なぜこれが機能しないのか誰かが知っていますか?

ありがとう、以下のコード:

#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;
}
4

2 に答える 2

3

これは、フックプロシージャ内でSetCursorPosを呼び出す際の問題のようです。これはVista/Windows 7で明示的に禁止されていると思いますが、それを確認するためのドキュメントが見つかりませんでした。コードを少し変更して、カーソルを移動したいときにスレッドメッセージを投稿し、メッセージ手順内で実際のSetCursorPosを実行します。これが行われると、正常に動作します。

フック手順では:

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

メッセージループ内:

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

(これは単なるデモンストレーションであり、実際の修正ではないことに注意してください。)

そうは言っても、コードには多くの深刻な問題があります。ここでそれらすべてに入るのは適切ではないと思いますが、https://codereview.stackexchange.com/に投稿することをお勧めします。

于 2013-01-21T15:32:56.880 に答える
0

座標を変換する必要があるようです。ClientToScreenドキュメントに従って、ポイントを呼び出すかScreenToClient、翻訳する必要があります。どのウィンドウが参照されているのかわかりません。そのウィンドウハンドルをポイントとして(パラメータとして)パラメータとして渡す必要があります。次に、変更されたポイントをで使用しますSetCursorPos

を確認してください

画面が必要な場合はGetDC(NULL)、返されたハンドルをに渡す必要がありますClientToScreen

于 2013-01-21T14:22:07.250 に答える