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

📄 itemadddlg.cpp

📁 KepWare的OPC Client 示例.面向C
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// **************************************************************************
// itemadddlg.cpp
//
// Description:
//	Implements a dialog class for adding OPC items.  Allows user to browse for
//	items and other handy things.
//
// 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 "itemadddlg.h"
#include "item.h"
#include "group.h"
#include "server.h"

// Registry sections;
static LPCTSTR lpszRegSection	= _T("Add Items");
static LPCTSTR lpszAutoValidate	= _T("Auto Validate");
static LPCTSTR lpszBrowseFlat	= _T("Browse Flat");

// Default add item list size:
#define DEF_ITEM_LIST_SIZE		16

// Branch dummy item data:
#define NULL_ITEM_NAME			_T("_QCNULL_DUMMY")
#define NULL_ITEM_DATA			0xFFFFFFFF

// Image list indices:
#define ILI_BRANCH				8
#define ILI_SELBRANCH			9
#define ILI_LEAF				3

// Access rights filter combo box indices:
#define CB_ACCESS_ANY			0
#define CB_ACCESS_READONLY		1
#define CB_ACCESS_WRITEONLY		2
#define CB_ACCESS_READWRITE		4


/////////////////////////////////////////////////////////////////////////////
// CKItemAddDlg dialog
/////////////////////////////////////////////////////////////////////////////

// **************************************************************************
BEGIN_MESSAGE_MAP (CKItemAddDlg, CDialog)
	//{{AFX_MSG_MAP(CKItemAddDlg)
	ON_BN_CLICKED (IDC_NEW, OnNew)
	ON_NOTIFY (TVN_ITEMEXPANDING, IDC_BRANCHLIST, OnBranchExpanding)
	ON_NOTIFY (TVN_SELCHANGED, IDC_BRANCHLIST, OnBranchSelected)
	ON_CBN_SELCHANGE (IDC_FILTERACCESS, OnAccessFilterChange)
	ON_EN_CHANGE (IDC_FILTERLEAF, OnLeafFilterChange)
	ON_CBN_SELCHANGE (IDC_FILTERTYPE, OnVartypeFilterChange)
	ON_BN_CLICKED (IDC_NEXT, OnNext)
	ON_BN_CLICKED (IDC_PREVIOUS, OnPrevious)
	ON_BN_CLICKED (IDC_VALIDATEITEM, OnValidateItem)
	ON_EN_CHANGE (IDC_FILTERBRANCH, OnBranchFilterChange)
	ON_NOTIFY (NM_DBLCLK, IDC_LEAFLIST, OnClickLeafList)
	ON_EN_CHANGE (IDC_ITEMID, OnChange)
	ON_BN_CLICKED (IDC_DELETE, OnDelete)
	ON_BN_CLICKED (IDC_DUPLICATE, OnDuplicate)
	ON_BN_CLICKED (IDC_ADD_LEAVES, OnAddLeaves)
	ON_EN_CHANGE (IDC_ACCESSPATH, OnChange)
	ON_BN_CLICKED (IDC_ACTIVE, OnChange)
	ON_CBN_SELCHANGE (IDC_DATATYPE, OnChange)
	ON_BN_CLICKED (IDC_AUTOVALIDATE, OnAutoValidate)
	ON_WM_SHOWWINDOW ()
	ON_BN_CLICKED (IDC_BROWSEFLAT, OnBrowseFlat)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP ()


// **************************************************************************
// CKItemAddDlg ()
//
// Description:
//	Constructor.
//
// Parameters:
//  CKGroup							*pGroup		Group to add item to.
//	IOPCBrowseServerAddressSpace	*pIBrowse	Server browse interface.
//	CWnd*							pParent		Parent window.  If it is NULL,
//												the dialog object抯 parent 
//												window is set to the main
//												application window.
//
// Returns:
//  none
// **************************************************************************
CKItemAddDlg::CKItemAddDlg (CKGroup *pGroup, IOPCBrowseServerAddressSpace *pIBrowse, CWnd *pParent /*=NULL*/)
	: CDialog (CKItemAddDlg::IDD, pParent)
	{
	// Initialize member variables:
	ASSERT (pGroup != NULL);
	m_pGroup = pGroup;
	m_pIBrowse = pIBrowse;

	m_nListIndex = 0;
	m_nSelIndex = 0;
	m_bModified = false;
	m_pIItemMgt = NULL;

	// Load registry settings.  These are settings we may want to use each time
	// we add some items:
	m_bAutoValidate = AfxGetApp ()->GetProfileInt (lpszRegSection, lpszAutoValidate, FALSE);
	m_bBrowseFlat = AfxGetApp ()->GetProfileInt (lpszRegSection, lpszBrowseFlat, FALSE);

	// Allocate memory for add item list:
	try
		{
		m_cItemList.SetSize (DEF_ITEM_LIST_SIZE, DEF_ITEM_LIST_SIZE);
		}
	catch (...)
		{
		ASSERT (FALSE);
		}

	//{{AFX_DATA_INIT(CKItemAddDlg)
	m_strAccessPath = ITEM_DEFAULT_ACCESSPATH;
	m_bActive = ITEM_DEFAULT_ACTIVESTATE;
	m_strItemID = ITEM_DEFAULT_ITEMID;
	m_vtDataType = ITEM_DEFAULT_DATATYPE;
	m_strFilterLeaf = _T("");
	m_strFilterBranch = _T("");
	//}}AFX_DATA_INIT

	// Initialize bitmap buttons:
	m_cNext.Initialize (IDB_NEXT, IDB_NEXTGRAY);
	m_cPrev.Initialize (IDB_PREVIOUS, IDB_PREVIOUSGRAY);
	m_cNew.Initialize (IDB_NEWITEM, IDB_NEWITEMGRAY);
	m_cDuplicate.Initialize (IDB_DUPITEM, IDB_DUPITEMGRAY);
	m_cDelete.Initialize (IDB_DELETEITEM, IDB_DELETEITEMGRAY);
	m_cValidate.Initialize (IDB_VALIDATEITEM, IDB_VALIDATEITEMGRAY);
	}

