emulate two mice like on an iPhone -


I've heard on iPhones that it's possible to stick both fingers next to each other on the display, then drag your fingers away from one another to signal a 'zoom in' operation.

I'm wondering if this can be emulated using a standard win32 mouse message loop? For testing, I can hook up two mice to simulate two fingers. To signal this gesture, I would need to register two sets of mouse move messages with a timestamp difference of only a few milliseconds - and one mouse move message has to be moving away from the other mouse move message over time to qualify as this type of gesture.

This is really just for fun as I was trying to figure out how the iPhone people would do it (I'm not really going to make a user interface like this! for PC!).

To start I was thinking something like:

struct  MM {
    int ,_x;
    int m_y;
    DateTime m_timestamp;

list<MM> m_Moves;
void CMyWindow::OnMouseDown(int x, int y)

void CMyWindow::OnMouseMove(int x, int y)
    m_Moves.push_back(MM(x, y, now());

void CMyWindow::OnMouseUp(Int x, int y)
    // Now run through all the generated mouse move messages,
    // and see if they fit the gesture pattern we're looking for.
    // Sort all the mouse move messages by timestamp.
     For the first message, see if there is another message in the list at about the
     same timestamp. Record the x,y distance between them. Then look for the
     next timestamp, and a mouse message at about the same timestamp. Get
     their x,y distance. If less than the 1st, it's not our gesture. If greater or
     equal, keep going. If later timestamped messages keep growing further
     apart in their x,y distance, we can consider it a match. Do this for some
     threshold like 3 message pair checks.

I'd have to sit down and put some work into the above initial idea. I can see the need to eliminate a lot of 'noisy' mouse move messages - somehow average them as a lot may be generated and if all used, could throw off the interpretation.

Just wondering if you all had any other initial idea, or does this seem like a doable thing?

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

DJ_AM_JuiceboxAuthor Commented:
Hmm or even simpler - if two mouse downs and two mouse ups are registered, check the distance between the two mouse down points, and the two mouse up points:

vector<Point> m_MouseDown;
vector<Point> m_MouseUp;

void CMyView::OnMouseDown(int x, int y)
    // Should happen twice before a call to OnMouseUp().

void CMyView::OnMouseUp(int x, int y)
    // Push on the release point, this can happen twice!
    m_MouseUp.push_back(x, y);

    // Now if we had two mouse downs and ups....
    if (m_MouseDown.size() > 1 &&
         m_MouseUp.size() > 1))
          double dStart = DistanceBetween2Pts(m_MouseDown);
          double dEnd   = DistanceBetween2Pts(m_MouseUp);
          if (dEnd > dStart) {
               // Yes it was the gesture we want!

That looks a lot easier.
evilrixSenior Software Engineer (Avast)Commented:
>> This is really just for fun
Hi DJ, maybe you just need to get out more ;-)

>> does this seem like a doable thing?
I have no idea if this is doable; however, some people on the following thread seem to imply it is but it would involve the use of DirectX.

Hm, why don't you check for two mouse buttons instead of two mice, that seems way easier to me. The trick would be to check the time differenc between WM_LBUTTONDOWN' and 'WM_RBUTTONDOWN' (as well as their 'up' counterparts) and discard teh operation if it is too long. That way, you could

void CMyView::OnLButtonDownOnLButtonDown(
   UINT nFlags,
   CPoint point
    m_lLButtonTime = GetMessageTime();


void CMyView::OnRButtonDownOnLButtonDown(
   UINT nFlags,
   CPoint point
    m_lRButtonTime = GetMessageTime();


void CMyView::CheckButtonAction()

    if (abs(m_lButtonTime - m_RButtonTime) < BUTTON_TRESHOLD))

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

From novice to tech pro — start learning today.