Esempio n. 1
0
//------------------------------------------------------------------------
//! Update the subtitle in the group header
//!
//! @param nGroupId ID of the group
//! @param strSubtitle The subtitle description text
//! @return Succeeded in updating the group subtitle
//------------------------------------------------------------------------
BOOL CGridListCtrlGroups::SetGroupSubtitle(int nGroupId, const CString& strSubtitle)
{
	if (!IsGroupStateEnabled())
		return FALSE;

#if _WIN32_WINNT >= 0x0600
	LVGROUP lg = {0};
	lg.cbSize = sizeof(lg);
	lg.mask = LVGF_SUBTITLE;
#ifdef UNICODE
	lg.pszSubtitle = (LPWSTR)(LPCTSTR)strSubtitle;
	lg.cchSubtitle = strSubtitle.GetLength();
#else
	CComBSTR bstrSubtitle = strSubtitle;
	lg.pszSubtitle = bstrSubtitle;
	lg.cchSubtitle = bstrSubtitle.Length();
#endif

	if (SetGroupInfo(nGroupId, (PLVGROUP)&lg)==-1)
		return FALSE;

	return TRUE;
#else
	return FALSE;
#endif
}
Esempio n. 2
0
//------------------------------------------------------------------------
//! Update the description text of the group footer
//!
//! @param nGroupId ID of the group
//! @param strFooter The footer description text
//! @param dwAlign Indicates the alignment of the footer text for the group
//! @return Succeeded in updating the group footer
//------------------------------------------------------------------------
BOOL CGridListCtrlGroups::SetGroupFooter(int nGroupId, const CString& strFooter, DWORD dwAlign)
{
	if (!IsGroupStateEnabled())
		return FALSE;

#if _WIN32_WINNT >= 0x0600
	LVGROUP lg = {0};
	lg.cbSize = sizeof(lg);
	lg.mask = LVGF_FOOTER | LVGF_ALIGN;
	lg.uAlign = dwAlign;
#ifdef UNICODE
	lg.pszFooter = (LPWSTR)(LPCTSTR)strFooter;
	lg.cchFooter = strFooter.GetLength();
#else
	CComBSTR bstrFooter = strFooter;
	lg.pszFooter = bstrFooter;
	lg.cchFooter = bstrFooter.Length();
#endif

	if (SetGroupInfo(nGroupId, (PLVGROUP)&lg)==-1)
		return FALSE;

	return TRUE;
#else
	return FALSE;
#endif
}
Esempio n. 3
0
//------------------------------------------------------------------------
//! Create a group for each unique values within a column
//!
//! @param nCol The index of the column
//! @return Succeeded in creating the group
//------------------------------------------------------------------------
BOOL CGridListCtrlGroups::GroupByColumn(int nCol)
{
	CWaitCursor waitCursor;

	SetSortArrow(-1, false);

	SetRedraw(FALSE);

	RemoveAllGroups();

	EnableGroupView( GetItemCount() > 0 );

	if (IsGroupViewEnabled())
	{
		CSimpleMap<CString,CSimpleArray<int> > groups;

		// Loop through all rows and find possible groups
		for(int nRow=0; nRow<GetItemCount(); ++nRow)
		{
			CString cellText = GetItemText(nRow, nCol);

			int nGroupId = groups.FindKey(cellText);
			if (nGroupId==-1)
			{
				CSimpleArray<int> rows;
				groups.Add(cellText, rows);
				nGroupId = groups.FindKey(cellText);
			}
			groups.GetValueAt(nGroupId).Add(nRow);
		}

		// Look through all groups and assign rows to group
		for(int nGroupId = 0; nGroupId < groups.GetSize(); ++nGroupId)
		{
			const CSimpleArray<int>& groupRows = groups.GetValueAt(nGroupId);
			DWORD dwState = LVGS_NORMAL;
#ifdef LVGS_COLLAPSIBLE
			if (IsGroupStateEnabled())
				dwState = LVGS_COLLAPSIBLE;
#endif
			VERIFY( InsertGroupHeader(nGroupId, nGroupId, groups.GetKeyAt(nGroupId), dwState) != -1);

			for(int groupRow = 0; groupRow < groupRows.GetSize(); ++groupRow)
			{
				VERIFY( SetRowGroupId(groupRows[groupRow], nGroupId) );
			}
		}

		SetRedraw(TRUE);
		Invalidate(FALSE);
		return TRUE;
	}

	SetRedraw(TRUE);
	Invalidate(FALSE);
	return FALSE;
}
Esempio n. 4
0
//------------------------------------------------------------------------
//! Update the image icon in the group header together with top and bottom
//! description. Microsoft encourage people not to use this functionality.
//!
//! @param nGroupId ID of the group
//! @param nImage Index of the title image in the control imagelist.
//! @param strTopDesc Description text placed oppposite of the image
//! @param strBottomDesc Description text placed below the top description
//! @return Succeeded in updating the group image
//------------------------------------------------------------------------
BOOL CGridListCtrlGroups::SetGroupTitleImage(int nGroupId, int nImage, const CString& strTopDesc, const CString& strBottomDesc)
{
	if (!IsGroupStateEnabled())
		return FALSE;

#if _WIN32_WINNT >= 0x0600
	LVGROUP lg = {0};
	lg.cbSize = sizeof(lg);
	lg.mask = LVGF_TITLEIMAGE;
	lg.iTitleImage = nImage;	// Index of the title image in the control imagelist.

#ifdef UNICODE
	if (!strTopDesc.IsEmpty())
	{
		// Top description is drawn opposite the title image when there is
		// a title image, no extended image, and uAlign==LVGA_HEADER_CENTER.
		lg.mask |= LVGF_DESCRIPTIONTOP;
		lg.pszDescriptionTop = (LPWSTR)(LPCTSTR)strTopDesc;
		lg.cchDescriptionTop = strTopDesc.GetLength();
	}
	if (!strBottomDesc.IsEmpty())
	{
		// Bottom description is drawn under the top description text when there is
		// a title image, no extended image, and uAlign==LVGA_HEADER_CENTER.
		lg.mask |= LVGF_DESCRIPTIONBOTTOM;
		lg.pszDescriptionBottom = (LPWSTR)(LPCTSTR)strBottomDesc;
		lg.cchDescriptionBottom = strBottomDesc.GetLength();
	}
#else
	CComBSTR bstrTopDesc = strTopDesc;
	CComBSTR bstrBottomDesc = strBottomDesc;
	if (!strTopDesc.IsEmpty())
	{
		lg.mask |= LVGF_DESCRIPTIONTOP;
		lg.pszDescriptionTop = bstrTopDesc;
		lg.cchDescriptionTop = bstrTopDesc.Length();
	}
	if (!strBottomDesc.IsEmpty())
	{
		lg.mask |= LVGF_DESCRIPTIONBOTTOM;
		lg.pszDescriptionBottom = bstrBottomDesc;
		lg.cchDescriptionBottom = bstrBottomDesc.Length();
	}
#endif

	if (SetGroupInfo(nGroupId, (PLVGROUP)&lg)==-1)
		return FALSE;

	return TRUE;
#else
	return FALSE;
#endif
}
Esempio n. 5
0
//------------------------------------------------------------------------
//! The framework calls this member function when the user double-clicks
//! the left mouse button. Used to expand and collapse groups when group
//! header is clicked.
//!
//! @param nFlags Indicates whether various virtual keys are down (MK_CONTROL, MK_SHIFT, etc.)
//! @param point Specifies the x- and y-coordinate of the cursor relative to the upper-left corner of the window.
//------------------------------------------------------------------------
void CGridListCtrlGroups::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	CGridListCtrlEx::OnLButtonDblClk(nFlags, point);

	if (!IsGroupStateEnabled())
		return;
	
	int nGroupId = GroupHitTest(point);
	if (nGroupId!=-1)
	{
		if (HasGroupState(nGroupId, LVGS_COLLAPSED))
			SetGroupState(nGroupId, LVGS_NORMAL);
		else
			SetGroupState(nGroupId, LVGS_COLLAPSED);
	}
}
Esempio n. 6
0
//------------------------------------------------------------------------
//! Expand all groups
//------------------------------------------------------------------------
void CGridListCtrlGroups::ExpandAllGroups()
{
	if (!IsGroupStateEnabled())
		return;

	// Loop through all rows and find possible groups
	for(int nRow=0; nRow<GetItemCount(); ++nRow)
	{
		int nGroupId = GetRowGroupId(nRow);
		if (nGroupId!=-1)
		{
			if (HasGroupState(nGroupId,LVGS_COLLAPSED))
			{
				SetGroupState(nGroupId,LVGS_NORMAL);
			}
		}
	}
}
Esempio n. 7
0
//------------------------------------------------------------------------
//! Override this method to change the context menu when activating context
//! menu for the group headers
//!
//! @param pWnd Handle to the window in which the user right clicked the mouse
//! @param point Position of the cursor, in screen coordinates, at the time of the mouse click.
//! @param nGroupId ID of the group
//------------------------------------------------------------------------
void CGridListCtrlGroups::OnContextMenuGroup(CWnd* pWnd, CPoint point, int nGroupId)
{
	CMenu menu;
	UINT uFlags = MF_BYPOSITION | MF_STRING;
	VERIFY( menu.CreatePopupMenu() );
	
	const CString& groupHeader = GetGroupHeader(nGroupId);

	// Provide menu-options for collapsing groups, if the collapsible state is not available
#ifndef LVGS_COLLAPSIBLE
	if (IsGroupStateEnabled())
	{
		if (HasGroupState(nGroupId,LVGS_COLLAPSED))
		{
			CString menuText = CString(_T("Expand group: ")) + groupHeader;
			menu.InsertMenu(0, uFlags, 1, menuText);
		}
		else
		{
			CString menuText = CString(_T("Collapse group: ")) + groupHeader;
			menu.InsertMenu(0, uFlags, 2, menuText);
		}
	}
#endif

	if (GetExtendedStyle() & LVS_EX_CHECKBOXES)
	{
		CString menuText = CString(_T("Check group: ")) + groupHeader;
		menu.InsertMenu(1, uFlags, 3, menuText);
		menuText = CString(_T("Uncheck group: ")) + groupHeader;
		menu.InsertMenu(2, uFlags, 4, menuText);
	}

	int nResult = menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RETURNCMD, point.x, point.y, this, 0);
	switch(nResult)
	{
		case 1: SetGroupState(nGroupId, LVGS_NORMAL); break;
		case 2: SetGroupState(nGroupId, LVGS_COLLAPSED); break;
		case 3: CheckEntireGroup(nGroupId, true); break;
		case 4: CheckEntireGroup(nGroupId, false); break;
	}
}
Esempio n. 8
0
//------------------------------------------------------------------------
//! Override this method to change the context menu when activating context
//! menu in client area with no rows
//!
//! @param pWnd Handle to the window in which the user right clicked the mouse
//! @param point Position of the cursor, in screen coordinates, at the time of the mouse click.
//------------------------------------------------------------------------
void CGridListCtrlGroups::OnContextMenuGrid(CWnd* pWnd, CPoint point)
{
	if (IsGroupStateEnabled())
	{
		CMenu menu;
		UINT uFlags = MF_BYPOSITION | MF_STRING;
		VERIFY( menu.CreatePopupMenu() );

		menu.InsertMenu(0, uFlags, 1, _T("Expand all groups"));
		menu.InsertMenu(1, uFlags, 2, _T("Collapse all groups"));
		menu.InsertMenu(2, uFlags, 3, _T("Disable grouping"));

		int nResult = menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RETURNCMD, point.x, point.y, this, 0);
		switch(nResult)
		{
			case 1: ExpandAllGroups(); break;
			case 2: CollapseAllGroups(); break;
			case 3: RemoveAllGroups(); EnableGroupView(FALSE); break;
		}
	}
}
Esempio n. 9
0
//------------------------------------------------------------------------
//! Updates the state of a group
//!
//! @param nGroupId ID of the group
//! @param dwState Specifies the new state of the group
//! @return The group state was updated (true / false)
//------------------------------------------------------------------------
BOOL CGridListCtrlGroups::SetGroupState(int nGroupId, DWORD dwState)
{
	// Vista SDK - ListView_SetGroupState / LVM_SETGROUPINFO
	if (!IsGroupStateEnabled())
		return FALSE;

	LVGROUP lg = {0};
	lg.cbSize = sizeof(lg);
	lg.mask = LVGF_STATE;
	lg.state = dwState;
	lg.stateMask = dwState;

#ifdef LVGS_COLLAPSIBLE
	// Maintain LVGS_COLLAPSIBLE state
	if (HasGroupState(nGroupId, LVGS_COLLAPSIBLE))
		lg.state |= LVGS_COLLAPSIBLE;
#endif

	if (SetGroupInfo(nGroupId, (PLVGROUP)&lg)==-1)
		return FALSE;

	return TRUE;
}
Esempio n. 10
0
//------------------------------------------------------------------------
//! Find the group-id below the given point
//!
//! @param point Mouse position
//! @return ID of the group
//------------------------------------------------------------------------
int CGridListCtrlGroups::GroupHitTest(const CPoint& point)
{
	if (!IsGroupViewEnabled())
		return -1;

	if (HitTest(point)!=-1)
		return -1;

	if (IsGroupStateEnabled())
	{
#if _WIN32_WINNT >= 0x0600
#ifdef ListView_HitTestEx
#ifdef LVHT_EX_GROUP
#ifdef ListView_GetGroupInfoByIndex
		LVHITTESTINFO lvhitinfo = {0};
		lvhitinfo.pt = point;
		ListView_HitTestEx(m_hWnd, &lvhitinfo);
		if ((lvhitinfo.flags & LVHT_EX_GROUP)==0)
			return -1;

		LVGROUP lg = {0};
		lg.cbSize = sizeof(lg);
		lg.mask = LVGF_GROUPID;
		VERIFY( ListView_GetGroupInfoByIndex(m_hWnd, lvhitinfo.iGroup, &lg) );
		return lg.iGroupId;
#endif
#endif
#endif
#endif
	}

	if (IsGroupStateEnabled())
	{
		// Running on Vista or newer, but compiled without _WIN32_WINNT >= 0x0600
#ifndef LVM_GETGROUPINFOBYINDEX
#define LVM_GETGROUPINFOBYINDEX   (LVM_FIRST + 153)
#endif
#ifndef LVM_GETGROUPCOUNT
#define LVM_GETGROUPCOUNT         (LVM_FIRST + 152)
#endif
#ifndef LVM_GETGROUPRECT
#define LVM_GETGROUPRECT          (LVM_FIRST + 98)
#endif
#ifndef LVGGR_HEADER
#define LVGGR_HEADER		      (1)
#endif

		LRESULT groupCount = SNDMSG((m_hWnd), LVM_GETGROUPCOUNT, (WPARAM)0, (LPARAM)0);
		if (groupCount <= 0)
			return -1;
		for(int i = 0 ; i < groupCount; ++i)
		{
			LVGROUP lg = {0};
			lg.cbSize = sizeof(lg);
			lg.mask = LVGF_GROUPID;

			VERIFY( SNDMSG((m_hWnd), LVM_GETGROUPINFOBYINDEX, (WPARAM)(i), (LPARAM)(&lg)) );

			CRect rect(0,LVGGR_HEADER,0,0);
			VERIFY( SNDMSG((m_hWnd), LVM_GETGROUPRECT, (WPARAM)(lg.iGroupId), (LPARAM)(RECT*)(&rect)) );

			if (rect.PtInRect(point))
				return lg.iGroupId;
		}
		// Don't try other ways to find the group
		return -1;
	}

	// We require that each group contains atleast one item
	if (GetItemCount()==0)
		return -1;

	// This logic doesn't support collapsible groups
	int nFirstRow = -1;
	CRect gridRect;
	GetWindowRect(&gridRect);
	for(CPoint pt = point ; pt.y < gridRect.bottom ; pt.y += 2)
	{
		nFirstRow = HitTest(pt);
		if (nFirstRow!=-1)
			break;
	}

	if (nFirstRow==-1)
		return -1;

	int nGroupId = GetRowGroupId(nFirstRow);

	// Extra validation that the above row belongs to a different group
	int nAboveRow = GetNextItem(nFirstRow,LVNI_ABOVE);
	if (nAboveRow!=-1 && nGroupId==GetRowGroupId(nAboveRow))
		return -1;

	return nGroupId;
}
Esempio n. 11
0
BOOL CFeedIcoItemListCtrl::GroupAllFeedsByType(int nType)
{
	if (!IsCommonControlsEnabled())
		return FALSE;

	SetRedraw(FALSE);

	RemoveAllGroups();
	RemoveAllGroupData();
	EnableGroupView( GetItemCount() > 0 );

	if (IsGroupViewEnabled())
	{
		// Loop through all rows and find possible groups
		for(int nItem = 0; nItem < GetItemCount(); nItem++ )
		{
			CString strCatalogName = GetResString( IDS_UNKNOWN );

			CRssFeed* pFeed = (CRssFeed*)GetItemData(nItem);

			if (pFeed == NULL)
				continue;

			if ( pFeed->m_uCatalogId != FeedCatalog::INVALID_CATALOG_ID )
			{
				FeedCatalog & catalog = CFeedCatalogs::GetInstance()[pFeed->m_uCatalogId];
				ASSERT(catalog.m_uId == pFeed->m_uCatalogId);
				ASSERT(catalog.IsLeaf());

				FeedCatalog * catalogParent;
				if (catalog.m_pParent != NULL)
				{
					catalogParent = catalog.m_pParent;
					strCatalogName = catalogParent->m_strName;
				}
			}

			int nGroupId = m_mapGroups.FindKey(strCatalogName);
			if (nGroupId == -1)
			{
				CSimpleArray<int> nItems;
				m_mapGroups.Add(strCatalogName, nItems);
				nGroupId = m_mapGroups.FindKey(strCatalogName);
			}

			//必须添加不重复数据
			if (m_mapGroups.GetValueAt(nGroupId).Find(nItem) == -1)
			{
				m_mapGroups.GetValueAt(nGroupId).Add(nItem);
			}
			
		}

		// Look through all groups and assign rows to group
		for(int nGroupId = 0; nGroupId < m_mapGroups.GetSize(); nGroupId++)
		{
			const CSimpleArray<int>& groupRows = m_mapGroups.GetValueAt(nGroupId);
			DWORD dwState = LVGS_NORMAL;

#ifdef LVGS_COLLAPSIBLE
			if (IsGroupStateEnabled())
				dwState = LVGS_COLLAPSIBLE;
#endif

			VERIFY( InsertTypeGroup(nGroupId, nGroupId, m_mapGroups.GetKeyAt(nGroupId), dwState) != -1);

			for(int groupRow = 0; groupRow < groupRows.GetSize(); ++groupRow)
			{
				VERIFY( SetItemGroupId(groupRows[groupRow], nGroupId) );
			}
		}

	}

	SetRedraw(TRUE);

	Invalidate(TRUE);
	return FALSE;
}
Esempio n. 12
0
BOOL CFeedIcoItemListCtrl::GroupFeedByType(int nIndex, int nType)
{
	if (!IsCommonControlsEnabled())
		return FALSE;

	SetRedraw(FALSE);

	EnableGroupView(TRUE);
	if (IsGroupViewEnabled())
	{
		CString cellText = GetResString( IDS_UNKNOWN );
		bool	bNew = false;//Is new Group?

		CRssFeed* pFeed = (CRssFeed*)GetItemData(nIndex);
		
		if (pFeed == NULL)
			return FALSE;

		if ( pFeed->m_uCatalogId != FeedCatalog::INVALID_CATALOG_ID )
		{
			FeedCatalog & catalog = CFeedCatalogs::GetInstance()[pFeed->m_uCatalogId];
			ASSERT(catalog.m_uId == pFeed->m_uCatalogId);
			ASSERT(catalog.IsLeaf());

			FeedCatalog * catalogParent;
			if (catalog.m_pParent != NULL)
			{
				catalogParent = catalog.m_pParent;
				cellText = catalogParent->m_strName;
			}
		}

		int nGroupId = m_mapGroups.FindKey(cellText);
		if (nGroupId == -1)
		{
			CSimpleArray<int> nItems;
			m_mapGroups.Add(cellText, nItems);
			nGroupId = m_mapGroups.FindKey(cellText);

			bNew = true;
		}

		//必须添加不重复数据
		if (m_mapGroups.GetValueAt(nGroupId).Find(nIndex) == -1)
		{
			m_mapGroups.GetValueAt(nGroupId).Add(nIndex);
		}

		if (bNew)//new Group
		{
			DWORD dwState = LVGS_NORMAL;

			#ifdef LVGS_COLLAPSIBLE
					if (IsGroupStateEnabled())
						dwState = LVGS_COLLAPSIBLE;
			#endif

			//InsertTypeGroup(nGroupId, nGroupId, cellText, dwState);
			VERIFY(InsertTypeGroup(nGroupId, nGroupId, cellText, dwState) != -1);
		}

		VERIFY( SetItemGroupId(nIndex, nGroupId) );
	}

	SetRedraw(TRUE);
	Invalidate(TRUE);
	

	return FALSE;
}