📄 clv_listview.c
字号:
{
int iColumnIDX = pListData->m_piColumnOrder[_iColIDX];
int iTextOffset = 0;
int iNextCursorX;
if(pListData->m_pColumns[iColumnIDX].m_dwFlags & CPLV_COLFLAG_HIDDEN)
continue;
rHeaderItem.left = iCursorX;
rHeaderItem.right = iCursorX + pListData->m_pColumns[iColumnIDX].m_iColumnWidth;
rHeaderItem.top = pListData->m_rHeader.top;
rHeaderItem.bottom = pListData->m_rHeader.bottom;
if(rHeaderItem.right > (pListData->m_rHeader.right - CPC_HEADERCOLLAPSETHRESHOLD))
rHeaderItem.right = pListData->m_rHeader.right;
iNextCursorX = rHeaderItem.right;
// Draw this header item down - if it's the clicked or dragged header item
if( (pListData->m_enWindowMode == wmHeader_Click || pListData->m_enWindowMode == wmHeader_ChangeOrder)
&& iColumnIDX == pListData->m_iActiveHeaderCol)
{
iTextOffset = 1;
CPIG_TiledFill(&drawcontext, &rHeaderItem, &glb_pSkin->mpl_rListHeader_SourceTile, glb_pSkin->mpl_pListHeader_Down, CIC_TILEDFILOPTIONS_NONE);
}
else
CPIG_TiledFill(&drawcontext, &rHeaderItem, &glb_pSkin->mpl_rListHeader_SourceTile, glb_pSkin->mpl_pListHeader_Up, CIC_TILEDFILOPTIONS_NONE);
rHeaderItem.left += glb_pSkin->mpl_rListHeader_SourceTile.left + iTextOffset;
rHeaderItem.right -= glb_pSkin->mpl_pListHeader_Down->m_szSize.cx - glb_pSkin->mpl_rListHeader_SourceTile.right;
rHeaderItem.top += iTextOffset;
if(pListData->m_pColumns[iColumnIDX].m_pColumnText)
CLV_DrawText(&drawcontext, pListData->m_pColumns[iColumnIDX].m_pColumnText, &rHeaderItem, pListData->m_pColumns[iColumnIDX].m_enAlign);
iCursorX = iNextCursorX;
if(iCursorX == rClient.right)
break;
}
// Draw a dummy last column
if(iCursorX < rClient.right)
{
rHeaderItem.left = iCursorX;
rHeaderItem.right = pListData->m_rHeader.right;
rHeaderItem.top = pListData->m_rHeader.top;
rHeaderItem.bottom = pListData->m_rHeader.top + pListData->m_iItemHeight;
CPIG_TiledFill(&drawcontext, &rHeaderItem, &glb_pSkin->mpl_rListHeader_SourceTile, glb_pSkin->mpl_pListHeader_Up, CIC_TILEDFILOPTIONS_NONE);
}
}
// Draw the (horiz) scrollbar
if(pListData->m_bScrollBarVisible_Horiz == TRUE)
{
RECT rHScrollBarTrack = pListData->m_rScrollbar_Horiz;
rHScrollBarTrack.left += glb_pSkin->mpl_pHScrollBar_Left->m_pImage->m_szSize.cx;
rHScrollBarTrack.right -= glb_pSkin->mpl_pHScrollBar_Right->m_pImage->m_szSize.cx;
// Draw buttons
CPIG_DrawStateImage( &drawcontext,
pListData->m_rScrollbar_Horiz.left,
rHScrollBarTrack.top,
glb_pSkin->mpl_pHScrollBar_Left,
(pListData->m_enWindowMode == wmHScrollbar_Scroll_Left && pListData->m_bMouseOverScrollbutton)
? igsActive : igsQuiescent);
CPIG_DrawStateImage( &drawcontext,
rHScrollBarTrack.right,
rHScrollBarTrack.top,
glb_pSkin->mpl_pHScrollBar_Right,
(pListData->m_enWindowMode == wmHScrollbar_Scroll_Right && pListData->m_bMouseOverScrollbutton)
? igsActive : igsQuiescent);
// Scrollbar background
CPIG_TiledFill(&drawcontext, &rHScrollBarTrack, &glb_pSkin->mpl_rHScrollBar_Bk_Tile, glb_pSkin->mpl_pHScrollBar_Bk, CIC_TILEDFILOPTIONS_NONE);
// Track
CPIG_TiledFill( &drawcontext,
&pListData->m_rScrollbar_Horiz_Thumb,
&glb_pSkin->mpl_rHScrollBar_Track_Tile,
pListData->m_enWindowMode == wmHScrollbar_DragThumb ? glb_pSkin->mpl_pHScrollBar_TrackDn : glb_pSkin->mpl_pHScrollBar_TrackUp, CIC_TILEDFILOPTIONS_NONE);
}
// Draw the (vert) scrollbar
if(pListData->m_bScrollBarVisible_Vert == TRUE)
{
RECT rHeaderPad;
RECT rVScrollBarTrack = pListData->m_rScrollbar_Vert;
rVScrollBarTrack.top += glb_pSkin->mpl_pHScrollBar_Left->m_iStateHeight;
rVScrollBarTrack.bottom -= glb_pSkin->mpl_pHScrollBar_Right->m_iStateHeight;
// Draw buttons
CPIG_DrawStateImage( &drawcontext,
rVScrollBarTrack.left, pListData->m_rScrollbar_Vert.top,
glb_pSkin->mpl_pVScrollBar_Up,
(pListData->m_enWindowMode == wmVScrollbar_Scroll_Up && pListData->m_bMouseOverScrollbutton)
? igsActive : igsQuiescent);
CPIG_DrawStateImage( &drawcontext,
rVScrollBarTrack.left, rVScrollBarTrack.bottom,
glb_pSkin->mpl_pVScrollBar_Down,
(pListData->m_enWindowMode == wmVScrollbar_Scroll_Down && pListData->m_bMouseOverScrollbutton)
? igsActive : igsQuiescent);
// Scrollbar background
CPIG_TiledFill(&drawcontext, &rVScrollBarTrack, &glb_pSkin->mpl_rVScrollBar_Bk_Tile, glb_pSkin->mpl_pVScrollBar_Bk, CIC_TILEDFILOPTIONS_NONE);
// Track
CPIG_TiledFill( &drawcontext,
&pListData->m_rScrollbar_Vert_Thumb,
&glb_pSkin->mpl_rVScrollBar_Track_Tile,
pListData->m_enWindowMode == wmVScrollbar_DragThumb ? glb_pSkin->mpl_pVScrollBar_TrackDn : glb_pSkin->mpl_pVScrollBar_TrackUp,
CIC_TILEDFILOPTIONS_NONE);
// Draw some background above the scrollbar (and beyond the header area)
rHeaderPad = pListData->m_rHeader;
rHeaderPad.left = rHeaderPad.right;
rHeaderPad.right = pListData->m_rClient.right;
CLV_DrawBackgroundRect(pListData, &drawcontext, &rHeaderPad);
}
// Draw a background area in the gap between the 2 scrollbars
if(pListData->m_bScrollBarVisible_Horiz == TRUE && pListData->m_bScrollBarVisible_Vert == TRUE)
{
RECT rScrollbarGap;
rScrollbarGap = pListData->m_rClient;
rScrollbarGap.top = pListData->m_rScrollbar_Vert.bottom;
rScrollbarGap.left = pListData->m_rScrollbar_Horiz.right;
CLV_DrawBackgroundRect(pListData, &drawcontext, &rScrollbarGap);
}
// Draw the list
// - clip to list rect
{
RECT rList = pListData->m_rList;
OffsetRect(&rList, drawcontext.m_ptOffset.x, drawcontext.m_ptOffset.y);
IntersectClipRect(drawcontext.m_dcDraw, rList.left, rList.top, rList.right, rList.bottom);
}
// - draw background
CPIG_TiledFill(&drawcontext, &pListData->m_rList, &glb_pSkin->mpl_rListBackground_SourceTile, glb_pSkin->mpl_pListBackground, CIC_TILEDFILOPTIONS_NONE);
// Draw the selection
{
int iItemIDX;
int iFirstVisibleItem;
int iLastVisibleItem;
BOOL bInSelection;
RECT rSelection;
// Setup bounds
iFirstVisibleItem = pListData->m_iFirstVisibleItem - 1;
iLastVisibleItem = iFirstVisibleItem + ((pListData->m_rList.bottom-pListData->m_rList.top)/pListData->m_iItemHeight) + 1;
if(iFirstVisibleItem < 0)
iFirstVisibleItem = 0;
if(iLastVisibleItem >= pListData->m_iNumItems)
iLastVisibleItem = pListData->m_iNumItems-1;
// Part initialise selection rect
rSelection.left = -pListData->m_iXOrigin + glb_pSkin->mpl_rListBackground_SourceTile.left;
rSelection.right = (pListData->m_iXScrollExtent - pListData->m_iXOrigin) - (glb_pSkin->mpl_pListBackground->m_szSize.cx - glb_pSkin->mpl_rListBackground_SourceTile.right);
// Draw selection (grouping adjacent selected items)
bInSelection = FALSE;
for(iItemIDX = iFirstVisibleItem; iItemIDX <= iLastVisibleItem; iItemIDX++)
{
// Is this item selected?
if(pListData->m_pItems[iItemIDX].m_dwFlags & CPLV_ITEMFLAG_SELECTED)
{
// Open a new selection (if we are not in one already)
if(bInSelection == FALSE)
{
bInSelection = TRUE;
rSelection.top = (iItemIDX + 1 - pListData->m_iFirstVisibleItem) * pListData->m_iItemHeight;
}
}
else
{
// Are we in a selection (if so complete it)
if(bInSelection)
{
bInSelection = FALSE;
rSelection.bottom = (iItemIDX + 1 - pListData->m_iFirstVisibleItem) * pListData->m_iItemHeight;
CPIG_TiledFill(&drawcontext, &rSelection, &glb_pSkin->mpl_rSelection_Tile, glb_pSkin->mpl_pSelection, CIC_TILEDFILOPTIONS_NONE);
}
}
}
// Close any open groups
if(bInSelection)
{
bInSelection = FALSE;
rSelection.bottom = ((iLastVisibleItem+2) - pListData->m_iFirstVisibleItem) * pListData->m_iItemHeight;
CPIG_TiledFill(&drawcontext, &rSelection, &glb_pSkin->mpl_rSelection_Tile, glb_pSkin->mpl_pSelection, CIC_TILEDFILOPTIONS_NONE);
}
// Draw focus item
if(pListData->m_iFocusItem != CPC_INVALIDITEM
&& pListData->m_iFocusItem >= iFirstVisibleItem && pListData->m_iFocusItem <= iLastVisibleItem
&& pListData->m_bHasFocus == TRUE)
{
RECT rFocus;
rFocus = rSelection;
rFocus.top = (pListData->m_iFocusItem + 1 - pListData->m_iFirstVisibleItem) * pListData->m_iItemHeight;
rFocus.bottom = (pListData->m_iFocusItem + 2 - pListData->m_iFirstVisibleItem) * pListData->m_iItemHeight;
CPIG_TiledFill(&drawcontext, &rFocus, &glb_pSkin->mpl_rFocus_Tile, glb_pSkin->mpl_pFocus, CIC_TILEDFILOPTIONS_NOCENTRE);
}
}
// Draw the items
{
int iCursorX;
unsigned int _iColIDX;
int iFirstVisibleItem;
int iLastVisibleItem;
RECT rItem;
iFirstVisibleItem = pListData->m_iFirstVisibleItem;
iLastVisibleItem = iFirstVisibleItem + ((pListData->m_rList.bottom-pListData->m_rList.top)/pListData->m_iItemHeight);
if(iLastVisibleItem >= pListData->m_iNumItems)
iLastVisibleItem = pListData->m_iNumItems-1;
// Draw items column by column
iCursorX = -pListData->m_iXOrigin;
SetBkMode(drawcontext.m_dcDraw, TRANSPARENT);
for(_iColIDX = 0; _iColIDX < pListData->m_iNumColumns; _iColIDX++)
{
int iColumnIDX = pListData->m_piColumnOrder[_iColIDX];
int iItemIDX;
int iNextCursorX;
if(pListData->m_pColumns[iColumnIDX].m_dwFlags & CPLV_COLFLAG_HIDDEN)
continue;
rItem.left = iCursorX;
rItem.right = iCursorX + pListData->m_pColumns[iColumnIDX].m_iColumnWidth;
if(rItem.right > (pListData->m_rHeader.right - CPC_HEADERCOLLAPSETHRESHOLD))
rItem.right = pListData->m_rHeader.right;
iNextCursorX = rItem.right;
// Line text up with header
rItem.left += glb_pSkin->mpl_rListHeader_SourceTile.left;
rItem.right -= glb_pSkin->mpl_pListHeader_Down->m_szSize.cx - glb_pSkin->mpl_rListHeader_SourceTile.right;
// Draw item text (if there is any and this column is inside the clip box)
if(pListData->m_pColumns[iColumnIDX].m_pfnTextAccessor
&& rItem.right > drawcontext.m_rClip.left
&& rItem.left < drawcontext.m_rClip.right)
{
int iCursorY = pListData->m_rList.top;
for(iItemIDX = iFirstVisibleItem; iItemIDX <= iLastVisibleItem; iItemIDX++)
{
// Set the text colour depending on whether we are selected
const char* pcText = pListData->m_pColumns[iColumnIDX].m_pfnTextAccessor(pListData->m_pItems[iItemIDX].m_pItemData);
if(pcText)
{
if(pListData->m_pItems[iItemIDX].m_dwFlags & CPLV_ITEMFLAG_SELECTED)
SetTextColor(drawcontext.m_dcDraw, glb_pSkin->mpl_ListTextColour_Selected);
else
{
if(pListData->m_pColumns[iColumnIDX].m_pfnGetCustomDrawColour)
{
CPe_CustomDrawColour enDrawColour;
enDrawColour = pListData->m_pColumns[iColumnIDX].m_pfnGetCustomDrawColour(pListData->m_pItems[iItemIDX].m_pItemData);
if(enDrawColour == cdcNormal)
SetTextColor(drawcontext.m_dcDraw, glb_pSkin->mpl_ListTextColour);
else if(enDrawColour == cdcLowlighted)
SetTextColor(drawcontext.m_dcDraw, RGB(0,0,0));
else
SetTextColor(drawcontext.m_dcDraw, RGB(255,255,255));
}
else
SetTextColor(drawcontext.m_dcDraw, glb_pSkin->mpl_ListTextColour);
}
// Draw item's text
rItem.top = iCursorY;
rItem.bottom = iCursorY + pListData->m_iItemHeight;
CLV_DrawText(&drawcontext, pcText, &rItem, pListData->m_pColumns[iColumnIDX].m_enAlign);
}
iCursorY += pListData->m_iItemHeight;
}
}
iCursorX = iNextCursorX;
if(iCursorX == pListData->m_rList.right)
break;
}
}
// Cleanup
SelectObject(drawcontext.m_dcDraw, hfOld);
if(hbmSurface)
{
BitBlt(dcPaint,
drawcontext.m_rClip.left, drawcontext.m_rClip.top,
drawcontext.m_rClip.right-drawcontext.m_rClip.left,
drawcontext.m_rClip.bottom-drawcontext.m_rClip.top,
drawcontext.m_dcDraw, 0, 0, SRCCOPY);
SelectObject(drawcontext.m_dcDraw, hbmSurface_Old);
DeleteDC(drawcontext.m_dcDraw);
DeleteObject(hbmSurface);
}
EndPaint(pListData->m_hWnd, &ps);
}
//
//
//
void CLV_CalcItemHeight(CIs_ListViewData* pListData)
{
HDC dcWindow;
SIZE szText;
HFONT hfOld;
dcWindow = GetDC(pListData->m_hWnd);
hfOld = (HFONT)SelectObject(dcWindow, glb_pSkin->mpl_hfFont);
GetTextExtentPoint(dcWindow, "Xy", 2, &szText);
pListData->m_iItemHeight = szText.cy;
SelectObject(dcWindow, hfOld);
ReleaseDC(pListData->m_hWnd, dcWindow);
}
//
//
//
int CLV_HitTest_Header_X(CIs_ListViewData* pListData, const int iTestX)
{
// We are in the header - which one?
int iCursorX;
int iLastCursorX;
unsigned int _iColIDX;
iCursorX = -pListData->m_iXOrigin;
iLastCursorX = 0;
for(_iColIDX = 0; _iColIDX < pListData->m_iNumColumns; _iColIDX++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -