LISTBOX–>LISTVIEW
0-1.
WC_LISTVIEW
要在对话框模板中使用list-view控件,
在创建对话框实例前,须调用InitCommonControls / InitCommonsControlEx。
默认下,list-view控件用图标标题字体。
可用WM_SETFONT指定文本字体。(应在插入任何项前发送此消息。)
要为每一项定制字体,用自定义绘制。
HWND CreateListView (HWND hwndParent)
{
INITCOMMONCONTROLSEX icex; // Structure for control initialization.
icex.dwICC = ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&icex);
RECT rcClient; // The parent window's client area.
GetClientRect (hwndParent, &rcClient);
// Create the list-view window in report view with label editing enabled.
HWND hWndListView = CreateWindow(WC_LISTVIEW,
L"",
WS_CHILD | LVS_REPORT | LVS_EDITLABELS,
0, 0,
rcClient.right - rcClient.left,
rcClient.bottom - rcClient.top,
hwndParent,
(HMENU)IDM_CODE_SAMPLES,
g_hInst,
NULL);
return (hWndListView);
}
VOID SetView(HWND hWndListView, DWORD dwView)
{
// Retrieve the current window style.
DWORD dwStyle = GetWindowLong(hWndListView, GWL_STYLE);
// Set the window style only if the view bits changed.
if ((dwStyle & LVS_TYPEMASK) != dwView)
{
SetWindowLong(hWndListView,
GWL_STYLE,
(dwStyle & ~LVS_TYPEMASK) | dwView);
} // Logical OR'ing of dwView with the result of
} // a bitwise AND between dwStyle and
// the Unary complenent of
LVS_TYPEMASK.
0-2.
在大小图像列表里的图像和次序都是一样的。
LVM_SETIMAGELIST / ListView_SetImageList
LVM_GETIMAGELIST。
BOOL InitListViewImageLists(HWND hWndListView)
{
HICON hiconItem; // Icon for list-view items.
HIMAGELIST hLarge; // Image list for icon view.
HIMAGELIST hSmall; // Image list for other views.
// Create the full-sized icon image lists.
hLarge = ImageList_Create(GetSystemMetrics(SM_CXICON),
GetSystemMetrics(SM_CYICON),
ILC_MASK, 1, 1);
hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON),
ILC_MASK, 1, 1);
// Add an icon to each image list.
hiconItem = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ITEM));
ImageList_AddIcon(hLarge, hiconItem);
ImageList_AddIcon(hSmall, hiconItem);
DestroyIcon(hiconItem);
// When you are dealing with multiple icons, you can use the previous four lines of
// code inside a loop. The following code shows such a loop. The
// icons are defined in the application's header file as resources, which
// are numbered consecutively starting with IDS_FIRSTICON. The number of
// icons is defined in the header file as C_ICONS.
/*
for(index = 0; index < C_ICONS; index++)
{
hIconItem = LoadIcon (g_hinst, MAKEINTRESOURCE(IDS_FIRSTICON + index));
ImageList_AddIcon(hSmall, hIconItem);
ImageList_AddIcon(hLarge, hIconItem);
Destroy(hIconItem);
}
*/
// Assign the image lists to the list-view control.
ListView_SetImageList(hWndListView, hLarge, LVSIL_NORMAL);
ListView_SetImageList(hWndListView, hSmall, LVSIL_SMALL);
return TRUE;
}
0-3.
LVM_INSERTCOLUMN / ListView_InsertColumn
LVM_DELETECOLUMN。
// InitListViewColumns: Adds columns to a list-view control.
// hWndListView: Handle to the list-view control.
// Returns TRUE if successful, and FALSE otherwise.
BOOL InitListViewColumns(HWND hWndListView)
{
WCHAR szText[256]; // Temporary buffer.
LVCOLUMN lvc;
int iCol;
// Initialize the LVCOLUMN structure.
// The mask specifies that the format, width, text,
// and subitem members of the structure are valid.
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
// Add the columns.
for (iCol = 0; iCol < C_COLUMNS; iCol++)
{
lvc.iSubItem = iCol;
lvc.pszText = szText;
lvc.cx = 100; // Width of column in pixels.
if ( iCol < 2 )
lvc.fmt = LVCFMT_LEFT; // Left-aligned column.
else
lvc.fmt = LVCFMT_RIGHT; // Right-aligned column.
// Load the names of the column headings from the string resources.
LoadString(g_hInst,
IDS_FIRSTCOLUMN + iCol,
szText,
sizeof(szText)/sizeof(szText[0]));
// Insert the columns into the list view.
if (ListView_InsertColumn(hWndListView, iCol, &lvc) == -1)
return FALSE;
}
return TRUE;
}
0-4.
LVM_INSERTITEM + LVITEM / ListView_InsertItem
// InsertListViewItems: Inserts items into a list view.
// hWndListView: Handle to the list-view control.
// cItems: Number of items to insert.
// Returns TRUE if successful, and FALSE otherwise.
BOOL InsertListViewItems(HWND hWndListView, int cItems)
{
LVITEM lvI;
// Initialize LVITEM members that are common to all items.
lvI.pszText = LPSTR_TEXTCALLBACK; // Sends an LVN_GETDISPINFO message.
lvI.mask = LVIF_TEXT | LVIF_IMAGE |LVIF_STATE;
lvI.stateMask = 0;
lvI.iSubItem = 0;
lvI.state = 0;
// Initialize LVITEM members that are different for each item.
for (int index = 0; index < cItems; index++)
{
lvI.iItem = index;
lvI.iImage = index;
// Insert items into the list.
if (ListView_InsertItem(hWndListView, &lvI) == -1)
return FALSE;
}
return TRUE;
}
// HandleWM_NOTIFY - Handles the LVN_GETDISPINFO notification code that is
// sent in a WM_NOTIFY to the list view parent window. The function
// provides display strings for list view items and subitems.
//
// lParam - The LPARAM parameter passed with the WM_NOTIFY message.
// rgPetInfo - A global array of structures, defined as follows:
// struct PETINFO
// {
// TCHAR szKind[10];
// TCHAR szBreed[50];
// TCHAR szPrice[20];
// };
//
// PETINFO rgPetInfo[ ] =
// {
// {TEXT("Dog"), TEXT("Poodle"), TEXT("$300.00")},
// {TEXT("Cat"), TEXT("Siamese"), TEXT("$100.00")},
// {TEXT("Fish"), TEXT("Angel Fish"), TEXT("$10.00")},
// {TEXT("Bird"), TEXT("Parakeet"), TEXT("$5.00")},
// {TEXT("Toad"), TEXT("Woodhouse"), TEXT("$0.25")},
// };
//
void HandleWM_NOTIFY(LPARAM lParam)
{
NMLVDISPINFO* plvdi;
switch (((LPNMHDR) lParam)->code)
{
case LVN_GETDISPINFO:
plvdi = (NMLVDISPINFO*)lParam;
switch (plvdi->item.iSubItem)
{
case 0:
plvdi->item.pszText = rgPetInfo[plvdi->item.iItem].szKind;
break;
case 1:
plvdi->item.pszText = rgPetInfo[plvdi->item.iItem].szBreed;
break;
case 2:
plvdi->item.pszText = rgPetInfo[plvdi->item.iItem].szPrice;
break;
default:
break;
}
break;
}
// NOTE: In addition to setting pszText to point to the item text, you could
// copy the item text into pszText using StringCchCopy. For example:
//
// StringCchCopy(plvdi->item.pszText,
// plvdi->item.cchTextMax,
// rgPetInfo[plvdi->item.iItem].szKind);
return;
}
0-5.tile views
ListView_SetTileViewInfo + LVTILEVIEWINFO。
ListView_SetTileInfo + LVTILEINFO。
SIZE size = { 100, 50 };
LVTILEVIEWINFO tileViewInfo = {0};
tileViewInfo.cbSize = sizeof(tileViewInfo);
tileViewInfo.dwFlags = LVTVIF_FIXEDSIZE;
tileViewInfo.dwMask = LVTVIM_COLUMNS | LVTVIM_TILESIZE;
tileViewInfo.cLines = 2;
tileViewInfo.sizeTile = size;
ListView_SetTileViewInfo(hWndListView, &tileViewInfo);
0-6.How to Use Groups in a List-View
LVS_ALIGNTOP。
ListView_EnableGroupView。
LVGROUP group;
group.cbSize = sizeof(LVGROUP);
group.mask = LVGF_HEADER | LVGF_GROUPID;
group.pszHeader = TEXT("Dogs");
group.iGroupId = 1;
ListView_InsertGroup(hWndListView, -1, &group);
把项插入列表时,在LVITEM的iGroupId里指定组Id。
0-7.How to Use List-View Working Areas
void SetWorkAreas1(HWND hWndListView)
{
#define EMPTY_SPACE 25
RECT rcClient;
GetClientRect(hWndListView, &rcClient);
rcClient.left += EMPTY_SPACE;
rcClient.top += EMPTY_SPACE;
rcClient.right -= (EMPTY_SPACE * 2);
SendMessage(hWndListView, LVM_SETWORKAREAS, 1, (LPARAM)&rcClient);
return;
}
void SetWorkAreas2(HWND hWndListView)
{
#define EMPTY_SPACE 25
RECT rcClient;
RECT rcWork[2];
GetClientRect(hWndListView, &rcClient);
rcWork[0].left = rcClient.left + EMPTY_SPACE;
rcWork[0].top = rcClient.top + EMPTY_SPACE;
rcWork[0].right = (rcClient.right/2) - EMPTY_SPACE;
rcWork[0].bottom = rcClient.bottom;
rcWork[1].left = (rcClient.right/2) + EMPTY_SPACE;
rcWork[1].top = rcClient.top + EMPTY_SPACE;
rcWork[1].right = rcClient.right - EMPTY_SPACE;
rcWork[1].bottom = rcClient.bottom;
SendMessage(hWndListView, LVM_SETWORKAREAS, 2, (LPARAM)rcWork);
return;
}
int GetItemWorkingArea(HWND hWndListView, int iItem)
{
UINT uWorkAreas = 0;
int nReturn = -1;
LPRECT pRects;
POINT pt;
if(!ListView_GetItemPosition(hWndListView, iItem, &pt))
return nReturn;
ListView_GetNumberOfWorkAreas(hWndListView, &uWorkAreas);
if(uWorkAreas)
{
pRects = (LPRECT)GlobalAlloc(GPTR, sizeof(RECT) * uWorkAreas);
if(pRects)
{
UINT i;
nReturn = 0;
ListView_GetWorkAreas(hWndListView, uWorkAreas, pRects);
for(i = 0; i < uWorkAreas; i++)
{
if(PtInRect((pRects + i), pt))
{
nReturn = i;
break;
}
}
GlobalFree((HGLOBAL)pRects);
}
}
return nReturn;
}
0-8.How to Use Virtual List-View Controls
struct RndItem
{
int iIcon; // Bitmap assigned to this item.
UINT state; // Item state value.
TCHAR Title[BUFFER_SIZE]; // BUFFER_SIZE is a user-defined macro value.
TCHAR SubText1[BUFFER_SIZE]; // Text for the label of the first sub-item.
TCHAR SubText2[BUFFER_SIZE]; // Text for the label of the second item.
};
virtual list-view控件,可发送LVN_ODCACHEHINT,LVN_ODFINDITEM。
Process Virtual List-View Control Notification Codes:
LRESULT OnNotify(HWND hwnd, NMHDR* pnmhdr)
{
HRESULT hr;
LRESULT lrt = FALSE;
switch (pnmhdr->code)
{
case LVN_GETDISPINFO:
{
RndItem rndItem;
NMLVDISPINFO* plvdi = (NMLVDISPINFO*) pnmhdr;
if (-1 == plvdi->item.iItem)
{
OutputDebugString(TEXT("LVOWNER: Request for -1 item?\n"));
DebugBreak();
}
// Retrieve information for item at index iItem.
RetrieveItem( &rndItem, plvdi->item.iItem );
if(plvdi->item.mask & LVIF_STATE)
{
// Fill in the state information.
plvdi->item.state |= rndItem.state;
}
if(plvdi->item.mask & LVIF_IMAGE)
{
// Fill in the image information.
plvdi->item.iImage = rndItem.iIcon;
}
if(plvdi->item.mask & LVIF_TEXT)
{
// Fill in the text information.
switch (plvdi->item.iSubItem)
{
case 0:
// Copy the main item text.
hr = StringCchCopy(plvdi->item.pszText, MAX_COUNT, rndItem.Title);
if(FAILED(hr))
{
// Insert error handling code here. MAX_COUNT
// is a user-defined value. You must not enter
// more characters than specified by MAX_COUNT or
// the text will be truncated.
}
break;
case 1:
// Copy SubItem1 text.
hr = StringCchCopy( plvdi->item.pszText, MAX_COUNT, rndItem.SubText1);
if(FAILED(hr))
{
// Insert error handling code here. MAX_COUNT
// is a user-defined value. You must not enter
// more characters than specified by MAX_COUNT or
// the text will be truncated..
}
break;
case 2:
// Copy SubItem2 text.
hr = StringCchCopy(plvdi->item.pszText, MAX_COUNT, rndItem.SubText2);
if(FAILED(hr))
{
// Insert error handling code here. MAX_COUNT
// is a user-defined value. You must not enter
// more characters than specified by MAX_COUNT or
// the text will be truncated..
}
break;
default:
break;
}
}
lrt = FALSE;
break;
}
case LVN_ODCACHEHINT:
{
NMLVCACHEHINT* pcachehint = (NMLVCACHEHINT*) pnmhdr;
// Load the cache with the recommended range.
PrepCache( pcachehint->iFrom, pcachehint->iTo );
break;
}
case LVN_ODFINDITEM:
{
LPNMLVFINDITEM pnmfi = NULL;
pnmfi = (LPNMLVFINDITEM)pnmhdr;
// Call a user-defined function that finds the index according to
// LVFINDINFO (which is embedded in the LPNMLVFINDITEM structure).
// If nothing is found, then set the return value to -1.
break;
}
default:
break;
} // End Switch block.
return(lrt);
}
Optimize the Cache:
在显示内容改变时,virtual list-view控件发送LVN_ODCACHEHINT通知消息。
消息包含要被cached条目的范围信息。
当接收到此通知消息,应用应该准备加载请求范围内条目信息的cache,一般当LVN_GETDISPINFO被发送时,信息可获取。
void PrepCache(int iFrom, int iTo)
{
/* Global Variables
* g_priCache[ ]: the main cache.
* g_iCache: the index of the first item in the main cache.
* g_cCache: the count of items in the main cache.
*
* g_priEndCache[ ]: the cache of items at the end of the list.
* g_iEndCache: the index of the first item in the end cache.
* g_cEndCache: the count of items in the end cache.
*/
// Local Variables
int i;
BOOL fOLFrom = FALSE;
BOOL fOLTo = FALSE;
// Check to see if this is the end cache.
if ((iTo == g_cCache - 1) && ((iTo - iFrom) < 30)) // 30 entries wide.
{
// Check to see if this is a portion of the current end cache.
if ((g_cCache) && (iFrom >= g_iEndCache) && (iFrom < g_iEndCache+g_cEndCache))
return;
// If it is a part of current end cache, no loading is necessary.
// This is a new end cache. Free the old memory.
if ( g_priEndCache )
GlobalFree( g_priEndCache );
// Set the index and count values for the new end cache,
// and then retrieve the memory.
g_iEndCache = iFrom;
g_cEndCache = (iTo - iFrom + 1);
g_priEndCache = (RndItem *)GlobalAlloc(GPTR, sizeof(RndItem) * g_cEndCache);
if (! g_priEndCache)
{
// TODO: Out of memory. Perform error handling.
}
// Loop to fill the cache with the recommended items.
for (i=0; i<g_cEndCache; i++)
{
// TODO: Call a function that accesses item information and
// fills a cache element.
}
}
else
{
// It is not a member of the current end cache.
// Try the primary cache instead.
// Check to see if iFrom is within the primary cache.
if ((g_cCache) && (iFrom >= g_iCache) && (iFrom < g_iCache+g_cCache))
fOLFrom = TRUE;
// Check to see if iTo is within the primary cache.
if ((g_cCache) && (iTo >= g_iCache) && (iTo <= g_iCache+g_cCache))
fOLTo = TRUE;
// do nothing if both iFrom and iTo are within the current cache.
if (fOLFrom && fOLTo)
return;
// Enlarge the cache size rather than make it specific to this hint.
if (fOLFrom)
iFrom = g_iCache;
else if (fOLTo)
iTo = g_iCache + g_cCache;
// A new primary cache is needed. Free the old primary cache.
if ( g_priCache )
GlobalFree( g_priCache );
// Set the index and count values for the new primary cache,
// and then retrieve the memory.
g_iCache = iFrom;
g_cCache = (iTo - iFrom + 1);
g_priCache = (RndItem *)GlobalAlloc( GPTR, sizeof( RndItem ) * g_cCache );
if (!g_priEndCache)
{
// TODO: Out of memory. Do error handling.
}
// Loop to fill the cache with the recommended items.
for (i=0; i<g_cEndCache; i++)
{
// TODO: Call a function that accesses item information
// and fills a cache element.
}
}
}
Retrieve an Item From the Cache:
void RetrieveItem( RndItem * prndItem, int index )
{
// Global Variables
// g_priCache[ ]: the main cache.
// g_iCache: the index of the first item in the main cache.
// c_cCache: the count of items in the main cache.
//
// g_priEndCache[ ]: the cache of items at the end of the list.
// g_iEndCache: the index of the first item in the end cache.
// g_cEndCache: the count of items in the end cache.
//
// Check to see if the item is in the main cache.
if ((index >= g_iCache) && (index < g_iCache + g_cCache))
*prndItem = g_priCache[index-g_iCache];
// If it is not in the main cache, then check to see if
// the item is in the end area cache.
else if ((index >= g_iEndCache) && (index < g_iEndCache + g_cEndCache))
*prndItem = g_priEndCache[index-g_iEndCache];
else
{
// The item is not in either cache.
// Therefore, retrieve the item information manually.
}
}
1.List-View Views
视图
1.1.Icon view(图标)
LVS_ICON / (LVM_SETVIEW + LV_VIEW_ICON)。
1.2.Small icon view(图标)
LVS_SMALLICON / (LVM_SETVIEW + LV_VIEW_SMALLICON)。
1.1和1.2下图标排列:
LVS_ALIGNTOP / LVS_ALIGNLEFT。
LVS_ALIGNMASK。
1.3.List view(单列)
LVS_LIST / (LVM_SETVIEW + LV_VIEW_LIST)。
1.4.Report (details) view(多列)
LVS_REPORT / (LVM_SETVIEW + LV_VIEW_DETAILS)。
1.5.Tile View(图标+信息)
Version 6 and later
LVM_SETVIEW + LV_VIEW_TILE。
窗口风格取得&改变:
GetWindowLong/SetWindowLong。
LVS_TYPEMASK。
2.List-View Style
LVS_EDITLABELS:条目文本可编辑。父窗口需处理LVN_ENDLABELEDIT。
LVS_ICON:图标视图
LVS_LIST:列表视图
LVS_NOCOLUMNHEADER:report view+列表头不显示。
LVS_NOSORTHEADER:report view + 列表头下,单击列表头,不执行排序。
LVS_OWNERDATA:
LVS_OWNERDRAWFIXED:report view + 自绘制。
为每个要绘制的项,给拥有者发送WM_DRAWITEM。
DRAWITEMSTRUCT包含绘制项信息。每个子项不再发送WM_DRAWITEM。
LVS_REPORT:第一列左对齐。不可用LVCFMT_RIGHT改为右对齐。
LVS_SHAREIMAGELISTS:图像列表在此控件销毁时不会被自动删除。
LVS_SHOWSELALWAYS:选择总是可辨认。
LVS_SINGLESEL:单选。
LVS_SMALLICON:小图标视图。
LVS_SORTASCENDING:升序排列。基于项文本。
LVS_SORTDESCENDING:降序排列。
//LVS_ALIGNLEFT:左对齐+小图标视图
//LVS_ALIGNTOP:顶部对齐+图标或小图标视图
//LVS_AUTOARRANGE:图标自动排列+图标或小图标视图
//LVS_NOLABELWRAP:图标视图+文本单行。
//LVS_NOSCROLL:不可滚动。
3.Extended List-View Styles
取得设置扩展风格信息,不用GetWindowLong/SetWindowLong。
用:LVM_SETEXTENDEDLISTVIEWSTYLE和LVM_GETEXTENDEDLISTVIEWSTYLE。
LVS_EX_AUTOCHECKSELECT:单击时,自动选择复选框。
LVS_EX_CHECKBOXES:项以复选形式呈现。
LVS_EX_FULLROWSELECT:
全行选择。LVS_REPORT下有效。
LVS_EX_GRIDLINES:LVS_REPORT下有效。网格。
LVS_EX_TRANSPARENTBKGND:背景由父窗口通过WM_PAINTCLIENT绘制。
//LVS_EX_AUTOSIZECOLUMNS:列自动调整大小。
//LVS_EX_BORDERSELECT:项被选择时,项边框色改变(默认为项被加亮)
//LVS_EX_COLUMNOVERFLOW:
在LVS_EX_HEADERINALLVIEWS 下有效。
//LVN_COLUMNOVERFLOWCLICK
//LVS_EX_HEADERDRAGDROP:
//LVS_EX_HEADERINALLVIEWS:
//LVS_EX_INFOTIP:LVN_GETINFOTIP在显示一个条提示前被发到父窗口。
//LVS_EX_ONECLICKACTIVATE:用户单击项时给父窗口发LVN_ITEMACTIVATE。
//LVS_EX_SUBITEMIMAGES:
//LVS_EX_TWOCLICKACTIVATE:
双击下,发送LVN_ITEMACTIVATE给父窗口。
Comctl32.dll version 6使用前提:在应用清单指定。
4.Virtual List-View Style
LVS_OWNERDATA风格的列表。
此风格可以使控件能处理数百万条目,因为控件拥有者负责管理条目数据。
其它需要条目信息的处理,用LVN_GETDISPINFO来获取数据。
5.List-View Working Areas
默认无工作区。
创建工作区+LVM_SETITEMPOSITION/LVM_SETITEMPOSITION32(把指定项移入指定工作区)
工作区重叠时,重叠部分的条目,归属于索引较低的工作区。
获取工作区数量:LVM_GETNUMBEROFWORKAREAS。
设置&取得:LVM_SETWORKAREAS / LVM_GETWORKAREAS。
工作区最大个数:LV_MAX_WORKAREAS。
6.List-View Image Lists
默认下,list-view control 不显示条目图像。
要显示条目图像:创建图像列表+将其于控件关联。
一个list-view control可以有三个图像列表:
6.1.图像列表,包含完整尺寸的图标,在icon view下显示。
6.2.图像列表,包含小图标,在small icon view, list view, or report view下显示。
6.3.图像列表,包含状态图像。被显示在完整图标或小图标的左边。icon view, small icon view, list view, and report view下都显示。
full-sized and small icon image lists 可包含可覆盖图像。
使用:
1.用ImageList_SetOverlayImage分配一个overlay image索引给完整和小图标图像列表里的一个图像。
2.ListView_InsertItem / ListView_SetItem,关联一个overlay image索引到一个条目。
用INDEXTOOVERLAYMASK宏来指定一个overlay image索引,在条目的LVITEM的state成员。
要关联状态图像到一个条目,用INDEXTOSTATEIMAGEMASK宏指定一个状态图像索引,在LVITEM结构的state成员里。
状态图像索引,0表示无状态图像。
7.List-View Items and Subitems
每个项,在list-view控件中的,有一个图标,标签,当前状态,应用定义值。
每个项,可以有一个或多个子项。
一个子项,在report view中,是一个字符串,被显示在独立于项图标和标签的列。
要指定子项文本,用LVM_SETITEMTEXT / LVM_SETITEM。
子项个数由列数决定。
LVITEM定义了list-view的一个项或子项。
iltem:项索引。
iSubItem:0,结构包含项信息。> 0,结构包含子项信息。
添加项:
LVM_INSERTITEM + LVITEM。
在添加多项前, 可以给控件发送LVM_SETITEMCOUNT,来通知控件最终包含的项个数。使控件重新分配它的内部数据结构,而不必每次添加项时,再分配。
取得项个数:LVM_GETITEMCOUNT。
重绘开关:WM_SETREDRAW。
该表list-view项属性:LVM_SETITEM + LVITEM。
取得list-view项信息:LVM_GETITEM + LVITEM。
删除list-view项:LVM_DELETEITEM。
删除所有:LVM_DELETEALLITEMS。
8.List-View Item States
项的状态是一个值,可指定项的可获得性,指明用户行为,或其它反映项状态的方面。
项状态,由LVITEM的state指定。
设置项状态:LVM_SETITEMSTATE / LVM_SETITEM。
取得项状态:LVM_GETITEMSTATE / LVM_GETITEM。
设置项的overlay 图像,
1.LVITEM的stateMask须包含LVIS_OVERLAYMASK。
2.state成员须包含基于1的移位左8位后的叠加图像索引,通过INDEXTOOVERLAYMASK。
索引0,指定无重叠图像。
设置项的状态图像:
1.LVITEM的stateMask须包含LVIS_STATEIMAGEMASK。
2.state成员须包含基于1的左移12位后的状态图像索引,通过INDEXTOSTATEIMAGEMASK。
索引0,指定无状态图像。
3.List-View Item States
LVIS_CUT
LVIS_DROPHILITED
LVIS_FOCUSED
LVIS_OVERLAYMASK
LVIS_SELECTED
LVIS_STATEIMAGEMASK
9.Callback Items and the Callback Mask
list-view控件,对它的每一项,典型地存储标签文本,条目图标在图像列表的索引和表示项状态的位集合。
你可定义回调项或改变控件的callback mask,来指定让应用存储部分或全部的这些信息。
定义:
LVM_INSERTITEM。
此时
LVITEM的pszText被设置为LPSTR_TEXTCALLBACK。
LVITEM的ilmage被设置为I_IMAGECALLBACK。
list-view控件的callback mask是标志位集合,指定应用而非控件存储当前项状态数据。
设置:LVM_SETCALLBACKMASK。
取得:LVM_GETCALLBACKMASK。
当list-view控件,须显示或排序一个信息被应用存储的list-view项时,控件给父窗口发
LVN_GETDISPINFO通知码。NMLVDISPINFO。
如果list-view控件,检测到项的callback信息的改变,控件发送LVN_SETDISPINFO。
改变回调项属性或状态位后,使用LVM_UPDATE来强制控件重绘项。
LVM_REDARWITEMS:让控件客户区部分无效来触发重绘。
10.List-View Item Position
LVM_GETITEMPOSITION
LVM_SETITEMPOSITION // 图标/小图标视图下可用。
LVM_HITTEST。
LVM_GETITEMRECT。
11.Arranging, Sorting, and Finding Items
排列:
LVS_AUTOARRANGE。
LVM_ARRANGE。
排序:
LVM_SORTITEM + 自定义回调排序函数(项关联数据,插入列表时LVITEM的lParam指定)。
LVS_SORTASCENDING / LVS_SORTDESCENDING。(依据项的标签文本排序)。此时,插入时LVITEM的pszText不能为LPSTR_TEXTCALLBACK。
搜索:
LVM_FINDITEM。
LVM_GETNEXTITEM。
12.List-View Columns
report view有效。
每一列,有标题,宽度。
子项0是项的图标和标签。
列属性由LVCOLUMN结构定义。
添加列:
LVM_INSERTCOLUMN。
删除列:
LVM_DELETECOLUMN。
取得列信息:
LVM_GETCOLUMN。
设置列信息:
LVM_SETCOLUMN。
取得&改变列宽:LVM_GETCOLUMNWIDTH / LVM_SETCOLUMNWIDTH。
有列头时,单击列头,会给父窗口发送LVN_COLUMNCLICK通知码。
可在列标题旁显示图像:
LVCF_IMAGE + 给LVCOLUMN的image成员分配图像索引。
列显示顺序:
LVCF_ORDER + 给LVCOLUMN的iOrder分配列顺序。(左–>右)
13.List-View Scroll Position
取得当前视图原点:
LVM_GETORIGIN。—在图标/小图标下可用。
list/report下,当前滚动位置由顶部索引定义。LVM_GETTOPINDEX。
LVM_GETVIEWRECT,取得所有可视条目的边框矩形。
LVM_GETCOUNTPERPAGE。
LVM_SCROLL:滚动。
LVM_ENSUREVISIBLE:滚动使指定项可见。
14.List-View Label Editing
LVS_EDITLABELS / LVM_EDITLABEL。
list-view控件通知父窗口,在编辑开始,取消或完成时。
编辑完成时,父窗口负责更新条目标签。
编辑开始时,一个edit控件被创建,放置,初始化。
在它被显示前,list-view控件给父窗口发送LVN_BEGINLABELEDIT通知码。
一个对LVN_BEGINLABELEDIT的使用是,控制用户可编辑那个标签。
阻止标签编辑,返回非0值。
为定制标签编辑,让通知处理取得编辑控件句柄,通过发送LVM_GETEDITCONTROL给list-view控件。
当标签编辑被取消或完成,list-view控件给父窗口发送LVN_ENDLABELEDIT通知码。
lParam为指向NMLVDISPINFO结构指针。
编辑取消,LVITEM的pszText为NULL。
编辑完成,LVITEM的pszText为编辑文本。
父窗口负责更新条目标签。
15.List-View Colors
应用可为list-view控件取得/设置3类颜色。
文本色:LVM_GETTEXTCOLOR / LVM_SETTEXTCOLOR。
文本背景色:LVM_GETTEXTBKCOLOR / LVM_SETTEXTBKCOLOR。
窗口背景色:LVM_GETBKCOLOR / LVM_SETBKCOLOR。
为了更明显的定制list-view外观,使用NM_CUSTOMDRAW。
16.Arranging List Items by Group
组可基于条目属性,其它特征建立。
可用LVGROUP存储组信息,如头和脚文本,当前组状态等。
组API使你管理组和组元素,如添加项到组,添加组到视图,排序组内项,查询组内项大小等。
例:
ListView_SetGroupMetrics / ListView_GetGroupMetrics。
list视图不可用分组,LVS_OWNERDATA风格控件不可用分组。
17.Insertion Marks