⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gfxcategorymanager.cpp

📁 一个多线程的网络数据采集系统(客户端)
💻 CPP
字号:
// GfxCategoryManager.cpp: implementation of the CGfxCategoryManager class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "WspProcess.h"
#include "GfxCategoryManager.h"
#include "GfxListCtrl.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//初始化列表数据集目录
CGfxCategoryManager::CGfxCategoryManager()
{
	lMode = 0;

	pItems = NULL;
	iItems = 0;

	iCategory = 0; 
	pCategory = NULL;

	pCallBackOwner = NULL;
	m_fpCategoryFun = NULL;
	m_fpDaoCategoryFun = NULL;
}

//撤消列表数据集目录
CGfxCategoryManager::~CGfxCategoryManager()
{
	if (iItems > 0 && pItems) GlobalFree((HGLOBAL) pItems);
	if (iCategory && pCategory)
	{
		for (iCategory--; iCategory >= 0; iCategory --)
			pCategory[iCategory].Clear();

		GlobalFree((HGLOBAL)pCategory);
	}
}

//在列表数据集目录中查找指定目录项
int CGfxCategoryManager::FindCategory(const char * cText)
{
	for (long t = 0; t < iCategory; t++)
		if (pCategory[t].lKind == fcFixedTextCategory && lstrcmp(cText, pCategory[t].cCategory) == 0) return t;

	return -1;
}

int CGfxCategoryManager::FindCategory(const CTime tmTime)
{
	for (long t = 0; t < iCategory; t++)
		if (pCategory[t].lKind == fcTimeCategory && tmTime >= pCategory[t].tmFrom && tmTime < pCategory[t].tmTo) return t;

	return -1;
}

int CGfxCategoryManager::FindCategory(const double dbVal)
{
	for (long t = 0; t < iCategory; t++)
		if (pCategory[t].lKind == fcNumericCategory && dbVal >= pCategory[t].dbMin && dbVal < pCategory[t].dbMax) return t;

	return -1;
}

//在列表数据集目录中增加目录项
int CGfxCategoryManager::AddCategory(const char * cText, const char * cCategory)
{
	iCategory ++;
	if (iCategory > 1) 
		pCategory = (CGfxCategory *)GlobalReAlloc((HGLOBAL) pCategory, 
			sizeof(CGfxCategory) * (iCategory), GMEM_MOVEABLE|GMEM_ZEROINIT);
	else pCategory = (CGfxCategory *) GlobalAlloc(GPTR, sizeof(CGfxCategory));

	ASSERT(pCategory != NULL);

	pCategory[iCategory - 1].Init(cText, cCategory);

	if (iItems > 0)
	{
		pCategory[iCategory - 1].iItems = 0;
		pCategory[iCategory - 1].pItems = (long *) GlobalAlloc(GMEM_FIXED, sizeof(long) * iItems);
		ASSERT(pCategory[iCategory - 1].pItems);
	}

	return iCategory - 1;
}

int CGfxCategoryManager::AddCategory(const char * cText, const CTime tmFrom, const CTime tmTo)
{
	iCategory ++;
	if (iCategory > 1) pCategory = (CGfxCategory *) GlobalReAlloc((HGLOBAL) pCategory, sizeof(CGfxCategory) * (iCategory), GMEM_MOVEABLE|GMEM_ZEROINIT);
	else pCategory = (CGfxCategory *) GlobalAlloc(GPTR, sizeof(CGfxCategory));

	ASSERT(pCategory != NULL);

	pCategory[iCategory - 1].Init(cText, tmFrom, tmTo);

	if (iItems > 0)
	{
		pCategory[iCategory - 1].iItems = 0;
		pCategory[iCategory - 1].pItems = (long *) GlobalAlloc(GMEM_FIXED, sizeof(long) * iItems);
		ASSERT(pCategory[iCategory - 1].pItems);
	}

	return iCategory - 1;
}

int CGfxCategoryManager::AddCategory(const char * cText, const dbMin, const dbMax)
{
	iCategory ++;
	if (iCategory > 1) pCategory = (CGfxCategory *) GlobalReAlloc((HGLOBAL) pCategory, sizeof(CGfxCategory) * (iCategory), GMEM_MOVEABLE|GMEM_ZEROINIT);
	else pCategory = (CGfxCategory *) GlobalAlloc(GPTR, sizeof(CGfxCategory));

	ASSERT(pCategory != NULL);

	pCategory[iCategory - 1].Init(cText, dbMin, dbMax);

	if (iItems > 0)
	{
		pCategory[iCategory - 1].iItems = 0;
		pCategory[iCategory - 1].pItems = (long *) GlobalAlloc(GMEM_FIXED, sizeof(long) * iItems);
		ASSERT(pCategory[iCategory - 1].pItems);
	}

	return iCategory - 1;
}