// **************************************************************************
// ~CKItemAddDlg ()
//
// Description:
//	Destructor.
//
// Parameters:
//  none
//
// Returns:
//  none
// **************************************************************************
CKItemAddDlg::~CKItemAddDlg ()
	{
	// Save registry settings:
	AfxGetApp ()->WriteProfileInt (lpszRegSection, lpszAutoValidate, m_bAutoValidate);
	AfxGetApp ()->WriteProfileInt (lpszRegSection, lpszBrowseFlat, m_bBrowseFlat);
	}

// **************************************************************************
// DoDataExchange ()
//
// Description:
//	This method is called by the framework to exchange and validate dialog data.
//
// Parameters:
//  CDataExchange	*pDX	A pointer to a CDataExchange object.
//
// Returns:
//  void
// **************************************************************************
void CKItemAddDlg::DoDataExchange (CDataExchange *pDX)
	{
	// Perform default processing:
	CDialog::DoDataExchange (pDX);

	// Exchange data between controls and associated member variables:
	//{{AFX_DATA_MAP(CKItemAddDlg)
	DDX_Text (pDX, IDC_ACCESSPATH, m_strAccessPath);
	DDX_Check (pDX, IDC_ACTIVE, m_bActive);
	DDX_Text (pDX, IDC_ITEMID, m_strItemID);
	DDX_Text (pDX, IDC_FILTERLEAF, m_strFilterLeaf);
	DDX_Text (pDX, IDC_FILTERBRANCH, m_strFilterBranch);
	//}}AFX_DATA_MAP

	DDX_Check (pDX, IDC_BROWSEFLAT, m_bBrowseFlat);
	DDX_Check (pDX, IDC_AUTOVALIDATE, m_bAutoValidate);

	// Transfer data type combo box index to vartype:
	CComboBox *pCombo = (CComboBox *)GetDlgItem (IDC_DATATYPE);

	// If save and validate, transfer data type combo box index to
	// vartype member variable:
	if (pDX->m_bSaveAndValidate)
		{
		CString strType;
		pCombo->GetLBText (pCombo->GetCurSel (), strType);
		m_vtDataType = VartypeFromString (strType);
		}

	// else use current member variable value to make combo box selection:
	else
		{
		CString strType;

		// Convert data type to combo box entry string:
		switch (m_vtDataType & ~VT_ARRAY)
			{
			case VT_BOOL:	strType = _T("Boolean");	break;
			case VT_UI1:	strType = _T("Byte");		break;
			case VT_I1:		strType = _T("Char");		break;
			case VT_UI2:	strType = _T("Word");		break;
			case VT_I2:		strType = _T("Short");		break;
			case VT_UI4:	strType = _T("DWord");		break;
			case VT_I4:		strType = _T("Long");		break;
			case VT_R4:		strType = _T("Float");		break;
			case VT_R8:		strType = _T("Double");		break;
			case VT_BSTR:	strType = _T("String");		break;
			default:		strType = _T("Native");		break;
			}

		// Update array flag data:
		if ((m_vtDataType & VT_ARRAY) != 0)
			strType += _T(" Array");
		
		// Select combo box entry:
		pCombo->SelectString (-1, strType);
		}
	}


/////////////////////////////////////////////////////////////////////////////
// CKItemAddDlg message handlers
/////////////////////////////////////////////////////////////////////////////

