Click here to Skip to main content
Click here to Skip to main content

Simple Auto-Repeat (Fire Control) Button Control

, 10 May 2001 CPOL
Rate this:
Please Sign up or sign in to vote.
Simple drop-in button control that allows type-o-matic repeating on a button
<!-- Download Links --> <!-- Article image -->

Sample Image - RepeatButton.jpg

<!-- Add the rest of your HTML here -->

Introduction

I needed an ordinary button that would act like it was being constantly clicked as long as the mouse button was held down. Sounds pretty simple. You see this kind of thing in games and in XWindows projects I have seen widgets that did this everywhere. But I couldn't find one. Noooo!

I did find some neat code that did a "mouse repeat" which sounded like it would do the job, albeit less cleanly. This just repeated the Left Mouse Button Down message as long as the button was down. Cool. But button controls only send the BN_CLICKED message to the owning dialog when the mouse button goes UP (the BN_CLICKED message is the typical one that you handle and that VC++ supports in its resource editor)!

So, it looked like I was going to have to subclass the standard CButton control (subclassing is how one intercepts messages to a control and is a Windows thing, not a C++ thing). Windows subclassing is something I had never done. Fortunately there are some good subclassing articles at CodeProject.

What it does

The new button class, CRepeatButton, captures the LButtonDown, LButtonUp, and Timer messages.

  1. When the left mouse button goes down, a timer is set. The duration is the same as for keyboard auto-repeat. Also, the initial BN_CLICKED message is posted to the parent of the control.
  2. When the timer fires the first time, the timer is reset to the interval between clicks during auto-repeat. And another BN_CLICKED message is sent to the parent.
  3. Every time the timer goes off after this, the BN_CLICKED message is posted.

If the mouse leaves the control's rectangle or if the mouse button is lifted, the timer is cancelled and no further messages are posted to the parent.

So far, not too bad. However, since this button is acting slightly strangely, I felt it was important to give some kind of visual and audible clues. So when in auto-repeat mode (after the initial delay), the background color of the button changes to yellow. This involved the dreaded DrawItem function and turning on Owner Draw. But I grabbed this code from somebody else so it hardly hurt at all.

And each time the BN_CLICKED message is posted, a "click" wav image is played.

Since this may annoy some, I have included lots of comments for removing these features.

How I did it

Basically, I stole reused some code I found here at CodeProject:

How do I get it in my project?

There are probably better, cleaner, more graceful ways to do this, but this worked and was pretty simple.

First, I needed to let VC++ know about the new class, so I used the Class Wizard to create a new class based upon CButton called CRepeatButton. The Class Wizard creates RepeatButton.h and RepeatButton.cpp

Then I copied in my own RepeatButton.h and RepeatButton.cpp files.

I then rebuilt the project on the general principle that making too many changes too fast confuses VC++.

Back to the resource editor to add in the new buttons: Add an ordinary button to the dialog and change the resource id as needed. For the demo project included here, I called it IDC_BUTTON1. Astoundingly, this is the very name the resource editor assigned it!

Now use the Class Wizard to add a member variable to the dialog. The variable Category is Control (not that there is a lot of choice). And the variable type is CRepeatButton (not CButton).

That's it! The ordinary CButton has been hijacked and is now effectively a CRepeatButton.

I built this with VC++ 6.0 (MFC 4.2) but I don't think it is all that version-specific.

One little weirdness is that the WAV sound is not a file nor a resource. It is so small (10 milliseconds) that I couldn't bear the thought of the overhead of searching for it every time through the loop. So I converted the file to an array of characters and send the address to the sndPlaySound() function. But this will annoy some so I included comments to undo this...

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Harold Bamford
Software Developer (Senior) Thales Visionix
United States United States
No Biography provided

Comments and Discussions

 
Generalgood Pinmemberassaids4-Jan-04 18:36 
GeneralNice PinmemberBrian Bull23-Oct-03 7:05 
GeneralSetFocus when you click Pinsusswalster21-Jul-03 12:16 
GeneralRe: SetFocus when you click PinmemberHarold Bamford21-Jul-03 12:38 
GeneralRepeat continued even after disabled PinmemberNimai2-Jun-03 16:14 
Generalcan't stop the auto repeat Pinmemberkurin2-Apr-03 22:16 
GeneralRe: can't stop the auto repeat PinmemberHarold Bamford3-Apr-03 4:48 
GeneralRe: can't stop the auto repeat PinmemberHarold Bamford4-Apr-03 5:52 
GeneralSpace bar support PinsussDirk Luetjens18-Oct-02 16:04 
QuestionHow does it work for Toolbar buttons PinsussAnonymous20-Sep-02 3:39 
AnswerRe: How does it work for Toolbar buttons PinmemberHarold Bamford20-Sep-02 5:57 
AnswerRe: How does it work for Toolbar buttons PinmemberRod Stone14-Nov-03 1:01 
GeneralRe: How does it work for Toolbar buttons Pinmemberjaybonomad11-Dec-03 21:57 
Generalbug fix for stuck button PinsussWally Blume18-Sep-02 12:35 
GeneralRe: bug fix for stuck button PinmemberHarold Bamford19-Sep-02 6:27 
GeneralRe: bug fix for stuck button Pinmemberbartvandiepen3-May-05 4:24 
GeneralAlmost perfect PinmemberRobert Hoschek9-May-02 12:55 
GeneralRe: Almost perfect PinmemberHarold Bamford9-May-02 13:39 
Generaluseful Pinmemberlucy2-Jan-02 11:10 
GeneralGood PinmemberJan Vidar Berger30-May-01 14:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141223.1 | Last Updated 11 May 2001
Article Copyright 2001 by Harold Bamford
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid