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