#include "ListViewX.h"
#include "_Structures.h"
#include "_Constants.h"
#include "_GlobalVars.h"
short
ListView_GetColumnCount(HWND hwndLV)
{
short sCol = 0;
LVCOLUMN lvCol;
lvCol.mask = LVCF_WIDTH;
while(ListView_GetColumn(hwndLV, sCol++, &lvCol))
;
return --sCol;
}
void
ListView_RefillLParamOrder(HWND hwndLV)
{
int i, nCount;
nCount = ListView_GetItemCount(hwndLV);
for(i = 0; i< nCount; i++)
{
LVITEM lvItem;
lvItem.mask = LVIF_PARAM;
lvItem.lParam = (LPARAM)i;
lvItem.iItem = i;
ListView_SetItem(hwndLV, &lvItem);
}
}
void
ListView_SetNextHeaderAppearance(HWND hwndLV)
{
HWND hwndHdr;
POINT ptCursorPos;
HDHITTESTINFO hdHitInfo;
LRESULT lResult;
hwndHdr = ListView_GetHeader(hwndLV);
GetCursorPos(&ptCursorPos);
ScreenToClient(hwndHdr, &ptCursorPos);
hdHitInfo.pt = ptCursorPos;
hdHitInfo.iItem = -1;
hdHitInfo.flags = 0;
lResult = SendMessage(hwndHdr, HDM_HITTEST, 0, (LPARAM)(LPHDHITTESTINFO)&hdHitInfo);
if((lResult >= 0) && (hdHitInfo.flags & ~(HHT_ONDIVIDER | HHT_ONDIVOPEN)) && (hdHitInfo.iItem >= 0))
{
HDITEM hdItem;
char buf[256];
int x, nColIdx = hdHitInfo.iItem;
short nColCount = ListView_GetColumnCount(hwndLV);
// Set image for clicked item.
hdItem.mask = HDI_FORMAT | HDI_TEXT;
hdItem.pszText = buf;
hdItem.cchTextMax = 255;
Header_GetItem(hwndHdr, nColIdx, &hdItem);
hdItem.mask = HDI_FORMAT | HDI_BITMAP | HDI_TEXT;
hdItem.fmt = HDF_BITMAP | HDF_STRING | HDF_BITMAP_ON_RIGHT;
hdItem.hbm = g_pcListColumns[nColIdx].nSortOrder == ASCENDING ? g_hbmAsc :
(g_pcListColumns[nColIdx].nSortOrder == DESCENDING ? g_hbmDesc : g_hbmNone);
Header_SetItem(hwndHdr, nColIdx, &hdItem);
// Reset image to none from all other items.
for(x = 0; x < nColCount; x++)
{
if(x == nColIdx)
continue;
hdItem.mask = HDI_BITMAP | HDI_TEXT;
Header_GetItem(hwndHdr, x, &hdItem);
if(hdItem.hbm)
{
hdItem.mask = HDI_FORMAT | HDI_BITMAP | HDI_TEXT;
hdItem.fmt = HDF_BITMAP | HDF_STRING | HDF_BITMAP_ON_RIGHT;
hdItem.hbm = g_hbmNone;
Header_SetItem(hwndHdr, x, &hdItem);
}
}
}
}
int
ListView_OnSort(HWND hDlg, HWND hwndLV, int iColumn, PFNLVCOMPARE lpfnCompare)
{
int nColCount;
DLGSORTDATA ds;
nColCount = ListView_GetColumnCount(hwndLV);
if(iColumn < nColCount)
{
if(g_pcListColumns[iColumn].nSortOrder == ASCENDING)
g_pcListColumns[iColumn].nSortOrder = DESCENDING;
else if(g_pcListColumns[iColumn].nSortOrder == DESCENDING)
g_pcListColumns[iColumn].nSortOrder = NONE;
else
g_pcListColumns[iColumn].nSortOrder = ASCENDING;
ds.hDlg = hDlg;
ds.nSortOrder = g_pcListColumns[iColumn].nSortOrder;
ds.nSortType = g_pcListColumns[iColumn].nSortType;
ds.nColIdx = iColumn;
return (int)ListView_SortItems(hwndLV, lpfnCompare, (LPARAM)(&ds));
}
else
return 0;
}
BOOL
InsertRowInList(HWND hwndLV, int nInsertCount, ...)
{
int nCount, nItem;
va_list marker;
DWORD dwId;
register int i;
LVITEM lvItem;
if(!IsWindow(hwndLV))
return FALSE;
nCount = ListView_GetItemCount(hwndLV);
lvItem.mask = LVIF_TEXT | LVIF_PARAM;
lvItem.pszText = " ";
lvItem.cchTextMax = strlen(" ");
lvItem.iItem = nCount;
lvItem.iImage = 0;
lvItem.iSubItem = 0;
lvItem.state = 0;
lvItem.stateMask = 0;
lvItem.iIndent = 0;
lvItem.lParam = nCount;
nItem = ListView_InsertItem(hwndLV, &lvItem);
va_start(marker, nInsertCount);
dwId = *((DWORD *)(va_arg(marker, DWORD*)));
lvItem.mask = LVIF_PARAM;
lvItem.iItem = nCount;
lvItem.iSubItem = 0;
lvItem.lParam = (LPARAM)dwId;
ListView_SetItem(hwndLV, &lvItem);
for(i = 0; i < nInsertCount - 1; i += 2)
{
char *szItemText;
short sImage;
sImage = va_arg(marker, short);
szItemText = va_arg(marker, char*);
lvItem.mask = LVIF_TEXT | (sImage == -1 ? 0 : LVIF_IMAGE);
lvItem.iItem = nCount;
lvItem.iSubItem = i / 2;
lvItem.iImage = sImage;
lvItem.pszText = szItemText;
lvItem.cchTextMax = strlen(szItemText);
ListView_SetItem(hwndLV, &lvItem);
}
va_end(marker);
return TRUE;
}
BOOL
ListView_EnsureColumnVisible(HWND hwndLV, short sColIndex)
{
int iCount, nLVCount = ListView_GetItemCount(hwndLV), nMaxWidth = 0, nMaxHeaderWidth = 0;
HDC hLVDC;
// ensure some conditions
// is a window?
if(!IsWindow(hwndLV))
return FALSE;
// is a listview?
{
TCHAR lpszLVClassName[_MAX_PATH + 1];
if(!GetClassName(hwndLV, lpszLVClassName, _MAX_PATH + 1) || (_tcsicmp(lpszLVClassName, WC_LISTVIEW) != 0))
return FALSE;
}
// is in report style?
if(!(GetWindowLong(hwndLV, GWL_STYLE) & LVS_REPORT))
return FALSE;
// column out of range
if(sColIndex > ListView_GetColumnCount(hwndLV)) // it is 0-based
return FALSE;
nMaxWidth = ListView_GetColumnWidth(hwndLV, sColIndex);
hLVDC = GetDC(hwndLV);
if(hLVDC)
{
// get image width, if column has subitem images
int nIconSize = 0;
{
HIMAGELIST himgList = ListView_GetImageList(hwndLV, LVSIL_SMALL);
if(himgList)
{
int cx, cy;
if(ImageList_GetIconSize(himgList, &cx, &cy))
{
nIconSize = cx;
}
}
}
for(iCount = 0; iCount < nLVCount; iCount++)
{
LVITEM lvItem;
TCHAR lpszBuffer[_MAX_PATH + 1];
SIZE sizeLVText;
// ensure also extra space if column have and image inside
lvItem.mask = LVIF_TEXT | LVIF_IMAGE;
lvItem.pszText = lpszBuffer;
lvItem.cchTextMax = _MAX_PATH + 1;
lvItem.iItem = iCount;
lvItem.iSubItem = sColIndex;
lvItem.iImage = -1;
if(ListView_GetItem(hwndLV, &lvItem))
{
if(GetTextExtentPoint32(hLVDC, lpszBuffer, _tcslen(lpszBuffer), &sizeLVText))
{
if(lvItem.iImage >= 0) // also has image
{
if(nMaxWidth < sizeLVText.cx + nIconSize)
nMaxWidth = sizeLVText.cx + nIconSize;
}
else
{
if(nMaxWidth < sizeLVText.cx)
nMaxWidth = sizeLVText.cx;
}
}
}
}
}
ReleaseDC(hwndLV, hLVDC);
// last test: need header greater size?
{
HWND hwndHD;
hwndHD = ListView_GetHeader(hwndLV);
if(hwndHD)
{
HDITEM hdItem;
TCHAR lpszHeaderText[_MAX_PATH + 1];
hdItem.mask = HDI_BITMAP | HDI_TEXT;
hdItem.pszText = lpszHeaderText;
hdItem.cchTextMax = _MAX_PATH + 1;
hdItem.hbm = 0;
if(Header_GetItem(hwndHD, sColIndex, &hdItem))
{
SIZE sizeHDText;
HDC hHDDC;
hHDDC = GetDC(hwndHD);
if(GetTextExtentPoint32(hHDDC, lpszHeaderText, _tcslen(lpszHeaderText), &sizeHDText))
{
// assume text only
nMaxHeaderWidth = sizeHDText.cx;
if(hdItem.hbm) // has bitmap
{
SIZE sizeBmp;
if(GetBitmapDimensionEx(hdItem.hbm, &sizeBmp))
nMaxHeaderWidth += sizeBmp.cx;
}
}
ReleaseDC(hwndHD, hHDDC);
}
}
}
if(nMaxWidth < nMaxHeaderWidth)
nMaxWidth = nMaxHeaderWidth;
// now, since we established the maximum string size inside column, ensure this new column size
return ListView_SetColumnWidth(hwndLV, sColIndex, nMaxWidth);
}
BOOL
ListView_EnsureAllColumnsVisible(HWND hwndLV)
{
short sCount, sColCount;
// ensure some conditions
// is a window?
if(!IsWindow(hwndLV))
return FALSE;
// is a listview?
{
TCHAR lpszLVClassName[_MAX_PATH + 1];
if(!GetClassName(hwndLV, lpszLVClassName, _MAX_PATH + 1) || (_tcsicmp(lpszLVClassName, WC_LISTVIEW) != 0))
return FALSE;
}
// is in report style?
if(!(GetWindowLong(hwndLV, GWL_STYLE) & LVS_REPORT))
return FALSE;
sColCount = ListView_GetColumnCount(hwndLV);
for(sCount = 0; sCount < sColCount; sCount++)
{
if(!ListView_EnsureColumnVisible(hwndLV, sCount))
return FALSE;
}
return TRUE;
}