Solved

Programming in Visual C++ for Mouse Events

Posted on 2000-03-22
7
1,711 Views
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 ?
0
Comment
Question by:wannabeguru
  • 3
  • 3
7 Comments
 

Expert Comment

by:FAQ
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.
0
 
LVL 4

Expert Comment

by:abancroft
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'?
0
 

Author Comment

by:wannabeguru
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.

0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 4

Expert Comment

by:abancroft
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:
  ON_NOTIFY_EX( TTN_NEEDTEXT, 0, ToolTip)
  :
  :
BOOL CMyDlg::ToolTip(UINT id, NMHDR * pTTTStruct, LRESULT * pResult)
{
  TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pTTTStruct;
  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();
  }

  return(TRUE);
}

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?
0
 

Author Comment

by:wannabeguru
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.
 
0
 
LVL 4

Accepted Solution

by:
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):
CDlg::OnMouseMove(...)
{
  if (mouse is over radio button)
  {
    m_nHover = radio button id;
    DrawRadioImages();
  }
  else if (-1!=m_nHover)
  {
    // Not over any radio, but was in last mouse move message, so clear hover image
    m_nHover = -1;
    DrawRadioImages();
  }
}

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.
0
 

Author Comment

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

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Entering a date in Microsoft Access can be tricky. A typo can cause month and day to be shuffled, entering the day only causes an error, as does entering, say, day 31 in June. This article shows how an inputmask supported by code can help the user a…
A short article about problems I had with the new location API and permissions in Marshmallow
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

758 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now