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

404 lines
8.1 KiB
C++

#include "stdafx.h"
#include "UIIListCtrl.h"
#include "UIIInplaceEdit.h"
#include "UIIInplaceComboBox.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CUIIListCtrl::CUIIListCtrl()
{
}
CUIIListCtrl::~CUIIListCtrl()
{
}
BEGIN_MESSAGE_MAP(CUIIListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CUIIListCtrl)
ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndlabeledit)
ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
ON_NOTIFY_REFLECT(LVN_KEYDOWN, OnKeydown)
ON_WM_HSCROLL()
ON_WM_VSCROLL()
ON_WM_MOUSEWHEEL()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CUIIListCtrl::OnMouseWheel( UINT nFlags, short zDelta, CPoint pt )
{
if( GetFocus() != this)
SetFocus();
return CListCtrl::OnMouseWheel(nFlags, zDelta, pt);
}
void CUIIListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if( GetFocus() != this)
SetFocus();
CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CUIIListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if( GetFocus() != this)
SetFocus();
CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
}
BOOL CUIIListCtrl::SetColumnItemData(int nCol,void * pXData,EType eType)
{
CHeaderCtrl * pHead = GetHeaderCtrl();
int nCount = pHead->GetItemCount();
if(nCol > nCount)
{
return FALSE;
}
m_mapColEnum.SetAt(nCol,eType);
if(pXData != NULL)
{
m_mapColXData.SetAt(nCol,pXData);
}
return TRUE;
}
void* CUIIListCtrl::GetColumnItemData(int nCol,EType& eType)
{
CHeaderCtrl * pHead = GetHeaderCtrl();
int nCount = pHead->GetItemCount();
if(nCol > nCount)
{
return NULL;
}
m_mapColEnum.Lookup(nCol,eType);
void * pXData = NULL;
m_mapColXData.Lookup(nCol,pXData);
return pXData;
}
void CUIIListCtrl::DeleteXData(BOOL bDelete)
{
POSITION pos = NULL;
void * pXData = NULL;
int nCol = 0;
for(pos = m_mapColXData.GetStartPosition();pos!= NULL;)
{
m_mapColXData.GetNextAssoc(pos,nCol,pXData);
if(pXData != NULL && bDelete)
{
delete(pXData);
}
}
m_mapColXData.RemoveAll();
}
BOOL CUIIListCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style |= WS_CHILD |
LVS_REPORT |
LVS_SINGLESEL |
LVS_SHOWSELALWAYS;
return CListCtrl::PreCreateWindow(cs);
}
void CUIIListCtrl::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO *plvDispInfo = (LV_DISPINFO*)pNMHDR;
LV_ITEM *plvItem = &plvDispInfo->item;
if( plvItem->iItem != -1 && // valid item
plvItem->pszText ) // valid text
{
SetItemText( plvItem->iItem, plvItem->iSubItem, plvItem->pszText);
}
*pResult = 0;
}
void CUIIListCtrl::OnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
int nItem = pNMListView->iItem;
int nCol = pNMListView->iSubItem ;
EType eType;
BOOL bFind = this->m_mapColEnum.Lookup(nCol,eType);
if(bFind)
{
if(eType == ET_Edit)
{
EditItem(pNMListView->iItem, pNMListView->iSubItem);
}
else if(eType == ET_Combo)
{
ComboItem(pNMListView->iItem, pNMListView->iSubItem);
}
else if(eType = ET_Check)
{
CheckItem(pNMListView->iItem, pNMListView->iSubItem,-1);
}
}
*pResult = 0;
}
void CUIIListCtrl::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;
switch(pLVKeyDow->wVKey)
{
case VK_DELETE:
{
int nItem = GetSelectionMark();
if(nItem!=-1)
{
DeleteItem( nItem );
}
} break;
default :break;
}
*pResult = 0;
}
CComboBox * CUIIListCtrl::ComboItem( int nItem, int nSubItem)
{
CString strFind = GetItemText(nItem, nSubItem);
//basic code start
CRect rect;
int offset = 0;
// Make sure that the item is visible
if( !EnsureVisible(nItem, TRUE))
return NULL;
GetSubItemRect(nItem, nSubItem, 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(nSubItem);
if(rect.right > rcClient.right)
{
rect.right = rcClient.right;
}
rect.bottom += 30 * rect.Height();//dropdown area
DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST;
#define IDC_COMBOBOXINLISTVIEW 0x1235
CStringList * pStrList = NULL;
BOOL bFind = m_mapColXData.Lookup(nSubItem,(void *&)pStrList);
if(bFind == FALSE)
{
return NULL;
}
CImageList * pImageList = GetImageList(LVSIL_SMALL);
if(pImageList != NULL && nSubItem == 0)
{
rect.DeflateRect(16,0,3,1);
}
else
{
rect.DeflateRect(2,0,3,1);
}
CComboBox *pList = new CUIIInplaceComboBox(nItem, nSubItem,pStrList);
pList->Create(dwStyle, rect, this, IDC_COMBOBOXINLISTVIEW);
pList->ModifyStyleEx(0,WS_EX_CLIENTEDGE);//can we tell at all
pList->ShowDropDown();
pList->SelectString(-1, strFind.GetBuffer(1));
return pList;
}
CEdit * CUIIListCtrl::EditItem( int nItem, int nSubItem)
{
CRect rect;
int offset = 0;
if(!EnsureVisible(nItem, TRUE))
{
return NULL;
}
GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect);
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(nSubItem);
if(rect.right > rcClient.right)
rect.right = rcClient.right;
LV_COLUMN lvcol;
lvcol.mask = LVCF_FMT;
GetColumn(nSubItem, &lvcol);
DWORD dwStyle = 0;
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;
CImageList * pImageList = GetImageList(LVSIL_SMALL);
if(pImageList != NULL && nSubItem == 0)
{
rect.DeflateRect(16,0,3,1);
}
else
{
rect.DeflateRect(2,0,3,1);
}
rect.bottom = rect.top + 16;
rect.OffsetRect(3,0);
dwStyle |= WS_BORDER | WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL|ES_LEFT;
CString _s(GetItemText(nItem, nSubItem));
CEdit *pEdit = new CUIIInplaceEdit(nItem, nSubItem, _s);
#define IDC_EDITCTRL 0x1234
pEdit->Create(dwStyle, rect, this, IDC_EDITCTRL);
pEdit->SetSel(0,-1);
return pEdit;
}
void CUIIListCtrl::CheckItem( int nItem, int nSubItem,BOOL bCheck)
{
EType eType;
GetColumnItemData(nSubItem,eType);
if (eType != ET_Check)
return;
CRect rect;
int offset = 0;
if(!EnsureVisible(nItem, TRUE))
{
return;
}
GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect);
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(nSubItem);
if(rect.right > rcClient.right)
rect.right = rcClient.right;
LV_COLUMN lvcol;
lvcol.mask = LVCF_FMT;
GetColumn(nSubItem, &lvcol);
CImageList * pImageList = GetImageList(LVSIL_SMALL);
if(pImageList != NULL && nSubItem == 0)
{
rect.DeflateRect(16,0,3,1);
}
else
{
rect.DeflateRect(2,0,3,1);
}
rect.bottom = rect.top + 16;
rect.OffsetRect(3,0);
int nCheck = 0;
CString sKey;
sKey.Format(_T("%d%d"),nItem,nSubItem);
if ( m_mapItemSubToCheck.Lookup(sKey,nCheck) )
{
if (nCheck)
{
if (bCheck == -1)
{
//取反
SetItemText(nItem,nSubItem,_T("X"));
m_mapItemSubToCheck.SetAt(sKey,FALSE);
}
}
else
{
if (bCheck == -1)
{
//取反
SetItemText(nItem,nSubItem,_T("√"));
m_mapItemSubToCheck.SetAt(sKey,TRUE);
}
}
}
else
{
if (bCheck)
{
SetItemText(nItem,nSubItem,_T("√"));
m_mapItemSubToCheck.SetAt(sKey,TRUE);
}
else
{
SetItemText(nItem,nSubItem,_T("X"));
m_mapItemSubToCheck.SetAt(sKey,0);
}
}
}
BOOL CUIIListCtrl::SetItemText(int nItem, int nSubItem, LPCTSTR lpszText)
{
CListCtrl::SetItemText(nItem,nSubItem,lpszText);
return TRUE;
}
BOOL CUIIListCtrl::SetItemText(int nItem, int nSubItem, LPCTSTR lpszText,BOOL bCheck)
{
SetItemText(nItem,nSubItem,lpszText);
CheckItem(nItem,nSubItem,bCheck);
return TRUE;
}
BOOL CUIIListCtrl::GetCheck(int nItem,int nSubItem)
{
CString sKey;
sKey.Format(_T("%d%d"),nItem,nSubItem);
int nCheck = 0;
m_mapItemSubToCheck.Lookup(sKey,nCheck);
return nCheck;
}