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

📄 itemview.cpp

📁 KepWare的OPC Client 示例.面向C
💻 CPP
📖 第 1 页 / 共 5 页
字号:

			// Add a separator if we have already added menu items:
			if (cMenu.GetMenuItemCount () > 0)
				cMenu.AppendMenu (MF_SEPARATOR);

			// Add Cut menu item:
			pMainMenu->GetMenuString (ID_EDIT_CUT, strMenuText, MF_BYCOMMAND);
			cMenu.AppendMenu (nFlags, ID_EDIT_CUT, strMenuText);

			// Add Copy menu item:
			pMainMenu->GetMenuString (ID_EDIT_COPY, strMenuText, MF_BYCOMMAND);
			cMenu.AppendMenu (nFlags, ID_EDIT_COPY, strMenuText);

			// Add Paste menu item:
			pMainMenu->GetMenuString (ID_EDIT_PASTE, strMenuText, MF_BYCOMMAND);
			cMenu.AppendMenu (nFlags, ID_EDIT_PASTE, strMenuText);

			// Add Delete menu item:
			pMainMenu->GetMenuString (ID_EDIT_DELETE, strMenuText, MF_BYCOMMAND);
			cMenu.AppendMenu (nFlags, ID_EDIT_DELETE, strMenuText);

			// Add separator:
			cMenu.AppendMenu (MF_SEPARATOR);

			// Add Properties menu item:
			pMainMenu->GetMenuString (ID_EDIT_PROPERTIES, strMenuText, MF_BYCOMMAND);
			cMenu.AppendMenu (nFlags, ID_EDIT_PROPERTIES, strMenuText);
			}

		// If popup menu is not empty, display it at hit point:
		if (cMenu.GetMenuItemCount () > 0)
			cMenu.TrackPopupMenu (TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, AfxGetMainWnd ());
		}
	}


/////////////////////////////////////////////////////////////////////////////
// CKItemView list handlers
/////////////////////////////////////////////////////////////////////////////

// **************************************************************************
// Insert ()
//
// Description:
//	Insert an item into view.
//
// Parameters:
//  CKItem		*pItem		Pointer to item object to add.
//
// Returns:
//  void
// **************************************************************************
void CKItemView::Insert (CKItem *pItem)
	{
	// 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);

	// Make sure item pointer was set (debuf only):
	ASSERT (pItem != NULL);

	// If sorted item list is full, we need to allocate another block of
	// memory big enough for current list plus room for more items and
	// transfer current list to it:
	if (m_cnSortedItems == m_nSortedListSize)
		{
		DWORD *p = NULL;

		// Be prepared to deal with allocation problems (p will be NULL in
		// this event):
		try
			{
			// Allocate the next largest size:
			p = new DWORD [m_nSortedListSize + GROWLIST];

			// Initialize new memory:
			ZeroMemory (p, sizeof (sm_pSortedItemList [0]) * (m_nSortedListSize + GROWLIST));

			// Transfer existing items to the new memory:
			if (m_cnSortedItems)
				{
				// Copy old to new:
				memcpy (p, sm_pSortedItemList, m_cnSortedItems * sizeof (sm_pSortedItemList [0]));

				// Free old memory:
				delete [] sm_pSortedItemList;
				}

			// Point to new list:
			sm_pSortedItemList = p;

			// Increment allocated list size:
			m_nSortedListSize += GROWLIST;
			}
		
		catch (...)
			{
			p = NULL;
			}
		}

	// Add the item to the sorted list:
	sm_pSortedItemList [m_cnSortedItems++] = (DWORD)pItem;
	}

// **************************************************************************
// DeleteAllItems ()
//
// Description:
//	Delete all items.
//
// Parameters:
//  none
//
// Returns:
//  void
// **************************************************************************
void CKItemView::DeleteAllItems ()
	{
	// 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 our list control:
	CListCtrl &cList = GetListCtrl ();

	// Reset sorted item list:
	ZeroMemory (sm_pSortedItemList,
		sizeof (sm_pSortedItemList[0]) * (m_nSortedListSize));

	// Reset sorted item counter:
	m_cnSortedItems = 0;

	// Set the list control item count to zero.  (This is how it must
	// be done for virtual list view style.  See comments in PreCreateWindow ()).
	cList.SetItemCountEx (0, LVSICF_NOSCROLL | LVSICF_NOINVALIDATEALL);

	// Force a repaint of the view:
	cList.Invalidate (true);
	cList.UpdateWindow ();
	}

