359 lines
8.2 KiB
C++
359 lines
8.2 KiB
C++
#include "stdafx.h"
|
|
#include "KTAxisGridListCtrl.h"
|
|
|
|
#define IDC_INPLACECOMBOBOX 1110
|
|
#define WM_USERDEFINEHIT WM_USER + 0X1003
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
KTAxisGridListCtrl::KTAxisGridListCtrl()
|
|
{
|
|
m_pComboBox = NULL;
|
|
m_nInitFlag = 0;
|
|
}
|
|
|
|
KTAxisGridListCtrl::~KTAxisGridListCtrl()
|
|
{
|
|
if (m_pComboBox != NULL)
|
|
{
|
|
delete m_pComboBox;
|
|
m_pComboBox = NULL;
|
|
}
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(KTAxisGridListCtrl, CListCtrl)
|
|
//{{AFX_MSG_MAP(KTAxisGridListCtrl)
|
|
ON_WM_VSCROLL()
|
|
ON_WM_HSCROLL()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndlabeledit)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
void KTAxisGridListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
|
{
|
|
if( GetFocus() != this ) SetFocus();
|
|
CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
|
|
}
|
|
|
|
void KTAxisGridListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
|
{
|
|
if( GetFocus() != this ) SetFocus();
|
|
CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
|
|
}
|
|
|
|
void KTAxisGridListCtrl::OnLButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
CListCtrl::OnLButtonDown(nFlags, point);
|
|
HitItemTest(point);
|
|
}
|
|
|
|
void KTAxisGridListCtrl::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
LV_DISPINFO *plvDispInfo = (LV_DISPINFO *)pNMHDR;
|
|
LV_ITEM *plvItem = &plvDispInfo->item;
|
|
|
|
if (plvItem->pszText != NULL)
|
|
{
|
|
// 如果和原内容对比没有变化则直接返回。
|
|
CString sOldText = GetItemText(plvItem->iItem, plvItem->iSubItem);
|
|
if (sOldText.Compare(plvItem->pszText) == 0)
|
|
return;
|
|
|
|
// 设置新内容到item中
|
|
SetItemText(plvItem->iItem, plvItem->iSubItem, plvItem->pszText);
|
|
|
|
// 设置新建行的个数为1
|
|
CString sTemp = GetItemText(plvItem->iItem, 0);
|
|
if (!GetItemText(plvItem->iItem, 0).IsEmpty() && GetItemText(plvItem->iItem, 1).IsEmpty())
|
|
{
|
|
SetItemText(plvItem->iItem, 1, _T("1"));
|
|
}
|
|
|
|
// 自动添加一行
|
|
if (plvItem->iItem == GetItemCount() - 1
|
|
&& !GetItemText(plvItem->iItem, 0).IsEmpty()
|
|
&& !GetItemText(plvItem->iItem, 1).IsEmpty())
|
|
{
|
|
InsertItem(plvItem->iItem + 1, _T(""));
|
|
}
|
|
|
|
GetParent()->SendMessage(WM_ITEMEDITED,plvItem->iItem,plvItem->iSubItem);
|
|
}
|
|
*pResult = 0;
|
|
}
|
|
|
|
void KTAxisGridListCtrl::HitItemTest(CPoint &point)
|
|
{
|
|
int index;
|
|
int colnum;
|
|
if( ( index = HitTestEx( point, &colnum )) != -1 )
|
|
{
|
|
SetItemState( index, LVIS_SELECTED | LVIS_FOCUSED ,
|
|
LVIS_SELECTED | LVIS_FOCUSED);
|
|
|
|
UINT flag = LVIS_FOCUSED;
|
|
if( (GetItemState( index, flag ) & flag) == flag && colnum >= 0)
|
|
{
|
|
if (!InReadOnlyColumn(colnum))
|
|
{
|
|
EditSubLabel( index, colnum );
|
|
}
|
|
}
|
|
else
|
|
SetItemState( index, LVIS_SELECTED | LVIS_FOCUSED ,
|
|
LVIS_SELECTED | LVIS_FOCUSED);
|
|
}
|
|
}
|
|
|
|
BOOL KTAxisGridListCtrl::InReadOnlyColumn(int nCol)
|
|
{
|
|
int nSize = m_arReadOnlyCol.GetSize();
|
|
|
|
for(int i = 0;i < nSize;i++)
|
|
{
|
|
if (nCol == m_arReadOnlyCol.GetAt(i))
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
void KTAxisGridListCtrl::EditSubLabel( int nItem, int nCol )
|
|
{
|
|
if( !EnsureVisible( nItem, TRUE ) ) return;
|
|
|
|
// 列可见
|
|
CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
|
|
int nColumnCount = pHeader->GetItemCount();
|
|
if( nCol >= nColumnCount || GetColumnWidth(nCol) < 5 ) return;
|
|
|
|
// 列偏移
|
|
int offset = 0;
|
|
for( int i = 0; i < nCol; i++ )
|
|
offset += GetColumnWidth( i );
|
|
|
|
CRect rect;
|
|
GetItemRect( nItem, &rect, LVIR_BOUNDS );
|
|
|
|
// 滚动列,便于操作
|
|
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;
|
|
}
|
|
|
|
// 获取列的对齐方式
|
|
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;
|
|
|
|
rect.left += offset + 1;
|
|
//if (nCol == 0) rect.left += 14;//第一列,留出图标6+12 + 2
|
|
|
|
if (nCol > 0)
|
|
rect.right = rect.left + GetColumnWidth( nCol );// - 6;
|
|
else
|
|
rect.right = rect.left + GetColumnWidth( nCol );// - 20;
|
|
|
|
if( rect.right > rcClient.right) rect.right = rcClient.right;
|
|
|
|
//rect.top += 2;
|
|
rect.bottom = rect.top + 12 * rect.Height();
|
|
|
|
dwStyle |= WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP|CBS_DROPDOWN;
|
|
if (m_pComboBox != NULL)
|
|
{
|
|
delete m_pComboBox;
|
|
m_pComboBox = NULL;
|
|
}
|
|
m_pComboBox = new CInPlaceComboBox(nItem, nCol, GetItemText(nItem, nCol));
|
|
m_pComboBox->m_nInitFlag = m_nInitFlag;
|
|
m_pComboBox->Create(dwStyle, rect, this, IDC_INPLACECOMBOBOX);
|
|
m_pComboBox->SetItemHeight(-1, 13);
|
|
m_pComboBox->SetFocus();
|
|
}
|
|
|
|
int KTAxisGridListCtrl::HitTestEx(CPoint &point, int *col) const
|
|
{
|
|
int row = HitTest( point, NULL );
|
|
if( col != NULL ) *col = 0;
|
|
|
|
// 只针对LVS_REPORT样式
|
|
if( (GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT )
|
|
return row;
|
|
|
|
// 获取可见的底顶行
|
|
row = GetTopIndex();
|
|
int bottom = row + GetCountPerPage();
|
|
if( bottom > GetItemCount() )
|
|
bottom = GetItemCount();
|
|
|
|
// 获取列数
|
|
CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
|
|
int nColumnCount = pHeader->GetItemCount();
|
|
|
|
int colnum = 0;
|
|
|
|
// 从可见的行中找
|
|
for( ;row <=bottom;row++)
|
|
{
|
|
// 获取光标落在的位置的BOUNDS
|
|
CRect rect;
|
|
GetItemRect( row, &rect, LVIR_BOUNDS );
|
|
if( rect.PtInRect(point) )
|
|
{
|
|
// 通过比较宽度,找到列
|
|
for( colnum = 0; colnum < nColumnCount; colnum++ )
|
|
{
|
|
int colwidth = GetColumnWidth(colnum);
|
|
if( point.x >= rect.left
|
|
&& point.x <= (rect.left + colwidth ) )
|
|
{
|
|
if( col != NULL ) *col = colnum;
|
|
return row;
|
|
}
|
|
rect.left += colwidth;
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void KTAxisGridListCtrl::DoInsert()
|
|
{
|
|
SetFocus();
|
|
|
|
int nCurSel = GetNextItem(-1, LVIS_SELECTED);
|
|
if (nCurSel == -1) nCurSel = GetItemCount() - 1;
|
|
CString strData = (m_nInitFlag == 0) ? _T("1500") : _T("10");
|
|
InsertItem(nCurSel,strData);
|
|
SetItemText(nCurSel,1,_T("1"));
|
|
}
|
|
|
|
void KTAxisGridListCtrl::DoDelete()
|
|
{
|
|
SetFocus();
|
|
|
|
int nCurSel = GetNextItem(-1, LVIS_SELECTED);
|
|
DeleteItem(nCurSel);
|
|
}
|
|
|
|
void KTAxisGridListCtrl::DoCut()
|
|
{
|
|
SetFocus();
|
|
|
|
int nCurSel = GetNextItem(-1, LVIS_SELECTED);
|
|
CString szClipBuff = _T("");
|
|
szClipBuff = GetItemText(nCurSel, 1);
|
|
szClipBuff += _T("*");
|
|
szClipBuff += GetItemText(nCurSel, 0);
|
|
SetClipboardText(szClipBuff.LockBuffer());
|
|
DeleteItem(nCurSel);
|
|
}
|
|
|
|
void KTAxisGridListCtrl::DoCopy()
|
|
{
|
|
int nCurSel = GetNextItem(-1, LVIS_SELECTED);
|
|
CString szClipBuff = _T("");
|
|
szClipBuff = GetItemText(nCurSel, 1);
|
|
szClipBuff += _T("*");
|
|
szClipBuff += GetItemText(nCurSel, 0);
|
|
SetClipboardText(szClipBuff.LockBuffer());
|
|
}
|
|
|
|
void KTAxisGridListCtrl::DoPaste()
|
|
{
|
|
SetFocus();
|
|
int nCurSel = GetNextItem(-1, LVIS_SELECTED);
|
|
LPTSTR buff;
|
|
CString szClipBuff, szSize, szData;
|
|
GetClipboardText(buff);
|
|
szClipBuff.Format(_T("%s"), buff);
|
|
if (szClipBuff.CompareNoCase(_T("*")) == 0) return;
|
|
|
|
if (nCurSel == -1) nCurSel = GetItemCount() - 1;
|
|
int nFind = -1;
|
|
if ((nFind = szClipBuff.Find(_T('*'),0)) > -1)
|
|
{
|
|
szSize = szClipBuff.Left(nFind);
|
|
szData = szClipBuff.Mid(nFind + 1);
|
|
|
|
InsertItem(nCurSel,szData);
|
|
SetItemText(nCurSel,1,szSize);
|
|
}
|
|
}
|
|
|
|
BOOL KTAxisGridListCtrl::SetClipboardText(LPTSTR lpszBuffer)
|
|
{
|
|
HGLOBAL hGlobal; // Global memory handle
|
|
LPTSTR lpszData; // Pointer to clipboard data
|
|
unsigned long nSize; // Size of clipboard data
|
|
|
|
OpenClipboard();
|
|
EmptyClipboard();
|
|
|
|
nSize = _tcslen(lpszBuffer) * sizeof(TCHAR);
|
|
hGlobal = GlobalAlloc(GMEM_ZEROINIT, nSize+1);
|
|
|
|
if (hGlobal == NULL)
|
|
{
|
|
CloseClipboard();
|
|
return FALSE;
|
|
}
|
|
|
|
lpszData = (LPTSTR)GlobalLock(hGlobal);
|
|
|
|
for (UINT i = 0; i < nSize + 1; ++i)
|
|
*(lpszData + i) = *(lpszBuffer + i);
|
|
|
|
GlobalUnlock(hGlobal);
|
|
SetClipboardData(CF_TEXT, hGlobal);
|
|
CloseClipboard();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL KTAxisGridListCtrl::GetClipboardText(LPTSTR& lpszBuffer)
|
|
{
|
|
HGLOBAL hGlobal; // Global memory handle
|
|
LPTSTR lpszData; // Pointer to clipboard data
|
|
unsigned long nSize; // Size of clipboard data
|
|
|
|
OpenClipboard();
|
|
hGlobal = GetClipboardData(CF_TEXT);
|
|
|
|
if (hGlobal == NULL)
|
|
{
|
|
CloseClipboard();
|
|
return FALSE;
|
|
}
|
|
|
|
lpszData = (LPTSTR)GlobalLock(hGlobal);
|
|
nSize = GlobalSize(hGlobal);
|
|
|
|
lpszBuffer = lpszData;
|
|
lpszBuffer += _T('\0');
|
|
|
|
GlobalUnlock(hGlobal);
|
|
CloseClipboard();
|
|
|
|
return TRUE;
|
|
}
|