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

📄 gfxlistctrl.cpp

📁 一个多线程的网络数据采集系统(客户端)
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		{
			GetSubItemRect(i+1,iCol,rc);
			InvalidateRect(rc, true);
		}
	}
}

//
void CGfxListCtrl::OnInit()
{
	//保证列表控件为报表模式
	if ((GetStyle()&LVS_TYPEMASK) == LVS_REPORT)
	{
		//自定义标题控件子类化
		HWND hHead = ::GetDlgItem(m_hWnd,0);
		VERIFY(wndHeader.SubclassWindow(hHead));
		TRACE0("Header subclassed.\n");
		wndToolTip.Create(this);
		wndToolTip.ShowWindow(SW_HIDE);
		ModifyStyle(0,WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
	}
}

void CGfxListCtrl::OnPaint() 
{
	int iItemCount = GetItemCount();
	CRect rcAllLabels, rc;

	if (iItemCount > 0)
	{
		GetItemRect(0,rcAllLabels,LVIR_BOUNDS);
		if (dwFlag&fHighRowSelect)
		{
			if (rcAllLabels.right<m_cxClient)
			{
 				CPaintDC dc(this);
				CRect rcClip;
				dc.GetClipBox(rcClip);
				if (!rcClip.IsRectEmpty())
				{
					rcClip.left = min(rcAllLabels.right-1, rcClip.left);
					rcClip.right = m_cxClient;
					InvalidateRect(rcClip,FALSE);
				}
			}
		}
	}
	const MSG *msg = GetCurrentMessage();
	DefWindowProc( msg->message, msg->wParam, msg->lParam );

	if (iItemCount == 0)
	{
		GetClientRect(rc);
		CRect hrc;
		CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
		ASSERT(pHeader);
		pHeader->GetClientRect(hrc);
		rc.top += hrc.Height() + 2;
		rc.bottom += 20;
		CClientDC dc(this);
		COLORREF ocrt = dc.SetTextColor(GetSysColor(COLOR_GRAYTEXT));
		int obk = dc.SetBkMode(TRANSPARENT);
		CFont * oft = dc.SelectObject(&ftNormal);
		dc.FillSolidRect(rc, m_clrTextBk);
		dc.DrawText(CString("Nessun elemento presente nella lista"),rc, DT_SINGLELINE|DT_CENTER);
		dc.SelectObject(oft);
		dc.SetBkMode(obk);
		dc.SetTextColor(ocrt);
		if (dwFlag&fScrollBarAlways) EnableScrollBar(SB_HORZ, ESB_DISABLE_BOTH);
	}
	else 
	{
		if (dwFlag&fScrollBarAlways) 
		{
			CRect rcAllLabels;
			GetItemRect(0,rcAllLabels,LVIR_BOUNDS);
			EnableScrollBar(SB_HORZ, rcAllLabels.Width() < m_cxClient ? ESB_DISABLE_BOTH : ESB_ENABLE_BOTH);
		}
	}
}

//确定点击位置所在的行索引和对应的列索引
int CGfxListCtrl::HitTestEx(CPoint & point, int * col) const
{
	int colnum = 0;
	int row = HitTest(point, NULL);
	
	if (col) *col = 0;

	//确定列表视图控件为LVS_REPORT风格
	if ((GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT) return row;
	
	//得到最顶端和最低端的的可见行
	row = GetTopIndex();
	int bottom = row + GetCountPerPage();
	if (bottom > GetItemCount()) bottom = GetItemCount();
	int nColumnCount = GetColumnCount();
	for( ;row <=bottom;row++)//row < bottom
	{
		CRect rect;
		GetItemRect(row, &rect, LVIR_BOUNDS);
		if (rect.PtInRect(point))
		{
			for (colnum = 0; colnum < nColumnCount; colnum++)
			{
				int colwidth = GetColumnWidth(colnum);
				if (point.x >= rect.left && point.x <= (rect.left + colwidth))
				{
					if (col) *col = colnum;
					return row;
				}
				rect.left += colwidth;
			}
		}
	}
	return -1;
}

void CGfxListCtrl::OnLButtonUp(UINT nFlags, CPoint point) 
{
	CListCtrl::OnLButtonUp(nFlags, point);
}

// 创建组合框控件以编辑指定条目子项
CGfxInCombo * CGfxListCtrl::ComboSubLabel(int nItem, int nCol, bool bEditable, bool bClick)
{
	//使用行和列索引,并在创建组合框控件前使指定条目子项可见,然后以合适的尺寸和文本调整创建组合框控件
	
	//保证条目可见
	if (!EnsureVisible(nItem, TRUE)) return NULL;

	////保证条目子项可见
	EnsureSubItemVisible(nCol);
	//if(!EnsureSubItemVisible(nCol)) return NULL;
	
	int nColumnCount = GetColumnCount();
	int iColWidth = GetColumnWidth(nCol);
	if (nCol >= nColumnCount || iColWidth < 5) return NULL;

	int offset = 0;
	for (int i = 0; i < nCol; i++) offset += GetColumnWidth(i);

	CRect rect;
	GetItemRect(nItem, &rect, LVIR_BOUNDS);
	rect.bottom -= iAutoPreviewHeight;
	rect.top ++;
	rect.bottom -= 2;

	CRect rcClient;
	GetClientRect(&rcClient);
	LV_COLUMN lvcol;
	lvcol.mask = LVCF_FMT;
	GetColumn(nCol, &lvcol);
	DWORD dwStyle = 0;

	//enum { OFFSET_FIRST = 2, OFFSET_OTHER = 6 };
	rect.left += offset+OFFSET_OTHER;//+4;
	rect.right = rect.left + GetColumnWidth(nCol)- OFFSET_OTHER;// - 3 ;
	if (rect.right > rcClient.right) rect.right = rcClient.right;

	dwStyle |= WS_CHILD|WS_VISIBLE;


	LXHDREX	lxhd;

	lxhd.iNotifyCode = NTEX_COMBOREQUEST;
	lxhd.CtrlId = iCtrlId < 0 ? GetDlgCtrlID() : iCtrlId;
	lxhd.iItem = nItem;
	lxhd.iSubItem = GetColumnIndex(nCol);
	lxhd.dwFlag = 0;
	lxhd.dwItemData = GetItemData(nItem);
	lxhd.dwMask = LXHDREX::exComboArray;

	GetItemTextEx(nItem, nCol, lxhd.csText, &(lxhd.dwItemData));

	lxhd.pComboArray = new CStringArray;
	ASSERT(lxhd.pComboArray);
	if (!SendInfoExMsg(&lxhd))
	{
		ASSERT(lxhd.pComboArray);
		delete lxhd.pComboArray;
		return NULL;
	}

	CGfxInCombo * pCombo = new CGfxInCombo(nItem, nCol, lxhd.csText, lxhd.pComboArray, bEditable, bClick);

	pCombo->bLightBorder = pCategoryManager == NULL;

	if (dwFlag&fExInfo)
	{
		lxhd.iNotifyCode = NTEX_ITEMINFO;

		CWnd * pWnd = GetReciper();
		if (SendInfoExMsg(&lxhd))
		{
			//设置组合框控件字体
			if (lxhd.dwFlag&LXHDREX::exHFont) pCombo->hFontHandle = lxhd.hfText;
			else if (lxhd.dwFlag&LXHDREX::exBold) pCombo->hFontHandle = (HFONT) ftBold.GetSafeHandle();
			else if (lxhd.dwFlag&LXHDREX::exItalic) pCombo->hFontHandle = (HFONT) ftItalic.GetSafeHandle();
			else if (lxhd.dwFlag&LXHDREX::exUnderline) pCombo->hFontHandle = (HFONT) ftUnderline.GetSafeHandle();
			else pCombo->hFontHandle = (HFONT) ftNormal.GetSafeHandle();

			//设置组合框控件文本颜色
			if (lxhd.dwFlag&LXHDREX::exTextColor) pCombo->crColor = lxhd.crText;
		}
	}
	// defie IDC_IPEDIT as you want; is a control id
	pCombo->Create(dwStyle, rect, this, IDC_IPEDIT);

	return pCombo;
}

// 创建编辑控件以编辑行索引为nItem、列索引为nCol的列表单元
//(bClick=flase表示在编辑控件中全选被编辑文本,bClick=true表示在编辑控件中不选任何内容)
CRichEditCtrl * CGfxListCtrl::EditSubLabel(int nItem, int nCol, bool bClick)
{
	//使用行和列索引,并在创建编辑控件前使指定列表单元可见,然后以合适的尺寸和文本调整创建编辑控件
	
	//保证行可见
	if (!EnsureVisible(nItem, TRUE)) return NULL;

	//保证列可见
	EnsureSubItemVisible(nCol);
	//if(!EnsureSubItemVisible(nCol)) return NULL;
    
	int nColumnCount = GetColumnCount();
	int iColWidth = GetColumnWidth(nCol);
	if (nCol >= nColumnCount || iColWidth < 5) return NULL;

	int offset = 0;
	for (int i = 0; i < nCol; i++) offset += GetColumnWidth(i);

	CRect rect;
	GetItemRect(nItem, &rect, LVIR_BOUNDS);

	rect.bottom -= iAutoPreviewHeight;

	rect.top ++;
	rect.bottom -= 2;

	CRect rcClient;
	GetClientRect(&rcClient);

	//得到列的对齐方式设置列表单元编辑控件风格
	LV_COLUMN lvcol;
	lvcol.mask = LVCF_FMT;
	GetColumn(nCol, &lvcol);
	DWORD dwStyle = WS_CHILD|WS_VISIBLE;
	if ((lvcol.fmt&LVCFMT_JUSTIFYMASK) == LVCFMT_LEFT) dwStyle |= ES_LEFT;//why not ES_LEFT|ES_MULTILINE
	else if ((lvcol.fmt&LVCFMT_JUSTIFYMASK) == LVCFMT_RIGHT) dwStyle |= ES_RIGHT|ES_MULTILINE;
	else dwStyle |= ES_CENTER|ES_MULTILINE;

	//enum { OFFSET_FIRST = 2, OFFSET_OTHER = 6 };
	rect.left += offset+OFFSET_OTHER;//+4;
	rect.right = rect.left + GetColumnWidth(nCol)- OFFSET_OTHER- OFFSET_OTHER;// - 3 ;
	if (rect.right > rcClient.right) rect.right = rcClient.right;

	DWORD dwData = GetItemData(nItem);

	//获取指定列表单元的文本
	CString csItem;
	GetItemTextEx(nItem, nCol, csItem, &dwData);

    //在指定位置上创建编辑控件
	CRichEditCtrl *pEdit = new CGfxInEdit(nItem, nCol, csItem, bClick);
	pEdit->Create(dwStyle, rect, this, IDC_IPEDIT);

	//设置列表单元编辑控件属性
	LXHDREX	lxhd;

	if (dwFlag&fExInfo)
	{
		lxhd.iNotifyCode = NTEX_ITEMINFO;
		lxhd.CtrlId = iCtrlId < 0 ? GetDlgCtrlID() : iCtrlId;
		lxhd.iItem = nItem;
		lxhd.iSubItem = GetColumnIndex(nCol);
		lxhd.dwFlag = 0;
		lxhd.dwItemData = dwData;

		//获取列表单元附属信息已设置编辑控件
		if (SendInfoExMsg(&lxhd))
		{
			//设置列表单元编辑控件文本字体
			if (lxhd.dwFlag&LXHDREX::exHFont) pEdit->SendMessage(WM_SETFONT, (WPARAM) lxhd.hfText, MAKELPARAM(FALSE, 0));
			else if (lxhd.dwFlag&LXHDREX::exBold) pEdit->SendMessage(WM_SETFONT, (WPARAM) ftBold.GetSafeHandle(), MAKELPARAM(FALSE, 0));
			else if (lxhd.dwFlag&LXHDREX::exItalic) pEdit->SendMessage(WM_SETFONT, (WPARAM) ftItalic.GetSafeHandle(), MAKELPARAM(FALSE, 0));
			else if (lxhd.dwFlag&LXHDREX::exUnderline) pEdit->SendMessage(WM_SETFONT, (WPARAM) ftUnderline.GetSafeHandle(), MAKELPARAM(FALSE, 0));
			else pEdit->SendMessage(WM_SETFONT, (WPARAM) ftNormal.GetSafeHandle(), MAKELPARAM(FALSE, 0));

			//设置列表单元编辑控件文本颜色
			if (lxhd.dwFlag&LXHDREX::exTextColor) 
			{
				CHARFORMAT chf;
				chf.cbSize = sizeof(CHARFORMAT);
				chf.crTextColor = lxhd.crText;
				chf.dwMask = CFM_COLOR;

				CHARRANGE cr;
				pEdit->GetSel(cr);

				pEdit->SetSel(0,-1);
				pEdit->SetDefaultCharFormat(chf);
				pEdit->SetSelectionCharFormat(chf);

				pEdit->SetSel(cr);
			}
		}
	}
	return pEdit;
}

//处理在列表控件中对列表单元的单击
void CGfxListCtrl::OnClick(NMHDR* pNMHDR, LRESULT* pResult) 
{
	if (GetFocus() != this) SetFocus();

	//获取焦点的屏幕坐标,并将其转换为用户坐标
	CPoint point;
	GetCursorPos(&point);
	ScreenToClient(&point);

	int index, colnum;
	if ((index = HitTestEx(point, &colnum)) != -1)
	{
		int cate = -1;
		if (pCategoryManager != NULL) 
		{
			//列表为折叠展开态
			cate = pCategoryManager->IsListItemACategory(GetItemData(index));
			if (cate >= 0)
			{
				//此条目为目录项条目
				if (colnum == 0)
				{
					//点击了目录项条目的折叠展开按钮
					if (pCategoryManager->pCategory[cate].bExpanded)
					{
						//折叠此目录项
						pCategoryManager->RemoveCategoryItems(cate, index, this);
						CRect rcAllLabels;
						GetItemRect(index,rcAllLabels,LVIR_BOUNDS);
						CRect rc;
						GetClientRect(&rc);
						if (rc.right > rcAllLabels.right)
						{
							rc.left = rcAllLabels.right;
							rc.top = rcAllLabels.bottom;
							InvalidateRect(rc, true);
						}						
					}
					else
					{
						//展开此目录项
						pCategoryManager->FillCategoryItems(cate, index, this);
					}

					//设置此目录项的展开标志
					pCategoryManager->pCategory[cate].bExpanded = !(pCategoryManager->pCategory[cate].bExpanded);

					//重绘此目录项条目
					CRect rcLittleBox;
					GetSubItemRect(index, 0, rcLittleBox);
					rcLittleBox.bottom ++;
					rcLittleBox.right ++;
					InvalidateRect(rcLittleBox, false);

					if (dwFlag&fScrollBarAlways) 
					{
						//列表控件具有滚动风格
						
						//显示水平和垂直滚动条
						ShowScrollBar(SB_BOTH);
						int iPageItem = GetCountPerPage();
						int iItemCount = GetItemCount();
						if (iItemCount < iPageItem) EnableScrollBar(SB_VERT, ESB_DISABLE_BOTH);//禁止垂直滚动条上的2个箭头按钮
						else EnableScrollBar(SB_VERT, ESB_ENABLE_BOTH);//恢复垂直滚动条上的2个箭头按钮

						CRect rcAllLabels;
						GetItemRect(0,rcAllLabels,LVIR_BOUNDS);

						//禁止或恢复水平滚动条上的2个箭头按钮
						EnableScrollBar(SB_HORZ, rcAllLabels.Width() < m_cxClient ? ESB_DISABLE_BOTH : ESB_ENABLE_BOTH);
					}

					*pResult = 1;
					return;
				}
			}
		}


		if (iSubItemFocus != colnum)
		{
			CRect src;
			GetSubItemRect(index, iSubItemFocus, src);
			InvalidateRect(src);
			iSubItemFocus = colnum;
			GetSubItemRect(index, iSubItemFocus, src);
			InvalidateRect(src);
		}
		UINT flag = LVIS_FOCUSED;
		if ((GetItemState(index, flag) & flag) == flag)
		{
			if (cate < 0)
			{
				//此条目非目录项条目
				int irealcol = GetColumnIndex(colnum);
				//此行可用编辑框编辑则就地生成编辑框对子项进行编辑;
				//此行可用组合框编辑则就地生成组合框对子项进行编辑;
				//此行可用组合框编辑则就地生成组合框对子项进行编辑;
				if (dwhEdit&(1 << irealcol)) EditSubLabel(index, colnum);
				else if (dwhCombo&(1 << irealcol)) ComboSubLabel(index, colnum);
				else if (dwhComboEx&(1 << irealcol)) ComboSubLabel(index, colnum, true);
			}
		}
		else 
		{
			SetItemState(index, LVIS_SELECTED | LVIS_FOCUSED , LVIS_SELECTED | LVIS_FOCUSED);
		}
	}
	
	*pResult = 1;
}

//处理LVN_ENDLABELEDIT通告以便使编辑框编辑的结果被接受,并更新列表控件的显示
void CGfxListCtrl::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
	LV_ITEM	*plvItem = &pDispInfo->item;
	*pResult = 0;

	if (plvItem->pszText == NULL) return;
	//debug
/*	CString str11;
	str11.Format("%s and %d", ((dwFlag & fAllowMultiChange) ? "multi" : "single"), GetSelectedCount());
	AfxMessageBox(str11);*/
	//debug

	if (dwFlag & fAllowMultiChange && GetSelectedCount() > 1)
	{
		//若允许多行编辑且有多行被编辑
		{
			LXHDREX	lxhd;
			lxhd.iNotifyCode = NTEX_SETTEXT;
			lxhd.CtrlId = iCtrlId < 0 ? GetDlgCtrlID() : iCtrlId;
			lxhd.dwFlag = 0;
			int idx = GetNextItem(-1, LVNI_SELECTED);
			while (idx >= 0)
			{
				lxhd.iItem = idx;
				lxhd.iSubItem = GetColumnIndex(plvItem->iSubItem);
				lxhd.dwItemData = GetItemData(idx);
				lxhd.csText = plvItem->pszText;
				
				if (SendInfoExMsg(&lxhd)) ModifyItemEx(lxhd.iItem, plvItem->iSubItem, lxhd.dwItemData, lxhd.csText);
				else ModifyItemEx(lxhd.iItem, plvItem->iSubItem, lxhd.dwItemData);

				idx = GetNextItem(idx, LVNI_SELECTED);
			}
			SetFocus();
			return;
		}
	}
	if (plvItem->pszText != NULL)
	{
		LXHDREX	lxhd;
		lxhd.iNotifyCode = NTEX_SETTEXT;

⌨️ 快捷键说明

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