void CXTPSkinObjectFrame::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
    if (m_pButtonHot)
    {
        TrackCaptionButton();
    }

    CPoint ptClient(point);
    ScreenToFrame(&ptClient);

    for (int i = 0; i < 2; i++)
    {
        XTP_SKINSCROLLBARPOSINFO* pSBInfo = &m_spi[i];
        int ht = HitTestScrollBar(pSBInfo, ptClient);

        if (ht != HTNOWHERE)
        {
            TrackInit(ptClient, pSBInfo, (GetKeyState(VK_SHIFT) < 0) ? TRUE : FALSE);
            return;
        }
    }

    if (nHitTest == HTZOOM || nHitTest == HTREDUCE || nHitTest == HTCLOSE || nHitTest == HTHELP)
        return;

    CXTPSkinObject::OnNcLButtonDown(nHitTest, point);
}
LRESULT CXTPSkinObjectFrame::HandleNcHitTest(CPoint point)
{
    ScreenToFrame(&point);

    DWORD dwStyle = GetStyle();

    if ((dwStyle & WS_VSCROLL) && m_spi[SB_VERT].fVisible && ::PtInRect(&m_spi[SB_VERT].rc, point))
        return (LRESULT)HTVSCROLL;

    if ((dwStyle & WS_HSCROLL) &&m_spi[SB_HORZ].fVisible && ::PtInRect(&m_spi[SB_HORZ].rc, point))
        return (LRESULT)HTHSCROLL;

    if ((dwStyle & WS_VSCROLL) && m_spi[SB_VERT].fVisible && (dwStyle & WS_HSCROLL) && m_spi[SB_HORZ].fVisible && IsSizeBox())
    {
        CRect rcSizeGripper(m_spi[SB_HORZ].rc.right, m_spi[SB_VERT].rc.bottom,
                            m_spi[SB_VERT].rc.right, m_spi[SB_HORZ].rc.bottom);

        if (rcSizeGripper.PtInRect(point))
            return GetExStyle() & WS_EX_LAYOUTRTL ? HTBOTTOMLEFT : HTBOTTOMRIGHT;
    }

    CCaptionButton* pButtonHot = HitTestButton(point);

    if (pButtonHot)
    {
        return pButtonHot->m_nHTCode;
    }

    return (LRESULT)HTNOWHERE;
}
void CXTPSkinObjectFrame::OnNcRButtonUp(UINT nHitTest, CPoint point)
{
    CPoint ptClient(point);
    ScreenToFrame(&ptClient);

    for (int i = 0; i < 2; i++)
    {
        XTP_SKINSCROLLBARPOSINFO* pSBInfo = &m_spi[i];
        int ht = HitTestScrollBar(pSBInfo, ptClient);

        if (ht != HTNOWHERE)
        {
            m_bLockFrameDraw++;
            RECT rc = CXTPWindowRect(this);
            SendMessage(WM_NCCALCSIZE, FALSE, (LPARAM)&rc);
            m_bLockFrameDraw--;

            SendMessage(WM_CONTEXTMENU, (WPARAM)m_hWnd, MAKELPARAM(point.x, point.y));

            RefreshFrameStyle();
            return;
        }
    }

    CXTPSkinObject::OnNcRButtonDown(nHitTest, point);
}
void CXTPSkinObjectFrame::TrackCaptionButton()
{
    SetCapture();
    BOOL bAccept = FALSE;
    m_pButtonPressed = m_pButtonHot;
    CCaptionButton* pButtonPressed = m_pButtonHot;
    ASSERT(pButtonPressed);

    RedrawFrame();

    while (::GetCapture() == m_hWnd)
    {
        MSG msg;

        if (!::GetMessage(&msg, NULL, 0, 0))
        {
            AfxPostQuitMessage((int)msg.wParam);
            break;
        }

        if (msg.message == WM_LBUTTONUP)
        {
            bAccept = m_pButtonPressed == pButtonPressed;
            break;
        }
        else if (msg.message == WM_NCMOUSELEAVE)
        {

        }
        else if (msg.message == WM_MOUSEMOVE)
        {
            POINT point = msg.pt;
            ScreenToFrame(&point);

            CCaptionButton* pButton = HitTestButton(point) == pButtonPressed ? pButtonPressed : NULL;

            if (pButton != m_pButtonPressed)
            {
                m_pButtonPressed = pButton;
                RedrawFrame();
            }
        }
        else
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    m_pButtonPressed = NULL;
    m_pButtonHot = NULL;
    ReleaseCapture();
    RedrawFrame();

    if (bAccept)
    {
        SendMessage(WM_SYSCOMMAND, pButtonPressed->m_nCommand);
    }
}
BOOL CXTPSkinObjectFrame::HandleMouseMove(CPoint point)
{
    CPoint ptClient(point);
    ScreenToFrame(&ptClient);

    CCaptionButton* pButton = HitTestButton(ptClient);

    if (m_pButtonHot != pButton)
    {
        if (m_pButtonHot && !pButton)
            CancelMouseLeaveTracking();

        m_pButtonHot = pButton;
        InvalidateButtons();

        if (m_pButtonHot)
        {
            SetTimer(XTP_TID_MOUSELEAVE, 50, &OnTimerInternal);
            return  TRUE;
        }
    }

    if (m_pSBTrack)
        return TRUE;

    BOOL bResult = FALSE;
    for (int i = 0; i < 2; i++)
    {
        XTP_SKINSCROLLBARPOSINFO* pSBInfo = &m_spi[i];
        int ht = HitTestScrollBar(pSBInfo, ptClient);

        if (ht != pSBInfo->ht && pSBInfo->fVisible)
        {
            if (pSBInfo->ht != HTNOWHERE && ht == HTNOWHERE && !bResult)
            {
                CancelMouseLeaveTracking();
            }

            pSBInfo->ht = ht;
            RedrawScrollBar(pSBInfo);
        }

        if (ht != HTNOWHERE)
        {
            SetTimer (XTP_TID_MOUSELEAVE, 50, &OnTimerInternal);
            bResult = TRUE;
        }
    }

    return bResult;
}
void
TracksCoordinator::NotifyMouseMoved(BPoint point, uint32 data,
	const BMessage* message, Render* who)
{
	if (fPrimaryButton) {
		if (!who->IsSelected())
			_AddToSelection(who);

		int64 frame = fStart+ScreenToFrame(point.x);
		if (frame < fPointer)
			_UpdateSelection(frame, fPointer);
		else
			_UpdateSelection(fPointer, frame);

		InvalidateSelection();
	}
}
void
TracksCoordinator::NotifyMouseDown(BPoint point, BMessage* message,
	Render* who)
{
	uint32 button = 0;
	uint32 click = 0;

	message->FindInt32("buttons", (int32*)&button);
	message->FindInt32("clicks", (int32*)&click);

	if (button == B_PRIMARY_MOUSE_BUTTON) {
		fPointer = fStart+ScreenToFrame(point.x);
		if (SelectionActive())
			_CleanupSelection();
		else
			fPrimaryButton = true;

		who->MakeFocus();
		if (fCurrentRender != NULL)
			fCurrentRender->Invalidate();
		who->Invalidate();
		fCurrentRender = who;
	}
}
void CXTPSkinObjectFrame::ClientToFrame(LPPOINT lpPoint)
{
    ClientToScreen(lpPoint);
    ScreenToFrame(lpPoint);
}