-1

Is there a way to identify the mouse movement ?

I want to take some action when the mouse moves, I did a Google search and found that it can be done with WM_MOUSEMOVE, WM_MOUSEMOVE Is taking handle of the mouse movement But when I use WM_MOUSEMOVE, nothing happens. I want the program to detect mouse movement, and then MessageBeep will be called.

Example:

LRESULT CALLBACK WindowProcessMessages(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    switch (msg)
    {
    case WM_CREATE: {

    }
    break;
    case WM_DESTROY: {
        PostQuitMessage(0);
    }
    break;
    case WM_MOUSEMOVE: {
        MessageBeep(MB_ICONERROR);
    }
    break;
    default:
        return DefWindowProc(hwnd, msg, wparam, lparam);
    }

    return 0;
}

It works but there is a problem, it is a bit stuck, when I don't move the mouse the program do MessageBeep and also when I move then the mouse program sometimes do MessageBeep and sometimes not.

I have also tried with MessageBox but now it just spamming the right corner in the screen with MessageBoxes, Even when I'm not moving the mouse.

nakE
  • 362
  • 1
  • 13
  • Did you register the window class and what about main message loop? – Asesh Dec 07 '19 at 13:11
  • @Asesh Okay sorry, it works but there is a problem, it is a bit stuck, when I don't move the mouse the program do `MessageBeep` and also when I move then the mouse program sometimes do `MessageBeep` and sometimes not. – nakE Dec 07 '19 at 13:14
  • Then please post the relevant code. You have not posted enough code for us to analyze your issue. – Asesh Dec 07 '19 at 13:16
  • @Asesh I have edited my post. – nakE Dec 07 '19 at 13:17
  • 2
    That doesn't work, in fact it doesn't even compile. Most branches in your window procedure do not return a value. That's an ill-formed program. Stack Overflow expects visitors to have a basic command of the programming environment they are working with. – IInspectable Dec 07 '19 at 13:19
  • There's no break in case `WM_MOUSEMOVE`. You should also return 0 from that window procedure – Asesh Dec 07 '19 at 13:20
  • @IInspectable Yes it is compile, and it works, but now only when I move my mouse on my console, it execute the command. (MessageBeep). – nakE Dec 07 '19 at 13:22
  • @Asesh I have edited my code again, Now only when I move my mouse on my console, it execute the command. (`MessageBeep`), and when I move my mouse a little bit, the `MessageBeep` is execute like 200 Times. Any Suggestions ? – nakE Dec 07 '19 at 13:25
  • `WM_MOUSEMOVE` will continuously send movement data as the mouse keeps moving. You might want to call that beep after the mouse stops or use some logic to prevent it – Asesh Dec 07 '19 at 13:51
  • 2
    That's incorrect. `WM_MOUSEMOVE` does not generated continuously, as the mouse moves. It gets generated whenever a message retrieval function is called, and the mouse has moved since the last time a message retrieval function has been called. This is the same as `WM_PAINT`: [Paint messages will come in as fast as you let them](https://devblogs.microsoft.com/oldnewthing/20111219-00/?p=8863). – IInspectable Dec 07 '19 at 15:08
  • 1
    @Asesh How can I call that beep after the mouse stops ? – nakE Dec 07 '19 at 19:58
  • [The Definitive C++ Book Guide and List](https://stackoverflow.com/q/388242/1889329). – IInspectable Dec 08 '19 at 08:16

1 Answers1

2

From the comments, it seems that you don't want to be limited to detecting whether the mouse moves in the program, and you want to call that beep when the mouse stops moving.

So you can do it by setting the timer and hook.

An application installs the hook procedure by specifying the WH_MOUSE_LL hook type and a pointer to the hook procedure in a call to the SetWindowsHookEx function.

If you are unfamiliar with using hooks.Don't worry. There are special documents to explain how to use hooks.

Don't forget to use GetLastInputInfo which can retrieve the time of the last input event.

Please note: This GetLastInputInfo function takes into consideration ALL input events, not just mouse events.

How to use GetLastInputInfo? Refer @Roger Rowland's answer.

For details, please see my code.

#include <Windows.h>
#include <iostream>
#pragma comment(lib,"Winmm.lib")
using namespace std;

HHOOK mouseHook;
static DWORD t1;

DWORD GetIdleTime()
{
    LASTINPUTINFO pInput;
    pInput.cbSize = sizeof(LASTINPUTINFO);

    if (!GetLastInputInfo(&pInput))
    {
        // report error, etc. 
    }

    return pInput.dwTime;
}

void CALLBACK f(HWND hwnd, UINT uMsg, UINT timerId, DWORD dwTime)
{
    DWORD t2 = GetIdleTime();
    if (t2 != t1)  //When the mouse is moving, t1 == t2
    {
        MessageBeep(MB_ICONERROR); 
    }
    cout << "t1:   " << t1 << endl; //For test 
    cout << "t2:   " << t2 << endl; 
    cout << endl;
}


LRESULT __stdcall MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode >= 0)
    {   
        Sleep(10); //Used to correct the value of t1
        t1 = GetIdleTime();
    }


    return CallNextHookEx(mouseHook, nCode, wParam, lParam);
}

void SetHook()
{
    if (!(mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookCallback, NULL, 0)))
    {
        cout << "Failed to install mouse hook!" << endl;
    }
}

void ReleaseHook()
{
    UnhookWindowsHookEx(mouseHook);
}

int main()
{   
    SetHook(); //Install hook 
    SetTimer(NULL, 0, 3000, (TIMERPROC)&f); //Check every three seconds
    MSG msg;

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

Debug:

If mouse is moving, t1 == t2.

1

If mouse stop moving, t1 != t2. MessageBeep will be called.

2

If you don't need a console, please replace int main() with int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

Strive Sun
  • 5,988
  • 1
  • 9
  • 26