⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 itemview.cpp

📁 KepWare的OPC Client 示例.面向C
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			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 + -