// **************************************************************************
// OnGetDispInfo ()
//
// Description:
//	Handle notification to fill item information for display.
//
// 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 CKItemView::OnGetDispInfo (NMHDR *pNMHDR, LRESULT *pResult) 
	{
	// 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);

	// Cast generic notification message pointer to list view notification
	// message pointer:
	LV_DISPINFO *plvdi = (LV_DISPINFO *)pNMHDR;

	// Get pointer to list view item information structure from message
	// notification structure:
	LV_ITEM *plvItem = &plvdi->item;

	// If there are no items in the sorted item list, then there is no
	// work to be done here.
	if (sm_pSortedItemList == NULL || m_cnSortedItems == 0)
		return;

	// If index of item we are being ased to supply information for is 
	// greater than the number of items in our sorted item list, then
	// there is something wrong.  Return immediately.
	if (plvItem->iItem >= m_cnSortedItems)
		return;

	// Get pointer to CKItem object from sorted item list:
	CKItem *pItem = (CKItem *)sm_pSortedItemList [plvItem->iItem];
	ASSERT (pItem != NULL);

	// If we are being asked to supply item text:
	if (plvItem->mask & LVIF_TEXT)
		{
		// See what subitem (column) text is needed for.  Copy requested
		// text to output structure:
		switch (plvItem->iSubItem)
			{
			case 0:	// Item ID
				lstrcpyn (plvItem->pszText, pItem->GetItemID (), plvItem->cchTextMax);
				break;

			case 1:	// Data Type
				{
				// Convert data type to string:
				static CString strDataType;
				StringFromVartype (pItem->GetDataType (), strDataType);

				lstrcpyn (plvItem->pszText, strDataType, plvItem->cchTextMax);
				}
				break;

			case 2:	// Value
				{
				static CString strValue;
				pItem->GetValue (strValue);

				lstrcpyn (plvItem->pszText, strValue, plvItem->cchTextMax);
				}
				break;

			case 3:	// Timestamp
				{
				static CString strTimestamp;
				pItem->GetTimeStamp (strTimestamp);

				lstrcpyn (plvItem->pszText, strTimestamp, plvItem->cchTextMax);
				}
				break;

			case 4: // Quality
				lstrcpyn (plvItem->pszText, pItem->GetQuality (), plvItem->cchTextMax);
				break;

			case 5:	// Update Count
				{
				// Format numerical value as string:
				TCHAR szNum [64];
				wsprintf (szNum, _T("%u"), pItem->GetUpdateCount ());
				
				lstrcpyn (plvItem->pszText, szNum, plvItem->cchTextMax);
				}
				break;

			default:
				break;
			}
		}

	// If we are being asked to supply item image.  Return index into
	// list control's image list:
	if (plvItem->mask & LVIF_IMAGE)
		{
		// If item is valid, specify active or inactive item image
		// as the case may be.
		if (pItem->IsValid ())
			plvItem->iImage = pItem->IsActive () ? 0 : 1;

		// Else specify invalid item image:
		else
			plvItem->iImage = 2;
		}
	}