//初始化当前目录项
void CGfxCategoryManager::CGfxCategory::Init(const char * _cText, const char * _cCategory)
{
	ASSERT(_cText != NULL && _cCategory != NULL);

	cText = new char[lstrlen(_cText) + 1];
	lstrcpy(cText, _cText);

	cCategory = new char[lstrlen(_cCategory) + 1];
	lstrcpy(cCategory, _cCategory);

	lKind = fcFixedTextCategory;
	iItems = 0;
	pItems = NULL;
	bExpanded = false;
}

void CGfxCategoryManager::CGfxCategory::Init(const char * _cText, const CTime _tmFrom, const CTime _tmTo)
{
	ASSERT(_cText != NULL);

	cText = new char[lstrlen(_cText) + 1];
	lstrcpy(cText, _cText);

	cCategory = NULL;

	tmFrom = _tmFrom;
	tmTo = _tmTo;

	lKind = fcTimeCategory;
	iItems = 0;
	pItems = NULL;
	bExpanded = false;
}

void CGfxCategoryManager::CGfxCategory::Init(const char * _cText, const double _dbMin, const double _dbMax)
{
	ASSERT(_cText != NULL);

	cText = new char[lstrlen(_cText) + 1];
	lstrcpy(cText, _cText);

	cCategory = NULL;

	dbMin = _dbMin;
	dbMax = _dbMax;

	lKind = fcNumericCategory;
	iItems = 0;
	pItems = NULL;
	bExpanded = false;
}

//清空当前目录项
void CGfxCategoryManager::CGfxCategory::Clear()
{
	if (cText) 
	{
		delete [] cText;
		cText = NULL;
	}
	if (cCategory) 
	{
		delete [] cCategory;
		cCategory = NULL;
	}
	if (pItems != NULL)
	{
		GlobalFree((HGLOBAL) pItems);
	}
	iItems = 0;
	pItems = NULL;
}

//在列表数据集目录中向索引为_iCategoryp的目录项添加一行信息
void CGfxCategoryManager::AddItemToCategory(const int _iCategory, const long dwData)
{
	ASSERT(_iCategory >= 0 && _iCategory < iCategory);
	pCategory[_iCategory].pItems[pCategory[_iCategory].iItems] = dwData;
	pCategory[_iCategory].iItems++;
}

/*
// Author: Keith Rule -- keithr@europa.com
//
// Copyright (c) 1995-1996, Keith Rule
// May be freely used provided this comment
// is included with the source and all derived
// versions of this source.
void StatusBarMessage(char* fmt, ...)
{
	if (AfxGetApp() != NULL && AfxGetApp()->m_pMainWnd != NULL) {
		char buffer[256];
		CStatusBar* pStatus = (CStatusBar*) 
			AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR);
		va_list argptr;
		va_start(argptr, fmt);
		vsprintf(buffer, fmt, argptr);
		va_end(argptr);
		if (pStatus != NULL) {
			pStatus->SetPaneText(0, buffer);
			pStatus->UpdateWindow();
		}
	}
}
*/

//建立列表数据集目录并建立列表(显示目录项)
void CGfxCategoryManager::SetupList(CGfxListCtrl * pList)
{
	if (iItems > 0 && pItems) 
	{
		GlobalFree((HGLOBAL) pItems);
		iItems = 0;
		pItems = NULL;
	}
	int t, max = pList->GetItemCount();
	if (max < 0) return;
	pItems = (long *) GlobalAlloc(GPTR, sizeof(long) * max);
	ASSERT(pItems);
	iItems = max;

	ASSERT(m_fpCategoryFun != NULL || m_fpDaoCategoryFun != NULL);

	//构建列表数据集目录(层叠式)
	if (m_fpCategoryFun)
	{
		for (t = 0; t < max; t++)
		{
			pItems[t] = pList->GetItemData(t);
			//void CSuperGrid1View::CategoryCallBack(CGfxCategoryManager * pCatMan, long & lData)
			(pCallBackOwner->*m_fpCategoryFun)(this, pItems[t]);
		}
	}
	else if (m_fpDaoCategoryFun)
	{
		for (t = 0; t < max; t++) pItems[t] = t;
		(pCallBackOwner->*m_fpDaoCategoryFun)(this);
	}

	//依列表数据集目录重新设置列表(显示目录项)
	InsertCategoryInList(pList);
}

