Mousemove event in a control created with MFC.

Posted on 1998-02-10
Last Modified: 2013-11-25
If I inside a custom mfc-activex control's MouseMove event uses SetCapture on some window,
and later release the capture. Then the activex control starts notifying me wrongly that
the "button" is pressed in the mousemove event, even though it isnt...

Its very simple (For me atleast) to recreate the "feature", using Visual Basic 5.0 and
Visual C++ 5.0.

Start Visual C++ 5.0
1. Create a MFC ActiveX control, just name it and finish the wizard...
2. Add the stock event "MouseMove"
3. Compile the activex control and register it.

Start Visual Basic 5.0
1. Create a new project.
2. Place a picturebox control(Picture1) and the "MFC activex control" (MFC1) on the form.
3. Insert this code into the form's code view:

   Private Sub MFC1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
       debug.Print Button
       If Button = vbLeftButton Then
           SetCapture Picture1.hWnd
       End If
   End Sub

   Private Sub Picture1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
   End Sub

As you see, pressing the button on the mfc control and moving the mouse will "capture" the
windows messages to the "Picture1" control. Which again will release it as soon as you
release the left button...
After this, the "MFC1_MouseMove" event will start reporting that "Button" is 1, ie pressed
even though it isnt... (See it in the debug window)

Am I missing something vital???

Should I do something at "WM_CAPTURECHANGED"??

Any help will be appreciated...
Question by:mtoft
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 2
  • 2
  • +1
LVL 15

Expert Comment

by:Tommy Hui
ID: 1315950
The usual capturing is done at the WM_LBUTTONDOWN message at the source window and not on the WM_MOUSEMOVE message. Then a flag is kept, so that on WM_LBUTTONUP for the source, it knows that something has been dropped.


Author Comment

ID: 1315951
If you switch the MFC1 control with some other control this problem does not exist (Try the picture1 control, f.eks).

Ie, its a problem local to MFC, *i think* - it doesnt really matter whether its normally done in WM_LBUTTONDOWN... agree?


Expert Comment

ID: 1315952
Why are you not satisfied with thui's answer? He shoed you classical solution for capturing mouse event, that can be implemented anywhere and not only in ActiveX control.
Creating Instructional Tutorials  

For Any Use & On Any Platform

Contextual Guidance at the moment of need helps your employees/users adopt software o& achieve even the most complex tasks instantly. Boost knowledge retention, software adoption & employee engagement with easy solution.


Author Comment

ID: 1315953
Excuse me? Im not trying to implement or solve anything about capturing...

My problem is that when I DO capture the windows messages, and releases this capture... After which the MFC control starts behaving oddly... The MFC control-event "MouseMove" or "MouseDown" starts the capture, and some other control ends it... After the capture is ended, the MFC control keeps sending events to my window that the "button" argument in MFC_MouseMove is 1, ie pressed...

I can send you some sample code that illustrates the problem... It might just be me that is unable to clarify the problem...


Author Comment

ID: 1315954
Adjusted points to 500

Expert Comment

ID: 1315955
Please send me your code. My E-mail is
LVL 11

Accepted Solution

mikeblas earned 500 total points
ID: 1315956
MFC itself is setting the capture when the button is pressed. This is by-design, because the default MFC control implementation in COleControl fires MouseDown and MouseUp events. It has to set capture when the mouse goes down so the control can fire a matched MouseUp event even if the user drags off the control.  (If MFC didn't do this, it would be tough to handle drag-and-drop off the control, for example.)

Look at the MFC source for COleControl::ButtonDown() or COleControl::ButtonUp() in the MFC\SRC\CTLEVENT.CPP source to see what's going on.

When you click on the MFC control, it accepts capture. It also makes a note to itself (in the m_iButtonState member) that the mouse button is down.  You then get MouseMove events, and give caputre to another control. The other control gets the WM_xBUTTONUP message, and releases capture because you've coded it that way in VB.

Since MFC never sees the WM_xBUTTONUP message, it never resets m_iButtonSave. It gets capture back, however, and starts firing MouseMove events because it sees the mouse moving around. It sends the wrong button flags because that's what it has cached.

Your solution is to write your own handlers for all the WM_xBUTTONDOWN and WM_xBUTTONUP messages in your MFC control and ignore the messages. If you want to take some action when the control is clicked, that's fine--but _don't_ call the base class implementation. Then, MFC won't capture the mouse messages for the control.

All this withstanding, switching capture on MouseMove seems crazy to me, and I can't understand why you've want to do that.

.B ekiM


Author Comment

ID: 1315957
Thank you, excellent...

Author Comment

ID: 1315958
Crazy or not... The MFC base class obviously isnt implementing the standard behaviour of these events.

If I create a control to some "consumer", then that consumer would and should expect the same behaviour of my control's mousedown event as the (example) picturebox control mousedown event...
LVL 11

Expert Comment

ID: 1315959
Actually, the MFC implmentation was the _first_ implementation, and provided the defacto stadnard.

The MFC implementation is geared towards controls that do want to fire the MouseDown and MouseUp events. If you don't want the tracking, simply write the handlers I've described and you're done.

.B ekiM

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA.…

751 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