Programming in Visual C++ for Mouse Events

Posted on 2000-03-22
Last Modified: 2012-08-14
I have a dialog based application with a lot of command buttons, and other miscellaneous controls (combo boxes, etc.), and I want to be able to hover the mouse over any button, and 1) highlight it, and 2) display help text for any of the controls.

I figured the way to do this would be to use the WM_MOUSEMOVE message. I tried this, and this gives me coordinates for anywhere in the dialog, except over the controls. (I'm assuming that the controls are intercepting the WM_MOUSEMOVE message.)

I was planning to use the coordinates to tell me when I was over each command button, and was planning to then implement code to do the highlighting, and bubble help.  

What is the best way to implement what I'm trying to do ?
Question by:wannabeguru
  • 3
  • 3

Expert Comment

ID: 2665742
As far as I know, you can't do that, the windows common controls are derived from one generic class and are self contained, think of them as separate windows that happen to interact with your program.

Expert Comment

ID: 2684596
For the 'help text' you could use a tooltip.

I can explain how to do it in MFC. Is that any use?

What do you mean by 'Highlight it'?

Author Comment

ID: 2685041
To abancroft:
  If you're good at tool tips, that would definitely help.  I'll explain a little more about my application.

 I have several command buttons, that have bitmaps associated with them.  The CBitmapButton class is really handy for "static", "pressed", "disabled" and "focused" states, but I want to change the bitmap on the button when I hover the mouse over it, and then once I click the button, I want to change the bitmap to a 3rd state, that remains until I click a different button.  Note how the palette buttons work in the "Paint" application.  

The only way I could figure out how to do this was to make static controls, and then write code to change the bitmaps on the fly, using the WM_MOUSEMOVE, and WM_LBUTTONDOWN messages.  I've got this working pretty good now by writing a fair amount of code, but I wonder if there's a more elegant way.  

Now, I also want to display tool tips over each of these static controls (which look just like bitmapped command buttons) to describe what each button does.  I know how to do tooltips over a CButton command button, but I've run into difficulty using the CStatic controls. The only way I've come up with so far, is to provide a tooltip for the entire dialog, and just change the tooltip text when the mouse is over one of my buttons.  I would rather just pass a pointer to the CStatic control, like I can do with a CButton object, but this doesn't seem to work.  CButton must automatically handle the TTN_NEEDTEXT message, and CStatic does not.  

Do you know how to do tooltips over static controls ?  I've been looking through the MSDN CD and found some examples for similar stuff, but not for exactly what I'm doing.

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.


Expert Comment

ID: 2685138
Sounds like you know what you're doing....

Here's how I do tooltips:
1. In OnInitDialog(), call EnableToolTips().
2. Handle the TTN_NEEDTEXT message:
BOOL CMyDlg::ToolTip(UINT id, NMHDR * pTTTStruct, LRESULT * pResult)
  UINT nID = pTTTStruct->idFrom;

  // idFrom is actually the HWND of the tool
  if (pTTT->uFlags & TTF_IDISHWND)
    nID = ::GetDlgCtrlID((HWND)nID);

  if (nID)
    pTTT->lpszText = MAKEINTRESOURCE(nID);
    pTTT->hinst = AfxGetResourceHandle();


This will try and use the string resource with the same id as the control. If no such resource exists, no tool tip. I haven't tried this for static controls, but unless MFC filters them it should work.

Sounds like you need radio buttons that act like & look like bitmap buttons. Is that correct?

Author Comment

ID: 2685325
Your statement is correct.  I want the functionality of a radio button, i.e. mutual exclusion, but in addition I want to change the bitmap on the button just by having the mouse over the button (unless the button is already selected, in which case the mouse over the button has no effect).

With regard to your sample code, how do I make the string resource with the same ID as the control ?  That may be my problem.  I saw the same sample code in the MSDN CD, and I tried it, but no tool tip showed up.  I used the AddTool method:

m_ToolTip.AddTool(&m_Btn1, "Button 1");

where "m_Btn1" is a CStatic member variable associated with my static control.  (I added the member using CLass Wizard.)  This exact code works if "m_Btn1" is for a CButton control, but not for a CStatic control.

Accepted Solution

abancroft earned 100 total points
ID: 2685450
For the bitmap radio buttons:
1. Create radio buttons in the dialog resource editor. As normal, use the 'Group' style to create a radio button group (so only 1 can be chosen at a time).
2. For each radio button, apply the 'Push-Like' and 'Bitmap' styles.
3. Use the class wizard to add an 'int' member variable and link it to the radio button group (I'll call it m_nRadio)
4. Add an int to hold the id of the radio button that the mouse is over(I'll call it m_nHover). In the constructor, initialise to -1.

Now you need to set the bitmaps at the appropriate points. One method is:
1. Create appropriate bitmap resources - the exact number is dependent on your requirements.
2. For each bitmap resource, add a CBitmap member to the dialog: load each CBitmap member with the corresponding resource in OnInitDialog().
3. Create a function (e.g. DrawRadioImages()) that'll send BM_SETIMAGE messages to each radio button. This'll need to take into account the m_nRadio & m_nHover variables.
4. Call this function at the end of DoDataExchange().
5. Add an ON_CONTROL_RANGE(BN_CLICKED, ...) handler for the range of radio button ids. In the handler, just call UpdateData(TRUE).

Now you just need to handle the hovering image (this is pseudo code):
  if (mouse is over radio button)
    m_nHover = radio button id;
  else if (-1!=m_nHover)
    // Not over any radio, but was in last mouse move message, so clear hover image
    m_nHover = -1;

You could also use image lists or arrays of CBitmap objects in place of the individual bitmaps.

Or use a CToolBarCtrl instead of radio buttons.

To make a string resource with the same id as a control, just insert a 'String Table' in resource view. Then add a string with the same id as the control (e.g. IDC_RADIO1).

I haven't used the AddTool() method: the one I described works for static controls though. Using resources also allows you to localise the tool tip text.

Author Comment

ID: 2685760
I didn't realize that radio buttons could be used with bitmaps.  I'll try that.  Thanks for your help !

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
add projects t working set in maven 2 24
Using Third Party DLL with Access VBA 14 41
Why use this lambda? 12 39
Create .bat File 16 36
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
A short article about problems I had with the new location API and permissions in Marshmallow

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question