Esempio n. 1
0
BOOL _ShowWindowAsync(
    PWND pwnd,
    int cmdShow)
{
    return PostEventMessage(GETPTI(pwnd), GETPTI(pwnd)->pq, QEVENT_SHOWWINDOW,
                            NULL, 0,(DWORD)HWq(pwnd),
                            MAKELONG(cmdShow, gfAnimate));
}
Esempio n. 2
0
void xxxTrackMouseMove(PWND pwnd, int htEx, UINT message)
{
    BOOL fNewpwndTrack;
    DWORD dwDTCancel = 0;
    TL tlpwnd;
    LPWSTR pstr;
    PDESKTOP pdesk = PtiCurrent()->rpdesk;
    PTHREADINFO ptiTrack;


#if DBG
    /*
     * Let's warn if this function gets reenterd so we can make sure
     * nothing bad will follow. This should be a rare situation.
     * Look in gptiReEntered to find out who is already here.
     */
    static UINT gcReEntered = 0;
    static PTHREADINFO gptiReEntered;
    if(gcReEntered++ != 0){
      RIPMSG2(RIP_WARNING, "Reentered xxxTrackMouseMove; previous thread was %#p, current thread is %#p", gptiReEntered, PtiCurrent());
    }
    gptiReEntered = PtiCurrent();

    CheckLock(pwnd);

    /*
     * We must be on an interactive window station.
     */
    if (pdesk->rpwinstaParent != NULL &&
            pdesk->rpwinstaParent->dwWSF_Flags & WSF_NOIO) {
        RIPMSG0(RIP_ERROR, "Can't use tooltips on non-interactive winsta");
    }

     {
        static POINT pt = {0, 0};

#ifdef UNDONE
        /*
         * We might have taken a guess on the hit test (see FindNCHitEx)
         *  so if we're at the same point and same window, something
         *  might be fishy
         */
        if ((pt.x == gpsi->ptCursor.x)
                    && (pt.y == gpsi->ptCursor.y)
                    && (pdesk->spwndTrack == pwnd)) {
            RIPMSG1(RIP_WARNING, "xxxTrackMouseMove: Same point & window. %#p", pwnd);
        }
#endif

        /*
         * Something is supposed to have changed or we're wasting time
         */
        UserAssert((pt.x != gpsi->ptCursor.x)
                    || (pt.y != gpsi->ptCursor.y)
                    || (pdesk->spwndTrack != pwnd)
                    || (pdesk->htEx != htEx)
                    || (message != WM_MOUSEMOVE));
        /*
         * Remember last tracked point
         */
        pt = gpsi->ptCursor;
     }
    /*
     * pwnd is supposed to be on the current thread and queue
     */
    UserAssert(PtiCurrent() == GETPTI(pwnd));
    UserAssert(PtiCurrent()->pq == GETPTI(pwnd)->pq);
#endif

    /*
     * Have we switched windows?
     */
    fNewpwndTrack = (pdesk->spwndTrack != pwnd);
    /*
     * If no tracking is taking place, just go set the new
     *  tracking state
     */
    if (!(pdesk->dwDTFlags & DF_MOUSEMOVETRK)) {
        goto SetNewState;
    }
    /*
     * Potentially while we leave the critical section below in
     * xxxCancelMouseMoveTracking, spwndTrack could be destroyed and unlocked
     * and then we go and create the tooltip. This would mean that
     * DF_TOOLTIPACTIVE (part of DF_MOUSEMOVETRK test above) would be set,
     * but pdesk->spwndTrack would be NULL and we can AV dereferencing
     * pdesk->spwndTrack below. Prevent this by making the check here.
     */
    if (pdesk->spwndTrack == NULL) {
        goto SetNewState;
    }

    /*
     * Nuke hottracking and deactivate tooltip state, if any.
     * Do it sychronously if we're tracking on the current queue;
     *  Otherwise, post an event and let it happen later.
     */
    ptiTrack = GETPTI(pdesk->spwndTrack);
    if  (PtiCurrent()->pq == ptiTrack->pq) {
        dwDTCancel |= DF_HOTTRACKING;
    } else if (pdesk->dwDTFlags & (DF_HOTTRACKING | DF_TOOLTIPACTIVE)) {
        PostEventMessage(ptiTrack, ptiTrack->pq,
                        QEVENT_CANCELMOUSEMOVETRK,
                        pdesk->spwndTrack,
                        pdesk->dwDTFlags,
                        pdesk->htEx, DF_HOTTRACKING);
       /*
        * Paranoid assertion. If we're switching queues, we must
        *  be switching windows. Did we just go through
        *  ReattachThreads?
        */
        UserAssert(pwnd != pdesk->spwndTrack);
        pdesk->dwDTFlags &= ~(DF_HOTTRACKING | DF_TOOLTIPACTIVE);
    }
    /*
     * If we're on the client area or the user clicked,
     *  nuke the tooltip (if any).
     * Since we might want to re-show the tooltip, we don't nuke it
     *  now if we swichted windows (we'll nuke it later if needed)
     */
    if ((htEx == HTCLIENT) || (message != WM_MOUSEMOVE)) {
        dwDTCancel |= DF_TOOLTIPACTIVE;
    }
    /*
     * If we switched windows or crossed client/nonclinet boundaries,
     *  end track mouse leave/hover.
     */
    if (fNewpwndTrack || ((pdesk->htEx == HTCLIENT) ^ (htEx == HTCLIENT))) {
        dwDTCancel |= DF_TRACKMOUSEEVENT;
    }
    /*
     * Cancel whatever is active and needs to go away
     */
    ThreadLockAlways(pdesk->spwndTrack, &tlpwnd);
    xxxCancelMouseMoveTracking(pdesk->dwDTFlags,
                           pdesk->spwndTrack,
                           pdesk->htEx,
                           dwDTCancel);
    ThreadUnlock(&tlpwnd);
    pdesk->dwDTFlags &= ~dwDTCancel;



SetNewState:
    /*
     * Hottracking/tooltip on mouse move if on NC hitest and enabled
     */
    if ((htEx != HTCLIENT) && (message == WM_MOUSEMOVE) && TestEffectUP(HOTTRACKING)) {
        /*
         * Hottrack the new hit test area
         */
        if (xxxHotTrack(pwnd, htEx, TRUE)) {
            pdesk->dwDTFlags |= DF_HOTTRACKING;
        }

        /*
         * Remove/set the tool tip.
         * We always do this synchronously because it doesn't mess
         *  with pwnd's or spwnTrack's queue
         */
        if ((pstr = IsTooltipHittest(pwnd, LOWORD(htEx))) != NULL) {
            PTOOLTIPWND pttwnd = (PTOOLTIPWND)pdesk->spwndTooltip;
            ThreadLockAlways(pttwnd, &tlpwnd);
            xxxCreateTooltip(pttwnd, pstr);
            ThreadUnlock(&tlpwnd);
            pdesk->dwDTFlags |= DF_TOOLTIP;
        } else  {
            PTOOLTIPWND pttwnd = (PTOOLTIPWND)pdesk->spwndTooltip;
            ThreadLockAlways(pttwnd, &tlpwnd);
            xxxResetTooltip(pttwnd);
            ThreadUnlock(&tlpwnd);
        }
    } /* if (htEx != HTCLIENT) */


    ValidateThreadLocks(NULL, PtiCurrent()->ptl, (ULONG_PTR)&pwnd, TRUE);

    /*
     * Update new track window if needed.
     */
    if (fNewpwndTrack) {
        PWND pwndActivate;

         Lock(&pdesk->spwndTrack, pwnd);
        /*
         * Active window tracking.
         * If there is non-zero timeout, get the window we're supposed to activate
         *  and set the timer. Otherwise, set the queue flag so
         *  xxxActiveWindowTracking can do its thing.
         */
         if ((message == WM_MOUSEMOVE) && TestUP(ACTIVEWINDOWTRACKING)) {
             if (UP(ACTIVEWNDTRKTIMEOUT) != 0) {
                 pwndActivate = GetActiveTrackPwnd(pwnd, NULL);
                 if (pwndActivate != NULL) {
                     InternalSetTimer(pwndActivate, IDSYS_WNDTRACKING,
                                     UP(ACTIVEWNDTRKTIMEOUT),
                                     xxxSystemTimerProc, TMRF_SYSTEM);
                 }
             } else {
                 PtiCurrent()->pq->QF_flags |= QF_ACTIVEWNDTRACKING;
             } /* if (TestUP(ACTIVEWNDTRKZORDER)) */
         } /* if (TestUP(ACTIVEWINDOWTRACKING)) */

    }

    /*
     * Save new hit test code
     */
    pdesk->htEx = htEx;

#if DBG
    --gcReEntered;
#endif
}