254 lines
5.3 KiB
C++
254 lines
5.3 KiB
C++
#include "stdafx.h"
|
|
#include "AECListCtrl.h"
|
|
#include "AECInplaceEdit.h"
|
|
#include "AECInplaceComboBox.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
AECListCtrl::AECListCtrl()
|
|
{
|
|
}
|
|
|
|
AECListCtrl::~AECListCtrl()
|
|
{
|
|
RemoveAllColXData();
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(AECListCtrl, CListCtrl)
|
|
//{{AFX_MSG_MAP(AECListCtrl)
|
|
ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndlabeledit)
|
|
ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
|
|
ON_NOTIFY_REFLECT(LVN_KEYDOWN, OnKeydown)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
BOOL AECListCtrl::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;
|
|
}
|
|
|
|
BOOL AECListCtrl::DeleteColumn( int nCol )
|
|
{
|
|
void * pXData = NULL;
|
|
BOOL bFind = this->m_mapColXData.Lookup(nCol,pXData);
|
|
if(bFind)
|
|
{
|
|
m_mapColXData.RemoveKey(nCol);
|
|
delete pXData;
|
|
}
|
|
return CListCtrl::DeleteColumn(nCol);
|
|
}
|
|
|
|
BOOL AECListCtrl::PreCreateWindow(CREATESTRUCT& cs)
|
|
{
|
|
cs.style |= WS_CHILD |
|
|
LVS_REPORT |
|
|
LVS_SINGLESEL |
|
|
LVS_SHOWSELALWAYS;
|
|
return CListCtrl::PreCreateWindow(cs);
|
|
}
|
|
|
|
void AECListCtrl::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);
|
|
|
|
// this will invoke an ItemChanged handler in parent
|
|
if ( plvItem->iSubItem != 0 )
|
|
{
|
|
TCHAR szText[0x10+1];
|
|
GetItemText( plvItem->iItem, 0, szText, 0x10);
|
|
SetItemText( plvItem->iItem, 0, szText);
|
|
}
|
|
}
|
|
*pResult = 0;
|
|
}
|
|
|
|
void AECListCtrl::OnClick(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
if( GetFocus() != this)
|
|
{
|
|
SetFocus();
|
|
}
|
|
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);
|
|
}
|
|
}
|
|
|
|
*pResult = 0;
|
|
}
|
|
|
|
void AECListCtrl::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 * AECListCtrl::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 | WS_VSCROLL | WS_HSCROLL|CBS_DROPDOWN;
|
|
|
|
#define IDC_COMBOBOXINLISTVIEW 0x1235
|
|
|
|
CStringList * pStrList = NULL;
|
|
BOOL bFind = m_mapColXData.Lookup(nSubItem,(void *&)pStrList);
|
|
if(bFind == FALSE)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if(nSubItem == 0)
|
|
{
|
|
rect.DeflateRect(1,0,0,0);
|
|
}
|
|
|
|
CComboBox *pList = new AECInplaceComboBox(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 * AECListCtrl::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;
|
|
|
|
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;
|
|
|
|
rect.DeflateRect(2,0,3,1);
|
|
rect.bottom = rect.top + 14;
|
|
rect.OffsetRect(3,2);
|
|
|
|
dwStyle |= WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL;
|
|
CString _s(GetItemText(nItem, nSubItem));
|
|
CEdit *pEdit = new AECInplaceEdit(nItem, nSubItem, _s);
|
|
|
|
#define IDC_EDITCTRL 0x1234
|
|
pEdit->Create(dwStyle, rect, this, IDC_EDITCTRL);
|
|
return pEdit;
|
|
}
|
|
|
|
void AECListCtrl::RemoveAllColXData()
|
|
{
|
|
int nCol = 0;
|
|
void * pXData = NULL;
|
|
POSITION pos = NULL;
|
|
for(pos = m_mapColXData.GetStartPosition();pos != NULL;)
|
|
{
|
|
m_mapColXData.GetNextAssoc(pos,nCol,pXData);
|
|
}
|
|
}
|