📄 supergridctrl.cpp
字号:
}
}
}
//hmmm
BOOL CSuperGridCtrl::DoDragDrop(CTreeItem* pTarget, CTreeItem* pSource)
{
if(pTarget==NULL)
return 0;
BOOL bUpdate=FALSE;
if(!IsCollapsed(pTarget))
bUpdate=TRUE; //children are expanded, want to see update right away
//make a copy of the source data
CItemInfo* lp = CopyData(GetData(pSource));
//create new node with the source data and make pTarget the parent
CTreeItem* pNewParent = InsertItem(pTarget, lp, bUpdate);
//if the source has children copy all source data and make the newly create item the parent
if(ItemHasChildren(pSource))
CopyChildren(pNewParent, pSource);
return 1;
}
void CSuperGridCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
//its not meself
if( GetFocus() != this)
SetFocus();
CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CSuperGridCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if( GetFocus() != this)
SetFocus();
CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
}
BOOL CSuperGridCtrl::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_KEYDOWN)
{
if(GetFocus()==this)
{
switch( pMsg->wParam )
{
case VK_LEFT:
{
// Decrement the order number.
m_CurSubItem--;
if(m_CurSubItem < 0)
m_CurSubItem = 0;
else{
CHeaderCtrl* pHeader = GetHeaderCtrl();
// Make the column visible.
// We have to take into account that the header may be reordered.
MakeColumnVisible( Header_OrderToIndex( pHeader->m_hWnd, m_CurSubItem));
// Invalidate the item.
int iItem = GetSelectedItem();
if( iItem != -1 )
{
CRect rcBounds;
GetItemRect(iItem, rcBounds, LVIR_BOUNDS);
InvalidateRect(&rcBounds);
UpdateWindow();
}
}
}
return TRUE;
case VK_RIGHT:
{
// Increment the order number.
m_CurSubItem++;
CHeaderCtrl* pHeader = GetHeaderCtrl();
int nColumnCount = pHeader->GetItemCount();
// Don't go beyond the last column.
if( m_CurSubItem > nColumnCount -1 )
m_CurSubItem = nColumnCount-1;
else
{
MakeColumnVisible(Header_OrderToIndex( pHeader->m_hWnd, m_CurSubItem));
int iItem = GetSelectedItem();
// Invalidate the item.
if( iItem != -1 )
{
CRect rcBounds;
GetItemRect(iItem, rcBounds, LVIR_BOUNDS);
InvalidateRect(&rcBounds);
UpdateWindow();
}
}
}
return TRUE;
case VK_RETURN://edit itemdata
{
BOOL bResult = OnVkReturn();
if(!bResult)
{
int iItem = GetSelectedItem();
if( m_CurSubItem != -1 && iItem != -1)
{
CHeaderCtrl* pHeader = GetHeaderCtrl();
int iSubItem = Header_OrderToIndex(pHeader->m_hWnd, m_CurSubItem);
if(iSubItem==0)//that's just me saying all nodes in col 0 are edit-controls, you may modify this
{
CRect rcItem;
GetItemRect(iItem, rcItem, LVIR_LABEL);
DWORD dwStyle = WS_BORDER | WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL|ES_LEFT;
// CEdit *pEdit = new CListEditCtrl(iItem, iSubItem, GetItemText(iItem, iSubItem));
// pEdit->Create(dwStyle, rcItem, this, 0x1233);
}
// else
// EditLabelEx(iItem, iSubItem);
return 1;
}
}
}
break;
default:
break;
}
}
}
return CListCtrl::PreTranslateMessage(pMsg);
}
#define IDC_EDITCTRL 0x1234
/*CEdit* CSuperGridCtrl::EditLabelEx(int nItem, int nCol)
{
CRect rect;
int offset = 0;
if(!EnsureVisible(nItem, TRUE))
return NULL;
GetSubItemRect(nItem, nCol, LVIR_BOUNDS, rect);
// 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::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO *plvDispInfo = (LV_DISPINFO*)pNMHDR;
LV_ITEM *plvItem = &plvDispInfo->item;
if (plvItem->pszText != NULL)//valid text
{
if(plvItem->iItem != -1) //valid item
{
CTreeItem*pSelItem = GetTreeItem(plvItem->iItem);
if(pSelItem != NULL)
{
OnUpdateListViewItem(pSelItem, plvItem);
}
}
}
*pResult = 0;
}*/
int CSuperGridCtrl::GetNumCol()
{
CHeaderCtrl* pHeader = GetHeaderCtrl();
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 = GetHeaderCtrl();
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 = GetHeaderCtrl();
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;
}
void CSuperGridCtrl::DrawFocusCell(CDC *pDC, int nItem, int iSubItem)
{
if(iSubItem==m_CurSubItem)
{
CRect rect;
GetSubItemRect(nItem, iSubItem, LVIR_BOUNDS, rect);
CBrush br(GetCellRGB());
if(iSubItem==0)
GetItemRect(iSubItem, rect, LVIR_LABEL);
pDC->FillRect(rect, &br);
pDC->DrawFocusRect(rect);
}
}
//insert item and return new parent pointer.
CSuperGridCtrl::CTreeItem* CSuperGridCtrl::InsertItem(CTreeItem *pParent, CItemInfo* lpInfo,
BOOL bUpdate)
{
if(pParent==NULL)
return NULL;
CTreeItem *pItem = NULL;
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(!bUpdate)
Hide(pParent, TRUE);
else
{
//calc listview index for the new node
int nIndex = NodeToIndex(pItem);
CString str = GetData(pItem)->GetItemText();
LV_ITEM lvItem;
lvItem.mask = LVIF_TEXT | LVIF_INDENT | LVIF_PARAM | LVIF_IMAGE;
lvItem.pszText = str.GetBuffer(1);
//insert item
lvItem.iItem = nIndex;
lvItem.iSubItem = 0;
lvItem.lParam = (LPARAM)pItem;
lvItem.iIndent = GetIndent(pItem);
lvItem.iImage = lpInfo->GetImage();
CListCtrl::InsertItem(&lvItem);
if(lpInfo->GetCheck())
SetCheck(nIndex);
//Get subitems
int nSize = GetData(pItem)->GetItemCount();
for(int i=0; i < nSize;i++)
{
CString str = GetData(pItem)->GetSubItem(i);
lvItem.mask = LVIF_TEXT;
lvItem.iSubItem = i+1;
lvItem.pszText = str.GetBuffer(1);
SetItem(&lvItem);
}
InternaleUpdateTree();//better do this
}
return pItem;
}
void CSuperGridCtrl::InternaleUpdateTree()
{
int nItems = GetItemCount();
for(int nItem=0; nItem < nItems; nItem++)
{
CTreeItem* pItem = GetTreeItem(nItem);
SetCurIndex(pItem, nItem);
}
}
int CSuperGridCtrl::NodeToIndex(CTreeItem *pNode)
{
int nStartIndex=0;
POSITION pos = m_RootItems.GetHeadPosition();
while(pos!=NULL)
{
CTreeItem * root = (CTreeItem*)m_RootItems.GetNext(pos);
int ret = _NodeToIndex(root, pNode, nStartIndex);
if(ret != -1)
return ret;
}
return -1;
}
CSuperGridCtrl::CTreeItem* CSuperGridCtrl::GetRootItem(int nIndex)
{
POSITION pos = m_RootItems.FindIndex(nIndex);
if(pos==NULL)
return NULL;
return (CTreeItem*)m_RootItems.GetAt(pos);
}
int CSuperGridCtrl::GetRootIndex(CTreeItem * root)
{
int nIndex = 0;
POSITION pos = m_RootItems.GetHeadPosition();
while(pos != NULL)
{
CTreeItem * pItem = (CTreeItem*)m_RootItems.GetNext(pos);
if(pItem== root)
return nIndex;
nIndex++;
}
return -1;
}
BOOL CSuperGridCtrl::IsRoot(CTreeItem * lpItem)
{
return m_RootItems.Find(lpItem) != NULL;
}
void CSuperGridCtrl::DeleteRootItem(CTreeItem * root)
{
POSITION pos = m_RootItems.Find(root);
if(pos!=NULL)
{
CTreeItem* pRoot=(CTreeItem*)m_RootItems.GetAt(pos);
if(pRoot->m_lpNodeInfo!=NULL)
delete pRoot->m_lpNodeInfo;
delete pRoot;
m_RootItems.RemoveAt(pos);
}
}
CSuperGridCtrl::CTreeItem* CSuperGridCtrl::InsertRootItem(CItemInfo * lpInfo)
{
if(lpInfo==NULL)
lpInfo = new CItemInfo;
CTreeItem* pRoot = NULL;
pRoot = new CTreeItem();
CleanMe(pRoot);
UpdateData(pRoot, lpInfo);
SetIndent(pRoot, 1);
SetCurIndex(pRoot, GetItemCount());
SetParentItem(pRoot, NULL);
CItemInfo* lp = GetData(pRoot);
LV_ITEM lvItem;
lvItem.mask = LVIF_TEXT | LVIF_INDENT | LVIF_PARAM | LVIF_IMAGE;
CString strItem = lp->GetItemText();
lvItem.pszText = strItem.GetBuffer(1);
lvItem.iItem = GetItemCount();
lvItem.lParam = (LPARAM)pRoot;
lvItem.iIndent = 1;
lvItem.iSubItem = 0;
lvItem.iImage = lpInfo->GetImage();
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_RootItems.AddTail(pRoot);
return pRoot;
}
void CSuperGridCtrl::DrawTreeItem(CDC* pDC, CTreeItem* pSelItem, int nListItem, const CRect& rcBounds)
{
int nColWidth = GetColumnWidth(0);
int yDown = rcBounds.top;
CPen* pPenTreeLine = pDC->SelectObject(&m_psTreeLine);
int iIndent = GetIndent(pSelItem);
int nHalfImage = (m_cxImage >> 1);
int nBottomDown = yDown + nHalfImage + ((rcBounds.Height() - m_cyImage) >> 1);
//
BOOL bChild = ItemHasChildren(pSelItem);
BOOL bCollapsed = IsCollapsed(pSelItem);
//draw outline
while(1)
{
CTreeItem* pParent = GetParentItem(pSelItem);
if(pParent==NULL)//no more parents, stop
break;
POSITION pos = pParent->m_listChild.GetTailPosition();
while(pos!=NULL)
{
CTreeItem *pLastChild = (CTreeItem*)pParent->m_listChild.GetPrev(pos);
int nIndex = GetCurIndex(pLastChild);
int nCurIndent = GetIndent(pLastChild);
if(nListItem > nIndex && iIndent > nCurIndent)//no need to go further in this loop
break;
//no drawing outside the 1st columns right
int xLine = rcBounds.left + nCurIndent * m_cxImage - nHalfImage;
if(nIndex == nListItem && nCurIndent==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 && nCurIndent==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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -