⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clv_listview.c

📁 VC++视频开发实例集锦(包括“远程视频监控”"语音识别系统"等13个经典例子)
💻 C
📖 第 1 页 / 共 5 页
字号:

            // Update only if the origin has changed
            if(iNewFirstVisibleItem != pListData->m_iFirstVisibleItem)
            {
                pListData->m_iFirstVisibleItem = iNewFirstVisibleItem;
                CLV_UpdateScrollBars(pListData);
                CLV_InvalidateWindow(pListData);
            }
        }
    }
    else if(pListData->m_enWindowMode == wmVScrollbar_Scroll_Up)
    {
        // We will draw the button up if the mouse isn't over it
        BOOL bNewButtonState;
        if(PtInRect(&pListData->m_rScrollbar_Vert, ptCursor) == TRUE
                && ptCursor.y < (pListData->m_rScrollbar_Vert.top + glb_pSkin->mpl_pVScrollBar_Up->m_iStateHeight) )
        {
            bNewButtonState = TRUE;
        }
        else
            bNewButtonState = FALSE;

        // State changed?
        if(bNewButtonState != pListData->m_bMouseOverScrollbutton)
        {
            pListData->m_bMouseOverScrollbutton = bNewButtonState;
            InvalidateRect(pListData->m_hWnd, &pListData->m_rScrollbar_Vert, FALSE);
        }
    }
    else if(pListData->m_enWindowMode == wmVScrollbar_Scroll_Down)
    {
        // We draw the button up if the mouse isn't over it
        BOOL bNewButtonState;
        if(PtInRect(&pListData->m_rScrollbar_Vert, ptCursor) == TRUE
                && ptCursor.y > (pListData->m_rScrollbar_Vert.bottom - glb_pSkin->mpl_pVScrollBar_Down->m_iStateHeight) )
        {
            bNewButtonState = TRUE;
        }
        else
            bNewButtonState = FALSE;

        // State changed?
        if(bNewButtonState != pListData->m_bMouseOverScrollbutton)
        {
            pListData->m_bMouseOverScrollbutton = bNewButtonState;
            InvalidateRect(pListData->m_hWnd, &pListData->m_rScrollbar_Vert, FALSE);
        }
    }
    else if(pListData->m_enWindowMode == wmList_Click)
    {
        // If the mouse has moved beyond our drag threshold then enter into header_orderchange mode
        if(	pListData->m_iFocusItem != CPC_INVALIDITEM
                && ((abs(ptCursor.x - pListData->m_ptMouseDown.x) > CPC_LISTDRAGDISTANCE
                     || abs(ptCursor.y - pListData->m_ptMouseDown.y) > CPC_LISTDRAGDISTANCE) )
                && (pListData->m_pItems[pListData->m_iFocusItem].m_dwFlags & CPLV_ITEMFLAG_SELECTED))

        {
            pListData->m_enWindowMode = wmList_Drag;
            if(pListData->m_hndlr_ItemDrag && pListData->m_iFocusItem != CPC_INVALIDITEM)
                pListData->m_hndlr_ItemDrag(pListData, pListData->m_iFocusItem, pListData->m_pItems[pListData->m_iFocusItem].m_pItemData);
        }
    }
    else
        SetCursor(LoadCursor(NULL, IDC_ARROW));
}
//
//
//
void CLV_StartAutoRepeat(CIs_ListViewData* pListData)
{
    DWORD dwRepeatDelay;
    SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &dwRepeatDelay, 0L);
    dwRepeatDelay = 250 + (dwRepeatDelay*250);
    pListData->m_bAutoRepeatFirst = TRUE;
    pListData->m_uiAutorepeatTimer = SetTimer(pListData->m_hWnd, CPC_TIMERID_AUTOREPEAT, dwRepeatDelay, NULL);
}
//
//
//
void CLV_Handle_WM_TIMER_AUTOREPEAT(CIs_ListViewData* pListData)
{
    POINT ptCursor;
    GetCursorPos(&ptCursor);
    ScreenToClient(pListData->m_hWnd, &ptCursor);

    // Are we autorepeating in the horizontal scrollbar?
    if(PtInRect(&pListData->m_rScrollbar_Horiz, ptCursor) == TRUE)
    {
        // In left button
        if(ptCursor.x < (pListData->m_rScrollbar_Horiz.left + glb_pSkin->mpl_pHScrollBar_Left->m_pImage->m_szSize.cx)
                && pListData->m_enWindowMode == wmHScrollbar_Scroll_Left)
        {
            CLV_Scroll_Horiz(pListData, -CPC_SCROLLBAR_HORIZ_LINESIZE);
        }
        // In right button
        else if(ptCursor.x > (pListData->m_rScrollbar_Horiz.right - glb_pSkin->mpl_pHScrollBar_Right->m_pImage->m_szSize.cx)
                && pListData->m_enWindowMode == wmHScrollbar_Scroll_Right)
        {
            CLV_Scroll_Horiz(pListData, CPC_SCROLLBAR_HORIZ_LINESIZE);
        }
        // In left page area
        else if(ptCursor.x < pListData->m_rScrollbar_Horiz_Thumb.left
                && pListData->m_enWindowMode == wmHScrollbar_Page_Left)
        {
            CLV_Scroll_Horiz(pListData, -CPC_SCROLLBAR_HORIZ_PAGESIZE);
        }
        // In right page area
        else if(ptCursor.x > pListData->m_rScrollbar_Horiz_Thumb.right
                && pListData->m_enWindowMode == wmHScrollbar_Page_Right)
        {
            CLV_Scroll_Horiz(pListData, CPC_SCROLLBAR_HORIZ_PAGESIZE);
        }
    }
    // Are we autorepeating in the vertical scrollbar?
    else if(PtInRect(&pListData->m_rScrollbar_Vert, ptCursor) == TRUE)
    {
        if(ptCursor.y < (pListData->m_rScrollbar_Vert.top + glb_pSkin->mpl_pVScrollBar_Up->m_iStateHeight)
                && pListData->m_enWindowMode == wmVScrollbar_Scroll_Up)
        {
            CLV_Scroll_Vert(pListData, -1);
        }
        // In down button
        else if(ptCursor.y > (pListData->m_rScrollbar_Vert.bottom - glb_pSkin->mpl_pVScrollBar_Down->m_iStateHeight)
                && pListData->m_enWindowMode == wmVScrollbar_Scroll_Down)
        {
            CLV_Scroll_Vert(pListData, 1);
        }
        // In top page area
        else if(ptCursor.y < pListData->m_rScrollbar_Vert_Thumb.top
                && pListData->m_enWindowMode == wmVScrollbar_Page_Up)
        {
            CLV_Scroll_Vert(pListData, -pListData->m_iNumItemsOnPage);
        }
        // In bottom page area
        else if(ptCursor.y > pListData->m_rScrollbar_Vert_Thumb.bottom
                && pListData->m_enWindowMode == wmVScrollbar_Page_Down)
        {
            CLV_Scroll_Vert(pListData, pListData->m_iNumItemsOnPage);
        }
    }

    // Do we need to update the timer (after the first autorepeat delay)
    if(pListData->m_bAutoRepeatFirst)
    {
        int iRepeatDelay;

        // Make the autorepeat the same as the keyboard autorepeat
        pListData->m_bAutoRepeatFirst = FALSE;
        SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &iRepeatDelay, 0L);
        iRepeatDelay = 400 - (iRepeatDelay*12);
        if(iRepeatDelay < 0)
            iRepeatDelay = 10;
        pListData->m_uiAutorepeatTimer = SetTimer(pListData->m_hWnd, CPC_TIMERID_AUTOREPEAT, iRepeatDelay, NULL);
    }
}
//
//
//
void CLV_InvalidateItem(CP_HLISTVIEW _hListData, const int iItemIDX)
{
    CIs_ListViewData* pListData;
    RECT rItemRect;

    pListData = (CIs_ListViewData*)_hListData;
    CP_CHECKOBJECT(pListData);

    if(iItemIDX == CPC_INVALIDITEM)
        return;
    CP_ASSERT(iItemIDX >= 0);
    CP_ASSERT(iItemIDX < pListData->m_iNumItems);

    rItemRect.left = pListData->m_rList.left;
    rItemRect.right = pListData->m_rList.right;
    rItemRect.top = pListData->m_rList.top + ( (iItemIDX - pListData->m_iFirstVisibleItem) * pListData->m_iItemHeight);
    rItemRect.bottom = rItemRect.top + pListData->m_iItemHeight;

    // Handle the possiblity that the previous/next item may be selected
    rItemRect.top -= glb_pSkin->mpl_pSelection->m_szSize.cy - glb_pSkin->mpl_rSelection_Tile.bottom;
    rItemRect.bottom += glb_pSkin->mpl_rSelection_Tile.top;

    InvalidateRect(pListData->m_hWnd, &rItemRect, FALSE);
}
//
//
//
void CLV_ItemSelChange(CIs_ListViewData* pListData, int iItemIDX)
{
    if(iItemIDX == CPC_INVALIDITEM)
        return;

    CP_ASSERT(iItemIDX >= 0);
    CP_ASSERT(iItemIDX < pListData->m_iNumItems);

    if(pListData->m_hndlr_ItemSelected
            && pListData->m_pItems[iItemIDX].m_dwFlags & CPLV_ITEMFLAG_SELECTED)
    {
        pListData->m_hndlr_ItemSelected(pListData, iItemIDX, pListData->m_pItems[iItemIDX].m_pItemData);
    }
}
//
//
//
void CLV_ActionFocusedItem(CIs_ListViewData* pListData)
{
    if(pListData->m_iFocusItem == CPC_INVALIDITEM)
        return;
    CP_ASSERT(pListData->m_iFocusItem >= 0);
    CP_ASSERT(pListData->m_iFocusItem < pListData->m_iNumItems);

    CLV_ClearSelection(pListData);
    pListData->m_pItems[pListData->m_iFocusItem].m_dwFlags |= CPLV_ITEMFLAG_SELECTED;
    CLV_ItemSelChange(pListData, pListData->m_iFocusItem);
    CLV_InvalidateItem(pListData, pListData->m_iFocusItem);
    pListData->m_iFocusItem = pListData->m_iFocusItem;
    pListData->m_iKeyboardAnchor = pListData->m_iFocusItem;

    if(pListData->m_hndlr_ItemAction)
        pListData->m_hndlr_ItemAction(pListData, pListData->m_iFocusItem, pListData->m_pItems[pListData->m_iFocusItem].m_pItemData);
}
//
//
//
void CLV_SelectRange(CIs_ListViewData* pListData, const int _iFirst, const int _iLast)
{
    int iStartRange;
    int iEndRange;
    int iItemIDX;

    if(_iFirst > _iLast)
    {
        iStartRange = _iLast;
        iEndRange = _iFirst;
    }
    else
    {
        iStartRange = _iFirst;
        iEndRange = _iLast;
    }
    CP_ASSERT(iStartRange >= 0);
    CP_ASSERT(iStartRange < pListData->m_iNumItems);
    CP_ASSERT(iEndRange >= 0);
    CP_ASSERT(iEndRange < pListData->m_iNumItems);

    for(iItemIDX = iStartRange; iItemIDX <= iEndRange; iItemIDX++)
    {
        pListData->m_pItems[iItemIDX].m_dwFlags |= CPLV_ITEMFLAG_SELECTED;
        CLV_ItemSelChange(pListData, iItemIDX);
        CLV_InvalidateItem(pListData, iItemIDX);
    }
}
//
//
//
void CLV_Handle_WM_LBUTTONDOWN(CIs_ListViewData* pListData, const POINTS _ptCursor, const DWORD dwKeys)
{
    POINT ptCursor;

    // Init
    ptCursor.x = _ptCursor.x;
    ptCursor.y = _ptCursor.y;
    pListData->m_ptMouseDown = ptCursor;
    pListData->m_dwMouseDown_Keys = dwKeys;

    // Hit test cursor
    // - in header?
    if(PtInRect(&pListData->m_rHeader, ptCursor) == TRUE)
    {
        pListData->m_iActiveHeaderCol = CLV_HitTest_HeaderSizer_X(pListData, ptCursor.x);
        if(pListData->m_iActiveHeaderCol != CPC_INVALIDCOLUMN)
        {
            // Resizing header
            SetCapture(pListData->m_hWnd);
            pListData->m_enWindowMode = wmHeader_ChangeWidth;
        }
        else
        {
            pListData->m_iActiveHeaderCol = CLV_HitTest_Header_X(pListData, ptCursor.x);
            if(pListData->m_iActiveHeaderCol != CPC_INVALIDCOLUMN)
            {
                // Resizing header
                SetCapture(pListData->m_hWnd);
                pListData->m_enWindowMode = wmHeader_Click;
                InvalidateRect(pListData->m_hWnd, &pListData->m_rHeader, FALSE);
            }
        }
    }
    // - In HScrollbar?
    else if(PtInRect(&pListData->m_rScrollbar_Horiz, ptCursor) == TRUE)
    {
        // In Thumb?
        if(PtInRect(&pListData->m_rScrollbar_Horiz_Thumb, ptCursor) == TRUE)
        {
            // Dragging thumb
            SetCapture(pListData->m_hWnd);
            pListData->m_enWindowMode = wmHScrollbar_DragThumb;
            pListData->m_ptMouseDown_OnHitItem.x = ptCursor.x - pListData->m_rScrollbar_Horiz_Thumb.left;
            pListData->m_ptMouseDown_OnHitItem.y = ptCursor.y - pListData->m_rScrollbar_Horiz_Thumb.top;
            InvalidateRect(pListData->m_hWnd, &pListData->m_rScrollbar_Horiz_Thumb, FALSE);
        }
        // In left button
        else if(ptCursor.x < (pListData->m_rScrollbar_Horiz.left + glb_pSkin->mpl_pHScrollBar_Left->m_pImage->m_szSize.cx) )
        {
            SetCapture(pListData->m_hWnd);
            pListData->m_enWindowMode = wmHScrollbar_Scroll_Left;
            CLV_Scroll_Horiz(pListData, -CPC_SCROLLBAR_HORIZ_LINESIZE);
            InvalidateRect(pListData->m_hWnd, &pListData->m_rScrollbar_Horiz, FALSE);
            pListData->m_bMouseOverScrollbutton = TRUE;
            CLV_StartAutoRepeat(pListData);
        }
        // In right button
        else if(ptCursor.x > (pListData->m_rScrollbar_Horiz.right - glb_pSkin->mpl_pHScrollBar_Right->m_pImage->m_szSize.cx) )
        {
            SetCapture(pListData->m_hWnd);
            pListData->m_enWindowMode = wmHScrollbar_Scroll_Right;
            CLV_Scroll_Horiz(pListData, CPC_SCROLLBAR_HORIZ_LINESIZE);
            InvalidateRect(pListData->m_hWnd, &pListData->m_rScrollbar_Horiz, FALSE);
            pListData->m_bMouseOverScrollbutton = TRUE;
            CLV_StartAutoRepeat(pListData);
        }
        // In left page area
        else if(ptCursor.x < pListData->m_rScrollbar_Horiz_Thumb.left)
        {
            SetCapture(pListData->m_hWnd);
            pListData->m_enWindowMode = wmHScrollbar_Page_Left;
            CLV_Scroll_Horiz(pListData, -CPC_SCROLLBAR_HORIZ_PAGESIZE);
            InvalidateRect(pListData->m_hWnd, &pListData->m_rScrollbar_Horiz, FALSE);
            CLV_StartAutoRepeat(pListData);
        }
        // In right page area
        else if(ptCursor.x > pListData->m_rScrollbar_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -