📄 itemview.cpp
字号:
break;
case 2: // Value
{
// Get string representation of values:
static CString strValue1;
static CString strValue2;
pItem1->GetValue (strValue1);
pItem2->GetValue (strValue2);
// Compare strings:
nRC = lstrcmp (strValue1, strValue2);
}
break;
case 3: // Timestamp
{
// Get string representation of timestamp:
static CString strTimeStamp1;
static CString strTimeStamp2;
pItem1->GetTimeStamp (strTimeStamp1);
pItem2->GetTimeStamp (strTimeStamp2);
// Compare strings:
nRC = lstrcmp (strTimeStamp1, strTimeStamp2);
}
break;
case 4: // Quality
// Quality is a string, so do string compare:
nRC = lstrcmp (pItem1->GetQuality (), pItem2->GetQuality ());
break;
case 5: // Update Count
{
// Get update counts:
DWORD dwUpdates1 = pItem1->GetUpdateCount ();
DWORD dwUpdates2 = pItem2->GetUpdateCount ();
// Compare numerical update counts:
if (dwUpdates1 == dwUpdates2)
nRC = 0;
else if (dwUpdates1 > dwUpdates2)
nRC = -1;
else
nRC = 1;
}
break;
// Unexpected column index:
default:
ASSERT (FALSE);
break;
}
// Equal items should be sorted by item ID:
if (sm_wSortColumn && nRC == 0)
nRC = lstrcmp (pItem1->GetItemID (), pItem2->GetItemID ());
// If the order is descending, reverse the result:
if (LOWORD (sm_wSortOrder) == DESCENDING)
nRC = -nRC;
// Return the result:
return (nRC);
}
// **************************************************************************
// SortList ()
//
// Description:
// Sort items in the list control. Registers a CompareItems function with
// qsort for sort comparisons.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKItemView::SortList ()
{
// Create a CSafeLock to make this object thread safe. Our critical
// section gets locked here, and will automatically be unlocked when the
// CSafeLock goes out of scope.
CSafeLock cs (&m_csSortedList);
// Get reference to out list control:
CListCtrl &cList = GetListCtrl ();
// If there are no items in the list, then there is nothing to do:
if (!m_cnSortedItems)
return;
// Get number of selected items:
int cnSelections = cList.GetSelectedCount ();
// Initialize a variable to contain the index of item with focus:
int nFocus = -1;
// Save off selected items so we can restore them after sort:
CMemFile cMem (cnSelections * sizeof (DWORD));
// Don't bother looking for selected items if there are none:
if (cnSelections)
{
// Find the first selected item:
int nSel = cList.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
// Save the items index if it has the focus:
if (cList.GetItemState (nSel, LVIS_FOCUSED) == LVIS_FOCUSED)
nFocus = sm_pSortedItemList [nSel];
// Clear the selection and store off the array element (pointer
// to CKItem object):
cList.SetItemState (nSel, 0, LVIS_SELECTED | LVIS_FOCUSED);
cMem.Write (&sm_pSortedItemList [nSel], sizeof (DWORD));
// Store off remaining selections:
int n = cnSelections;
while (--n)
{
// Get index of next selected item:
nSel = cList.GetNextItem (nSel, LVNI_BELOW | LVNI_SELECTED);
ASSERT (nSel != -1);
// Store it's index if it has the focus:
if (nFocus == -1 && cList.GetItemState (nSel, LVIS_FOCUSED) == LVIS_FOCUSED)
nFocus = sm_pSortedItemList [nSel];
// Clear the selection and store off the index:
cList.SetItemState (nSel, 0, LVIS_SELECTED | LVIS_FOCUSED);
cMem.Write (&sm_pSortedItemList [nSel], sizeof (DWORD));
}
}
// Sort the list. qsort function requires us to define a function to
// compare items.
qsort ((void *)sm_pSortedItemList, m_cnSortedItems,
sizeof (sm_pSortedItemList [0]), CompareItems);
// Now restore original selections:
if (cnSelections)
{
// Reset file pointer to beginning:
cMem.SeekToBegin ();
// There is one unsorted index in the memory file for each
// selection detected above:
for (int i = 0; i < cnSelections; i++)
{
// Read the index (actually pointer to CKItem object cast as DWORD)
// of first selected item:
DWORD dwIndex;
cMem.Read (&dwIndex, sizeof (DWORD));
// Find the item's location in the sorted array. Look at each
// element in array until we find the item:
for (int j = 0; j < m_cnSortedItems; j++)
{
// We have found the item if the array element is the original index:
if (sm_pSortedItemList [j] == dwIndex)
{
// Make sure the focused item is visible:
if (dwIndex == (DWORD)nFocus)
{
cList.EnsureVisible (j, false);
cList.SetItemState (j, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
}
// Restore selection:
else
cList.SetItemState (j, LVIS_SELECTED, LVIS_SELECTED);
// If we are here, we found the item. No need to continue
// searching so break out of loop.
break;
}
}
}
}
// Force the list control to repaint itself:
GetListCtrl ().Invalidate (true);
}
// **************************************************************************
// GetSelectedCount ()
//
// Description:
// Get number of items currently selected.
//
// Parameters:
// none
//
// Returns:
// int - Number of selected items.
// **************************************************************************
int CKItemView::GetSelectedCount ()
{
// Call the list control's GetSelectedCount function and return result:
return (GetListCtrl ().GetSelectedCount ());
}
// **************************************************************************
// GetSelectedItems ()
//
// Description:
// Load an object array with item objects currently selected in list control.
//
// Parameters:
// CObArray &cItemList Output array of items.
//
// Returns:
// int - Number of items loaded into array.
// **************************************************************************
int CKItemView::GetSelectedItems (CObArray &cItemList)
{
// Get number of selected items:
DWORD dwSelectedCount = GetSelectedCount ();
// If there are selected items, fill the object array with them:
if (dwSelectedCount)
{
// Get reference to our list control:
CListCtrl &cListCtrl = GetListCtrl ();
// Initialize some variables use in search for selected items:
int nSelIndex = -1;
CKItem *pItem = NULL;
DWORD dwCount = 0;
// Be prepared to handle exceptions that might be thrown by
// object array:
try
{
// Allocate enough array memory to hold all the selected items:
cItemList.SetSize (dwSelectedCount);
// Get the first selected item:
nSelIndex = cListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
// Continue loading selected items until we get them all:
while ((nSelIndex >= 0) && (dwCount <= dwSelectedCount))
{
// Insert the item this selection represents into the list:
pItem = (CKItem *) sm_pSortedItemList [nSelIndex];
ASSERT (pItem != NULL);
// Add the item to the array:
cItemList.SetAt (dwCount++, pItem);
// See if there is another selected item below the current one:
nSelIndex = cListCtrl.GetNextItem (nSelIndex, LVNI_ALL | LVNI_SELECTED);
}
}
catch (...)
{
ASSERT (FALSE);
dwSelectedCount = 0;
}
}
// Return the number of selected items:
return (dwSelectedCount);
}
// **************************************************************************
// GetSelectedGroup ()
//
// Description:
// Get pointer to currently selected group.
//
// Parameters:
// none
//
// Returns:
// CKGroup* - Pointer to selected group object.
// **************************************************************************
CKGroup* CKItemView::GetSelectedGroup ()
{
// Get pointer to out document object:
CKDocument *pDoc = (CKDocument *) GetDocument ();
ASSERT (pDoc != NULL);
// Ask document for pointer to selected group object. Document should
// have been advised of current selection.
CKGroup *pGroup = pDoc->GetSelectedGroup ();
// Return pointer:
return (pGroup);
}
// **************************************************************************
// GetSelectedServer ()
//
// Description:
// Get pointer to currently selected server.
//
// Parameters:
// none
//
// Returns:
// CKServer* - Pointer to selected server object.
// **************************************************************************
CKServer* CKItemView::GetSelectedServer ()
{
// Get pointer to out document object:
CKDocument *pDoc = (CKDocument *) GetDocument ();
ASSERT (pDoc != NULL);
// Ask document for pointer to selected server object. Document should
// have been advised of current selection.
CKServer *pServer = (pDoc->GetSelectedGroup ())->GetParentServer ();
// Return pointer:
return (pServer);
}
// **************************************************************************
// GetCellRectFromPoint ()
//
// Description:
// Return the cell boundaries that a point resides in, along with the
// associated list control row and column.
//
// Parameters:
// CPoint &cPoint Point.
// CRect &rc Rectangle that defines cell cPoint resides in.
// int *pCol Column cPoint resides in.
//
// Returns:
// int - The row cPoint resides in, or -1 if not in a cell.
// **************************************************************************
int CKItemView::GetCellRectFromPoint (CPoint &cPoint, CRect &rc, int *pCol) const
{
int nCol = 0;
int nRow = 0;
int nBottom = 0;
int cnColumns = 0;
// Get reference to our list control:
CListCtrl &cList = GetListCtrl ();
// Get the row number of top item:
nRow = cList.GetTopIndex ();
// Compute the row number of bottom item:
nBottom = nRow + cList.GetCountPerPage ();
// Make sure bottom row number is valid:
if (nBottom > cList.GetItemCount ())
nBottom = cList.GetItemCount ();
// Get the number of columns (better be NUMCOLUMNS):
CHeaderCtrl* pHeader = (CHeaderCtrl*) GetDlgItem (0);
cnColumns = pHeader->GetItemCount ();
// Determine which row the hit occurred. Loop over visible rows:
for (; nRow <= nBottom; nRow++)
{
// Get bounding rect of item:
cList.GetItemRect (nRow, &rc, LVIR_BOUNDS);
// If the point falls in bounds, we found the row:
if (rc.PtInRect (cPoint))
{
// Now find the column. Loop over columns:
for (nCol = 0; nCol < cnColumns; nCol++)
{
// Get the width of column:
int nColWidth = cList.GetColumnWidth (nCol);
// If the within the column boundaries, we found the column:
if (cPoint.x >= rc.left && cPoint.x <= (rc.left + nColWidth))
{
// At this point, rc will describe all but the right
// boundary of the cell. The top and bottom we set
// when we found the row. The left boundary was set
// when we checked this column.
// Now get client area. We will use it later:
CRect rcClient;
GetClientRect (&rcClient);
// Set the column number for output, provided pointer
// was set by colling function:
if (pCol)
*pCol = nCol;
// Adjust right boundary so that rc now full describes
// the cell:
rc.right = rc.left + nColWidth;
// Adjust the right boundary again to ensure that it does
// not exceed client area:
if (rc.right > rcClient.right)
rc.right = rcClient.right;
// We have everything we need now, so return:
return (nRow);
}
// Adjust the left boundary so we can check the next column:
rc.left += nColWidth;
}
}
}
// If we make it here, then hit was not over a cell. Return
// -1 to indicate this:
return (-1);
}
// **************************************************************************
// RequireCellToolTip ()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -