• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 476
  • Last Modified:

Detecting mouse move over a CBitmapButton

I'd like to set up my program so that when the user places the mouse over my button, the bitmap changes.  I've tried using the OnMouseMove function from my dialog, but it's detecting the wm_mousemove message everywhere but the button.  Has anyone done this before?  Please help!  Thanks!!
  • 3
  • 3
  • 2
  • +5
1 Solution
You can derive class from CButton and handle OnMouseMove method (it is a simplest way).
Don't forget SetCapture() or you may loose the mouse
leaving your window.

- hans
Tommy HuiEngineerCommented:
The mouse move message will usually go to the window that the mouse is over. Therefore you shouldn't use OnMouseMove for the dialog, but instead for the button. So you will need to derive a class from CBitmapButton and catch OnMouseMove there.

To clarify, any window can call SetCapture to continue receiving mouse messages even when the mouse is not over the window. In your case, though, you do not need this functionality.
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

SandymAuthor Commented:
I suppose I wasn't clear enough in my post.  Here's more details:
I don't have a seperate class for the button and doing so would require a lot of code changes.  
My button is a CBitmapButton that is located on a dialog window along with several other controls.  I have tried using the setCapture function, and it works wonderfully for the mousemove event, but renders the rest of my controls, the system menu, and all hotkeys useless..

Anyone have any suggestions now that i've properly stated my problem?
i agree with thui , u have to subclass your button in order to get its messages.

doi a derived class from CBitmapButton, and subclass it in the Dialog OnInitDialog function.
Thui is right, you derive and subclass.  You wont have to rewrite anything.  The following line placed in OnInitDialog() will do the subclassing:

    m_stcInfo.SubclassDlgItem(IDC_INFO, this);

where m_stcInfo is the member variable and IDC_INFO is the resource id.
SandymAuthor Commented:
I've added that line into the OnInitDialog() and it's still not sending any wm_mousemove messages to the main window.  What else do I need to do?

By the way, thanks so much for everyone who's helping me!
dear sadym.
i'll give you a brief explenation about sub class and its use:
sub class is when u have a dialog for instance , this dialog has controls, those control are actully classes, but you are using them as control, it means u are using just their derived class function in other words, every control derived from CWnd to get all the functionality of that class you have to sub class it do the following?:

go to Inser->NewClass, now give a new name to your class, and in the derived combobox choose CBitmapButton.
click OK, now this class is added to your project.
in your dialog cpp file add this:
#include "newclass.h"  // the class you just added" h file

now in the dialog OnInitDialog do this:
mNewClass.SubclassDlgItem(IDC_MYBUTTON, this);

mNewClass is object of the new class you added (remmember ?)
and IDC_MYBUTTON is the Button resource name.

now compile and link.

now every message of that button will direct to this new class you added, in that class you have to create message map for every message you want to catch using classwizard.

hope that help

don't hesitate to ask, this is what this site for :-)

good luck

You can override the PreTranslateMessage() and capture the WM_MOUSEMOVE message. Try something like this:
      BOOL CMyDlg::PreTranslateMessage(MSG* pMsg)
      // TODO: Add your specialized code here and/or call the base class
      CWnd *pwnd=GetDlgItem(IDC_PICBUTTON);
      CRect rect;
      CPoint pt=pMsg->pt;
            //write your code to change the bitmap
      return CDialog::PreTranslateMessage(pMsg);
Hope this helps.
Have a look to the MSJ, issue 10/1998.
Paul DiLascia wrote an excellent article about exactly that thing that you want to do.  You even can get the source of TrackMouseEvent (thats like he called the example app) under
 the text you should find under

SandymAuthor Commented:
That is what I had in the first place pagladasu.. and the button was not sending a WM_MOUSE message to catch.  I ended up doing the whole derive and subclass and adding to the OnInitDialog as Shay detailed.  It still wasn't working, so I used Spy++ to see that the button was sending a WM_SETCURSOR with a mouse message of WM_MOUSEMOVE.  I then used the OnSetCursor function and checked to see what the last parameter was.  If it matched up, I then post a message with WM_MOUSEMOVE.  This message then goes to my OnMouseMove function with a point of (0,0).  I know that if I have that point, that i'm on top of the button and to change the state of the button to focused so that the bitmap changed.  Anywhere else and I put the state back to normal.  I know it's not pretty, but it works and after 3 days of working on it, I'm happy!

Thanks for everyone's help
by the way Sandym you welcome...
More accutely, the URL for TrackMouseEvent is:

Featured Post

[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

  • 3
  • 3
  • 2
  • +5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now