//重置列表(只显示行不显示目录项)
void CGfxCategoryManager::ResetList(CGfxListCtrl * pList)
{
	pList->SetRedraw(false);
	//清空列表
	pList->DeleteAllItems();
	int t;
	//插入并设置列表数据集目录中的各行
	for (t = 0; t < iItems; t++)
		pList->SetItemData(pList->InsertItem(t, LPSTR_TEXTCALLBACK), pItems[t]);

	//清空各个目录项的行信息
	for (t = 0; t < iCategory; t++)
	{
		if (pCategory[t].iItems > 0 && pCategory[t].pItems != NULL) 
		{
			pCategory[t].iItems = 0;
			//应加上delete [] pCategory[t].pItems;
		}
	}

	//重绘列表
	pList->SetRedraw(true);
}

//判断列表项是否为列表数据集目录中的目录项(是则返回目录项索引,否则返回-1)
int CGfxCategoryManager::IsListItemACategory(DWORD dwData)
{
	for (int t = 0; t < iCategory; t++)
	{
		if (&pCategory[t] == (CGfxCategory *) dwData) return t;
	}
	return -1;
}

//依列表数据集目录重新设置列表(显示目录项)
void CGfxCategoryManager::InsertCategoryInList(CGfxListCtrl * pList)
{
	pList->SetRedraw(false);
	//清空列表
	pList->DeleteAllItems();

	int idx = 0;
	for (int t = 0; t < iCategory; t++)
	{
//		DWORD dw = t;
//		dw |= (1 << 31);
		//插入并设置目录项
		ASSERT(pCategory[t].cText);
		CString cs;
		cs.Format("Categoria: %s (%d element%c)", pCategory[t].cText, pCategory[t].iItems, pCategory[t].iItems == 1 ? 'o' : 'i');
		idx = pList->InsertItem(idx, cs);
		pList->SetItemData(idx, (DWORD) &pCategory[t]);
		idx ++;
		if (pCategory[t].bExpanded == true)
		{
			//插入并设置属于该目录项的行
			for (int x = 0; x < pCategory[t].iItems; x++)
			{
				idx = pList->InsertItem(idx, LPSTR_TEXTCALLBACK);
				pList->SetItemData(idx, pCategory[t].pItems[x]);
				idx ++;
			}
		}
	}
	//重绘列表
	pList->SetRedraw(true);
}

//向列表中插入属于索引为iCat的目录项(位于列表的第iIdx行)的所有行
void CGfxCategoryManager::FillCategoryItems(const int iCat, const int iIdx, CGfxListCtrl * pList)
{
	pList->SetRedraw(false);
	int idx = iIdx + 1;
	for (int t = 0; t < pCategory[iCat].iItems; t++)
	{
		idx = pList->InsertItem(idx, LPSTR_TEXTCALLBACK);
		pList->SetItemData(idx, pCategory[iCat].pItems[t]);
		idx ++;
	}
	pList->SetRedraw(true);
}

//从列表中删除属于索引为iCat的目录项(位于列表的第iIdx行)的所有行
void CGfxCategoryManager::RemoveCategoryItems(const int iCat, const int iIdx, CGfxListCtrl * pList)
{
	pList->SetRedraw(false);
	int max = pList->GetItemCount(), t;

	bool bLoop = true;
	DWORD dw;
	while (bLoop)
	{
		dw = pList->GetItemData(iIdx + 1);

		bool bIsCat = false;
		//判断当前条目是否为目录项
		for (t = 0; t < iCategory; t++)
		{
			if (&pCategory[t] == (CGfxCategory *) dw) 
			{
				bIsCat = true;
				break;
			}
		}

		//若为目录项将中止删除,否则从列表中删除此行
		if (bIsCat) bLoop = false;
		else
		{
			pList->DeleteItem(iIdx + 1);
			max --;
			if (iIdx + 1 >= max) bLoop = false;
		}

	}
	pList->SetRedraw(true);
}

