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

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;
}