Solved

Mousemove event in a control created with MFC.

Posted on 1998-02-10
10
960 Views
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)
       ReleaseCapture
   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...
0
Comment
Question by:mtoft
  • 5
  • 2
  • 2
  • +1
10 Comments
 
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.


0
 
LVL 2

Author Comment

by:mtoft
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?

0
 
LVL 7

Expert Comment

by:galkin
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.
0
 
LVL 2

Author Comment

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

0
 
LVL 2

Author Comment

by:mtoft
ID: 1315954
Adjusted points to 500
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 7

Expert Comment

by:galkin
ID: 1315955
Please send me your code. My E-mail is sasha@zsoft.com
0
 
LVL 11

Accepted Solution

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

0
 
LVL 2

Author Comment

by:mtoft
ID: 1315957
Thank you, excellent...
0
 
LVL 2

Author Comment

by:mtoft
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...
0
 
LVL 11

Expert Comment

by:mikeblas
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
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

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…
After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
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. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

707 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

12 Experts available now in Live!

Get 1:1 Help Now