How do I get recurring events from holding a button down?
-
Hi, I have a button that is supposed to increase the size of an image when it's held down. I want it so that when the button is held down, I get a repeated event. How do I know in my application that a button is held down, is there an event generated that is sent to the window procedure ?
-
Hi, I have a button that is supposed to increase the size of an image when it's held down. I want it so that when the button is held down, I get a repeated event. How do I know in my application that a button is held down, is there an event generated that is sent to the window procedure ?
You'll get a WM_CHAR message sent each time (a) a key is pressed or (b) a key has been held for long enough to trigger another 'key-pressed' event. Here's a minimal WindowProcedure
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
case WM_CHAR:
printf("Key Pressed: %c\n", wParam);
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
} -
You'll get a WM_CHAR message sent each time (a) a key is pressed or (b) a key has been held for long enough to trigger another 'key-pressed' event. Here's a minimal WindowProcedure
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
case WM_CHAR:
printf("Key Pressed: %c\n", wParam);
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}thanks for the reply, but when i say button I mean a button control not a keyboard key. I'm looking for an event such as WM_COMMAND that is generated while the button is pressed until the button is released. WM_COMMAND though just is generated on click not press as well.
-
thanks for the reply, but when i say button I mean a button control not a keyboard key. I'm looking for an event such as WM_COMMAND that is generated while the button is pressed until the button is released. WM_COMMAND though just is generated on click not press as well.
Since the keyboard auto-repeat, some of the 'low'-level stuff is already done. If however, you want a button control to have auto-repeat, you'll have to set a timer yourself. I'd imagine that you would set(create) the timer when the particular button was pressed. Each time the timer is triggered, you'd check to see if the button's state indicated that it was pressed. If so, simply send yourself another WM_COMMAND message. HOWEVER, this task is somewhat complicated by the fact that the WM_COMMAND is not sent by a button until either the mouse-button or the keyboard key that was used to press it is released, meaning that your first event is not fired until after the button is no longer pressed, hence no ability to auto-repeat. I suspect that you'll need to create this button as a custom-control, handling both the drawing (reasonably easy using the DrawThemeBackground(sp?) function) and the keyboard/mouse handling. Mouse handling should be pretty straight forward, using SetCapture and ReleaseCapture. You'll have to also work out which keyboard keys you want to be able to press the button too, setting the button's state to BS_PRESSED. This sounds like about the kind of functionality that the spin-button control offers, albeit with a single button rather than a pair of them. To that end, to find a solution quickly, I'd probably start looking for code for a custom spin-button control, editing as needed to fulfil your needs.
-
thanks for the reply, but when i say button I mean a button control not a keyboard key. I'm looking for an event such as WM_COMMAND that is generated while the button is pressed until the button is released. WM_COMMAND though just is generated on click not press as well.
See if you get BN_PUSHED[^] and BN_UNPUSHED[^] from the button, these are, as the documentation states, provided only for compatibility with 16-bit versions of Windows, so they might not work anymore, but if they do, you could try starting the timer with SetTimer[^] on BN_PUSHED and kill it with KillTimer[^] on BN_UNPUSHED, and do your zooming thing in the handler for WM_TIMER[^].
> The problem with computers is that they do what you tell them to do and not what you want them to do. < > If it doesn't matter, it's antimatter.<
-
Since the keyboard auto-repeat, some of the 'low'-level stuff is already done. If however, you want a button control to have auto-repeat, you'll have to set a timer yourself. I'd imagine that you would set(create) the timer when the particular button was pressed. Each time the timer is triggered, you'd check to see if the button's state indicated that it was pressed. If so, simply send yourself another WM_COMMAND message. HOWEVER, this task is somewhat complicated by the fact that the WM_COMMAND is not sent by a button until either the mouse-button or the keyboard key that was used to press it is released, meaning that your first event is not fired until after the button is no longer pressed, hence no ability to auto-repeat. I suspect that you'll need to create this button as a custom-control, handling both the drawing (reasonably easy using the DrawThemeBackground(sp?) function) and the keyboard/mouse handling. Mouse handling should be pretty straight forward, using SetCapture and ReleaseCapture. You'll have to also work out which keyboard keys you want to be able to press the button too, setting the button's state to BS_PRESSED. This sounds like about the kind of functionality that the spin-button control offers, albeit with a single button rather than a pair of them. To that end, to find a solution quickly, I'd probably start looking for code for a custom spin-button control, editing as needed to fulfil your needs.
-
thanks, I've managed to get the holding button down to work. I just used a global veriable to track the state of the button via the WM_DRAWITEM notification and then in my program loop referred to this variable.