📄 additemdlg.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
//
// OPC DataAccess VC++ Client: AddItemDlg.CPP
// (Source File)
//
/////////////////////////////////////////////////////////////////////////////
//
// Author: Raphael Imhof
// Initial Date: 11/04/98
// $Workfile: AddItemDlg.cpp $
// $Revision: 1 $
// $Date: 7/27/99 5:22p $
// Target System: Microsoft Windows NT 4.0
// Environment: Visual C++ 5.0 / OPC DataAccess 1.0/2.0
// Remarks:
//
/////////////////////////////////////////////////////////////////////////////
//
// Description: implementation of the CAddItemDlg class.
// Item Browser dialog.
//
//
/////////////////////////////////////////////////////////////////////////////
//
// History of Changes (Please remove very old comments and blank lines!)
// $Log: /IDK/OPCServer/clients/VC++/InfoServerExplorer/AddItemDlg.cpp $
//
// 1 7/27/99 5:22p Imhof
//
// 1 7/27/99 5:18p Imhof
//
// 15 2/24/99 2:02p Imhof
// Added ValidateItem option and support
//
// 14 2/24/99 10:28a Imhof
// Extracted common functionality into global.*
//
// 13 2/05/99 6:11p Imhof
// GetItems() is now called only once.
//
// 12 2/05/99 5:06p Imhof
// Clear the tag filed to avoid multiple adds with the OK button after
// using the Add button.
//
// 11 1/26/99 5:34p Betrisey
// Corrected bug when some items cannot be added to a group (AddItem)
//
// 10 1/15/99 6:43p Imhof
// Updated legal notice.
//
// 9 12/11/98 5:58p Imhof
// Made modifications for OPC 2.0.
//
// 8 12/03/98 1:53p Imhof
// Removed read after additems
//
// 7 11/10/98 2:20p Imhof
// Added file header's.
//
//
// $Nokeywords:$ (To avoid useless search while checking in.)
/////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1998, Siemens Building Technologies, Inc. Landis Division
//
// SIEMENS BUILDING TECHNOLOGIES, INC. IS PROVIDING THE FOLLOWING
// EXAMPLES OF CODE AS SAMPLE ONLY.
//
// SIEMENS BUILDING TECHNOLOGIES, INC. MAKES NO REPRESENTATIONS
// OR WARRANTIES OF ANY KIND WITH RESPECT TO THE VALIDTY OF THE
// CODES OR DESIRED RESULTS AND DISCLAIMS ALL SUCH
// REPRESENTATIONS AND WARRANTIES, INCLUDING FOR EXAMPLE,
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE. SIEMENS BUILIDNG TECHNOLOGIES, INC. DOES NOT
// REPRESENT OR WARRANT THAT THE FOLLOWING CODE SAMPLES ARE
// ACCURATE, VALID, COMPLETE OR CURRENT.
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "global.h"
#include "infoserverexplorer.h"
#include "AddItemDlg.h"
#include "IOPCBrowseServerAddressSpace.h"
#include "IOPCItemMgt.h"
#include "IOPCSyncIO.h"
#include "InfoServerExplorerDoc.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAddItemDlg dialog
CAddItemDlg::CAddItemDlg(CGroup* pGroup, CWnd* pParent /*=NULL*/)
: CDialog(CAddItemDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CAddItemDlg)
m_sItemTag = _T("");
m_sFilter = _T("*");
m_sStatus = _T("");
//}}AFX_DATA_INIT
m_pGroup = pGroup;
m_DataFilterType = VT_EMPTY;
m_DataAddType = VT_EMPTY;
}
void CAddItemDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAddItemDlg)
DDX_Control(pDX, IDC_ADD_ITEM_TAG, m_edItemTag);
DDX_Control(pDX, IDC_TAG_FILTER_ACCESS, m_cbTagFilterAccess);
DDX_Control(pDX, IDCANCEL, m_buCancel);
DDX_Control(pDX, IDC_TAG_ADD_TYPE, m_cbTagAddType);
DDX_Control(pDX, IDC_TAG_FILTER_TYPE, m_cbTagFilterType);
DDX_Control(pDX, IDC_TAG_LIST, m_TagList);
DDX_Text(pDX, IDC_ADD_ITEM_TAG, m_sItemTag);
DDX_Text(pDX, IDC_TAG_LIST_FILTER, m_sFilter);
DDX_Text(pDX, IDC_ADDDLG_STATUS, m_sStatus);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAddItemDlg, CDialog)
//{{AFX_MSG_MAP(CAddItemDlg)
ON_LBN_SELCHANGE(IDC_TAG_LIST, OnSelchangeTagList)
ON_EN_KILLFOCUS(IDC_TAG_LIST_FILTER, OnKillfocusTagListFilter)
ON_LBN_DBLCLK(IDC_TAG_LIST, OnDblclkTagList)
ON_CBN_SELCHANGE(IDC_TAG_FILTER_TYPE, OnSelchangeTagFilterType)
ON_BN_CLICKED(IDC_ADD, OnAdd)
ON_BN_CLICKED(IDC_FIND, OnFind)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAddItemDlg message handlers
BOOL CAddItemDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
m_DataFilterType = VT_EMPTY;
m_cbTagFilterType.SetCurSel(0);
m_DataAddType = VT_EMPTY;
m_cbTagAddType.SetCurSel(0);
m_cbTagFilterAccess.SetCurSel(0);
//LoadItemTagList();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CAddItemDlg::LoadItemTagList()
{
CWaitCursor wait;
HRESULT res_next, res;
CComPtr<IEnumString> pEnumString;
DWORD dwAccessRights = 0; //no filtering
CMainFrame* pMainFrame = (CMainFrame*) AfxGetMainWnd();
CInfoServerExplorerDoc* pDoc = (CInfoServerExplorerDoc*) pMainFrame->GetActiveDocument();
CIOPCBrowseServerAddressSpace browser(pDoc->GetInfoServer()->GetInterface());
USES_CONVERSION;
m_sStatus = _T("Loading...");
GetDlgItem(IDC_ADDDLG_STATUS)->SetWindowText(m_sStatus);
// get the item tags
m_TagList.ResetContent();
switch(m_cbTagFilterAccess.GetCurSel())
{
case 0: default: dwAccessRights = 0; break; //no filtering
case 1: dwAccessRights = OPC_READABLE; break; //read only
case 2: dwAccessRights = OPC_WRITEABLE; break; //readwrite
}
res = browser.BrowseOPCItemIDs( OPC_LEAF,
T2OLE(m_sFilter.GetBuffer(m_sFilter.GetLength())),
m_DataFilterType,
dwAccessRights,
&pEnumString);
if(SUCCEEDED(res))
{
int iRequested = pDoc->GetInfoServer()->GetBrowserEnumNextElements();
LPWSTR* pName = new LPWSTR[iRequested];
ULONG count = 0;
pEnumString->Reset();
do
{
res_next = pEnumString->Next(iRequested, pName, &count);
// CString does translation from UNICODE to native type
// (depends on the way the application is built)
for( ULONG index=0; index<count; index++ )
{
CString name( pName[index] );
m_TagList.AddString( name );
CoTaskMemFree(pName[index]);
}
}
while(res_next == S_OK);
if(FAILED(res_next)) pDoc->GetInfoServer()->DisplayError(res_next);
pEnumString.Release();
delete[] pName;
}
else
{
pDoc->GetInfoServer()->DisplayError(res);
}
m_TagList.SetCurSel( 0 );
m_sStatus.Format(_T("%d Tag(s) Retrieved."), m_TagList.GetCount());
GetDlgItem(IDC_ADDDLG_STATUS)->SetWindowText(m_sStatus);
}
void CAddItemDlg::OnSelchangeTagList()
{
// TODO: Add your control notification handler code here
m_TagList.GetText(m_TagList.GetCurSel(), m_sItemTag);
UpdateData(FALSE);
}
void CAddItemDlg::OnKillfocusTagListFilter()
{
// TODO: Add your control notification handler code here
/*
UpdateData(TRUE); //update msFilter
LoadItemTagList();
*/
//we use now only the Find button.
}
void CAddItemDlg::OnDblclkTagList()
{
// TODO: Add your control notification handler code here
OnOK();
}
void CAddItemDlg::OnOK()
{
// TODO: Add extra validation here
OnAdd();
CDialog::OnOK();
}
void CAddItemDlg::OnSelchangeTagFilterType()
{
// TODO: Add your control notification handler code here
m_DataFilterType = DataTypeSelectionToVartype(m_cbTagFilterType.GetCurSel());
LoadItemTagList();
}
VARTYPE CAddItemDlg::GetDataType()
{
return m_DataAddType;
}
void CAddItemDlg::OnAdd()
{
// TODO: Add your control notification handler code here
m_DataAddType = DataTypeSelectionToVartype(m_cbTagAddType.GetCurSel());
if(AddItem())
{
//after first add we can't cancel anymore !
m_buCancel.SetWindowText(_T("Close"));
//clear the existing selection
m_TagList.SetSel(-1, FALSE);
}
}
void CAddItemDlg::InsertItemIntoView(CItem* pItem)
{
//add group item
TV_INSERTSTRUCT TreeItem;
CMainFrame* pMainFrame = (CMainFrame*) AfxGetMainWnd();
CInfoServerExplorerDoc* pDoc = (CInfoServerExplorerDoc*) pMainFrame->GetActiveDocument();
CBrowserView* pView = pMainFrame->GetBrowserView();
CTreeCtrl& tree = pView->GetTreeCtrl();
HTREEITEM item = tree.GetSelectedItem(); //assume that group item is selected !
TreeItem.hParent = item;
TreeItem.hInsertAfter = TVI_SORT;
TreeItem.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;;
CString sName = pItem->GetName();
TreeItem.item.pszText = (LPSTR) sName.GetBuffer(sName.GetLength());
TreeItem.item.iImage = 2;
TreeItem.item.iSelectedImage = 2;
TreeItem.item.lParam = (LONG) pItem;
tree.EnsureVisible(tree.InsertItem(&TreeItem));
pDoc->SetModifiedFlag();
}
BOOL CAddItemDlg::AddItem()
{
USES_CONVERSION;
CIOPCItemMgt opcItemMgt(m_pGroup->GetInterface());
OPCITEMRESULT* pAddResults = NULL;
HRESULT* pErrors = NULL;
OPCHANDLE hItem;
HRESULT res;
BOOL bRet = FALSE;
CArray<CItem*,CItem*>* pItems = NULL;
m_pGroup->GetItems(&pItems);
if(pItems == NULL) return FALSE;
CMainFrame* pMainFrame = (CMainFrame*) AfxGetMainWnd();
CInfoServerExplorerDoc* pDoc = (CInfoServerExplorerDoc*) pMainFrame->GetActiveDocument();
CBrowserView* pView = pMainFrame->GetBrowserView();
//need to create before add, because we use the address as the client handle
int iItems = m_TagList.GetSelCount();
LPINT pSelBuffer = new int[iItems];
if(m_TagList.GetSelItems(iItems, pSelBuffer) != iItems)
{
delete pSelBuffer;
return FALSE;
}
OPCITEMDEF* add_items = new OPCITEMDEF[iItems];
CArray<CItem*, CItem*> AddItems;
for(int i = 0; i < iItems; i++)
{
CString sItemTag;
m_TagList.GetText(pSelBuffer[i], sItemTag);
AddItems.InsertAt(i, new CItem);
//init the value
CComVariant x;
AddItems[i]->SetValue(x);
add_items[i].szItemID = A2OLE(sItemTag);
add_items[i].szAccessPath = A2OLE("");
add_items[i].bActive = TRUE;
add_items[i].hClient = (OPCHANDLE) AddItems[i];
add_items[i].dwBlobSize = 0;
add_items[i].pBlob = NULL;
add_items[i].vtRequestedDataType = GetDataType();
}
delete[] pSelBuffer;
//no slection but a manually entered tag
UpdateData(TRUE);
if((iItems <= 0) && !m_sItemTag.IsEmpty())
{
iItems = 1;
AddItems.InsertAt(0, new CItem);
//init the value
CComVariant x;
AddItems[0]->SetValue(x);
add_items = new OPCITEMDEF[1]; //enlarge from 0 to 1
add_items[0].szItemID = A2OLE(m_sItemTag);
add_items[0].szAccessPath = A2OLE("");
add_items[0].bActive = TRUE;
add_items[0].hClient = (OPCHANDLE) AddItems[0];
add_items[0].dwBlobSize = 0;
add_items[0].pBlob = NULL;
add_items[0].vtRequestedDataType = GetDataType();
}
if(m_pGroup->GetInfoServer()->UseValidateItems()) //only if option is set
{
//validate
if(!m_pGroup->ValidateItems(iItems, add_items))
{
//cleanup
delete[] add_items;
for(int c = 0; c < AddItems.GetSize(); c++)
{
delete AddItems[0];
AddItems.RemoveAt(0);
}
return FALSE;
}
}
res = opcItemMgt.AddItems(iItems, add_items, &pAddResults, &pErrors);
if(SUCCEEDED(res))
{
for(i = 0; i < iItems; i++)
{
if(SUCCEEDED(pErrors[i]))
{
AddItems[i]->SetName(OLE2A(add_items[i].szItemID));
hItem = pAddResults[i].hServer;
AddItems[i]->SetHandle(hItem);
if(VT_EMPTY == add_items[i].vtRequestedDataType) //native
{
//if asked for native we want the server given type
AddItems[i]->SetDataType(pAddResults[i].vtCanonicalDataType);
}
else
{
//requested one
AddItems[i]->SetDataType(add_items[i].vtRequestedDataType);
}
AddItems[i]->SetGroup(m_pGroup);
//add it to the list
pItems->Add(AddItems[i]);
bRet = TRUE;
}
else
{
m_pGroup->GetInfoServer()->DisplayError(pErrors[i]);
delete AddItems[i];
AddItems[i] = NULL;
// AddItems.RemoveAt(i);
bRet = FALSE;
}
} //end for pErrors
//now read the values (from cache)
//m_pGroup->ReadItemsSync(OPC_DS_CACHE, iItems, phServer);
//delete[] phServer;
//insert items into view
/*
for(int a = 0; a < AddItems.GetSize(); a++)
{
InsertItemIntoView(AddItems[a]);
}
*/
pDoc->UpdateAllViews(pView, 0, NULL);
}
else
{
m_pGroup->GetInfoServer()->DisplayError(res);
for(int e = 0; e < AddItems.GetSize(); e++)
{
delete AddItems[0];
AddItems.RemoveAt(0);
}
bRet = FALSE;
}
CoTaskMemFree(pAddResults);
CoTaskMemFree(pErrors);
delete[] add_items;
//clear tag field to avoid multiple adds with the OK button !
if(bRet)
{
m_sItemTag = _T("");
UpdateData(FALSE);
}
return bRet;
}
void CAddItemDlg::OnFind()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE); //update msFilter
LoadItemTagList();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -