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