Esempio n. 1
0
/*****************************************************************************\
* GetAncestor()
*
* This gets one of:
*     * The _real_ parent.  This does NOT include the owner, unlike
*         GetParent().  Stops at a top level window unless we start with
*         the desktop.  In which case, we return the desktop.
*     * The _real_ root, caused by walking up the chain getting the
*         ancestor.
*     * The _real_ owned root, caused by GetParent()ing up.
\*****************************************************************************/
PWND WINAPI
_GetAncestor(PWND pwnd, UINT gaFlags)
{
    PWND pwndParent;

    /*
     * If we start with the desktop return NULL.
     */
    if (pwnd == PWNDDESKTOP(pwnd))
        return NULL;

    switch (gaFlags) {
    case GA_PARENT:
        pwnd = pwnd->spwndParent;
        break;

    case GA_ROOT:
        while ((pwnd->spwndParent != PWNDDESKTOP(pwnd)) &&
               (pwnd->spwndParent != PWNDMESSAGE(pwnd))) {
            pwnd = pwnd->spwndParent;
        }
        break;

    case GA_ROOTOWNER:
        while (pwndParent = _GetParent(pwnd)) {
            pwnd = pwndParent;
        }
        break;
    }

    return pwnd;
}
Esempio n. 2
0
/*****************************************************************************\
*
* RealChildWindowFromPoint()
*
* This returns the REAL child window at a point.  The problem is that
* ChildWindowFromPoint() doesn't deal with HTTRANSPARENT areas of
* standard controls.  We want to return a child behind a groupbox if it
* is in the "clear" area.  But we want to return a static field always
* even though it too returns HTTRANSPARENT.
*
\*****************************************************************************/
PWND WINAPI
_RealChildWindowFromPoint(PWND pwndParent, POINT pt)
{
    PWND    pwndChild;
    PWND    pwndSave;

    if (pwndParent != PWNDDESKTOP(pwndParent)) {
        pt.x += pwndParent->rcClient.left;
        pt.y += pwndParent->rcClient.top;
    }

    /*
     * Is this point even in the parent?
     */
    if (!PtInRect(&pwndParent->rcClient, pt)  ||
        (pwndParent->hrgnClip && !GrePtInRegion(pwndParent->hrgnClip, pt.x, pt.y))) {
        // Nope
        return NULL;
    }

    pwndSave = NULL;

    /*
     * Loop through the children.
     */
    for (pwndChild = pwndParent->spwndChild; pwndChild; pwndChild = pwndChild->spwndNext) {
        if (!TestWF(pwndChild, WFVISIBLE))
            continue;

        /*
         * Is this point in the child's window?
         */
        if (!PtInRect(&pwndChild->rcWindow, pt) ||
                (pwndChild->hrgnClip && !GrePtInRegion(pwndChild->hrgnClip, pt.x, pt.y)))
            continue;

        /*
         * OK, we are in somebody's window.  Is this by chance a group box?
         */
        if ((pwndChild->pcls->atomClassName == gpsi->atomSysClass[ICLS_BUTTON]) ||
                (GETFNID(pwndChild) == FNID_BUTTON)) {
            if (TestWF(pwndChild, BFTYPEMASK) == LOBYTE(BS_GROUPBOX)) {
               pwndSave = pwndChild;
               continue;
            }
        }

        return pwndChild;
    }

    /*
     * Did we save a groupbox which turned out to have nothing behind it
     * at that point?
     */
    if (pwndSave) {
        return pwndSave;
    } else {
        return pwndParent;
    }
}
Esempio n. 3
0
BOOL xxxPaintRect(
    PWND   pwndBrush,
    PWND   pwndPaint,
    HDC    hdc,
    HBRUSH hbr,
    LPRECT lprc)
{
    POINT ptOrg;

    CheckLock(pwndBrush);
    CheckLock(pwndPaint);

    if (pwndBrush == NULL) {
        pwndBrush = PtiCurrent()->rpdesk->pDeskInfo->spwnd;
    }

    if (pwndBrush == PWNDDESKTOP(pwndBrush)) {
        GreSetBrushOrg(
                hdc,
                0,
                0,
                &ptOrg);
    } else {
        GreSetBrushOrg(
                hdc,
                pwndBrush->rcClient.left - pwndPaint->rcClient.left,
                pwndBrush->rcClient.top - pwndPaint->rcClient.top,
                &ptOrg);
    }

    /*
     * If hbr < CTLCOLOR_MAX, it isn't really a brush but is one of our
     * special color values.  Translate it to the appropriate WM_CTLCOLOR
     * message and send it off to get back a real brush.  The translation
     * process assumes the CTLCOLOR*** and WM_CTLCOLOR*** values map directly.
     */
    if (hbr < (HBRUSH)CTLCOLOR_MAX) {
        hbr = xxxGetControlColor(pwndBrush,
                                 pwndPaint,
                                 hdc,
                                 HandleToUlong(hbr) + WM_CTLCOLORMSGBOX);
    }

    FillRect(hdc, lprc, hbr);

    GreSetBrushOrg(hdc, ptOrg.x, ptOrg.y, NULL);


    return TRUE;
}
Esempio n. 4
0
void xxxTooltipHandleTimer(PTOOLTIPWND pttwnd, UINT uTID)
{

    switch(uTID) {
        case TTT_SHOW: {
            /*
             * Move the tooltip window to the desktop so it can
             *  be shown. Then show it.
             */
            PWND pwndDesktop = PWNDDESKTOP(pttwnd);
            TL tlpwnd;
            ThreadLockAlways(pwndDesktop, &tlpwnd);
            xxxSetParent((PWND)pttwnd, pwndDesktop);
            ThreadUnlock(&tlpwnd);

            xxxShowTooltip(pttwnd);
            break;
        }

        case TTT_ANIMATE:
           /*
            * If animation is completed, set timer to hide
            */
           if (TooltipAnimate(pttwnd)) {
               SetTooltipTimer(pttwnd, TTT_HIDE, pttwnd->dwHideDelay);
           }
           break;

        case TTT_HIDE:
           /*
            * Hide it
            */
           xxxResetTooltip(pttwnd);
           break;
    }
}
Esempio n. 5
0
void xxxShowOwnedWindows(
    PWND pwndOwner,
    UINT cmdShow)
{
    BOOL fShow;
    int cmdZoom;
    HWND *phwnd;
    PBWL pbwl;
    PWND pwnd, pwndTopOwner;
    TL tlpwnd;

    CheckLock(pwndOwner);

    /*
     * Not interested in child windows
     */
    if (TestwndChild(pwndOwner))
        return;

    if ((pbwl = BuildHwndList(PWNDDESKTOP(pwndOwner)->spwndChild, BWL_ENUMLIST, NULL)) == NULL)
        return;

    /*
     * NOTE: The following code assumes the values of SW_* are 1, 2, 3, and 4
     */
    fShow = (cmdShow >= SW_PARENTOPENING);

    cmdZoom = 0;
    if (cmdShow == SW_OTHERZOOM)
        cmdZoom = SIZEZOOMHIDE;

    if (cmdShow == SW_OTHERUNZOOM)
        cmdZoom = SIZEZOOMSHOW;

    /*
     * If zoom/unzoom, then open/close all popups owned by all other
     * windows.  Otherwise, open/close popups owned by pwndOwner.
     */
    for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) {

        /*
         * Lock the window before we play with it.
         * If the window handle is invalid, skip it
         */
        if ((pwnd = RevalidateHwnd(*phwnd)) == NULL)
            continue;

        /*
         * Kanji windows can't be owned, so skip it.
         */
        if (TestCF(pwnd, CFKANJIWINDOW))
            continue;

        /*
         * If same as window passed in, skip it.
         */
        if (pwnd == pwndOwner)
            continue;

        /*
         * Find ultimate owner of popup, but only go up as far as pwndOwner.
         */
        if ((pwndTopOwner = pwnd->spwndOwner) != NULL) {

            /*
             * The TestwndHI is needed since if it has an icon, pwndOwner
             * is invalid.
             */
            while (!TestwndHI(pwndTopOwner) && pwndTopOwner != pwndOwner &&
                    pwndTopOwner->spwndOwner != NULL)
                pwndTopOwner = pwndTopOwner->spwndOwner;
        }

        /*
         * Zoom/Unzoom case.
         */
        if (cmdZoom != 0) {

            /*
             * If no parent, or parents are the same, skip.
             */
            if (pwndTopOwner == NULL || pwndTopOwner == pwndOwner)
                continue;

            /*
             * If owner is iconic, then this window should stay hidden,
             * UNLESS the minimized window is disabled, in which case we'd
             * better show the window.
             */
            if (   cmdShow == SW_OTHERUNZOOM
                && pwndTopOwner != NULL
                && TestWF(pwndTopOwner, WFMINIMIZED)
                && !TestWF(pwndTopOwner, WFDISABLED)
               )
                continue;
        } else {
            /*
             * Hide/Iconize/Show/Open case.
             */
            /*
             * If parents aren't the same, skip.
             */
            if (pwndTopOwner != pwndOwner)
                continue;
        }

        /*
         * Hide or show if:
         * Showing & this is a hidden popup
         *   OR
         * Hiding & this is a visible window
         */
        if ((fShow && TestWF(pwnd, WFHIDDENPOPUP)) ||
                (!fShow && TestWF(pwnd, WFVISIBLE))) {
            ThreadLockAlways(pwnd, &tlpwnd);
            xxxSendMessage(pwnd, WM_SHOWWINDOW, fShow, (LONG)cmdShow);
            ThreadUnlock(&tlpwnd);
        }
    }

    /*
     * Free the window list.
     */
    FreeHwndList(pbwl);
}
Esempio n. 6
0
VOID DoQueuedSyncPaint(
    PWND        pwnd,
    DWORD       flags,
    PTHREADINFO pti)
{
    PTHREADINFO ptiPwnd = GETPTI(pwnd);

    if ((ptiPwnd != pti)          &&
        TestWF(pwnd, WFSENDNCPAINT)    &&
        TestWF(pwnd, WFSENDERASEBKGND) &&
        TestWF(pwnd, WFVISIBLE)) {

        PSMS psms = ptiPwnd->psmsReceiveList;

        /*
         * If this window already has a WM_SYNCPAINT queue'd up, then there's
         * no need to send another one.  Also protects our heap from getting
         * chewed up.
         */
        while (psms != NULL) {

            if ((psms->message == WM_SYNCPAINT) && (psms->spwnd == pwnd)) {
                break;
            }

            psms = psms->psmsReceiveNext;
        }

        if (psms == NULL) {
            /*
             * This will give this message the semantics of a notify
             * message (sendmessage no wait), without calling back
             * the WH_CALLWNDPROC hook. We don't want to do that
             * because that'll let all these processes with invalid
             * windows to process paint messages before they process
             * "synchronous" erasing or framing needs.
             *
             * Hi word of wParam must be zero or wow will drop it
             *
             * LATER mikeke
             * Do we need to send down the flags with DWP_ERASE and DSP_FRAME
             * in it?
             */
            UserAssert(HIWORD(flags) == 0);
            QueueNotifyMessage(pwnd, WM_SYNCPAINT, flags, 0);

            /*
             * Set our syncpaint-pending flag, since we queued one up.  This
             * will be used to check when we validate-parents for windows
             * without clipchildren.
             */
            SetWF(pwnd, WFSYNCPAINTPENDING);
        }

        /*
         * If we posted a WM_SYNCPAINT for a top-level window that is not
         * of the current thread we're done; we'll pick up the children
         * when we process the message for real.  If we're the desktop
         * however make sure we get all it children.
         */
        if (pwnd != PWNDDESKTOP(pwnd))
            return;
    }

    /*
     * Normally we like to enumerate all of this window's children and have
     * them erase their backgrounds synchronously.  However, this is a bad
     * thing to do if the window is NOT CLIPCHLIDREN.  Here's the scenario
     * we want to to avoid:
     *
     * 1.  Window 'A' is invalidated
     * 2.  'A' erases itself (or not, doesn't matter)
     * 3.  'A's children are enumerated and they erase themselves.
     * 4.  'A' paints over its children (remember, 'A' isn't CLIPCHILDREN)
     * 5.  'A's children paint but their backgrounds aren't their ERASEBKND
     *    color (because 'A' painted over them) and everything looks like
     *    dirt.
     */
    if ((flags & DSP_ALLCHILDREN) ||
        ((flags & DSP_ENUMCLIPPEDCHILDREN) && TestWF(pwnd, WFCLIPCHILDREN))) {

        PWND pwndT;

        for (pwndT = pwnd->spwndChild; pwndT; pwndT = pwndT->spwndNext) {

            /*
             * Don't cause any more intertask sendmessages cause it does
             * bad things to cbt's windowproc hooks.  (Due to SetParent
             * allowing child windows in the topwindow hierarchy.
             * The child bit also catches the desktop window; we want to
             */
            if (TestWF(pwndT, WFCHILD) && (pti != GETPTI(pwndT)))
                continue;

            /*
             * Note that we pass only certain bits down as we recurse:
             * the other bits pertain to the current window only.
             */
            DoQueuedSyncPaint(pwndT, flags, pti);
        }
    }
}
Esempio n. 7
0
BOOL xxxSnapWindow(
    PWND pwnd)
{
    PTHREADINFO    ptiCurrent;
    RECT           rc;
    HDC            hdcScr = NULL;
    HDC            hdcMem = NULL;
    BOOL           fRet;
    HBITMAP        hbmOld;
    HBITMAP        hbm;
    HANDLE         hPal;
    LPLOGPALETTE   lppal;
    int            palsize;
    int            iFixedPaletteEntries;
    BOOL           fSuccess;
    PWND           pwndT;
    TL             tlpwndT;
    PWINDOWSTATION pwinsta;
    TL             tlpwinsta;

    CheckLock(pwnd);
    UserAssert(pwnd);

    ptiCurrent = PtiCurrent();

    /*
     * If this is a thread of winlogon, don't do the snapshot.
     */
    if (GetCurrentProcessId() == gpidLogon)
        return FALSE;

    /*
     * Get the affected windowstation
     */
    if (!NT_SUCCESS(ReferenceWindowStation(
            PsGetCurrentThread(),
            NULL,
            WINSTA_READSCREEN,
            &pwinsta,
            TRUE)) ||
            pwinsta->dwWSF_Flags & WSF_NOIO) {
        return FALSE;
    }

    /*
     * If the window is on another windowstation, do nothing
     */
    if (pwnd->head.rpdesk->rpwinstaParent != pwinsta)
        return FALSE;

    /*
     * Get the parent of any child windows.
     */
    while ((pwnd != NULL) && TestWF(pwnd, WFCHILD)) {
        pwnd = pwnd->spwndParent;
    }

    /*
     * Lock the windowstation before we leave the critical section
     */
    ThreadLockWinSta(ptiCurrent, pwinsta, &tlpwinsta);

    /*
     * Open the clipboard and empty it.
     *
     * pwndDesktop is made the owner of the clipboard, instead of the
     * currently active window; -- SANKAR -- 20th July, 1989 --
     */
    pwndT = ptiCurrent->rpdesk->pDeskInfo->spwnd;
    ThreadLockWithPti(ptiCurrent, pwndT, &tlpwndT);
    fSuccess = xxxOpenClipboard(pwndT, NULL);
    ThreadUnlock(&tlpwndT);

    if (!fSuccess) {
        ThreadUnlockWinSta(ptiCurrent, &tlpwinsta);
        return FALSE;
    }

    xxxEmptyClipboard(pwinsta);

    /*
     * Use the whole window.
     */
    CopyRect(&rc, &pwnd->rcWindow);

    /*
     * Only snap what is on the screen.
     */
    if (!IntersectRect(&rc, &rc, &gpDispInfo->rcScreen)) {
        fRet = FALSE;
        goto SnapExit;
    }

    rc.right -= rc.left;
    rc.bottom -= rc.top;

    /*
     * Figure out how far offset from window origin visible part is
     */
    if (pwnd != PWNDDESKTOP(pwnd)) {
        rc.left -= pwnd->rcWindow.left;
        rc.top -= pwnd->rcWindow.top;
    }

    /*
     * Get the entire window's DC.
     */
    hdcScr = _GetWindowDC(pwnd);
    if (!hdcScr)
        goto MemoryError;

    /*
     * Create the memory DC.
     */
    hdcMem = GreCreateCompatibleDC(hdcScr);
    if (!hdcMem)
        goto MemoryError;

    /*
     * Create the destination bitmap.  If it fails, then attempt
     * to create a monochrome bitmap.
     * Did we have enough memory?
     */

    if (SYSMET(SAMEDISPLAYFORMAT)) {
        hbm = GreCreateCompatibleBitmap(hdcScr, rc.right, rc.bottom);
    } else {
        hbm = GreCreateBitmap(rc.right, rc.bottom, 1, gpDispInfo->BitCountMax, NULL);
    }

    if (!hbm) {
        hbm = GreCreateBitmap(rc.right, rc.bottom, 1, 1, NULL);
        if (!hbm)
            goto MemoryError;
    }

    /*
     * Select the bitmap into the memory DC.
     */
    hbmOld = GreSelectBitmap(hdcMem, hbm);

    /*
     * Snap!!!
     * Check the return value because the process taking the snapshot
     * may not have access to read the screen.
     */
    fRet = GreBitBlt(hdcMem, 0, 0, rc.right, rc.bottom, hdcScr, rc.left, rc.top, SRCCOPY | CAPTUREBLT, 0);

    /*
     * Restore the old bitmap into the memory DC.
     */
    GreSelectBitmap(hdcMem, hbmOld);

    /*
     * If the blt failed, leave now.
     */
    if (!fRet)
        goto SnapExit;

    _SetClipboardData(CF_BITMAP, hbm, FALSE, TRUE);

    /*
     * If this is a palette device, let's throw the current system palette
     * into the clipboard also.  Useful if the user just snapped a window
     * containing palette colors...
     */
    if (TEST_PUSIF(PUSIF_PALETTEDISPLAY)) {

        int i;
        int iPalSize;

        palsize = GreGetDeviceCaps(hdcScr, SIZEPALETTE);

        /*
         * Determine the number of system colors.
         */
        if (GreGetSystemPaletteUse(hdcScr) == SYSPAL_STATIC)
            iFixedPaletteEntries = GreGetDeviceCaps(hdcScr, NUMRESERVED);
        else
            iFixedPaletteEntries = 2;

        lppal = (LPLOGPALETTE)UserAllocPoolWithQuota(
                (LONG)(sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * palsize),
                TAG_CLIPBOARD);

        if (lppal != NULL) {
            lppal->palVersion = 0x300;
            lppal->palNumEntries = (WORD)palsize;

            if (GreGetSystemPaletteEntries(hdcScr,
                                           0,
                                           palsize,
                                           lppal->palPalEntry)) {

                iPalSize = palsize - iFixedPaletteEntries / 2;

                for (i = iFixedPaletteEntries / 2; i < iPalSize; i++) {

                    /*
                     * Any non system palette enteries need to have the NOCOLLAPSE
                     * flag set otherwise bitmaps containing different palette
                     * indices but same colors get messed up.
                     */
                    lppal->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
                }

                if (hPal = GreCreatePalette(lppal))
                    _SetClipboardData(CF_PALETTE, hPal, FALSE, TRUE);
            }

            UserFreePool(lppal);
        }
    }
    PlayEventSound(USER_SOUND_SNAPSHOT);

    fRet = TRUE;

SnapExit:

    /*
     * Release the window/client DC.
     */
     if (hdcScr) {
         _ReleaseDC(hdcScr);
     }

    xxxCloseClipboard(pwinsta);
    Unlock(&pwinsta->spwndClipOwner);

    /*
     * Delete the memory DC.
     */
    if (hdcMem) {
        GreDeleteDC(hdcMem);
    }

    ThreadUnlockWinSta(ptiCurrent, &tlpwinsta);

    return fRet;

MemoryError:
    /*
     * Display an error message box.
     */
    ClientNoMemoryPopup();
    fRet = FALSE;
    goto SnapExit;
}