📄 dlgopcitemadd.cpp
字号:
// DlgAddOPCItem.cpp : implementation file
//
#include "stdafx.h"
#include "TYOPCClient.h"
#include "DlgOPCItemAdd.h"
#include "DlgModifyName.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// 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 10
#define ILI_SELBRANCH 11
#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
//
#define BEINGITEM_SELGROUP 10000000
/////////////////////////////////////////////////////////////////////////////
// CDlgOPCItemAdd dialog
CDlgOPCItemAdd::CDlgOPCItemAdd(COPCServer *pServer,CWnd* pParent /*=NULL*/)
: CDialog(CDlgOPCItemAdd::IDD, pParent)
{
//Initialize member variables:
ASSERT (pServer != NULL);
m_pServer = pServer;
m_pIBrowse = pServer->GetIBrowse ();
m_pBranchList=NULL;
m_pLeafList=NULL;
m_pAddItemList=NULL;
m_pIItemMgt = pServer->GetSelGroup ()->m_pIOPCItemMgt;
m_bActive=1;
m_vtDataType=0;
// 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_cAddItems.SetSize (DEF_ITEM_LIST_SIZE, DEF_ITEM_LIST_SIZE);
m_cAddItems.SetSize (0, DEF_ITEM_LIST_SIZE);
}
catch (...)
{
ASSERT (FALSE);
}
//{{AFX_DATA_INIT(CDlgOPCItemAdd)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
CDlgOPCItemAdd::~CDlgOPCItemAdd()
{
// Save registry settings:
AfxGetApp ()->WriteProfileInt (lpszRegSection, lpszAutoValidate, m_bAutoValidate);
AfxGetApp ()->WriteProfileInt (lpszRegSection, lpszBrowseFlat, m_bBrowseFlat);
}
void CDlgOPCItemAdd::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgOPCItemAdd)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDlgOPCItemAdd, CDialog)
//{{AFX_MSG_MAP(CDlgOPCItemAdd)
ON_NOTIFY(TVN_SELCHANGED, IDC_BRANCHLIST, OnSelChangedBranchList)
ON_NOTIFY(TVN_ITEMEXPANDING, IDC_BRANCHLIST, OnItemExpandingBranchList)
ON_NOTIFY(NM_DBLCLK, IDC_LEAFLIST, OnDblclkLeafList)
ON_CBN_SELCHANGE(IDC_FILTERTYPE, OnSelChangeFilterType)
ON_CBN_SELCHANGE(IDC_FILTERACCESS, OnSelChangeFilterAccess)
ON_BN_CLICKED(ID_ADDITEM, OnAddItem)
ON_BN_CLICKED(ID_DELITEM, OnDelItem)
ON_NOTIFY(NM_CLICK, IDC_LEAFLIST, OnClickLeafList)
ON_NOTIFY(NM_CLICK, IDC_ADDITEMLIST, OnClickAddItemlist)
ON_NOTIFY(NM_DBLCLK, IDC_ADDITEMLIST, OnDblclkAddItemList)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgOPCItemAdd message handlers
BOOL CDlgOPCItemAdd::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
InitializeBrowser();
m_pBtnAdd=(CButton*)GetDlgItem(ID_ADDITEM);
m_pBtnDel=(CButton*)GetDlgItem(ID_DELITEM);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CDlgOPCItemAdd::InitializeBrowser()
{
//支列表指针
m_pBranchList = (CTreeCtrl *) GetDlgItem (IDC_BRANCHLIST);
ASSERT (m_pBranchList != NULL);
//叶列表指针
m_pLeafList = (CListCtrl *) GetDlgItem (IDC_LEAFLIST);
ASSERT (m_pLeafList != NULL);
//增加数据项列表指针
m_pAddItemList = (CListCtrl *) GetDlgItem (IDC_ADDITEMLIST);
ASSERT (m_pAddItemList != NULL);
// Initialize the image list for the branch control. These are the
// images that show up to the left of each item in list. The bitmap
// must use a purple background color, RGB (255, 0, 255), so that the
// CImageList object can construct a mask. The images are 16x16 pixels.
// Set the image list background color to CLR_NONE so masked pixels will
// be transparent.
//
// Image number Use
// 0-7 not used
// 8 Branch
// 9 Self branch
m_cBranchImageList.Create (IDB_GROUPIMAGES, 16, 3, RGB (255, 0, 255));
m_cBranchImageList.SetBkColor (CLR_NONE);
m_pBranchList->SetImageList (&m_cBranchImageList, TVSIL_NORMAL);
// Initialize the image list for the leaf control. These are the images
// that show up to the left of each item in list. The bitmap must use a
// purple background color, RGB (255, 0, 255), so that the CImageList
// object can construct a mask. The images are 14x14 pixels. Set the
// image list background color to CLR_NONE so masked pixels will be
// transparent.
//
// Image number Use
// 0-2 not used
// 3 Leaf
m_cLeafImageList.Create (IDB_ITEMIMAGES, 14, 2, RGB (255, 0, 255));
m_cLeafImageList.SetBkColor (CLR_NONE);
m_pLeafList->SetImageList (&m_cLeafImageList, LVSIL_SMALL);
//在叶列表中插入一列:
CRect rc;
m_pLeafList->GetClientRect (&rc);
m_pLeafList->InsertColumn (0, _T(""), LVCFMT_LEFT, rc.Width ()-20);
//在增加数据列表中插入一列:
m_cAddItemImageList.Create (IDB_ITEMIMAGES, 14, 2, RGB (255, 0, 255));
m_cAddItemImageList.SetBkColor (CLR_NONE);
m_pAddItemList->SetImageList (&m_cAddItemImageList, LVSIL_SMALL);
m_pAddItemList->ModifyStyle (NULL,CCS_TOP); //LVS_EDITLABELS|允许就地编辑
m_pAddItemList->SetExtendedStyle (LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT);
int nIndex=0;
m_pAddItemList->GetClientRect (&rc);
m_pAddItemList->InsertColumn (nIndex++, _T("项ID"), LVCFMT_LEFT, 250);
m_pAddItemList->InsertColumn (nIndex++, _T("名 称"), LVCFMT_LEFT, 150);
m_pAddItemList->InsertColumn (nIndex++, _T("数据类型"), LVCFMT_CENTER, 80);
m_pAddItemList->InsertColumn (nIndex++, _T("活动"), LVCFMT_CENTER, 60);
m_pAddItemList->InsertColumn (nIndex++, _T("访问路径"), LVCFMT_CENTER, rc.Width ()-460);
//初始化过滤条件:
//支
m_strFilterBranch = "*";
((CEdit *) GetDlgItem (IDC_FILTERBRANCH))->SetWindowText (m_strFilterBranch);
//叶
m_strFilterLeaf = "*";
((CEdit *) GetDlgItem (IDC_FILTERLEAF))->SetWindowText (m_strFilterLeaf);
//数据类型
m_vtFilterType = VT_EMPTY;
((CComboBox *) GetDlgItem (IDC_FILTERTYPE))->SetCurSel (0);
//数据访问方式
m_dwFilterAccessRights = CB_ACCESS_ANY;
((CComboBox *) GetDlgItem (IDC_FILTERACCESS))->SetCurSel (CB_ACCESS_ANY);
// Intialize browse controls if browsing is supported, otherwise
// just disable the controls:
if (m_pIBrowse != NULL)
{
// 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;
HRESULT hr;
// Query the server name space:
hr = m_pIBrowse->QueryOrganization (&m_OpcNameSpace);
if (SUCCEEDED (hr))
{
// Browse root level:
switch (m_OpcNameSpace)
{
case OPC_NS_HIERARCHIAL:
case OPC_NS_FLAT:
BrowseRootLevel ();
break;
// Did the foundation add a new type?
default:
ASSERT (FALSE);
break;
}
}
// We will assume a hierarchial search if the server fails this request:
// (This allows us to work with any server that uses the ICONICS toolkit.)
else
{
TRACE (_T("OPC: Attempting agressive browsing since the server failed on QueryOrganization ()\r\n"));
m_OpcNameSpace = OPC_NS_HIERARCHIAL;
BrowseRootLevel ();
}
}
}
void CDlgOPCItemAdd::BrowseRootLevel()
{
HRESULT hr = E_FAIL;
HTREEITEM hItem = NULL;
try
{
// If hierarchial namespace:
if (m_OpcNameSpace == OPC_NS_HIERARCHIAL)
{
// Re-initialize server's browse position to the root:
do
{
// Use the OPC_BROWSE_UP rather than the OPC_BROWSE_TO which
// is only supported in OOPC version 2.0. We will have to
// browse up to root one level at a time. Function will
// fail when we are at root.
hr = m_pIBrowse->ChangeBrowsePosition (OPC_BROWSE_UP, L"\0");
} while (SUCCEEDED (hr));
// Insert our root level item:
hItem = m_pBranchList->InsertItem (m_pServer->GetProgID (),
ILI_BRANCH, ILI_SELBRANCH, TVI_ROOT);
// Set the item data and add a dummy child branch:
m_pBranchList->SetItemData (hItem, DWORD (-1));
AddDummyBranch (hItem);
}
// Else flat namespace:
else
{
ASSERT (m_OpcNameSpace == OPC_NS_FLAT);
// Insert our root level item (there is no need to add any dummy
// branches since a flat space will only have one level of leaves)
hItem = m_pBranchList->InsertItem (m_pServer->GetProgID (),
ILI_BRANCH, ILI_SELBRANCH, TVI_ROOT);
}
// Select root item:
if (hItem)
m_pBranchList->SelectItem (hItem);
}
catch (...)
{
m_pIBrowse = NULL;
// UpdateStatus (); //更新状态
}
}
void CDlgOPCItemAdd::AddDummyBranch(HTREEITEM hParent)
{
ASSERT (hParent != NULL);
HTREEITEM hDummyItem;
// Insert a dummy(哑巴) item:
hDummyItem = m_pBranchList->InsertItem (NULL_ITEM_NAME, hParent); //NULL_ITEM_NAME="_QCNULL_DUMMY"
ASSERT (hDummyItem != NULL);
m_pBranchList->SetItemData (hDummyItem, NULL_ITEM_DATA);
}
void CDlgOPCItemAdd::OnSelChangedBranchList(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
// Select the branch:
SelectBranch (pNMTreeView->itemNew.hItem);
*pResult = 0;
}
void CDlgOPCItemAdd::SelectBranch(HTREEITEM hItem)
{
ASSERT (hItem != NULL);
int nPos;
HRESULT hr;
LPENUMSTRING pIEnumString;
CStringArray strBranches;
HTREEITEM hParentItem;
#ifndef _UNICODE
WCHAR szFilter [DEFBUFFSIZE];
#endif
// Get the new browse position from the item that was previously
// selected:
nPos = (int) m_pBranchList->GetItemData (hItem);
//数型目录层次标识
BOOL bBrowseFlat= -1==nPos ? TRUE:FALSE; //在一级目录上
// m_bBrowseFlat= -1==nPos ? TRUE:FALSE; //在一级目录上
nPos++;
ASSERT (nPos >= 0);
try
{
//重新定位OPC服务器的位置到根层
// Re-intialize the server's position to the root level:
do
{
// Use the OPC_BROWSE_UP rather than the OPC_BROWSE_TO which
// is only supported in OOPC version 2.0. We will have to
// browse up to root one level at a time. Function will
// fail when we are at root.
hr = m_pIBrowse->ChangeBrowsePosition (OPC_BROWSE_UP, L"\0");
} while (SUCCEEDED (hr));
// Now browse down to the new position:
strBranches.SetSize (nPos + 1);
hParentItem = hItem;
//重新定位OPC服务器的位置到当前选择层
//
for (int i = 0; i <= nPos; i++)
{
ASSERT (hItem);
strBranches [i] = m_pBranchList->GetItemText (hParentItem);
TRACE(_T("%d %s\n"),i,strBranches [i]);
hParentItem = m_pBranchList->GetParentItem (hParentItem);
}
hr = S_OK;
// > 0 we do not want to include the "Root" item since the client
// only uses this branch:
while (SUCCEEDED (hr) && nPos-- > 0)
{
#ifdef _UNICODE
hr = m_pIBrowse->ChangeBrowsePosition (OPC_BROWSE_DOWN, strBranches [nPos]);
#else
WCHAR szBranch [DEFBUFFSIZE];
_mbstowcsz (szBranch, strBranches [nPos], sizeof (szBranch) / sizeof (WCHAR));
hr = m_pIBrowse->ChangeBrowsePosition (OPC_BROWSE_DOWN, szBranch);
#endif
}
// Browse for root level:
#ifdef _UNICODE
hr = m_pIBrowse->BrowseOPCItemIDs (
// m_bBrowseFlat ? OPC_FLAT : OPC_LEAF, // provide items with children
bBrowseFlat ? OPC_FLAT : OPC_LEAF, // provide items with children
m_strFilterLeaf, // item id filtering
m_vtFilterType, // datatype filter
m_dwFilterAccessRights, // access rights filtering
&pIEnumString); // store the interface pointer here
#else
_mbstowcsz (szFilter, m_strFilterLeaf, sizeof (szFilter) / sizeof (WCHAR));
hr = m_pIBrowse->BrowseOPCItemIDs (
// m_bBrowseFlat ? OPC_FLAT : OPC_LEAF, // provide items with children
bBrowseFlat ? OPC_FLAT : OPC_LEAF, // provide items with children
szFilter, // item id filtering
m_vtFilterType, // datatype filter
m_dwFilterAccessRights, // access rights filtering
&pIEnumString); // store the interface pointer here
#endif
// On success add the branches to the root:
if (SUCCEEDED (hr) && pIEnumString)
{
AddLeaves (pIEnumString);
pIEnumString->Release ();
}
else
throw (-1);
}
catch (...)
{
m_pIBrowse = NULL;
// UpdateStatus ();
}
}
void CDlgOPCItemAdd::AddLeaves(LPENUMSTRING pIEnumString)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -