   [Win32/C++] Detect that the Mouse Button is being HELD down
  HelloI 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);}
  If you've received the button down event, but not the "up" event, you know the button is being held down :);  ah lol, so simple. Thanks I should use my brain more :D   ;  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;;  Probably what you're after is a combination of GetCursorPos and ScreenToClient.   ;  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.   ;  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 ;)   ;  The problem with timers is:Quote:MSDNThe 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];  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.   