www.pudn.com > ListViewStradley_demo.zip > listctl.cpp


// listctl.cpp : implementation file 
// This is the class that handles all the messages that are sent to the  
// list control on the dialog box.  It also contains a class, CMyEdit, which 
// catches all the messages sent to the edit box during editing 
 
#include "stdafx.h" 
#include "ListView.h" 
#include "listctl.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CMyListCtl 
 
CMyListCtl::CMyListCtl() 
{ 
} // CMyListCtl 
 
CMyListCtl::~CMyListCtl() 
{ 
} // ~CMyListCtl 
 
BEGIN_MESSAGE_MAP(CMyListCtl, CListCtrl) 
    //{{AFX_MSG_MAP(CMyListCtl) 
    ON_NOTIFY_REFLECT(LVN_BEGINLABELEDIT, OnBeginLabelEdit) 
    ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndLabelEdit) 
    ON_NOTIFY_REFLECT(NM_CLICK, OnClick) 
    ON_WM_KEYDOWN() 
    ON_WM_GETDLGCODE() 
    //}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CMyListCtl message handlers 
 
// this is to tell the dialog that you do not want him to steal some of 
// your keystrokes (i.e. enter and tab) 
UINT  
CMyListCtl::OnGetDlgCode ()  
{ 
    UINT Code = CListCtrl::OnGetDlgCode () | DLGC_WANTARROWS | DLGC_WANTTAB; 
    return Code; 
} // OnGetDlgCode 
 
// this function puts the next or previous row in edit mode 
void 
CMyListCtl::selectNext (BOOL Forward /* = TRUE */) 
{ 
    int cItems = GetItemCount (); 
    int iItem = -1; 
    iItem = GetNextItem (iItem, LVIS_SELECTED); 
    int iEditItem = 0; 
    SetFocus (); 
    if (Forward) 
    { 
		if (iItem + 1 >= cItems) 
			iEditItem = 0; 
		else 
			iEditItem = iItem + 1; 
    } 
    else 
    { 
		if (iItem - 1 < 0) 
			iEditItem = cItems - 1; 
		else 
			iEditItem = iItem - 1; 
    } 
 
    EditLabel (iEditItem); 
} // selectNext 
 
// put the item in edit mode when the user clicks on it 
void  
CMyListCtl::OnClick (NMHDR* pNMHDR, LRESULT* pResult)  
{ 
    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; 
    EditLabel (pNMListView->iItem); 
 
    *pResult = 0;	 
} // OnClick 
 
// catch keys to navigate amongst the fields 
void  
CMyListCtl::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
	switch (nChar) 
	{ 
		case VK_TAB: 
		{ 
			// tab moves to the next field, shift + tab moves to the previous 
			BOOL Shift = (GetKeyState (VK_SHIFT) >= 0); 
			selectNext (Shift); 
			break; 
		} 
		case VK_UP : 
		{ 
			selectNext (FALSE); 
			break; 
		} 
		case VK_DOWN : 
		{ 
			selectNext (); 
			break; 
		} 
		case VK_F2: 
		{ 
			// F2 puts the current item in edit mode (like most spreadsheet programs) 
			int iItem = -1; 
			iItem = GetNextItem (iItem, LVIS_SELECTED); 
			EditLabel (iItem); 
			break; 
		} 
		default : 
		{ 
			CListCtrl::OnKeyDown(nChar, nRepCnt, nFlags); 
			break; 
		} 
    }	 
} // OnKeyDown 
 
// when the user begins editing, the CListStrl wants to pop an edit box. 
// we need to subclass that edit box, so that we may catch the key down 
// messages and forward them to the list for navigating 
void  
CMyListCtl::OnBeginLabelEdit (NMHDR* pNMHDR, LRESULT* pResult)  
{ 
    LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR; 
    *pResult = 1; 
     
    CRect ItemRect; 
    GetItemRect (pDispInfo->item.iItem, ItemRect, LVIR_LABEL); 
 
    HWND hWnd = (HWND)SendMessage (LVM_GETEDITCONTROL); 
    ASSERT (hWnd != NULL); 
    if (m_Edit.m_hWnd != 0) 
		m_Edit.DestroyWindow (); 
    VERIFY (m_Edit.SubclassWindow (hWnd)); 
 
    m_Edit.x = ItemRect.left; 
    m_Edit.y = ItemRect.top - 1; 
    m_Edit.SetWindowText (GetItemText (pDispInfo->item.iItem, 0)); 
 
    *pResult = 0; 
} // OnBeginLabelEdit 
 
// when the editing ends, we need to unsubclass the edit box before it gets destroyed 
void  
CMyListCtl::OnEndLabelEdit (NMHDR* pNMHDR, LRESULT* pResult)  
{ 
    LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR; 
    int iField = (int)pDispInfo->item.lParam; 
    CString NewText (pDispInfo->item.pszText); 
     
    SetItem (&pDispInfo->item); 
    *pResult = 1; 
 
    if (m_Edit.m_hWnd) 
		VERIFY (m_Edit.UnsubclassWindow () != NULL); 
} // OnEndLabelEdit