//------------------------------------------------------------------------ //! 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); } }
//------------------------------------------------------------------------ //! 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); } } } }
//------------------------------------------------------------------------ //! 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; } }
//------------------------------------------------------------------------ //! 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; }
void CFeedIcoItemListCtrl::DrawGroupInfo(CDC & dcMem, const CRect & rectClip, const CRect & rectClient) { dcMem.SelectObject(&m_FontBold); if (thePrefs.GetWindowsVersion() >= _WINVER_VISTA_ ) { int n = GetGroupCount(); for(int i = 0 ; i < n; ++i) { CString strGroupCaption = GetGroupCaption( i ); CString strGroupTotals; if ( strGroupCaption == m_mapGroups.GetKeyAt(i) ) { const CSimpleArray<int>& groupRows = m_mapGroups.GetValueAt(i); strGroupTotals.Format(_T("(共%d个)"), groupRows.GetSize()); } LVGROUP lg = GetGroupInfoByIndex(i, LVGF_GROUPID); CRect rcGroup = GetRectbyGroupID(lg.iGroupId, LVGGR_HEADER); CRect rcIntersect; rcIntersect.IntersectRect(rectClip, rcGroup); //rcGroup.DeflateRect(0, 7);//缩小7像素高度 //rcGroup.OffsetRect(0, -7);//向上偏移7像素 if ( !rcIntersect.IsRectEmpty() ) { DrawGroup(dcMem, rcGroup, strGroupCaption, strGroupTotals); } #ifdef LVGS_COLLAPSIBLE // Maintain LVGS_COLLAPSIBLE state CRect rcDropDown(rcGroup.right - 20, rcGroup.top + 10, rcGroup.right - 5, rcGroup.bottom - 3); if (HasGroupState(i, LVGS_COLLAPSED)) { if (m_imageRss_Group_Drop_Up_Nor) { m_imageRss_Group_Drop_Up_Nor->Draw(dcMem, rcDropDown.left, rcDropDown.top); } } else if (HasGroupState(i, LVGS_NORMAL)) { if (m_imageRss_Group_Drop_Down_Nor) { m_imageRss_Group_Drop_Down_Nor->Draw(dcMem, rcDropDown.left, rcDropDown.top); } } #endif //CRect rcDropDown(rcGroup.right - 20, rcGroup.top + 7, rcGroup.right - 5, rcGroup.bottom - 3); //CRgn rgDropDown;//画圆角矩形 //rgDropDown.CreateRoundRectRgn( rcDropDown.left, rcDropDown.top, rcDropDown.right, rcDropDown.bottom, 3, 3 ); // //CBrush* brushFrame; //brushFrame = new CBrush( GetSysColor(COLOR_GRAYTEXT) ); //dcMem.FrameRgn(&rgDropDown,brushFrame,1,1);//画焦点边框 //delete brushFrame; } } else { if ( nGroupHeight == -1 ) { CRect rcFirstItem;//算法有待优化 GetItemRect(0, rcFirstItem, LVIR_BOUNDS); if ( !rcFirstItem.IsRectEmpty() ) { nGroupHeight = rcFirstItem.top; } }//计算group 高度 CFeedCatalogs & feedCatalogs = CFeedCatalogs::GetInstance(); //遍历Catlogs 获得每个一级分类的Start RssData[只要用第一个就行了....第一个向上偏移绘制] for ( CFeedCatalogs::iterator it = feedCatalogs.GetBegin(); it != feedCatalogs.GetEnd(); ++it ) { FeedCatalog & feedCatlog = it->second; if ( feedCatlog.IsTop() && feedCatlog.GetFeedCount() > 0 ) { CRssFeedBase* feedStart = feedCatlog.GetFirstFeed(); int nStartIndex = GetItemIndex( (CRssFeed*)feedStart );//确定第一个item位置 if ( nStartIndex > -1 ) { int nGroupID = GetGroupIDByItemIndex( nStartIndex ); CString strGroupCaption = GetGroupCaption( nGroupID ); CString strGroupTotals; const CSimpleArray<int>& groupRows = m_mapGroups.GetValueAt(nGroupID); strGroupTotals.Format(_T("(共%d个)"), groupRows.GetSize()); //strGroupTotals.Format(_T("(共 %n 个)"), GetGroupCount()); CRect itemRect; GetItemRect(nStartIndex, &itemRect, LVIR_BOUNDS); //根据item rect获得group rect CRect rcGroup(rectClient.left, itemRect.top - nGroupHeight, rectClient.right, itemRect.top - 6); CRect rtIntersect; rtIntersect.IntersectRect(rectClip, rcGroup); if ( !rtIntersect.IsRectEmpty() ) { DrawGroup(dcMem, rcGroup, strGroupCaption, strGroupTotals); } } } } } }