📄 supergridctrl.cpp
字号:
CRect rect;
int offset = 0;
if(!EnsureVisible(nItem, TRUE))
return NULL;
#if _MSC_VER >= 1200
GetSubItemRect(nItem, nCol, LVIR_BOUNDS, rect);
#else
for( int i = 0; i < nCol; i++ )
offset += GetColumnWidth(i);
GetItemRect(nItem, &rect, LVIR_BOUNDS);
#endif
// Now scroll if we need to expose the column
CRect rcClient;
GetClientRect(rcClient);
if( offset + rect.left < 0 || offset + rect.left > rcClient.right )
{
CSize size(offset + rect.left,0);
Scroll(size);
rect.left -= size.cx;
}
rect.left += offset;
rect.right = rect.left + GetColumnWidth(nCol);
if(rect.right > rcClient.right)
rect.right = rcClient.right;
// Get Column alignment
LV_COLUMN lvcol;
lvcol.mask = LVCF_FMT;
GetColumn(nCol, &lvcol);
DWORD dwStyle;
if((lvcol.fmt & LVCFMT_JUSTIFYMASK) == LVCFMT_LEFT)
dwStyle = ES_LEFT;
else if((lvcol.fmt & LVCFMT_JUSTIFYMASK) == LVCFMT_RIGHT)
dwStyle = ES_RIGHT;
else
dwStyle = ES_CENTER;
dwStyle |=WS_BORDER|WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL;
CEdit *pEdit = new CListEditCtrl(nItem, nCol, GetItemText(nItem, nCol));
pEdit->Create(dwStyle, rect, this, IDC_EDITCTRL);
//pEdit->ModifyStyleEx(0,WS_EX_CLIENTEDGE); //funny thing happend here, uncomment this,
//and then edit an item,
//enter a long text so that the ES_AUTOHSCROLL comes to rescue
//yes that's look funny, ???.
return pEdit;
}
*/
/*
void CSuperGridCtrl::OnUpdateListViewItem(CTreeItem* lpItem, LV_ITEM *plvItem)
{
//default implementation you would go for this 9 out of 10 times
CItemInfo *lp = GetData(lpItem);
CString str = (CString)plvItem->pszText;
if(lp!=NULL)
{
if(plvItem->iSubItem==0)
lp->SetItemText(str);
else //subitem data
lp->SetSubItemText(plvItem->iSubItem-1, str);
UpdateData(lpItem, lp);
}
SetItemText(plvItem->iItem, plvItem->iSubItem, plvItem->pszText);
}*/
/*
void CSuperGridCtrl::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO *plvDispInfo = (LV_DISPINFO*)pNMHDR;
LV_ITEM *plvItem = &plvDispInfo->item;
if (plvItem->pszText != NULL)
{
if(plvItem->iItem!=-1)
{
CTreeItem*pSelItem = reinterpret_cast<CTreeItem*>(GetItemData(plvItem->iItem));
if(pSelItem!=NULL)
{
OnUpdateListViewItem(pSelItem, plvItem);
}
}
}
*pResult = 0;
}
*/
int CSuperGridCtrl::GetNumCol()
{
CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
return pHeader ? pHeader->GetItemCount() : 0;
}
//Think Rex Myer is spooking here
void CSuperGridCtrl::MakeColumnVisible(int nCol)
{
if(nCol < 0)
return;
// Get the order array to total the column offset.
CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
int nColCount = pHeader->GetItemCount();
ASSERT( nCol < nColCount);
int *pOrderarray = new int[nColCount];
Header_GetOrderArray(pHeader->m_hWnd, nColCount, pOrderarray);
// Get the column offset
int offset = 0;
for(int i = 0; pOrderarray[i] != nCol; i++)
offset += GetColumnWidth(pOrderarray[i]);
int colwidth = GetColumnWidth(nCol);
delete[] pOrderarray;
CRect rect;
GetItemRect(0, &rect, LVIR_BOUNDS);
// Now scroll if we need to show the column
CRect rcClient;
GetClientRect(&rcClient);
if(offset + rect.left < 0 || offset + colwidth + rect.left > rcClient.right)
{
CSize size(offset + rect.left,0);
Scroll(size);
InvalidateRect(NULL);
UpdateWindow();
}
}
//Think Rex Myer is spooking here
int CSuperGridCtrl::IndexToOrder( int iIndex )
{
// This translates a column index value to a column order value.
CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
int nColCount = pHeader->GetItemCount();
int *pOrderarray = new int[nColCount];
Header_GetOrderArray(pHeader->m_hWnd, nColCount, pOrderarray);
for(int i=0; i<nColCount; i++)
{
if(pOrderarray[i] == iIndex )
{
delete[] pOrderarray;
return i;
}
}
delete[] pOrderarray;
return -1;
}
COLORREF CSuperGridCtrl::GetCellRGB()
{
return RGB(192,0,0);
}
//insert item and return new parent pointer.
CSuperGridCtrl::CTreeItem* CSuperGridCtrl::InsertItem(CTreeItem *pParent, CItemInfo* lpInfo, BOOL bUpdate)
{
CTreeItem *pItem;
pItem = new CTreeItem();
if(lpInfo==NULL)
lpInfo = new CItemInfo;
UpdateData(pItem, lpInfo);
SetIndent(pItem, GetIndent(pParent)+1);
SetParentItem(pItem, pParent);
//add as the last child
pParent->m_listChild.AddTail(pItem);
if (!IsCollapsed(pParent))
bUpdate = TRUE;
if(!bUpdate)
Hide(pParent, TRUE);
else
{
int nIndex = NodeToIndex(pItem);
LV_ITEM lvItem;
lvItem.mask = LVIF_TEXT | LVIF_INDENT | LVIF_PARAM;
lvItem.pszText = LPSTR_TEXTCALLBACK;//str.GetBuffer(1);
//lvItem.pszText = pItem->m_lpNodeInfo->m_pFolder->m_strFolderName.GetBuffer(1);
//insert item
lvItem.iItem = nIndex;
lvItem.iSubItem = 0;
lvItem.lParam = (LPARAM)pItem;
lvItem.iIndent = GetIndent(pItem);
CListCtrl::InsertItem(&lvItem);
//::PostMessage(m_hWnd, LVM_INSERTITEM, 0, (LPARAM)&lvItem);
InternaleUpdateTree();//better do this
}
return pItem;
}
void CSuperGridCtrl::InternaleUpdateTree()
{
int nItems = GetItemCount();
for(int nItem=0; nItem < nItems; nItem++)
{
CTreeItem* pItem = reinterpret_cast<CTreeItem*>(GetItemData(nItem));
SetCurIndex(pItem, nItem);
}
}
int CSuperGridCtrl::NodeToIndex(CTreeItem *pNode)
{
int nStartIndex=0;
return _NodeToIndex(m_pRoot, pNode, nStartIndex);
}
void CSuperGridCtrl::DrawTreeItem(CDC* pDC, CTreeItem* pSelItem, int nListItem, const CRect& rcBounds)
{
int nColWidth = GetColumnWidth(0);
int nOffset = (rcBounds.Height() - m_cyImage) >> 1;
int yDown = rcBounds.top;
CPen psPen(PS_SOLID, 1, RGB(192,192,192));
CPen* pOldPen = pDC->SelectObject(&psPen);
int iIndent = GetIndent(pSelItem);
//setup plus/minus rectangle
int nHalfImage = (m_cxImage >> 1);
int nBottomDown = yDown + nHalfImage+nOffset;
SIZE right_bottom = {(m_cxImage>>1)+2+1, (m_cyImage>>1)+2+1};//from ANDY : the '+ 1' is to center the [+] or [-]
int left = rcBounds.left + GetIndent(pSelItem) * m_cxImage - nHalfImage;
int top = nBottomDown - (right_bottom.cy >> 1);
POINT left_top = {left - (right_bottom.cx >> 1), top};
//
BOOL bChild = ItemHasChildren(pSelItem);
BOOL bCollapsed = IsCollapsed(pSelItem);
//draw outline
while(m_pRoot != pSelItem)
{
CTreeItem* pParent = GetParentItem(pSelItem);
POSITION pos = pParent->m_listChild.GetTailPosition();
while(pos!=NULL)
{
CTreeItem *pLastChild = (CTreeItem*)pParent->m_listChild.GetPrev(pos);
int nIndex = GetCurIndex(pLastChild);
//no drawing outside the 1st columns right
int xLine = rcBounds.left + GetIndent(pLastChild) * m_cxImage - nHalfImage;
if(nIndex == nListItem && (GetIndent(pLastChild)==iIndent))
{
//draw '-
int x;
pDC->MoveTo(xLine, yDown);
pDC->LineTo(xLine, nBottomDown);
// -
xLine + nHalfImage > nColWidth ? x = nColWidth: x = xLine + nHalfImage;
pDC->MoveTo(xLine, nBottomDown);
pDC->LineTo(x, nBottomDown);
break;
}
else
if(nIndex > nListItem && (GetIndent(pLastChild)==iIndent))
{
//draw |-
int x;
xLine + nHalfImage > nColWidth ? x = nColWidth : x = xLine + nHalfImage;
pDC->MoveTo(xLine, nBottomDown);
pDC->LineTo(x, nBottomDown);
//-
pDC->MoveTo(xLine, yDown);
pDC->LineTo(xLine, rcBounds.bottom);
break;
}
else
if(nIndex > nListItem && (GetIndent(pLastChild) < iIndent))
{
//draw |
pDC->MoveTo(xLine, yDown);
pDC->LineTo(xLine, rcBounds.bottom);
break;
}
}
pSelItem = pParent;//next
}
//draw plus/minus sign
if(bChild)
{
//erase bkgrnd
CRect rc(left_top, right_bottom);
pDC->FillRect(rc, &CBrush(RGB(255,255,255)));
//draw rectangle
CPen psrect(PS_SOLID, 1, RGB(198,198,198));
CPen* pOldPen1 = pDC->SelectObject(&psrect);
pDC->Rectangle(rc);
pDC->SelectObject(pOldPen1);
//draw plus/minus sign
CPen psPen(PS_SOLID, 1, RGB(0,0,0));
CPen* pOldPen = pDC->SelectObject(&psPen);
int topdown = nBottomDown;
if(bCollapsed)
{
//plus
pDC->MoveTo(left, topdown-2);
pDC->LineTo(left, topdown+3);
//
pDC->MoveTo(left-2, topdown);
pDC->LineTo(left+3, topdown);
}
else {
//minus
pDC->MoveTo(left-2, topdown);
pDC->LineTo(left+3, topdown);
CPen psPen(PS_SOLID, 1, RGB(192,192,192));
CPen* pOldPen = pDC->SelectObject(&psPen);
int nOffset = (rcBounds.Height() - m_cyImage)/2;
pDC->MoveTo(left+ m_cxImage, rcBounds.top + m_cyImage+(nOffset/2));
pDC->LineTo(left + m_cxImage, rcBounds.bottom);
pDC->SelectObject(pOldPen);
}
pDC->SelectObject(pOldPen);
}
pDC->SelectObject(pOldPen);
}
BOOL CSuperGridCtrl::CreateTreeCtrl(CItemInfo* lpInfo)
{
CTreeItem* pRoot = NULL;
pRoot = new CTreeItem();
if(pRoot!=NULL)
{
if(lpInfo==NULL)//can't have this, if you didn't bother, I do.
lpInfo = new CItemInfo();
CleanMe(pRoot);
UpdateData(pRoot, lpInfo);
SetIndent(pRoot, 1);
SetCurIndex(pRoot, 0);
SetParentItem(pRoot, NULL);
CItemInfo* lp = GetData(pRoot);
LV_ITEM lvItem;
lvItem.mask = LVIF_TEXT | LVIF_INDENT | LVIF_PARAM;
//CString strItem = lp->GetItemText();
lvItem.pszText = LPSTR_TEXTCALLBACK;//strItem.GetBuffer(1);
lvItem.iItem = 0;
lvItem.lParam = (LPARAM)pRoot;
lvItem.iIndent = 1;
lvItem.iSubItem = 0;
//::PostMessage(m_hWnd, LVM_INSERTITEM, 0, (LPARAM)&lvItem);
CListCtrl::InsertItem(&lvItem);
/*
int nSize = lp->GetItemCount();
for(int i=0; i < nSize;i++)
{
CString str = lp->GetSubItem(i);
lvItem.mask = LVIF_TEXT;
lvItem.iSubItem = i+1;
lvItem.pszText = str.GetBuffer(1);
SetItem(&lvItem);
}*/
m_pRoot = pRoot;//store root ptr
return 1;
}
return 0;
}
//walk all over the place setting the hide/show flag of the nodes.
//it also deletes items from the listviewctrl.
void CSuperGridCtrl::HideChildren(CTreeItem *pItem, BOOL bHide,int nItem)
{
if(!IsCollapsed(pItem))
if (ItemHasChildren(pItem))
{
Hide(pItem, bHide);
POSITION pos = pItem->m_listChild.GetHeadPosition();
while (pos != NULL)
{
HideChildren((CTreeItem *)pItem->m_listChild.GetNext(pos),bHide,nItem+1);
DeleteItem(nItem);
}
}
}
void CSuperGridCtrl::Collapse(CTreeItem *pItem)
{
if(pItem != NULL && ItemHasChildren(pItem))
{
SetRedraw(0);
int nIndex = NodeToIndex(pItem);
HideChildren(pItem, TRUE, nIndex+1);
InternaleUpdateTree();
SetRedraw(1);
}
}
void CSuperGridCtrl::ExpandAll(CTreeItem *pItem, int& nScroll)
{
const int nChildren = pItem->m_listChild.GetCount();
if (nChildren > 0)
{
int nIndex = NodeToIndex(pItem);
nScroll=Expand(pItem, nIndex);
}
POSITION pos = pItem->m_listChild.GetHeadPosition();
while (pos)
{
CTreeItem *pChild = (CTreeItem*)pItem->m_listChild.GetNext(pos);
ExpandAll(pChild, nScroll);
}
}
int CSuperGridCtrl::Expand(CTreeItem* pSelItem, int nIndex)
{
int nOld = nIndex;
if(/*ItemHasChildren(pSelItem) && */IsCollapsed(pSelItem))
{
LV_ITEM lvItem;
lvItem.mask = LVIF_INDENT;
lvItem.iItem = nIndex;
lvItem.iSubItem = 0;
lvItem.lParam=(LPARAM)pSelItem;
lvItem.iIndent = GetIndent(pSelItem);
SetItem(&lvItem);
Hide(pSelItem, FALSE);
//expand children
POSITION pos = pSelItem->m_listChild.GetHeadPosition();
while(pos != NULL)
{
CTreeItem* pNextNode = (CTreeItem*)pSelItem->m_listChild.GetNext(pos);
//CString str = GetData(pNextNode)->GetItemText();
LV_ITEM lvItem;
lvItem.mask = LVIF_TEXT | LVIF_INDENT | LVIF_PARAM;
lvItem.pszText = LPSTR_TEXTCALLBACK; //str.GetBuffer(1);
lvItem.iItem = nIndex + 1;
lvItem.iSubItem = 0;
lvItem.lParam=(LPARAM)pNextNode;
lvItem.iIndent = GetIndent(pSelItem)+1;
CListCtrl::InsertItem(&lvItem);
//::PostMessage(m_hWnd, LVM_INSERTITEM, 0, (LPARAM)&lvItem);
//if(GetData(pNextNode)->GetCheck())
// SetCheck(nIndex + 1);
//get subitems
/*
int nSize = GetData(pNextNode)->GetItemCount();
for(int i=0; i< nSize;i++)
{
CString str=GetData(pNextNode)->GetSubItem(i);
lvItem.mask = LVIF_TEXT;
lvItem.iSubItem = i+1;
lvItem.pszText=str.GetBuffer(1);
SetItem(&lvItem);
}*/
nIndex++;
}
}
InternaleUpdateTree();
EnsureVisible(nOld, FALSE);
return nIndex;
}
int CSuperGridCtrl::SelectNode(CTreeItem *pLocateNode)
{
if(pLocateNode==m_pRoot)
{
UINT uflag = LVIS_SELECTED | LVIS_FOCUSED;
SetItemState(0, uflag, uflag);
return 0;
}
int nSelectedItem=-1;
CTreeItem* pNode = pLocateNode;
CTreeItem* pTopLevelParent=NULL;
//Get top parent
while(1)
{
CTreeItem *pParent = GetParentItem(pLocateNode);
if(pParent==m_pRoot)
break;
pLocateNode = pParent;
}
pTopLevelParent = pLocateNode;
//Expand the folder
if(pTopLevelParent!=NULL)
{
SetRedraw(0);
CWaitCursor wait;
CTreeItem *pRoot = GetParentItem(pTopLevelParent);
if(IsCollapsed(pRoot))
Expand(pRoot,0);
ExpandUntil(pTopLevelParent, pNode);
UINT uflag = LVIS_SELECTED | LVIS_FOCUSED;
nSelectedItem = NodeToIndex(pNode);
SetItemState(nSelectedItem, uflag, uflag);
SetRedraw(1);
EnsureVisible(nSelectedItem, TRUE);
}
return nSelectedItem;
}
void CSuperGridCtrl::ExpandUntil(CTreeItem *pItem, CTreeItem* pStopAt)
{
const int nChildren = pItem->m_listChild.GetCount();
if (nChildren > 0)
{
POSITION pos = pItem->m_listChild.GetHeadPosition();
while (pos)
{
CTreeItem *pChild = (CTreeItem*)pItem->m_listChild.GetNext(pos);
if(pChild==pStopAt)
{
int nSize = GetIndent(pChild);
CTreeItem** ppParentArray = new CTreeItem*[nSize];
int i=0;
while(1)
{
CTreeItem *pParent=GetParentItem(pChild);
if(pParent==m_pRoot)
break;
pChild = pParent;
ppParentArray[i] =pChild;
i++;
}
for(int x=i;x > 0; x--)
{
CTreeItem *pParent = ppParentArray[x-1];
Expand(pParent, NodeToIndex(pParent));
}
delete [] ppParentArray;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -