?? clv_listview.c
字號(hào):
// No (horiz) scrollbar needed?
if(pListData->m_iXScrollExtent <= iListRectWidth)
{
pListData->m_rList.bottom = pListData->m_rClient.bottom;
if(pListData->m_bScrollBarVisible_Horiz == TRUE)
CLV_InvalidateWindow(pListData);
pListData->m_bScrollBarVisible_Horiz = FALSE;
pListData->m_iXOrigin = 0;
SetRect(&pListData->m_rScrollbar_Horiz, 0, 0, 0, 0);
}
else
{
int iTrackWidth;
int iTrackThumbWidth;
int iTrackThumbPos;
int iTrackThumbWidth_Min;
int iTrackThumbWidth_Max;
pListData->m_rList.bottom = pListData->m_rClient.bottom - glb_pSkin->mpl_pHScrollBar_TrackUp->m_szSize.cy;
// The presence of this scrollbar may require a vertical scrollbar - take this into account
if(bCountedVScrollbar == FALSE)
{
iListRectHeight_Lines = CLV_GetListRect_Lines(pListData);
if(iListRectHeight_Lines < pListData->m_iNumItems)
{
bCountedVScrollbar = TRUE;
pListData->m_rList.right = pListData->m_rClient.right - glb_pSkin->mpl_pVScrollBar_TrackUp->m_szSize.cx;
iListRectWidth -= glb_pSkin->mpl_pVScrollBar_TrackUp->m_szSize.cx;
}
}
// Work out size of scroll track
iTrackWidth = iListRectWidth - (glb_pSkin->mpl_pHScrollBar_Left->m_pImage->m_szSize.cx
+ glb_pSkin->mpl_pHScrollBar_Right->m_pImage->m_szSize.cx);
// Setup scrollbar
if(pListData->m_bScrollBarVisible_Horiz == FALSE)
CLV_InvalidateWindow(pListData);
pListData->m_bScrollBarVisible_Horiz = TRUE;
pListData->m_rScrollbar_Horiz = pListData->m_rList;
pListData->m_rScrollbar_Horiz.top = pListData->m_rList.bottom;
pListData->m_rScrollbar_Horiz.bottom = pListData->m_rClient.bottom;
// Limit scroll to fit into window
if( (pListData->m_iXOrigin + iListRectWidth) > pListData->m_iXScrollExtent)
pListData->m_iXOrigin = pListData->m_iXScrollExtent - iListRectWidth;
// Setup track rect
iTrackThumbWidth = (int)( (( (float)iListRectWidth / (float)pListData->m_iXScrollExtent ) * (float)iTrackWidth));
iTrackThumbWidth_Min = glb_pSkin->mpl_rHScrollBar_Track_Tile.left
+ (glb_pSkin->mpl_pHScrollBar_TrackUp->m_szSize.cx - glb_pSkin->mpl_rHScrollBar_Track_Tile.right);
iTrackThumbWidth_Max = (pListData->m_rScrollbar_Horiz.right - pListData->m_rScrollbar_Horiz.left);
if(iTrackThumbWidth < iTrackThumbWidth_Min)
iTrackThumbWidth = iTrackThumbWidth_Min;
if(iTrackThumbWidth > iTrackThumbWidth_Max)
iTrackThumbWidth = iTrackThumbWidth_Max;
pListData->m_rScrollbar_Horiz_Thumb = pListData->m_rScrollbar_Horiz;
iTrackThumbPos = (int)( ( ((float)pListData->m_iXOrigin / (float)(pListData->m_iXScrollExtent - iListRectWidth)) * (float)(iTrackWidth-iTrackThumbWidth)));
pListData->m_rScrollbar_Horiz_Thumb.left = iTrackThumbPos + glb_pSkin->mpl_pHScrollBar_Left->m_pImage->m_szSize.cx;
pListData->m_rScrollbar_Horiz_Thumb.right = pListData->m_rScrollbar_Horiz_Thumb.left + iTrackThumbWidth;
InvalidateRect(pListData->m_hWnd, &pListData->m_rScrollbar_Horiz, FALSE);
}
// Vertical scrollbar
iListRectHeight_Lines = CLV_GetListRect_Lines(pListData);
if(pListData->m_iNumItems <= iListRectHeight_Lines)
{
pListData->m_rList.right = pListData->m_rClient.right;
pListData->m_rHeader.right = pListData->m_rList.right;
if(pListData->m_bScrollBarVisible_Vert == TRUE)
CLV_InvalidateWindow(pListData);
pListData->m_bScrollBarVisible_Vert = FALSE;
pListData->m_iFirstVisibleItem = 0;
SetRect(&pListData->m_rScrollbar_Vert, 0, 0, 0, 0);
}
else
{
int iTrackHeight;
int iTrackThumbHeight;
int iTrackThumbPos;
int iTrackThumbHeight_Min;
int iTrackThumbHeight_Max;
const int iListRectHeight = pListData->m_rList.bottom - pListData->m_rList.top;
// Work out size of scroll track
iTrackHeight = iListRectHeight - (glb_pSkin->mpl_pVScrollBar_Up->m_iStateHeight
+ glb_pSkin->mpl_pVScrollBar_Down->m_iStateHeight);
// Setup scrollbar
pListData->m_rList.right = pListData->m_rClient.right - glb_pSkin->mpl_pVScrollBar_TrackUp->m_szSize.cx;
pListData->m_rHeader.right = pListData->m_rList.right;
if(pListData->m_bScrollBarVisible_Vert == FALSE)
CLV_InvalidateWindow(pListData);
pListData->m_bScrollBarVisible_Vert = TRUE;
pListData->m_rScrollbar_Vert = pListData->m_rList;
pListData->m_rScrollbar_Vert.left = pListData->m_rList.right;
pListData->m_rScrollbar_Vert.right = pListData->m_rClient.right;
// Limit scroll to fit into window
if( (pListData->m_iFirstVisibleItem + iListRectHeight_Lines) > pListData->m_iNumItems)
pListData->m_iFirstVisibleItem = pListData->m_iNumItems - iListRectHeight_Lines;
// Setup track rect
iTrackThumbHeight = (int)( (( (float)iListRectHeight_Lines / (float)pListData->m_iNumItems ) * (float)iTrackHeight));
iTrackThumbHeight_Min = glb_pSkin->mpl_rVScrollBar_Track_Tile.top
+ (glb_pSkin->mpl_pVScrollBar_TrackUp->m_szSize.cy - glb_pSkin->mpl_rVScrollBar_Track_Tile.bottom);
iTrackThumbHeight_Max = (pListData->m_rScrollbar_Vert.bottom - pListData->m_rScrollbar_Vert.top);
if(iTrackThumbHeight < iTrackThumbHeight_Min)
iTrackThumbHeight = iTrackThumbHeight_Min;
if(iTrackThumbHeight > iTrackThumbHeight_Max)
iTrackThumbHeight = iTrackThumbHeight_Max;
pListData->m_rScrollbar_Vert_Thumb = pListData->m_rScrollbar_Vert;
iTrackThumbPos = (int)( ( ((float)pListData->m_iFirstVisibleItem / (float)(pListData->m_iNumItems - iListRectHeight_Lines)) * (float)(iTrackHeight-iTrackThumbHeight)));
pListData->m_rScrollbar_Vert_Thumb.top = iTrackThumbPos + pListData->m_rScrollbar_Vert.top + glb_pSkin->mpl_pVScrollBar_Up->m_iStateHeight;
pListData->m_rScrollbar_Vert_Thumb.bottom = pListData->m_rScrollbar_Vert_Thumb.top + iTrackThumbHeight;
InvalidateRect(pListData->m_hWnd, &pListData->m_rScrollbar_Horiz, FALSE);
}
}
//
//
//
void CLV_BeginBatch(CP_HLISTVIEW _hListData)
{
CIs_ListViewData* pListData = (CIs_ListViewData*)_hListData;
CP_CHECKOBJECT(pListData);
pListData->m_bInBatch = TRUE;
pListData->m_iBatchNesting ++;
}
//
//
//
void CLV_EndBatch(CP_HLISTVIEW _hListData)
{
CIs_ListViewData* pListData = (CIs_ListViewData*)_hListData;
CP_CHECKOBJECT(pListData);
pListData->m_iBatchNesting--;
if(pListData->m_iBatchNesting == 0)
{
pListData->m_bInBatch = FALSE;
CLV_InvalidateWindow(pListData);
CLV_UpdateScrollBars(pListData);
}
}
//
//
//
void CLV_Scroll_Horiz(CIs_ListViewData* pListData, const int iPixels)
{
const int iListRectWidth = pListData->m_rList.right-pListData->m_rList.left;
int iNewXOrigin;
iNewXOrigin = pListData->m_iXOrigin + iPixels;
// Ensure scoll is in range
if(iNewXOrigin < 0)
iNewXOrigin = 0;
if( (iNewXOrigin + iListRectWidth) > pListData->m_iXScrollExtent)
iNewXOrigin = pListData->m_iXScrollExtent - iListRectWidth;
// Update only if we have changed the origin
if(iNewXOrigin != pListData->m_iXOrigin)
{
pListData->m_iXOrigin = iNewXOrigin;
// Update display
CLV_UpdateScrollBars(pListData);
CLV_InvalidateWindow(pListData);
}
}
//
//
//
void CLV_Scroll_Vert(CIs_ListViewData* pListData, const int iLines)
{
const int iListRectHeight_Lines = CLV_GetListRect_Lines(pListData);
int iNewFirstVisibleItem;
iNewFirstVisibleItem = pListData->m_iFirstVisibleItem + iLines;
// Ensure scoll is in range
if(iNewFirstVisibleItem < 0)
iNewFirstVisibleItem = 0;
if( (iNewFirstVisibleItem + iListRectHeight_Lines) > pListData->m_iNumItems)
iNewFirstVisibleItem = pListData->m_iNumItems - iListRectHeight_Lines;
// Update only if we have changed the first visible item
if(iNewFirstVisibleItem != pListData->m_iFirstVisibleItem)
{
pListData->m_iFirstVisibleItem = iNewFirstVisibleItem;
CLV_UpdateScrollBars(pListData);
CLV_InvalidateWindow(pListData);
}
}
//
//
//
void CLV_UpdateWindowDims(CIs_ListViewData* pListData, const int iCX, const int iCY)
{
// Work out window parts
pListData->m_rClient.top = 0;
pListData->m_rClient.left = 0;
pListData->m_rClient.right = iCX;
pListData->m_rClient.bottom = iCY;
pListData->m_rHeader.top = 0;
pListData->m_rHeader.left = 0;
pListData->m_rHeader.right = iCX;
pListData->m_rHeader.bottom = pListData->m_iItemHeight;
pListData->m_rList.top = pListData->m_rHeader.bottom;
pListData->m_rList.left = 0;
pListData->m_rList.right = iCX;
pListData->m_rList.bottom = iCY;
CLV_UpdateScrollBars(pListData);
pListData->m_iNumItemsOnPage = (int)floor( (float)(pListData->m_rList.bottom-pListData->m_rList.top) / (float)pListData->m_iItemHeight);
}
//
//
//
void CLV_DrawBackgroundRect(CIs_ListViewData* pListData, CPs_DrawContext* pDC, const RECT* _prTarget)
{
// Call the parent and get it to draw into this rect
RECT rDraw;
POINT ptParentOffset;
CPs_DrawContext drawcontext;
HRGN rgnClip;
// Skip this draw if there is no handler registered
if(!pListData->m_hndlr_DrawBackgroundRect)
return;
// Skip this draw if we are totally clipped
if(_prTarget->right < pDC->m_rClip.left
|| _prTarget->bottom < pDC->m_rClip.top
|| _prTarget->left > pDC->m_rClip.right
|| _prTarget->top > pDC->m_rClip.bottom)
{
return;
}
// Get rect and clip relative to the parent's origin
IntersectRect(&rDraw, _prTarget, &pDC->m_rClip);
// Correct our draw context to bring it into our parent's domain
ptParentOffset.x = 0;
ptParentOffset.y = 0;
ClientToScreen(pListData->m_hWnd, &ptParentOffset);
ScreenToClient(GetParent(pListData->m_hWnd), &ptParentOffset);
drawcontext = *pDC;
drawcontext.m_ptOffset.x -= ptParentOffset.x;
drawcontext.m_ptOffset.y -= ptParentOffset.y;
drawcontext.m_rClip = rDraw;
OffsetRect(&drawcontext.m_rClip, ptParentOffset.x, ptParentOffset.y);
// Setup a GDI clip region
rgnClip = CreateRectRgn(rDraw.left + pDC->m_ptOffset.x, rDraw.top + pDC->m_ptOffset.y,
rDraw.right + pDC->m_ptOffset.x, rDraw.bottom + pDC->m_ptOffset.y);
SelectClipRgn(drawcontext.m_dcDraw, rgnClip);
pListData->m_hndlr_DrawBackgroundRect(&drawcontext);
SelectClipRgn(drawcontext.m_dcDraw, NULL);
}
//
//
//
void CLV_Handle_WM_PAINT(CIs_ListViewData* pListData)
{
RECT rClient;
PAINTSTRUCT ps;
HDC dcPaint;
HBITMAP hbmSurface, hbmSurface_Old;
HFONT hfOld;
CPs_DrawContext drawcontext;
BOOL bAvoidFlicker;
// Do some debug checking
CP_ASSERT(pListData->m_iFocusItem == CPC_INVALIDITEM || (pListData->m_iFocusItem >= 0 && pListData->m_iFocusItem < pListData->m_iNumItems));
// Prepare for draw
dcPaint = BeginPaint(pListData->m_hWnd, &ps);
rClient = pListData->m_rClient;
GetClipBox(dcPaint, &drawcontext.m_rClip);
// Null clip rgn?
if(drawcontext.m_rClip.right == drawcontext.m_rClip.left
|| drawcontext.m_rClip.top == drawcontext.m_rClip.bottom)
{
EndPaint(pListData->m_hWnd, &ps);
return;
}
bAvoidFlicker = TRUE;
if(bAvoidFlicker == TRUE)
{
hbmSurface = CreateCompatibleBitmap(dcPaint, drawcontext.m_rClip.right-drawcontext.m_rClip.left, drawcontext.m_rClip.bottom-drawcontext.m_rClip.top);
CP_ASSERT(hbmSurface);
drawcontext.m_dcDraw = CreateCompatibleDC(dcPaint);
CP_ASSERT(drawcontext.m_dcDraw);
hbmSurface_Old = (HBITMAP)SelectObject(drawcontext.m_dcDraw, hbmSurface);
drawcontext.m_ptOffset.x = -drawcontext.m_rClip.left;
drawcontext.m_ptOffset.y = -drawcontext.m_rClip.top;
}
else
{
hbmSurface = NULL;
drawcontext.m_dcDraw = dcPaint;
drawcontext.m_ptOffset.x = 0;
drawcontext.m_ptOffset.y = 0;
hbmSurface_Old = NULL;
}
// Draw header
hfOld = (HFONT)SelectObject(drawcontext.m_dcDraw, glb_pSkin->mpl_hfFont);
{
int iCursorX;
unsigned int _iColIDX;
RECT rHeaderItem;
// Draw header items
iCursorX = -pListData->m_iXOrigin;
SetTextColor(drawcontext.m_dcDraw, glb_pSkin->mpl_ListHeaderColour);
SetBkMode(drawcontext.m_dcDraw, TRANSPARENT);
for(_iColIDX = 0; _iColIDX < pListData->m_iNumColumns; _iColIDX++)
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -