Sign in to follow this  
gretty

[Win32/C++] Detect that the Mouse Button is being HELD down

Recommended Posts

gretty    273
Hello I want to detect in my Windows Proceedure when the left mouse button is held down. I can detect when the left mouse button is 1st pressed(WM_LBUTTONDOWN) but I cant get any more messages saying "the left mouse button is down". What I want to do is: when the left mouse button is pressed I create a dot on the client area, then set a timer for 1 second, during this period I cannot create a dot, when the timer expires if the left mouse button is down I want to create a dot again. So I am trying to find a way to check when the timer expires whether the left mouse button is down. I think I remember reading that when the WM_LBUTTONDOWN message is sent, there is also a part of the message that documents whether the button is still being held down or something like that, is that true?
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    
    switch(msg)
    {
        case WM_CREATE:
        {                  
             // Create GUI
             RECT clientR;
             GetClientRect(hwnd,&clientR);
             createGUI(hwnd,gInstance,clientR);
        }    
        break;
        case WM_LBUTTONDOWN:
        {
             RECT clientR;
             GetClientRect(hwnd,&clientR);
             POINT cursor;
             cursor.x = LOWORD(lParam); cursor.y = HIWORD(lParam);
             
             // if mouse has clicked INSIDE client area
             int collision = PtInRect(&clientR,cursor);
             if (collision != 0) {
                 myLaser.createTarget(hwnd,LOWORD(lParam),HIWORD(lParam));
             }
        }
        break;
        case WM_TIMER:
        {
             switch(LOWORD(wParam)) {
                        
                  case LA_TIMER:
                  {    // Laser can create another target now
                       myLaser.ceaseDelay(hwnd);
                       /* suedo code
                          if the mouse button is down I create a 'dot' &
                          I set the timer again.
*/

                  } 
                  break;    
                  default:
                  break;
             }
        } 
        break;
        case WM_CLOSE:
            myLaser.ceaseDelay(hwnd);
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default: 
        break;
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}


Share this post


Link to post
Share on other sites
gretty    273
Just another question...

I am trying to get the cursor x,y coordinates (client coords not screen coords) with code that is inside the message WM_TIMER (see code if this is confusing).The common way I use to get the cursor coords is to use the lParam but this only works inside the WM_LBUTTONDOWN message coz I think the lParam is different inside the WM_TIMER message.

So can anyone tell me how to get the cursor client area coords for the following code?


case WM_TIMER:
{
switch(LOWORD(wParam)) {

case LA_TIMER:
{ // Laser can create another target now
myLaser.ceaseDelay(hwnd);

// if left mouse button is still held down
if (myLaser.lButtonHeldDown) {

RECT clientR;
GetClientRect(hwnd,&clientR);
POINT cursor;
// How can I get the cursor coords??
//cursor.x = LOWORD(lParam); cursor.y = HIWORD(lParam); This doesn't work

// if mouse is INSIDE client area
int collision = PtInRect(&clientR,cursor);

if (collision != 0) {

myLaser.createTarget(hwnd,LOWORD(lParam),HIWORD(lParam));

}
}
}
break;
default:
break;
}
}
break;



Share this post


Link to post
Share on other sites
taz0010    277
Edit: Too late :(

You use the conveniently named GetCursorPos function. This gives you the position in screen coordinates though, so you normally call ScreenToClient to convert into client coordinates.

Share this post


Link to post
Share on other sites
ComicSansMS    138
correct me if i'm wrong, but using a timer here seems like a workaround to detect mouse movements. there is an event for that called WM_MOUSEMOVE which will be a much better fit for this task.
it also comes with a nifty flag for checking if the mouse button is currently down ;)

Share this post


Link to post
Share on other sites
szecs    2990
The problem with timers is:
Quote:
MSDN

The WM_TIMER message is a low-priority message. The GetMessage and PeekMessage functions post this message only when no other higher-priority messages are in the thread's message queue.
So if your system is slow and busy (for example dragging will produce a very slow redraw), it's possible, that you "never" get that message (until you keep dragging the stuff around). Even if that doesn't happen, it will be very imprecise.

So if that delay has to be precise, I suggest you to use the WM_MOUSEMOVE and query the time inside it (with timeGetTime for example).

It will be tricky, because you have to use the timer too (if no event occurs).
So you could use a trick: get time at every messages and reset the timer too:
cur_time = timeGetTime();
timer_delay = exact_time_when_you_want_to_get_WM_TIMER - cur_time;

SetTimer(win_state.hWnd,IDT_TIMER_TIME,timer_delay,NULL);
You have to do that with all (at least the most common: WM_MOUSEMOVE) messages.
WM_LBUTTONDOWN:
you have to calculate exact_time_when_you_want_to_get_WM_TIMER there:
exact_time_when_you_want_to_get_WM_TIMER = timeGetTime() + THE_DELAY_YOU_WANT;
WM_TIMER:
exact_time_when_you_want_to_get_WM_TIMER = timeGetTime() + THE_DELAY_YOU_WANT;

SetTimer(win_state.hWnd,IDT_TIMER_TIME,THE_DELAY_YOU_WANT,NULL);
//if you want to repeat continuosly.
These are just from the top of my head.

I hope that helps.

EDITED a stupid thing.
EDIT 2: Maybe you have to kill the timer before setting. I don't know if windows resets the timer with SetTimer.

[Edited by - szecs on May 1, 2010 3:16:25 AM]

Share this post


Link to post
Share on other sites
gretty    273
Thanks for the replies :)

Yeah I am now discovering how annoying timers are. But I still want to use a timer. I am going to make another thread about not being able to turn my timer off.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this