// **************************************************************************
// OnInitDialog ()
//
// Description:
//	Called immediately before the dialog box is displayed.  Use opportunity
//	to initialize controls.
//
// Parameters:
//  none
//
// Returns:
//	BOOL -  TRUE.
// **************************************************************************
BOOL CKItemAddDlg::OnInitDialog () 
	{
	CDialog::OnInitDialog ();

	// Limit the access path to 255 chars:
	((CEdit *)GetDlgItem (IDC_ACCESSPATH))->LimitText (255);
	
	// Allow 10 levels of 32 character names plus a tag name of 31 characters:
	((CEdit *)GetDlgItem (IDC_ITEMID))->LimitText (10*32 + 31);

	// Subclass image buttons:
	m_cNext.SubclassDlgItem (IDC_NEXT, this);
	m_cPrev.SubclassDlgItem (IDC_PREVIOUS, this);
	m_cNew.SubclassDlgItem (IDC_NEW, this);
	m_cDuplicate.SubclassDlgItem (IDC_DUPLICATE, this);
	m_cDelete.SubclassDlgItem (IDC_DELETE, this);
	m_cValidate.SubclassDlgItem (IDC_VALIDATEITEM, this);

	// Create tool tips for the image buttons:
	m_cToolTip.Create (this);
	m_cToolTip.AddWindowTool (&m_cNext);
	m_cToolTip.AddWindowTool (&m_cPrev);
	m_cToolTip.AddWindowTool (&m_cNew);
	m_cToolTip.AddWindowTool (&m_cDuplicate);
	m_cToolTip.AddWindowTool (&m_cDelete);
	m_cToolTip.AddWindowTool (&m_cValidate);

	// Get our group's item management interface pointer for the group:
	m_pIItemMgt = m_pGroup->GetIItemMgt ();

	// Intialize our item browser:
	InitializeBrowser ();

	// Intialize control status:
	UpdateStatus ();

	// return TRUE unless you set the focus to a control
	// EXCEPTION: OCX Property Pages should return FALSE
	return (TRUE);  
	}

// **************************************************************************
// OnShowWindow ()
//
// Description:
//	This method is called by the framework when this dialog is about to be
//	hidden or shown.  Use opportunity to set focus.
//
// Parameters:
//  BOOL		bShow		TRUE if the window is being shown;  FALSE if 
//							 the window is being hidden.
//	UINT		nStatus		Specifies the status of the window being shown.
//
// Returns:
//  void
// **************************************************************************
void CKItemAddDlg::OnShowWindow (BOOL bShow, UINT nStatus) 
	{
	// Perform default processing:
	CDialog::OnShowWindow (bShow, nStatus);
	
	// If showing dialog, set focus to item ID edit box:
	if (bShow)
		GetDlgItem (IDC_ITEMID)->SetFocus ();
	}

// **************************************************************************
// OnOK ()
//
// Description:
//	Override to perform the OK button action in a modal dialog box.  Use
//	opportunity to apply changes.
//
// Parameters:
//  none
//
// Returns:
//  void
// **************************************************************************
void CKItemAddDlg::OnOK () 
	{
	// Apply any outstanding changes:
	if (OnApplyChange ())
		{
		// Terminate the list.  Will allow us to process list using
		// "while (element)" loop if we want:
		if (m_nListIndex > 0)
			m_cItemList.SetAtGrow (m_nListIndex, NULL);

		// Perform default processing:
		CDialog::OnOK ();
		}
	}

// **************************************************************************
// OnCancel ()
//
// Description:
//	Override to perform the Cancel button or ESC key action.  Use opportunity
//	to free any items created.
//
// Parameters:
//  none
//
// Returns:
//  void
// **************************************************************************
void CKItemAddDlg::OnCancel () 
	{
	// Free any items we created:
	for (int nIndex = 0; nIndex < m_nListIndex; nIndex++)
		{
		// Get next element in list:
		CKItem *pItem = (CKItem *) m_cItemList.GetAt (nIndex);
		ASSERT (pItem != NULL);

		// Delete it:
		delete pItem;
		}
	
	// Perform default processing:
	CDialog::OnCancel ();
	}

// **************************************************************************
// OnNew ()
//
// Description:
//	New button event handler.  Select a new item for edits.
//
// Parameters:
//  none
//
// Returns:
//  void
// **************************************************************************
void CKItemAddDlg::OnNew () 
	{
	// No item currently in list should be selected on new:
	SelectItem (-1);
	}

// **************************************************************************
// OnDuplicate ()
//
// Description:
//	Duplicate button event handler.  Duplicate the current item.
//
// Parameters:
//  none
//
// Returns:
//  void
// **************************************************************************
void CKItemAddDlg::OnDuplicate () 
	{
	// Validate selected item first, and see if it has an address with
	// a dot bit format:
	bool bDotBitAddress = false;
	HRESULT hr = Validate (&bDotBitAddress);

	// If current item is not valid, don't duplicate it.  Instead,
	// tell user something is wrong with selected item:
	if (FAILED (hr))
		{
		// Define a string format for the validation return code:
		CString strHR;
		strHR.Format (_T("0x%08X"), hr);

		// Create an error string using above format for return code::
		CString strFailure;
		strFailure.FormatMessage (IDS_VALIDATE_ITEM_FAILED, m_strItemID, strHR);

		// Display a message box with error string:
		AfxMessageBox (strFailure);

		// Return now so we don't duplicate invalid item:
		return;
		}

	// Create a duplicate item dialog.  This will allow the user to specify
	// how many duplicates to make::
	CKDuplicateItemCountDlg dlg;

	// Show as modal dialog.  Duplicate item only if user hits "OK":
	if (dlg.DoModal () == IDOK)
		{
		// 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;

		// Postpone repaint until we are done.  This will make things go
		// faster and look smoother:
		SetRedraw (false);

⌨️ 快捷键说明

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