?? clv_listview.c
字號:
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "globals.h"
#include "resource.h"
////////////////////////////////////////////////////////////////////////////////
//
typedef enum _CIe_WindowMode
{
wmQuiescent,
wmHeader_Click,
wmHeader_ChangeWidth,
wmHeader_ChangeOrder,
wmHScrollbar_DragThumb,
wmHScrollbar_Scroll_Left,
wmHScrollbar_Scroll_Right,
wmHScrollbar_Page_Left,
wmHScrollbar_Page_Right,
wmVScrollbar_DragThumb,
wmVScrollbar_Scroll_Up,
wmVScrollbar_Scroll_Down,
wmVScrollbar_Page_Up,
wmVScrollbar_Page_Down,
wmList_Click,
wmList_Drag
} CIe_WindowMode;
//
//
//
typedef struct _CIs_ListView_Column
{
char* m_pColumnText;
int m_iColumnWidth;
DWORD m_dwFlags;
wp_GetItemText m_pfnTextAccessor;
wp_GetItemDrawColour m_pfnGetCustomDrawColour;
CPe_ListColumnAlign m_enAlign;
} CIs_ListView_Column;
//
//
//
typedef struct _CIs_ListView_Item
{
DWORD m_dwFlags;
const void* m_pItemData;
} CIs_ListView_Item;
//
//
//
typedef struct _CIs_ListViewData
{
HWND m_hWnd;
BOOL m_bInBatch;
int m_iBatchNesting;
BOOL m_bHasFocus;
unsigned int m_iItemHeight;
int m_iNumItemsOnPage;
RECT m_rClient;
RECT m_rHeader;
RECT m_rList;
RECT m_rScrollbar_Horiz;
RECT m_rScrollbar_Horiz_Thumb;
RECT m_rScrollbar_Vert;
RECT m_rScrollbar_Vert_Thumb;
// Columns
unsigned int m_iNumColumns;
CIs_ListView_Column* m_pColumns;
unsigned int* m_piColumnOrder;
// Items
CIs_ListView_Item* m_pItems;
int m_iNumItemsInBuffer;
int m_iNumItems;
// Selection, scroll & focus
int m_iXOrigin;
int m_iXScrollExtent;
BOOL m_bScrollBarVisible_Horiz;
BOOL m_bScrollBarVisible_Vert;
int m_iFirstVisibleItem;
int m_iFocusItem;
int m_iKeyboardAnchor;
// State
CIe_WindowMode m_enWindowMode;
unsigned int m_uiAutorepeatTimer;
BOOL m_bAutoRepeatFirst;
BOOL m_bMouseOverScrollbutton;
int m_iActiveHeaderCol;
int m_iClickedItem;
POINT m_ptMouseDown;
POINT m_ptMouseDown_OnHitItem;
DWORD m_dwMouseDown_Keys;
// Callback handlers
wp_DrawBackgroundRect m_hndlr_DrawBackgroundRect;
wp_HeaderChanged m_hndlr_HeaderChanged;
wp_ItemCallback m_hndlr_ItemSelected;
wp_ItemCallback m_hndlr_ItemAction;
wp_ItemCallback m_hndlr_ItemDrag;
wp_ItemSubCallback m_hndlr_ItemRightClick;
wp_ColHeaderClick m_hndlr_ColHeaderClick;
wp_UnhandledKeyPress m_hndlr_UnhandledKeyPress;
} CIs_ListViewData;
//
////////////////////////////////////////////////////////////////////////////////
#define CPC_HEADERCOLLAPSETHRESHOLD 8
#define CPC_HEADERDRAGDISTANCE 16
#define CPC_BUFFERQUANTISATION 128
#define CPC_HEADERDRAG_HTWIDTH 8
#define CPC_HEADERDRAG_DEFAULTWIDTH 100
#define CPC_SCROLLBAR_HORIZ_LINESIZE 10
#define CPC_SCROLLBAR_HORIZ_PAGESIZE 100
#define CPC_SCROLLBAR_MOUSEWHEELAMOUNT 5
#define CPC_TIMERID_AUTOREPEAT 1
#define CPC_LISTDRAGDISTANCE 4
LRESULT CALLBACK exp_ListViewWindowProc(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam);
#define CLC_COOLPLAYER_LISTVIEW_WINDOWCLASSNAME "CoolPlayer_ListView"
////////////////////////////////////////////////////////////////////////////////
//
//
//
CP_HLISTVIEW CLV_Create(HWND hWndParent, const int iX, const int iY, const int iWidth, const int iHeight)
{
WNDCLASS wcPlaylist;
HWND hWndWindow;
CIs_ListViewData* pListData;
wcPlaylist.style = CS_DBLCLKS;
wcPlaylist.lpfnWndProc = exp_ListViewWindowProc;
wcPlaylist.cbClsExtra = 0;
wcPlaylist.cbWndExtra = 0;
wcPlaylist.hInstance = GetModuleHandle(NULL);
wcPlaylist.hIcon = NULL; // We will explicity set our icons (so that we have a nice small icon)
wcPlaylist.hCursor = NULL;
wcPlaylist.hbrBackground = (HBRUSH)GetStockObject(HOLLOW_BRUSH); // Prevent the system drawing white over our invaid rgn before we can paint
wcPlaylist.lpszMenuName = NULL;
wcPlaylist.lpszClassName = CLC_COOLPLAYER_LISTVIEW_WINDOWCLASSNAME;
RegisterClass(&wcPlaylist);
pListData = (CIs_ListViewData*)malloc(sizeof(CIs_ListViewData));
pListData->m_bInBatch = FALSE;
pListData->m_iBatchNesting = 0;
pListData->m_bHasFocus = FALSE;
pListData->m_iNumColumns = 0;
pListData->m_pColumns = NULL;
pListData->m_piColumnOrder = NULL;
pListData->m_enWindowMode = wmQuiescent;
pListData->m_uiAutorepeatTimer = 0;
pListData->m_pItems = NULL;
pListData->m_iNumItems = 0;
pListData->m_iNumItemsInBuffer = 0;
pListData->m_iFirstVisibleItem = 0;
pListData->m_iXOrigin = 0;
pListData->m_bScrollBarVisible_Horiz = FALSE;
pListData->m_iFocusItem = CPC_INVALIDITEM;
pListData->m_iKeyboardAnchor = CPC_INVALIDITEM;
// Handlers
pListData->m_hndlr_DrawBackgroundRect = NULL;
pListData->m_hndlr_HeaderChanged = NULL;
pListData->m_hndlr_ItemSelected = NULL;
pListData->m_hndlr_ItemAction = NULL;
pListData->m_hndlr_ItemDrag = NULL;
pListData->m_hndlr_ItemRightClick = NULL;
pListData->m_hndlr_ColHeaderClick = NULL;
pListData->m_hndlr_UnhandledKeyPress = NULL;
hWndWindow = CreateWindowEx(WS_EX_ACCEPTFILES,
CLC_COOLPLAYER_LISTVIEW_WINDOWCLASSNAME,
"",
WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE,
iX, iY, iWidth, iHeight, hWndParent,
NULL,
GetModuleHandle(NULL),
pListData);
return (CP_HLISTVIEW)pListData;
}
//
//
//
HWND CLV_GetHWND(CP_HLISTVIEW _hListData)
{
CIs_ListViewData* pListData = (CIs_ListViewData*)_hListData;
CP_CHECKOBJECT(pListData);
return pListData->m_hWnd;
}
//
//
//
void CLV_EmptyItems(CIs_ListViewData* pListData)
{
if(pListData->m_pItems == NULL)
return;
free(pListData->m_pItems);
pListData->m_pItems = NULL;
pListData->m_iNumItems = 0;
pListData->m_iNumItemsInBuffer = 0;
}
//
//
//
void CLV_InvalidateWindow(CIs_ListViewData* pListData)
{
InvalidateRect(pListData->m_hWnd, NULL, FALSE);
}
//
//
//
int CLV_YOffsetToItem(CIs_ListViewData* pListData, const int iYOffset)
{
return pListData->m_iFirstVisibleItem
+ (int)floor( (float)(iYOffset-pListData->m_rList.top) / (float)pListData->m_iItemHeight);
}
//
//
//
int CLV_GetListRect_Lines(CIs_ListViewData* pListData)
{
return (int)floor( (float)(pListData->m_rList.bottom-pListData->m_rList.top) / (float)pListData->m_iItemHeight);
}
//
//
//
void CLV_CleanupWindowData(CIs_ListViewData* pListData)
{
// Free items
CLV_EmptyItems(pListData);
// Free columns
if(pListData->m_pColumns)
{
unsigned int iColumnIDX;
for(iColumnIDX = 0; iColumnIDX < pListData->m_iNumColumns; iColumnIDX++)
{
if(pListData->m_pColumns[iColumnIDX].m_pColumnText)
free(pListData->m_pColumns[iColumnIDX].m_pColumnText);
}
}
free(pListData);
}
//
//
//
void CLV_DrawText(CPs_DrawContext* pDC, const char* pcString, const RECT* _prTarget, const CPe_ListColumnAlign enAlign)
{
RECT rDraw;
UINT uiFlags;
// 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;
}
rDraw = *_prTarget;
if(enAlign == lcaLeft)
uiFlags = DT_LEFT;
else if(enAlign == lcaCentre)
uiFlags = DT_CENTER;
else if(enAlign == lcaRight)
{
uiFlags = DT_RIGHT;
rDraw.right -= 5;
if(rDraw.right < rDraw.left)
rDraw.right = rDraw.left;
}
else
uiFlags = 0L;
OffsetRect(&rDraw, pDC->m_ptOffset.x, pDC->m_ptOffset.y);
DrawText(pDC->m_dcDraw, pcString, -1, &rDraw, DT_WORD_ELLIPSIS | DT_NOPREFIX | uiFlags);
}
//
//
//
void CLV_UpdateScrollBars(CIs_ListViewData* pListData)
{
unsigned int _iColIDX;
int iListRectWidth;
int iListRectHeight_Lines;
BOOL bCountedVScrollbar;
// Get the total width
pListData->m_iXScrollExtent = 0;
for(_iColIDX = 0; _iColIDX < pListData->m_iNumColumns; _iColIDX++)
{
unsigned int iColumnIDX = pListData->m_piColumnOrder[_iColIDX];
if(pListData->m_pColumns[iColumnIDX].m_dwFlags & CPLV_COLFLAG_HIDDEN)
continue;
pListData->m_iXScrollExtent += pListData->m_pColumns[iColumnIDX].m_iColumnWidth;
}
// Work out available width
iListRectWidth = pListData->m_rClient.right-pListData->m_rClient.left;
// - If we need a vertical scrollbar (at this point) - then take this into account
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;
}
else
bCountedVScrollbar = FALSE;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -