📄 listeditctrl.cpp
字号:
// **************************************************************************
// listeditctrl.cpp
//
// Description:
// Implements a special combination list/edit control class used by the
// CKItemWriteDlg class.
//
// DISCLAIMER:
// This programming example is provided "AS IS". As such Kepware, Inc.
// makes no claims to the worthiness of the code and does not warranty
// the code to be error free. It is provided freely and can be used in
// your own projects. If you do find this code useful, place a little
// marketing plug for Kepware in your code. While we would love to help
// every one who is trying to write a great OPC client application, the
// uniqueness of every project and the limited number of hours in a day
// simply prevents us from doing so. If you really find yourself in a
// bind, please contact Kepware's technical support. We will not be able
// to assist you with server related problems unless you are using KepServer
// or KepServerEx.
// **************************************************************************
#include "stdafx.h"
#include "opctestclient.h"
#include "listeditctrl.h"
#define IDC_LISTEDIT 1
/////////////////////////////////////////////////////////////////////////////
// CKListEditCtrl
/////////////////////////////////////////////////////////////////////////////
// **************************************************************************
BEGIN_MESSAGE_MAP (CKListEditCtrl, CListCtrl)
//{{AFX_MSG_MAP(CKListEditCtrl)
ON_NOTIFY_REFLECT (LVN_ENDLABELEDIT, OnEndLabelEdit)
ON_WM_LBUTTONDOWN ()
//}}AFX_MSG_MAP
ON_MESSAGE (UM_ONUPARROW, OnPrevSubLabel)
ON_MESSAGE (UM_ONDNARROW, OnNextSubLabel)
END_MESSAGE_MAP ()
// **************************************************************************
// CKListEditCtrl ()
//
// Description:
// Constructor.
//
// Parameters:
// none
//
// Returns:
// none
// **************************************************************************
CKListEditCtrl::CKListEditCtrl ()
{
// Initialize member variables:
m_nSelItem = -1;
}
// **************************************************************************
// ~CKListEditCtrl ()
//
// Description:
// Destructor.
//
// Parameters:
// none
//
// Returns:
// none
// **************************************************************************
CKListEditCtrl::~CKListEditCtrl ()
{
}
// **************************************************************************
// HitTestEx ()
//
// Description:
// Determine which item or subitem was hit.
//
// Parameters:
// CPoint &cPoint Current locaction of mouse cursor
// int *pCol Gets set to column hit was in.
//
// Returns:
// int - Row hit was in, or -1 if hit was not on a cell.
// **************************************************************************
int CKListEditCtrl::HitTestEx (CPoint &cPoint, int *pCol)
{
int nCol = 0;
int nRow = HitTest (cPoint, NULL);
int nBottom = 0;
int cnColumns = 0;
// Initialize returned column number to zero:
if (pCol)
*pCol = 0;
// Make sure that the ListView is in LVS_REPORT format:
if ((GetWindowLong (m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT)
return (nRow);
// Get the top and bottom visible rows:
nRow = GetTopIndex ();
nBottom = nRow + GetCountPerPage ();
// Make sure bottom index is valid:
if (nBottom > GetItemCount ())
nBottom = GetItemCount ();
// Get the number of columns:
CHeaderCtrl* pHeader = (CHeaderCtrl*) GetDlgItem (0);
cnColumns = pHeader->GetItemCount ();
// Determine which row the hit occurred:
for (; nRow <= nBottom; nRow++)
{
// Get bounding rect of item:
CRect rect;
GetItemRect (nRow, &rect, LVIR_BOUNDS);
// Check to see if the point falls in bounds of that row:
if (rect.PtInRect (cPoint))
{
// Hit was in this row. Now find the column:
for (nCol = 0; nCol < cnColumns; nCol++)
{
int nColWidth = GetColumnWidth (nCol);
// If hit is within this column, return:
if (cPoint.x >= rect.left && cPoint.x <= (rect.left + nColWidth))
{
if (pCol)
*pCol = nCol;
return (nRow);
}
// Adjust left side of row's rectangle so we will look at
// next column ntext time around loop:
rect.left += nColWidth;
}
}
}
// If we make it here, then the hit was not on a cell. Return -1
// to indicate failure:
return (-1);
}
// **************************************************************************
// EditSubLabel ()
//
// Description:
// Edit the subitem value. Creates a CEdit object sized and placed to cover
// list control cell. This edit box is needed to receive user input, and
// will delete itself when its parent window is destroyed.
//
// Parameters:
// int nItem Index of item
// int nCol Column of item
//
// Returns:
// CEdit* - Pointer to a CEdit object to be used to edit cell.
// **************************************************************************
CEdit* CKListEditCtrl::EditSubLabel (int nItem, int nCol)
{
int cnColumns = 0;
int nColOffset = 0;
// Make sure that the item is visible:
if (!EnsureVisible (nItem, TRUE))
return (NULL);
// Get the number of columns:
CHeaderCtrl* pHeader = (CHeaderCtrl*) GetDlgItem (0);
cnColumns = pHeader->GetItemCount ();
// Make sure that column is valid:
if (nCol >= cnColumns || GetColumnWidth (nCol) < 5)
return (NULL);
// Get the column offset (from left boundary):
nColOffset = 0;
for (int i = 0; i < nCol; i++)
nColOffset += GetColumnWidth (i);
// Get selected item's rectangle:
CRect rect;
GetItemRect (nItem, &rect, LVIR_BOUNDS);
// Scroll if we need to expose the column:
CRect rcClient;
GetClientRect (&rcClient);
if (nColOffset + rect.left < 0 || nColOffset + rect.left > rcClient.right)
{
CSize size;
size.cx = nColOffset + rect.left;
size.cy = 0;
Scroll (size);
rect.left -= size.cx;
}
// Get column alignment:
LV_COLUMN lvcol;
lvcol.mask = LVCF_FMT;
GetColumn (nCol, &lvcol);
DWORD dwStyle;
switch (lvcol.fmt & LVCFMT_JUSTIFYMASK)
{
case LVCFMT_LEFT:
dwStyle = ES_LEFT;
break;
case LVCFMT_RIGHT:
dwStyle = ES_RIGHT;
break;
default:
dwStyle = ES_CENTER;
break;
}
rect.left += (nColOffset + 4);
rect.right = rect.left + GetColumnWidth (nCol) - 10;
if (rect.right > rcClient.right)
rect.right = rcClient.right;
// Defile edit control (base class) style:
dwStyle |= WS_BORDER | WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL;
// Create a new CKListEdit box (not to be confused with CKListEditCtrl):
CEdit *pEdit = new CKListEdit (nItem, nCol, GetItemText (nItem, nCol));
// Set style, size and position using base class:
pEdit->Create (dwStyle, rect, this, IDC_LISTEDIT);
// Update currently selected item:
m_nSelItem = nItem;
// Return pointer to new CKListEdit control:
return (pEdit);
}
/////////////////////////////////////////////////////////////////////////////
// CKListEditCtrl message handlers
/////////////////////////////////////////////////////////////////////////////
// **************************************************************************
// OnEndLabelEdit ()
//
// Description:
// Handles notification message that notifies a list view control parent
// window about the end of label editing for an item.
//
// Parameters:
// NMHDR *pNMHDR Contains information about a notification message.
// LRESULT *pResult A 32-bit value returned from a window procedure
// or callback function.
//
// Returns:
// void
// **************************************************************************
void CKListEditCtrl::OnEndLabelEdit (NMHDR *pNMHDR, LRESULT *pResult)
{
LV_DISPINFO *plvDispInfo = (LV_DISPINFO *)pNMHDR;
LV_ITEM *plvItem = &plvDispInfo->item;
// We are being asked for item's text:
if (plvItem->pszText != NULL)
SetItemText (plvItem->iItem, plvItem->iSubItem, plvItem->pszText);
}
// **************************************************************************
// OnLButtonDown ()
//
// Description:
// Left mouse button down event handler.
//
// Parameters:
// UINT nFlags Flags.
// CPoint cPoint Current location of mouse cursor.
//
// Returns:
// void
// **************************************************************************
void CKListEditCtrl::OnLButtonDown (UINT nFlags, CPoint cPoint)
{
int nIndex;
int nCol;
// Perform default processing:
CListCtrl::OnLButtonDown (nFlags, cPoint);
// Determine which item (i.e, row was hit):
if ((nIndex = HitTestEx (cPoint, &nCol)) != -1)
{
// If the item column clicked on is editable, display an edit control:
if (nCol > 1) // Only last column is editable
EditSubLabel (nIndex, nCol);
// otherwise select the item:
else
SetItemState (nIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
}
}
// **************************************************************************
// OnPrevSubLabel ()
//
// Description:
// On Up Arrow message handler.
//
// Parameters:
// WPARAM wParam Not used.
// LPARAM lParam Not used.
//
// Returns:
// long - 0.
// **************************************************************************
long CKListEditCtrl::OnPrevSubLabel (WPARAM wParam, LPARAM lParam)
{
// Previous item:
--m_nSelItem;
// Wrap to end if previous is invalid:
if (m_nSelItem < 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -