Mousemove event in a control created with MFC.

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...
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Tommy HuiEngineerCommented:
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.

mtoftAuthor Commented:
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?

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.
C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

mtoftAuthor Commented:
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...

mtoftAuthor Commented:
Adjusted points to 500
Please send me your code. My E-mail is
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


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
mtoftAuthor Commented:
Thank you, excellent...
mtoftAuthor Commented:
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...
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.