static INT PAGER_HitTest (PAGER_INFO* infoPtr, const POINT * pt) { RECT clientRect, rcTopLeft, rcBottomRight; POINT ptWindow; GetClientRect (infoPtr->hwndSelf, &clientRect); if (PtInRect(&clientRect, *pt)) { TRACE("child\n"); return -1; } ptWindow = *pt; PAGER_GetButtonRects(infoPtr, &rcTopLeft, &rcBottomRight, TRUE); if ((infoPtr->TLbtnState != PGF_INVISIBLE) && PtInRect(&rcTopLeft, ptWindow)) { TRACE("PGB_TOPORLEFT\n"); return PGB_TOPORLEFT; } else if ((infoPtr->BRbtnState != PGF_INVISIBLE) && PtInRect(&rcBottomRight, ptWindow)) { TRACE("PGB_BOTTOMORRIGHT\n"); return PGB_BOTTOMORRIGHT; } TRACE("nowhere\n"); return -1; }
static void PAGER_UpdateBtns(PAGER_INFO *infoPtr, INT scrollRange, BOOL hideGrayBtns) { BOOL resizeClient; BOOL repaintBtns; INT oldTLbtnState = infoPtr->TLbtnState; INT oldBRbtnState = infoPtr->BRbtnState; POINT pt; RECT rcTopLeft, rcBottomRight; /* get button rects */ PAGER_GetButtonRects(infoPtr, &rcTopLeft, &rcBottomRight, TRUE); GetCursorPos(&pt); ScreenToClient( infoPtr->hwndSelf, &pt ); /* update states based on scroll position */ if (infoPtr->nPos > 0) { if (infoPtr->TLbtnState == PGF_INVISIBLE || infoPtr->TLbtnState == PGF_GRAYED) infoPtr->TLbtnState = PGF_NORMAL; } else if (!hideGrayBtns && PtInRect(&rcTopLeft, pt)) infoPtr->TLbtnState = PGF_GRAYED; else infoPtr->TLbtnState = PGF_INVISIBLE; if (scrollRange <= 0) { infoPtr->TLbtnState = PGF_INVISIBLE; infoPtr->BRbtnState = PGF_INVISIBLE; } else if (infoPtr->nPos < scrollRange) { if (infoPtr->BRbtnState == PGF_INVISIBLE || infoPtr->BRbtnState == PGF_GRAYED) infoPtr->BRbtnState = PGF_NORMAL; } else if (!hideGrayBtns && PtInRect(&rcBottomRight, pt)) infoPtr->BRbtnState = PGF_GRAYED; else infoPtr->BRbtnState = PGF_INVISIBLE; /* only need to resize when entering or leaving PGF_INVISIBLE state */ resizeClient = ((oldTLbtnState == PGF_INVISIBLE) != (infoPtr->TLbtnState == PGF_INVISIBLE)) || ((oldBRbtnState == PGF_INVISIBLE) != (infoPtr->BRbtnState == PGF_INVISIBLE)); /* initiate NCCalcSize to resize client wnd if necessary */ if (resizeClient) SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); /* repaint when changing any state */ repaintBtns = (oldTLbtnState != infoPtr->TLbtnState) || (oldBRbtnState != infoPtr->BRbtnState); if (repaintBtns) SendMessageW(infoPtr->hwndSelf, WM_NCPAINT, 0, 0); }
static LRESULT PAGER_NCPaint (PAGER_INFO* infoPtr, HRGN hRgn) { RECT rcBottomRight, rcTopLeft; HDC hdc; if (infoPtr->dwStyle & WS_MINIMIZE) return 0; DefWindowProcW (infoPtr->hwndSelf, WM_NCPAINT, (WPARAM)hRgn, 0); if (!(hdc = GetDCEx (infoPtr->hwndSelf, 0, DCX_USESTYLE | DCX_WINDOW))) return 0; PAGER_GetButtonRects(infoPtr, &rcTopLeft, &rcBottomRight, FALSE); PAGER_DrawButton(hdc, infoPtr->clrBk, rcTopLeft, infoPtr->dwStyle & PGS_HORZ, TRUE, infoPtr->TLbtnState); PAGER_DrawButton(hdc, infoPtr->clrBk, rcBottomRight, infoPtr->dwStyle & PGS_HORZ, FALSE, infoPtr->BRbtnState); ReleaseDC( infoPtr->hwndSelf, hdc ); return 0; }
static LRESULT PAGER_MouseMove (PAGER_INFO* infoPtr, INT keys, INT x, INT y) { POINT clpt, pt; RECT wnrect, *btnrect = NULL; BOOL topLeft = FALSE; INT btnstate = 0; INT hit; HDC hdc; pt.x = x; pt.y = y; TRACE("[%p] to (%d,%d)\n", infoPtr->hwndSelf, x, y); ClientToScreen(infoPtr->hwndSelf, &pt); GetWindowRect(infoPtr->hwndSelf, &wnrect); if (PtInRect(&wnrect, pt)) { RECT TLbtnrect, BRbtnrect; PAGER_GetButtonRects(infoPtr, &TLbtnrect, &BRbtnrect, FALSE); clpt = pt; MapWindowPoints(0, infoPtr->hwndSelf, &clpt, 1); hit = PAGER_HitTest(infoPtr, &clpt); if ((hit == PGB_TOPORLEFT) && (infoPtr->TLbtnState == PGF_NORMAL)) { topLeft = TRUE; btnrect = &TLbtnrect; infoPtr->TLbtnState = PGF_HOT; btnstate = infoPtr->TLbtnState; } else if ((hit == PGB_BOTTOMORRIGHT) && (infoPtr->BRbtnState == PGF_NORMAL)) { topLeft = FALSE; btnrect = &BRbtnrect; infoPtr->BRbtnState = PGF_HOT; btnstate = infoPtr->BRbtnState; } /* If in one of the buttons the capture and draw buttons */ if (btnrect) { TRACE("[%p] draw btn (%ld,%ld)-(%ld,%ld), Capture %s, style %08lx\n", infoPtr->hwndSelf, btnrect->left, btnrect->top, btnrect->right, btnrect->bottom, (infoPtr->bCapture) ? "TRUE" : "FALSE", infoPtr->dwStyle); if (!infoPtr->bCapture) { TRACE("[%p] SetCapture\n", infoPtr->hwndSelf); SetCapture(infoPtr->hwndSelf); infoPtr->bCapture = TRUE; } if (infoPtr->dwStyle & PGS_AUTOSCROLL) SetTimer(infoPtr->hwndSelf, TIMERID1, 0x3e, 0); hdc = GetWindowDC(infoPtr->hwndSelf); /* OffsetRect(wnrect, 0 | 1, 0 | 1) */ PAGER_DrawButton(hdc, infoPtr->clrBk, *btnrect, infoPtr->dwStyle & PGS_HORZ, topLeft, btnstate); ReleaseDC(infoPtr->hwndSelf, hdc); return 0; } } /* If we think we are captured, then do release */ if (infoPtr->bCapture && (WindowFromPoint(pt) != infoPtr->hwndSelf)) { NMHDR nmhdr; infoPtr->bCapture = FALSE; if (GetCapture() == infoPtr->hwndSelf) { ReleaseCapture(); if (infoPtr->TLbtnState == PGF_GRAYED) { infoPtr->TLbtnState = PGF_INVISIBLE; SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); } else if (infoPtr->TLbtnState == PGF_HOT) { infoPtr->TLbtnState = PGF_NORMAL; /* FIXME: just invalidate button rect */ RedrawWindow(infoPtr->hwndSelf, NULL, NULL, RDW_FRAME | RDW_INVALIDATE); } if (infoPtr->BRbtnState == PGF_GRAYED) { infoPtr->BRbtnState = PGF_INVISIBLE; SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); } else if (infoPtr->BRbtnState == PGF_HOT) { infoPtr->BRbtnState = PGF_NORMAL; /* FIXME: just invalidate button rect */ RedrawWindow(infoPtr->hwndSelf, NULL, NULL, RDW_FRAME | RDW_INVALIDATE); } /* Notify parent of released mouse capture */ memset(&nmhdr, 0, sizeof(NMHDR)); nmhdr.hwndFrom = infoPtr->hwndSelf; nmhdr.idFrom = GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_ID); nmhdr.code = NM_RELEASEDCAPTURE; SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr); } if (IsWindow(infoPtr->hwndSelf)) KillTimer(infoPtr->hwndSelf, TIMERID1); } return 0; }