//向列表数据集目录及列表(末尾)中插入一新行(新行数据lData)
int CGfxCategoryManager::InsertNewItem(CGfxListCtrl * pList, const long lData)
{
	int iResult = -1;

	//向列表数据集目录(末尾)中行数据数组添加新行数据lData
	iItems ++;
	if (iItems > 1) pItems = (long *) GlobalReAlloc((HGLOBAL) pItems, sizeof(long) * iItems, GMEM_MOVEABLE|GMEM_ZEROINIT);
	else pItems = (long *) GlobalAlloc(GPTR, sizeof(long));
	pItems[iItems-1] = lData;

	//记录插入前列表数据集目录中的目录项信息
	int * iOldCatTot = iCategory > 0 ? new int[iCategory] : NULL, t;

	for (t = 0; t < iCategory; t++)
	{
		iOldCatTot[t] = pCategory[t].iItems;

		if (pCategory[t].pItems != NULL) pCategory[t].pItems = (long *) GlobalReAlloc((HGLOBAL) pCategory[t].pItems, sizeof(long) * iItems, GMEM_MOVEABLE|GMEM_ZEROINIT);
		else pCategory[t].pItems = (long *) GlobalAlloc(GPTR, sizeof(long));
	}
	CGfxCategory * pOldCat = pCategory;
	int iOldCat = iCategory;

	//向列表数据集目录(末尾)中插入该新行(归入相应目录项)
	(pCallBackOwner->*m_fpCategoryFun)(this, pItems[iItems-1]);

	//在插入新行后依列表数据集目录中老目录项的更新来修改列表中对应目录条目的相关数据
	CGfxCategory * pNewCat = pCategory;

	LV_FINDINFO lfv;
	lfv.flags = LVFI_PARAM;
	if (pNewCat != pOldCat)
	{
		ASSERT(iOldCat != iCategory);
		for (t = 0; t < iOldCat; t++)
		{
			lfv.lParam = (long) &(pOldCat[t]);
			int idx = pList->FindItem(&lfv, -1);
			if (idx >= 0)
			{
				pList->SetItemData(idx, (long) &(pNewCat[t]));
			}
//			pNewCat += sizeof(CGfxCategory);
//			pOldCat += sizeof(CGfxCategory);
		}
	}

	//
	for (t = 0; t < iCategory; t++)
	{
		//若为新增目录项或此目录项包含的行数变更
		if (t >= iOldCat || iOldCatTot[t] != pCategory[t].iItems)
		{
			//查找此目录项所对应的列表条目的索引
			lfv.lParam = (long) &(pCategory[t]);
			int idx = pList->FindItem(&lfv, -1);
			if (idx >= 0)
			{
				//此目录项包含的行数变更
				CString cs;
				cs.Format("Categoria: %s (%d element%c)", pCategory[t].cText, pCategory[t].iItems, pCategory[t].iItems == 1 ? 'o' : 'i');
				pList->SetItemText(idx, 0, cs);
				CRect rcItem;
				pList->GetItemRect(idx, rcItem, LVIR_BOUNDS);
				//重绘此目录项条目
				pList->InvalidateRect(rcItem, false);
				//若此目录项为展开态,在列表(末尾)中插入新行
				if (pCategory[t].bExpanded == true)
				{
					//iResult = pList->InsertItem(idx + 1, LPSTR_TEXTCALLBACK);
					//此处我已作修改,避免了显示次序的不一致
					iResult = pList->InsertItem(idx + pCategory[t].iItems, LPSTR_TEXTCALLBACK);
					pList->SetItemData(iResult, lData);
				}
			}
			else
			{
				//此目录项为新增目录项
				ASSERT(pCategory[t].cText);
				CString cs;
				cs.Format("Categoria: %s (%d element%c)", pCategory[t].cText, pCategory[t].iItems, pCategory[t].iItems == 1 ? 'o' : 'i');
				idx = pList->InsertItem(pList->GetItemCount(), cs);
				pList->SetItemData(idx, (DWORD) &pCategory[t]);

				CRect rcItem;
//				pList->GetSubItemRect(idx, 0, rcItem);
//				rcItem.bottom ++;
//				rcItem.right ++;
//				pList->ValidateRect(rcItem);
				pList->GetItemRect(idx, rcItem, LVIR_BOUNDS);
				pList->InvalidateRect(rcItem, false);
			}
		}
	}

	if (iOldCatTot) delete [] iOldCatTot;

	return iResult;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -