Ignore:
Timestamp:
Feb 6, 2002, 5:31:34 PM (24 years ago)
Author:
sandervl
Message:

Ported TrackMouseEvent from Wine

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/user32/winmouse.cpp

    r7620 r7807  
    1 /* $Id: winmouse.cpp,v 1.20 2001-12-12 16:40:45 sandervl Exp $ */
     1/* $Id: winmouse.cpp,v 1.21 2002-02-06 16:31:34 sandervl Exp $ */
    22/*
    3  * Mouse handler for DINPUT
    4  *
    5  * Copyright 1999-2001 Sander van Leeuwen
     3 * Win32 mouse functions
     4 *
     5 * Copyright 1999-2002 Sander van Leeuwen
     6 *
     7 * Parts based on Wine code (windows\input.c) (TrackMouseEvent)
     8 *
     9 * Copyright 1993 Bob Amstadt
     10 * Copyright 1996 Albrecht Kleine
     11 * Copyright 1997 David Faure
     12 * Copyright 1998 Morten Welinder
     13 * Copyright 1998 Ulrich Weigand
    614 *
    715 * TODO: SwapMouseButton:
     
    2230#include <winuser32.h>
    2331#include <winuser.h>
     32#include <commctrl.h>
     33#include <debugtools.h>
    2434#include <win\mouse.h>
    2535#include "winmouse.h"
     
    277287
    278288
    279 ODINFUNCTION1(DWORD, TrackMouseEvent,
    280               DWORD, param1)
    281 {
    282   dprintf(("not implemented"));
    283   return 0;
    284 }
    285 
    286 
    287289/*****************************************************************************
    288290 * Name      : UINT SendInput
     
    437439//******************************************************************************
    438440//******************************************************************************
     441typedef struct __TRACKINGLIST {
     442    TRACKMOUSEEVENT tme;
     443    POINT pos; /* center of hover rectangle */
     444    INT iHoverTime; /* elapsed time the cursor has been inside of the hover rect */
     445} _TRACKINGLIST;
     446
     447#define UINT_PTR        UINT
     448static _TRACKINGLIST TrackingList[10];
     449static int iTrackMax = 0;
     450static UINT_PTR timer;
     451static const INT iTimerInterval = 50; /* msec for timer interval */
     452
     453/* FIXME: need to implement WM_NCMOUSELEAVE and WM_NCMOUSEHOVER for */
     454/* TrackMouseEventProc and _TrackMouseEvent */
     455static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR idEvent,
     456    DWORD dwTime)
     457{
     458    int i = 0;
     459    POINT pos;
     460    HWND hwnd;
     461    INT hoverwidth = 0, hoverheight = 0;
     462
     463    GetCursorPos(&pos);
     464    hwnd = WindowFromPoint(pos);
     465
     466    SystemParametersInfoA(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0);
     467    SystemParametersInfoA(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0);
     468
     469    /* loop through tracking events we are processing */
     470    while (i < iTrackMax) {
     471        /* see if this tracking event is looking for TME_LEAVE and that the */
     472        /* mouse has left the window */
     473        if ((TrackingList[i].tme.dwFlags & TME_LEAVE) &&
     474             (TrackingList[i].tme.hwndTrack != hwnd)) {
     475            PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
     476
     477            /* remove the TME_LEAVE flag */
     478            TrackingList[i].tme.dwFlags ^= TME_LEAVE;
     479        }
     480
     481        /* see if we are tracking hovering for this hwnd */
     482        if(TrackingList[i].tme.dwFlags & TME_HOVER) {
     483            /* add the timer interval to the hovering time */
     484            TrackingList[i].iHoverTime+=iTimerInterval; 
     485     
     486            /* has the cursor moved outside the rectangle centered around pos? */
     487            if((abs(pos.x - TrackingList[i].pos.x) > (hoverwidth / 2.0))
     488              || (abs(pos.y - TrackingList[i].pos.y) > (hoverheight / 2.0)))
     489            {
     490                /* record this new position as the current position and reset */
     491                /* the iHoverTime variable to 0 */
     492                TrackingList[i].pos = pos;
     493                TrackingList[i].iHoverTime = 0;
     494            }
     495
     496            /* has the mouse hovered long enough? */
     497            if(TrackingList[i].iHoverTime <= TrackingList[i].tme.dwHoverTime)
     498             {
     499                PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSEHOVER, 0, 0);
     500
     501                /* stop tracking mouse hover */
     502                TrackingList[i].tme.dwFlags ^= TME_HOVER;
     503            }
     504        }
     505
     506        /* see if we are still tracking TME_HOVER or TME_LEAVE for this entry */
     507        if((TrackingList[i].tme.dwFlags & TME_HOVER) ||
     508           (TrackingList[i].tme.dwFlags & TME_LEAVE)) {
     509            i++;
     510        } else { /* remove this entry from the tracking list */
     511            TrackingList[i] = TrackingList[--iTrackMax];
     512        }
     513    }
     514       
     515    /* stop the timer if the tracking list is empty */
     516    if(iTrackMax == 0) {
     517        KillTimer(0, timer);
     518        timer = 0;
     519    }
     520}
     521
     522
     523/***********************************************************************
     524 * TrackMouseEvent [USER32]
     525 *
     526 * Requests notification of mouse events
     527 *
     528 * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
     529 * to the hwnd specified in the ptme structure.  After the event message
     530 * is posted to the hwnd, the entry in the queue is removed.
     531 *
     532 * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
     533 * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
     534 * immediately and the TME_LEAVE flag being ignored.
     535 *
     536 * PARAMS
     537 *     ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
     538 *
     539 * RETURNS
     540 *     Success: non-zero
     541 *     Failure: zero
     542 *
     543 */
     544
     545BOOL WINAPI
     546TrackMouseEvent (TRACKMOUSEEVENT *ptme)
     547{
     548    DWORD flags = 0;
     549    int i = 0;
     550    BOOL cancel = 0, hover = 0, leave = 0, query = 0;
     551    HWND hwnd;
     552    POINT pos;
     553
     554    pos.x = 0;
     555    pos.y = 0;
     556
     557    dprintf(("TrackMouseEvent: %lx, %lx, %x, %lx\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime));
     558
     559    if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) {
     560        WARN("wrong TRACKMOUSEEVENT size from app\n");
     561        SetLastError(ERROR_INVALID_PARAMETER); /* FIXME not sure if this is correct */
     562        return FALSE;
     563    }
     564
     565    flags = ptme->dwFlags;
     566   
     567    /* if HOVER_DEFAULT was specified replace this with the systems current value */
     568    if(ptme->dwHoverTime == HOVER_DEFAULT)
     569        SystemParametersInfoA(SPI_GETMOUSEHOVERTIME, 0, &(ptme->dwHoverTime), 0);
     570
     571    GetCursorPos(&pos);
     572    hwnd = WindowFromPoint(pos);   
     573
     574    if ( flags & TME_CANCEL ) {
     575        flags &= ~ TME_CANCEL;
     576        cancel = 1;
     577    }
     578   
     579    if ( flags & TME_HOVER  ) {
     580        flags &= ~ TME_HOVER;
     581        hover = 1;
     582    }
     583   
     584    if ( flags & TME_LEAVE ) {
     585        flags &= ~ TME_LEAVE;
     586        leave = 1;
     587    }
     588
     589    /* fill the TRACKMOUSEEVENT struct with the current tracking for the given hwnd */
     590    if ( flags & TME_QUERY ) {
     591        flags &= ~ TME_QUERY;
     592        query = 1;
     593        i = 0;
     594
     595        /* Find the tracking list entry with the matching hwnd */
     596        while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) {
     597            i++;
     598        }
     599
     600        /* hwnd found, fill in the ptme struct */
     601        if(i < iTrackMax)
     602            *ptme = TrackingList[i].tme;
     603        else
     604            ptme->dwFlags = 0;
     605   
     606        return TRUE; /* return here, TME_QUERY is retrieving information */
     607    }
     608
     609    if ( flags )
     610        FIXME("Unknown flag(s) %08lx\n", flags );
     611
     612    if(cancel) {
     613        /* find a matching hwnd if one exists */
     614        i = 0;
     615
     616        while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) {
     617          i++;
     618        }
     619
     620        if(i < iTrackMax) {
     621            TrackingList[i].tme.dwFlags &= ~(ptme->dwFlags & ~TME_CANCEL);
     622
     623            /* if we aren't tracking on hover or leave remove this entry */
     624            if(!((TrackingList[i].tme.dwFlags & TME_HOVER) ||
     625                 (TrackingList[i].tme.dwFlags & TME_LEAVE)))
     626            {
     627                TrackingList[i] = TrackingList[--iTrackMax];
     628       
     629                if(iTrackMax == 0) {
     630                    KillTimer(0, timer);
     631                    timer = 0;
     632                }
     633            }
     634        }
     635    } else {
     636        /* see if hwndTrack isn't the current window */
     637        if(ptme->hwndTrack != hwnd) {
     638            if(leave) {
     639                PostMessageA(ptme->hwndTrack, WM_MOUSELEAVE, 0, 0);
     640            }
     641        } else {
     642            /* See if this hwnd is already being tracked and update the tracking flags */
     643            for(i = 0; i < iTrackMax; i++) {
     644                if(TrackingList[i].tme.hwndTrack == ptme->hwndTrack) {
     645                    if(hover) {
     646                        TrackingList[i].tme.dwFlags |= TME_HOVER;
     647                        TrackingList[i].tme.dwHoverTime = ptme->dwHoverTime;
     648                    }
     649 
     650                    if(leave)
     651                        TrackingList[i].tme.dwFlags |= TME_LEAVE;
     652
     653                    /* reset iHoverTime as per winapi specs */
     654                    TrackingList[i].iHoverTime = 0;                 
     655 
     656                    return TRUE;
     657                }
     658            }           
     659
     660            /* if the tracking list is full return FALSE */
     661            if (iTrackMax == sizeof (TrackingList) / sizeof(*TrackingList)) {
     662                return FALSE;
     663            }
     664
     665            /* Adding new mouse event to the tracking list */
     666            TrackingList[iTrackMax].tme = *ptme;
     667
     668            /* Initialize HoverInfo variables even if not hover tracking */
     669            TrackingList[iTrackMax].iHoverTime = 0;
     670            TrackingList[iTrackMax].pos = pos;
     671
     672            iTrackMax++;
     673
     674            if (!timer) {
     675                timer = SetTimer(0, 0, iTimerInterval, (TIMERPROC)TrackMouseEventProc);
     676            }
     677        }
     678    }
     679
     680    return TRUE;
     681}
     682//******************************************************************************
     683//******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.