// **************************************************************************
// OnToolTipText
//
// Description:
//	Called by framework when tool tip text needs to be defined.
//
// Parameters:
//	UINT		uID				Identifier of the control that sent the notification.
//  NMHDR		*pNMHDR			Contains information about a notification message.
//	LRESULT		*pResult		A 32-bit value returned from a window procedure 
//								  or callback function.
//
// Returns:
//  BOOL - FALSE.
// **************************************************************************
BOOL CKItemView::OnToolTipText (UINT uID, NMHDR *pNMHDR, LRESULT *pResult)
	{
	// Get pointers for output text:
	TOOLTIPTEXTA *pTTTA = (TOOLTIPTEXTA *) pNMHDR;
	TOOLTIPTEXTW *pTTTW = (TOOLTIPTEXTW *) pNMHDR;

	CString strText;
	int nRow = 0;
	int nCol = 0;

	// Get ID of cell tool tip is needed for:
	UINT nID = pNMHDR->idFrom;

	// Get reference to our list control:
	CListCtrl &cList = GetListCtrl ();

	// Filter automatically created tip with ID 0:
	if (nID == 0)
		return (FALSE);

	// Decode the row and column from the ID we created earlier in OnToolHitTest():
	nRow = ((nID - 1) >> 10) & 0x3FFFFFF;
	nCol = (nID - 1) & 0x3FF;

	// Get the text from this cell:
	strText = cList.GetItemText (nRow, nCol);

	// Whether or not this application has been built for unicode or ansi is
	// irrelevant.  We need to pass the tootip text based on the request from
	// the OS.

	// Set the text:
#ifndef _UNICODE
	// This is an ANSI build.

	// If request is for ANSI, just copy string:
	if (pNMHDR->code == TTN_NEEDTEXTA)
		lstrcpyn (pTTTA->szText, strText, sizeof (pTTTA->szText) / sizeof (char));

	// Else request is for UNICODE, so convert from ANSI:
	else
		_mbstowcsz (pTTTW->szText, strText, sizeof (pTTTW->szText) / sizeof (WCHAR));
#else
	// This is a UNICODE build.

	// If request is for ANSI, convert from UNICODE:
	if (pNMHDR->code == TTN_NEEDTEXTA)
		_wcstombsz (pTTTA->szText, strText, sizeof (pTTTA->szText) / sizeof (char));

	// Else request is for UNICODE, so just copy string:
	else
		lstrcpyn (pTTTW->szText, strText, sizeof (pTTTW->szText) / sizeof (WCHAR));
#endif

	*pResult = 0;
	return (FALSE);
	}

// **************************************************************************
// OnColumnClick ()
//
// Description:
//	List control column header click event handler.  Sort the items based
//	on values in column.
//
// 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 CKItemView::OnColumnClick (NMHDR *pNMHDR, LRESULT *pResult) 
	{
	// Create a wait cursor object.  This will cause the wait cursor, 
	// usually an hourglass, to be displayed.  When this object goes
	// out of scope, its destructor will restore the previous cursor
	// type.
	CWaitCursor wc;

	// Get column index from message notification structure:
	WORD wColumn = ((NM_LISTVIEW *)pNMHDR)->iSubItem;

	// Record change in sorting parameters:

	// If same sort column selected, toggle the sort order:
	if (wColumn == sm_wSortColumn)
		sm_wSortOrder = !sm_wSortOrder;

	// Else sort using data in new sort column:
	else
		sm_wSortColumn = wColumn;

	// Sort the list using new column and order settings:
	SortList ();
	}

// **************************************************************************
// CompareItems ()
//
// Description:
//	Compares the order of items when sorting by values in one of the list
//	control columns.  Used by the qsort function, so we need to declare
//	parameters as void pointers.
//
// Parameters:
//  const void	*arg1		Pointer to the first items.
//	const void	*arg2		Pointer to the second item.
//
// Returns:
//  int - Returns a negative number if the arg1 comes first, 0 if arg1 and
//	arg2 are the same, or a positive value if arg2 comes first.
// **************************************************************************
int CKItemView::CompareItems (const void *arg1, const void *arg2)
	{
	// Initialize a variable to contain comparison result:
	int nRC = 0;

	// Cast arguments to CKItem pointers (this what the calling routine
	// is really comparing).
	CKItem *pItem1 = (CKItem *)(*(DWORD *)arg1);
	CKItem *pItem2 = (CKItem *)(*(DWORD *)arg2);

	// Sort based on the column parameter passed to SortItems():
	switch (sm_wSortColumn)
		{
		case 0: // Item ID
			// Item ID is a string, so do a simple string compare:
			nRC = lstrcmp (pItem1->GetItemID (), pItem2->GetItemID ());
			break;

		case 1:	// Data Type
			{
			// Must get data types and convert them to strings:
			static CString strType1;
			static CString strType2;
			
			StringFromVartype (pItem1->GetDataType (), strType1);
			StringFromVartype (pItem2->GetDataType (), strType2);

			// Now compare strings:
			nRC = lstrcmp (strType1, strType2);
			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -