Click here to Skip to main content
15,891,607 members
Articles / Programming Languages / C++

WindowsNT System Manager

Rate me:
Please Sign up or sign in to vote.
4.73/5 (8 votes)
30 Nov 19998 min read 90.3K   3.1K   40  
This article presents a comprehensive system control manager for NT
#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;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Romania Romania
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions