Files
envi-code/SourceCode/Code2026/CoreCommand/SuperGridCtrlEx.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

396 lines
9.2 KiB
C++

#include "stdafx.h"
#include "SuperGridCtrlEx.h"
#include "ComboInListView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CSuperGridCtrlEx::CSuperGridCtrlEx()
{
m_bDrag = TRUE;
}
CSuperGridCtrlEx::~CSuperGridCtrlEx()
{
}
BEGIN_MESSAGE_MAP(CSuperGridCtrlEx, CSuperGridCtrl)
//{{AFX_MSG_MAP(CSuperGridCtrlEx)
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
int CSuperGridCtrlEx::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CSuperGridCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}
//helper function to copy CItemInfo used when drag/drop you must override this this function to suit your own CItemInfo class
CItemInfo* CSuperGridCtrlEx::CopyData(CItemInfo* lpSrc)
{
ASSERT(lpSrc!=NULL);
CItemInfo* lpDest = new CItemInfo;
//well okay I put all the copy thing in one function, located in CItemInfo class,
//so you should check out this function, remember to modify this function each time you add new data to CItemInfo class.
lpDest->CopyObjects(lpSrc);
return lpDest;
}
//override, like red!
COLORREF CSuperGridCtrlEx::GetCellRGB()
{
return RGB(192,192,192);
}
//this is my override of GetIcon, override this to set what ever icon suits you
int CSuperGridCtrlEx::GetIcon(const CTreeItem* pItem)
{
if(pItem!=NULL)
{
int n = GetData(pItem)->GetImage();
if(n!=-1)
return n;
int iImage = 0;
if(ItemHasChildren(pItem))
{
IsCollapsed(pItem) ? iImage = 1/*close icon*/:iImage = 0;/*open icon*/
}
else
iImage = 2;//doc icon
return iImage;
}
return 0;
}
//override called when OnLButtondown
void CSuperGridCtrlEx::OnControlLButtonDown(UINT nFlags, CPoint point, LVHITTESTINFO& ht)
{
//now I am sure I added a combobox some where, so check for this control
CTreeItem*pSelItem = GetTreeItem(ht.iItem);
if(pSelItem!=NULL)
{
CItemInfo* pInfo = GetData(pSelItem);
CItemInfo::CONTROLTYPE ctrlType;
if(pInfo->GetControlType(ht.iSubItem-1, ctrlType))
{
if(ctrlType== CItemInfo::combobox)
{
if(this->m_bEditStyle && pSelItem->m_bCanEditMe)
{
CStringList* list=NULL;
pInfo->GetListData(ht.iSubItem-1, list);
CComboBox * pList = ShowList(ht.iItem, ht.iSubItem, list);
}
}
}
else
{
if(this->m_bEditStyle && pSelItem->m_bCanEditMe)
{
CSuperGridCtrl::OnControlLButtonDown(nFlags, point, ht);
}
}
}
}
BOOL CSuperGridCtrlEx::OnVkReturn()
{
BOOL bResult=FALSE;
int iItem = GetNextItem( -1, LVNI_ALL | LVNI_SELECTED);
if( GetCurSubItem() != -1 && iItem != -1)
{
CTreeItem*pSelItem = GetTreeItem(iItem);
if(pSelItem!=NULL)
{
CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
int iSubItem = Header_OrderToIndex(pHeader->m_hWnd, GetCurSubItem());
CItemInfo* pInfo = GetData(pSelItem);
CItemInfo::CONTROLTYPE ctrlType;
if(pInfo->GetControlType(iSubItem-1, ctrlType))
{
switch(ctrlType)
{
/*put in your own control here*/
case CItemInfo::datecontrol:break;
case CItemInfo::spinbutton:break;
case CItemInfo::dropdownlistviewwhatevercontrol:break;
case CItemInfo::combobox:
{
CStringList* list=NULL;
pInfo->GetListData(iSubItem-1, list);
CComboBox * pList = ShowList(iItem, iSubItem, list);
bResult=TRUE; //I'll handle it from here
}break;
default:break;
}
}
}
}
return bResult;
}
#define IDC_COMBOBOXINLISTVIEW 0x1235
CComboBox* CSuperGridCtrlEx::ShowList(int nItem, int nCol, CStringList *lstItems)
{
CString strFind = GetItemText(nItem, nCol);
//basic code start
CRect rect;
int offset = 0;
// Make sure that the item is visible
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;
size.cx = offset + rect.left;
size.cy = 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;
//basic code end
rect.bottom += 10 * rect.Height();//dropdown area
DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL|CBS_DROPDOWNLIST;
CComboBox *pList = new CComboInListView(nItem, nCol, lstItems);
pList->Create(dwStyle, rect, this, IDC_COMBOBOXINLISTVIEW);
pList->ModifyStyleEx(0,WS_EX_CLIENTEDGE);//can we tell at all
pList->SetHorizontalExtent(CalcHorzExtent(pList, lstItems));
pList->ShowDropDown();
pList->SelectString(-1, strFind.GetBuffer(1));
// The returned pointer should not be saved
return pList;
}
int CSuperGridCtrlEx::CalcHorzExtent(CWnd* pWnd, CStringList *pList)
{
int nExtent=0;
if(pWnd!=NULL)
{
CDC* pDC = pWnd->GetDC();
HFONT hFont = (HFONT)pWnd->SendMessage(WM_GETFONT); //why not pWnd->GetFont();..I like the send thing alot and
CFont *pFont = CFont::FromHandle(hFont); //this way I get to use this function..cool :)
if(pFont!=NULL) //ya what ever makes me happy,.right :}
{
CFont* pOldFont = pDC->SelectObject(pFont);
CSize newExtent;
POSITION pos = pList->GetHeadPosition();
while(pos != NULL)
{
CString str(pList->GetNext(pos));
newExtent = pDC->GetTextExtent(str);
newExtent.cx += 6;
if (newExtent.cx > nExtent)
{
nExtent = newExtent.cx;
}
}
pDC->SelectObject(pOldFont);
}
pWnd->ReleaseDC(pDC);
}
return nExtent;
}
CTreeItem* CSuperGridCtrlEx::Search(CString strItem,...)
{
if(!GetItemCount())
return NULL;
va_list args;
va_start(args, strItem);
int nCount=0;
for(;;)
{
LPCTSTR lpsz = va_arg(args, LPCTSTR);
if(lpsz==NULL)
break;
nCount++;
}
POSITION pos = GetRootHeadPosition();
while(pos != NULL)
{
CTreeItem *pParent = (CTreeItem*)GetNextRoot(pos);
CTreeItem *pItem = pParent;
CItemInfo* lp = GetData(pParent);
CString strData = lp->GetItemText();
if(strData==strItem)//must be a match before going further...suit you self
{
va_start(args, strItem);
int nResult=0;
for(int i=0; i<nCount;i++)
{
LPCTSTR lpsz = va_arg(args, LPCTSTR);
for(int nCol=0; nCol < lp->GetItemCount(); nCol++)
{
CString str = lp->GetSubItem(nCol);
if(!str.CompareNoCase(lpsz))
{
nResult++;
break;
}
}
}
va_end(args);
if(nCount==nResult)//all args was found return node
return pParent;
}
//GetNext ....loop through all children
for(;;)
{
CTreeItem *pCur = GetNext(pParent, pItem, TRUE, FALSE/*regardless of the item are hidden or not, set to TRUE if only visible items must be included in the search*/);
if(!IsChildOf(pParent, pCur))
break;
else
if(pCur==pItem)
break;
CItemInfo* lp = GetData(pCur);
CString strData = lp->GetItemText();
if(strData==strItem)//must be a match before going further
{
va_start(args, strItem);
int nResult=0;
for(int i=0; i<nCount;i++)
{
LPCTSTR lpsz = va_arg(args, LPCTSTR);
for(int nCol=0; nCol < lp->GetItemCount(); nCol++)
{
CString str = lp->GetSubItem(nCol);
if(!str.CompareNoCase(lpsz))
{
nResult++;
break;
}
}
}
va_end(args);
if(nCount==nResult)//all args was found return node
return pCur;
}
pItem=pCur;//next;
}
}
return NULL;
}
void CSuperGridCtrlEx::SortData()
{
int nIndex = GetNextItem(-1, LVNI_ALL | LVNI_SELECTED);
if(nIndex==-1)
return;
CTreeItem *pItem = reinterpret_cast<CTreeItem*>(GetItemData(nIndex));
if(AfxMessageBox(_T("Sort all children(Yes)\nor just sort rootitems(No)"),MB_YESNO)==IDYES)
Sort(pItem, TRUE);
else
Sort(pItem, FALSE);
//do a simple refresh thing
if(ItemHasChildren(pItem))
{
SetRedraw(0);
Collapse(pItem);
Expand(pItem, nIndex);
SetRedraw(1);
}
}
//another search thing
CTreeItem* CSuperGridCtrlEx::SearchEx(CTreeItem *pStartPosition, CString strItem)
{
CItemInfo* lp = GetData(pStartPosition);
//if(lp->GetCheck()) another condition here maybe
CString strData = lp->GetItemText();
if(strData==strItem)
{
return pStartPosition;
}
const int nChildren = NumChildren(pStartPosition);
if (nChildren > 0)
{
POSITION pos = GetHeadPosition(pStartPosition);
while (pos)
{
CTreeItem *pChild = GetNextChild(pStartPosition, pos);
CItemInfo* lp = GetData(pChild);
CString strData = lp->GetItemText();
if(strData==strItem)
{
return pChild;
}
}
}
POSITION pos = GetHeadPosition(pStartPosition);
while (pos)
{
CTreeItem *pChild = GetNextChild(pStartPosition, pos);
CItemInfo* lp = GetData(pChild);
CString strData = lp->GetItemText();
if(strData==strItem)
{
return pChild;
}
pChild = SearchEx(pChild, strItem);
if(pChild!=NULL)
return pChild;
}
return NULL;
}
BOOL CSuperGridCtrlEx::OnDeleteItem(CTreeItem* pItem, int nIndex)
{
return 1;
}
BOOL CSuperGridCtrlEx::OnItemExpanding(CTreeItem *pItem, int iItem)
{
return 1;
}
BOOL CSuperGridCtrlEx::OnItemExpanded(CTreeItem* pItem, int iItem)
{
return 1;
}
BOOL CSuperGridCtrlEx::OnCollapsing(CTreeItem *pItem)
{
return 1;
}
BOOL CSuperGridCtrlEx::OnItemCollapsed(CTreeItem *pItem)
{
return 1;
}
CImageList *CSuperGridCtrlEx::CreateDragImageEx(int nItem)
{
if(m_bDrag)
return CSuperGridCtrl::CreateDragImageEx(GetDragItem());
else
return NULL;
}