You are on page 1of 4
osroar2021 ‘An AuloRepeat Button Class - CodeProject An AutoRepeat Button Class Ps Arends Thisis an altemative for “An AutoRepeat Button Class? Download source - 1.7 KB Download demo - 132.6 KB @B AutoRepeatPushButton =X Test 30 Introduction | am in need of an autorepeat button. A button that when the user presses and holds it down will fre multiple BN_CLICKED notifications. | did a search and found Joseph M. Newcomer's aticle "An AutoRepeat Button Class". While the code presented in the article worked exactly as advertised, it had one major flaw. It did not work when the user pressed the space bar, it only worked with the left mouse button. The comments attached to the article provided some ideas on how to fixit, but none were ideal, | took the ideas presented in the article and some of the comments and came up with the cade | am sharing here. Using the Code ‘The best way to get the button control to do what | needed it to do was to subclass the CBut ton control and override its OnL But tonDown, OnLButttonUp, OnKeyDown, and OnKeyUp message handlers. | added four bool member variables that act as flags to control what has happened and what has to happen next when the control i used. The first two variables are KeyPress andMousePress that control whether itis the mouse button or the space bar that started the timer. The next one is TimerActive that prevents the timer from being restarted when the key press auto-repeats. The last one isMessageSent that controls whether a BN_CLICK message should be sent when the button is released void CAutoRepeatButton: :OnkeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { if (IMousePress) // Only if not already activated by the mouse t if (VK_SPACE == nChar && ITinerActive) { SetTimer(TIMERID, InitialTime, NULL); Tineractive = trues Keypress = true; > Button: :OnkeyDown(nchar, nRepCnt, nFlags); hitps:lwwn.codeproject.com/Artcles/1181670/An-AutoRepeat-Button-Class-??6lsplay=Print 4 31032021 ‘An AuloRepeat Button Class - CodeProject } + void CAutoRepeatButton: :OnLButtonDown(UINT nFlags, CPoint point) { if (IKeyPress) // Only if not already activated with the space bar if (ITimeractive) { SetTimer(TIMERID, InitialTime, NULL); TimerActive = true; MousePress = trues y Button: :onLButtonDown (nFlags, point); } } ‘When the button is pressed with either the left mouse button or the space bar, we first check that the button is not already { by the other one. Then we check ifthe timer is not already started and start it with the intial delay time if it was not. Finally, place a call to the base class handler to do the default handler which captures the mouse and draws the button as depressed, void CAutoRepeatButton: :OnTimer(UINT_PTR nIDEvent) « if (nIDEvent { TIMERID) if (BST_PUSHED { (BST_PUSHED & GetState())) if (1MessageSent) SetTimer(TIMERID, RepeatTime, NULL); Messagesent = trues } Parent->SendMessage(nM_COMMAND, MAKELPARAM(GetD1gCtr1ID(), 8N_CLICKED), (WPARAM)m_hivnd) 5 y } else { Button: :OnTimer(nTDEvent) ; } ‘When the timer fires, we first check the state of the button. I the mouse was used to start the timer and then itis moved off of the button, the button will no longer be pushed so we will not want the BN_CLICKED messages to be sent. But we do want them to continue ifthe mouse moves back onta the button. After the initial time delay, the timer is reset to the repeat time and a BN_CLICKED message is sent. void CAutoRepeatButto { OnkeyUp(UINT nChar, INT nRepCnt, UINT nFlags) if (VK_SPACE t nChar && KeyPress) Kil] Timer(TIMERID) 5 if (MessageSent) ReleaseCapture(); // CButton::0nKeyDown captures the mouse Setstate(a); // Redraw button as not pushed y else { + Timeractive = false; KeyPress = false; MessageSent = false; Button: :OnkeyUp(nChar, nRepCnt, nFlags); } hitps:wwn.codeproject.com/Artcles/1181670/An-AutoRepest-Button-Class-??6lsplay=Print aa 31032021 ‘An AuloRepeat Button Class - CodeProject , void ChutoRepeatButton: :OnLButtonUp(UINT nFlags, CPoint point) « if (MousePress) fe KGLLTimer (TIMERID) 5 if (MessageSent) i ReleaseCapture(); Setstate(a); i else < Coutton: :OnLButtonup(nFlags, point); } TimerActive = false; MousePress = false; MessageSent = false; > , ‘When the button is released, the timer is stopped. And then, depending on whether the button was held down long enough to generate a BN_CLICKED message, we either simply release the mouse capture and draw the button as not pressed or we call the base class handler to fire off a BN_CLICKED message. Then the flags are reset for the next time the button is pressed. void CAutoRepeatButton: :OnLButtonDb1Clk(UINT nFlags, CPoint point) « x OnLButtonDown(nFlags, point); ‘The last thing to handle i ifthe user double clicks and then holds the button down. I simply call OnLButtonDown to teat the double click asa second single click If this isnot done, then the timer isnot started void CAutoRepeatButto { SetTimes(UINT Initial, UINT Repeat) Initialtime RepeatTime Initial; Repeat Finally, as a convenience function, | added the ability to set the intial and repeating delay time interval History ‘+ April 13, 2017 - Published on CodeProject License This article, along with any associated source code and file, is licensed under The Code Project Open License (CPOL) About the Author hitps:lwwu.codeproject.com/Artcles/1181670/An-AutoRepest-Button-Class-??olsplay=Print aia osroar2021 ‘An AuloRepeat Button Class - CodeProject PJ Arends President Canada No Biography provided Saws 4 Comments and Discussions (4 messages have been posted for this article Visit https://mww.cadeproject.com/Articles/1181670/An-AutoRepest-Button- CClass-2 to post and view comments on this article, or click here to get a print view with messages Permalink Article Copyright 2017 by Pl Arends Advertise Everything else Copyright © CodeProject, 1999- Privacy 2021 Cookies Terms of Use Wweb02 28202103012 hitps:lwwn.codeproject.com/Artcles/1181670/An-AutoRepest-Button-Class-27display 48

You might also like