📄 editlistview.cpp
字号:
// EditListView.cpp : implementation file
//
#include "stdafx.h"
#include "ODBCTrans.h"
#include "EditListView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CEditListView
//●>
#include "ODBCTransDoc.h"
//<●
#define IDC_LISTEDIT WM_USER+100
// CListEdit
CListEdit::CListEdit(int iItem, int iSubItem, CString sInitText)
{
m_iItem = iItem;
m_iSubItem = iSubItem;
m_bESC = FALSE;
}
CListEdit::~CListEdit()
{
}
void CListEdit::SetItemData(int iItem, int iSubItem, CString sInitText)
{
m_iItem = iItem;
m_iSubItem = iSubItem;
m_bESC = FALSE;
}
BEGIN_MESSAGE_MAP(CListEdit, CEdit)
//{{AFX_MSG_MAP(CListEdit)
ON_WM_KILLFOCUS()
ON_WM_NCDESTROY()
ON_WM_CHAR()
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////
//CListEdit类的代码:
BOOL CListEdit::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if( pMsg->message == WM_KEYDOWN )
{
if(pMsg->wParam == VK_RETURN
|| pMsg->wParam == VK_DELETE
|| pMsg->wParam == VK_ESCAPE
|| GetKeyState( VK_CONTROL)
)
{
::TranslateMessage(pMsg);
::DispatchMessage(pMsg);
return TRUE; // DO NOT process further
}
}
return CEdit::PreTranslateMessage(pMsg);
}
void CListEdit::OnKillFocus(CWnd* pNewWnd)
{
CEdit::OnKillFocus(pNewWnd);
CString str;
GetWindowText(str);
// Send Notification to parent of ListView ctrl
LV_DISPINFO dispinfo;
dispinfo.hdr.hwndFrom = GetParent()->m_hWnd;
dispinfo.hdr.idFrom = GetDlgCtrlID();
dispinfo.hdr.code = LVN_ENDLABELEDIT;
dispinfo.item.mask = LVIF_TEXT;
dispinfo.item.iItem = m_iItem;
dispinfo.item.iSubItem = m_iSubItem;
dispinfo.item.pszText = m_bESC ? NULL : LPTSTR((LPCTSTR)str);
dispinfo.item.cchTextMax = str.GetLength();
GetParent()->GetParent()->SendMessage( WM_NOTIFY, GetParent()->GetDlgCtrlID(),
(LPARAM)&dispinfo );
DestroyWindow();
}
void CListEdit::OnNcDestroy()
{
CEdit::OnNcDestroy();
// TODO: Add your message handler code here
delete this;
}
void CListEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
if( nChar == VK_ESCAPE || nChar == VK_RETURN)
{
if( nChar == VK_ESCAPE )
m_bESC = TRUE;
GetParent()->SetFocus();
return;
}
CEdit::OnChar(nChar, nRepCnt, nFlags);
// Resize edit control if needed
// Get text extent
CString str;
GetWindowText( str );
CWindowDC dc(this);
CFont *pFont = GetParent()->GetFont();
CFont *pFontDC = dc.SelectObject( pFont );
CSize size = dc.GetTextExtent( str );
dc.SelectObject( pFontDC );
size.cx += 5; // add some extra buffer
// Get client rect
CRect rect, parentrect;
GetClientRect( &rect );
GetParent()->GetClientRect( &parentrect );
// Transform rect to parent coordinates
ClientToScreen( &rect );
GetParent()->ScreenToClient( &rect );
// Check whether control needs to be resized
// and whether there is space to grow
if( size.cx > rect.Width() )
{
if( size.cx + rect.left < parentrect.right )
rect.right = rect.left + size.cx;
else
rect.right = parentrect.right;
MoveWindow( &rect );
}
//●
m_Modified=TRUE;
//●
// CEdit::OnChar(nChar, nRepCnt, nFlags);
}
int CListEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CEdit::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
if (CEdit::OnCreate(lpCreateStruct) == -1)
return -1;
// Set the proper font
CFont* font = GetParent()->GetFont();
SetFont(font);
SetWindowText( m_sInitText );
SetFocus();
SetSel( 0, -1 );
m_Modified=FALSE;
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// CListEdit message handlers
//●●●●●●
IMPLEMENT_DYNCREATE(CEditListView, CListView)
CEditListView::CEditListView()
{
m_dwDefaultStyle |= LVS_REPORT|LVS_EDITLABELS;
m_bEditing=FALSE;
}
CEditListView::~CEditListView()
{
}
BEGIN_MESSAGE_MAP(CEditListView, CListView)
//{{AFX_MSG_MAP(CEditListView)
ON_WM_HSCROLL()
ON_WM_VSCROLL()
ON_WM_LBUTTONDOWN()
ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndlabeledit)
ON_COMMAND(ID_TRANS, OnTrans)
ON_UPDATE_COMMAND_UI(ID_TRANS, OnUpdateTrans)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CEditListView drawing
void CEditListView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
}
/////////////////////////////////////////////////////////////////////////////
// CEditListView diagnostics
#ifdef _DEBUG
void CEditListView::AssertValid() const
{
CListView::AssertValid();
}
void CEditListView::Dump(CDumpContext& dc) const
{
CListView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CEditListView message handlers
/////////////////////////////////////////////////////////////////////////////
void CEditListView::OnInitialUpdate()
{
CListView::OnInitialUpdate();
// TODO: Add your specialized code here and/or call the base class
//●
CODBCTransDoc * pDoc;
pDoc=(CODBCTransDoc * )GetDocument();
m_List=&GetListCtrl();
if(pDoc->m_pSet==NULL)
{
AfxMessageBox("尚未初始化ODBC记录集!");
return;
}
if(!pDoc->m_pSet->IsOpen())
{
pDoc->m_pSet->Open();
}
//1. 添加列:
short i,j;
CODBCFieldInfo Fi;
CString tmp;
LV_COLUMN lc;
lc.mask = LVCF_FMT | LVCF_WIDTH |
LVCF_TEXT | LVCF_SUBITEM;
for(i=0;i<pDoc->m_pSet->m_nFields;i++)
{
pDoc->m_pSet->GetODBCFieldInfo(i,Fi);
lc.iSubItem = i;
lc.fmt = LVCFMT_CENTER;
lc.cx = Fi.m_strName.GetLength()*10+16;
lc.pszText=Fi.m_strName.GetBuffer(Fi.m_strName.GetLength());
GetListCtrl().InsertColumn(i, &lc);
}
//2. 添加行:
LV_ITEM Item;
CString str;
CDBVariant var;
i=0;
if(pDoc->m_pSet->IsEOF())
{
AfxMessageBox("当前视图没有记录!");
return;
}
pDoc->m_pSet->MoveFirst();
while(pDoc->m_pSet->IsEOF()==0)
{
Item.mask=LVIF_TEXT;
//第i 行:
Item.iItem=i;
//第一列:
Item.iSubItem=0;
pDoc->m_pSet->GetFieldValue((short)0,str);
Item.pszText=str.GetBuffer(str.GetLength());
m_List->InsertItem(&Item);
//其它各列:
for(j=1;j<pDoc->m_pSet->m_nFields;j++)
{
//==>Wrong!
pDoc->m_pSet->GetFieldValue((short)j,str);//获取数据;
m_List->SetItemText(i,j,str.GetBuffer(str.GetLength()));
}
pDoc->m_pSet->MoveNext();
i++;//计数器;
}
//★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★
//●
pDoc->m_pSet->m_pDatabase->BeginTrans();
//●
}
//根据point值,判断point所在行和列:
int CEditListView::HitTestEx(CPoint &point, int *col)
{
int column = 0;
int row = m_List->HitTest( point,NULL );
if( col ) *col = 0;
// Make sure that the ListView is in LVS_REPORT
if( (GetWindowLong(m_List->m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT )
return row;
// Get the top and bottom row visible
row = m_List->GetTopIndex();
int bottom = row + m_List->GetCountPerPage();
if( bottom > m_List->GetItemCount() )
bottom = m_List->GetItemCount();
// Get the number of columns
CHeaderCtrl* pHeader = (CHeaderCtrl*)m_List->GetDlgItem(0);
int nColumnCount = pHeader->GetItemCount();
// Loop through the visible rows
for( ;row <=bottom;row++)
{
// Get bounding rect of item and check whether point falls in it.
CRect rect;
m_List->GetItemRect( row, &rect, LVIR_BOUNDS );
if( rect.PtInRect(point) )
{
// Now find the column
for( column = 0; column < nColumnCount; column++ )
{
int colwidth = m_List->GetColumnWidth(column);
if( point.x >= rect.left
&& point.x <= (rect.left + colwidth ) )
{
if( col ) *col = column;
CString tp;
return row;
}
rect.left += colwidth;
}
}
}
if( col ) *col = -1;
return -1;
}
///////////////////////////////////////////////////////////
CEdit * CEditListView::EditSubLabel(int nItem, int nCol)
{
// The returned pointer should not be saved
// Make sure that the item is visible
if( !m_List->EnsureVisible( nItem, TRUE ) ) return NULL;
// Make sure that nCol is valid
CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
int nColumnCount = pHeader->GetItemCount();
if( nCol >= nColumnCount ||m_List->GetColumnWidth(nCol) < 5 )
return NULL;
// Get the column offset
int offset = 0;
for( int i = 0; i < nCol; i++ )
offset += m_List->GetColumnWidth( i );
CRect rect;
m_List->GetItemRect(nItem,&rect,LVIR_BOUNDS);
// Now scroll if we need to expose the column
CRect rcClient;
m_List->GetClientRect( &rcClient );
if( offset + rect.left < 0 || offset + rect.left > rcClient.right )
{
CSize size;
size.cx = offset + rect.left;
size.cy = 0;
m_List->Scroll( size );
rect.left -= size.cx;
}
// Get Column alignment
LV_COLUMN lvcol;
lvcol.mask = LVCF_FMT;
m_List->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+4;
rect.right = rect.left + m_List->GetColumnWidth( nCol ) - 3 ;
if( rect.right > rcClient.right) rect.right = rcClient.right;
dwStyle |= WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL;
pEdit = new CListEdit(nItem, nCol,m_List->GetItemText( nItem, nCol ));
pEdit->Create(dwStyle,rect,this,IDC_LISTEDIT );
pEdit->m_sInitText=m_List->GetItemText(nItem,nCol);
pEdit->SetWindowText(pEdit->m_sInitText);
pEdit->SetSel(0,-1,FALSE);
m_bEditing=TRUE;
return pEdit;
}
void CEditListView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call default
if( GetFocus() != this ) SetFocus();
CListView::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CEditListView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call default
if( GetFocus() != this ) SetFocus();
CListView::OnVScroll(nSBCode, nPos, pScrollBar);
}
void CEditListView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CListView::OnLButtonDown(nFlags, point);
int index;
int column;
if( ( index = HitTestEx( point, &column )) != -1 )
{
UINT flag = LVIS_FOCUSED;
if( (m_List->GetItemState( index, flag ) & flag) == flag && column > 0)
{
// Add check for LVS_EDITLABELS
if( GetWindowLong(m_hWnd, GWL_STYLE) & LVS_EDITLABELS )
EditSubLabel( index, column );
}
else
m_List->SetItemState( index, LVIS_SELECTED | LVIS_FOCUSED ,
LVIS_SELECTED | LVIS_FOCUSED);
}
// CListView::OnLButtonDown(nFlags, point);
}
void CEditListView::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
// TODO: Add your control notification handler code here
LV_ITEM *plvItem = &pDispInfo->item;
if (plvItem->pszText != NULL)
{
m_List->SetItemText(plvItem->iItem, plvItem->iSubItem, plvItem->pszText);
}
m_bEditing=FALSE;
*pResult = 0;
//●
m_Modified=pEdit->m_Modified;
if(m_Modified)
{
Modify(plvItem->iItem, plvItem->iSubItem, plvItem->pszText);
}
//●
}
BOOL CEditListView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// TODO: Add your specialized code here and/or call the base class
if(m_bEditing)
{
switch (((NMHDR*)lParam)->code)
{
case HDN_BEGINTRACKW:
case HDN_BEGINTRACKA:
*pResult = TRUE; // disable tracking
return TRUE; // Processed message
}
}
return CListView::OnNotify(wParam, lParam, pResult);
}
void CEditListView::Modify(int r,int c, CString Val)
{
CODBCTransDoc * pDoc;
pDoc=(CODBCTransDoc * )GetDocument();
if(!pDoc->m_pSet->IsOpen())
{
AfxMessageBox("记录集对象尚未打开!");
return;
}
if(pEdit->m_Modified)
{
pDoc->m_pSet->MoveFirst();
pDoc->m_pSet->Move(r);
TRY
{
pDoc->m_pSet->Edit();
switch(c)
{
case 0:
{
pDoc->m_pSet->m_ID=atol(Val);
break;
}
case 1:
{
pDoc->m_pSet->m_column1=Val;
break;
}
case 2:
{
pDoc->m_pSet->m_column2=Val;
break;
}
case 3:
{
pDoc->m_pSet->m_column3=atol(Val);
break;
}
case 4:
{
CString Year,Month,Day,Hour,Min,Sec;
CString OldTime;
int yy,mm,dd,hh,mi,ss;
if(Val.GetLength()!=19)
{
pDoc->m_pSet->GetFieldValue(c,OldTime);
AfxMessageBox("时间格式不对!");
m_List->SetItemText(r,c,OldTime);
break;
}
Year=Val.Left(4);
Month=Val.Mid(5,2);
Day=Val.Mid(8,2);
Hour=Val.Mid(11,2);
Min=Val.Mid(14,2);
Sec=Val.Mid(17,2);
yy=atoi(Year);
mm=atoi(Month);
dd=atoi(Day);
hh=atoi(Hour);
mi=atoi(Min);
ss=atoi(Sec);
if(!(dd>= 1 && dd<= 31))
{
AfxMessageBox("日期应该在1-31之间!");
break;
}
if(!(mm>= 1 &&mm<= 12))
{
AfxMessageBox("月份应该在1-12之间!");
break;
}
if(!(yy>= 1900))
{
AfxMessageBox("年份应该在1900年之后!");
break;
}
CTime time(yy,mm,dd,hh,mi,ss);
pDoc->m_pSet->m_column4=time;
break;
}
case 5:
{
pDoc->m_pSet->m_column5=Val;
break;
}
case 6:
{
pDoc->m_pSet->m_column6=atol(Val);
break;
}
case 7:
{
pDoc->m_pSet->m_column7=Val;
break;
}
};
pDoc->m_pSet->Update();
}
CATCH_ALL(e)
{
AfxMessageBox("更新数据库失败,将事务回滚!");
pDoc->m_pSet->m_pDatabase->Rollback();
}
END_CATCH_ALL
}
}
void CEditListView::OnTrans()
{
// TODO: Add your command handler code here
CODBCTransDoc * pDoc;
pDoc=(CODBCTransDoc * )GetDocument();
if(pEdit->m_Modified)
{
TRY
{
pDoc->m_pSet->m_pDatabase->CommitTrans();
}
CATCH(CDBException,e)
{
AfxMessageBox("提交事务失败,开始回滚事务!");
pDoc->m_pSet->m_pDatabase->Rollback();
}
END_CATCH
}
m_Modified=FALSE;
}
void CEditListView::OnUpdateTrans(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if(m_Modified&&(!m_bEditing))
{
pCmdUI->Enable(TRUE);
}
else
{
pCmdUI->Enable(FALSE);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -