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

📄 additemdlg.cpp

📁 一个OPC客户端监视程序
💻 CPP
字号:
/**************************************************************************
  Description:  Dialog to add an item. The OPC Browse interface is used
                to display the server's items.
                To support browsing on demand, the tree keeps a flag
                in each item's data which is true if the branch has
                been expanded. A dummy is inserted below each item
                so the expand button will be displayed.
**************************************************************************/
#include "stdafx.h"
#include "OPCClientSpy.h"
#include "AddItemDlg.h"
#include "ItemPropertiesDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

LPCWSTR empty = {L""};
CONST ULONG NEXT_COUNT = 100; // number of elements to request when calling
                              // enumerator::Next()

/////////////////////////////////////////////////////////////////////////////
// AddItemDlg dialog

AddItemDlg::AddItemDlg(CValueMsgView* parent, IOPCServer* pServer, CWnd* pParent /*=NULL*/)
   : CDialog(AddItemDlg::IDD, pParent), m_pView( parent )
{
   browse.Attach( pServer );  // Get a Browse interface
   m_vt = VT_EMPTY;
   nameSpaceType = OPC_NS_HIERARCHIAL;
   //{{AFX_DATA_INIT(AddItemDlg)
   m_filter = _T("*");
   m_accessPath = _T("");
   m_itemID = _T("");
   //}}AFX_DATA_INIT
}


void AddItemDlg::DoDataExchange(CDataExchange* pDX)
{
   CDialog::DoDataExchange(pDX);
   //{{AFX_DATA_MAP(AddItemDlg)
   DDX_Control(pDX, IDC_FLAT, m_flat);
   DDX_Control(pDX, IDC_TAGS, m_tags);
   DDX_Control(pDX, IDC_TREE, m_tree);
   DDX_Text(pDX, IDC_FILTER, m_filter);
   DDX_Text(pDX, IDC_ACCESS_PATH, m_accessPath);
   DDX_Text(pDX, IDC_ITEMID, m_itemID);
   //}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(AddItemDlg, CDialog)
   //{{AFX_MSG_MAP(AddItemDlg)
   ON_BN_CLICKED(IDC_NATIVE, OnNative)
   ON_BN_CLICKED(IDC_BOOL, OnBool)
   ON_BN_CLICKED(IDC_SHORT, OnShort)
   ON_BN_CLICKED(IDC_LONG, OnLong)
   ON_BN_CLICKED(IDC_DOUBLE, OnDouble)
   ON_BN_CLICKED(IDC_STRING, OnString)
   ON_LBN_SELCHANGE(IDC_TAGS, OnSelchangeTags)
   ON_NOTIFY(TVN_SELCHANGED, IDC_TREE, OnSelchangedTree)
   ON_LBN_SELCHANGE(IDC_FLAT, OnSelchangeFlat)
   ON_BN_CLICKED(ID_ADDITEM, OnAdditem)
   ON_NOTIFY(TVN_ITEMEXPANDING, IDC_TREE, OnItemexpandingTree)
   ON_EN_KILLFOCUS(IDC_FILTER, OnNewFilter)
   ON_LBN_DBLCLK(IDC_TAGS, OnDblclkTags)
   ON_LBN_DBLCLK(IDC_FLAT, OnDblclkFlat)
   ON_BN_CLICKED(ID_OPC_ITEMPARAMETERS, OnOpcItemparameters)
   //}}AFX_MSG_MAP
END_MESSAGE_MAP()

//**************************************************************************
BOOL AddItemDlg::OnInitDialog()
{
USES_CONVERSION;
   CWaitCursor wait;
   CDialog::OnInitDialog();

   GetDlgItem(ID_OPC_ITEMPARAMETERS)->EnableWindow(FALSE);
   CheckRadioButton( IDC_NATIVE, IDC_STRING, IDC_NATIVE );

   // Fill the tree with the server's hierarchy
   if( !browse.IsOk() )
   {
      m_tree.ShowWindow( FALSE );
      m_tags.ShowWindow( FALSE );
      m_flat.ShowWindow( TRUE );
      m_flat.AddString( _T("Browsing not supported") );
      return TRUE;
   }

   HRESULT hr = browse.QueryOrganization(&nameSpaceType);
   if( FAILED(hr) )
   {
      browse.Detach();
      return TRUE;
   }

   if( nameSpaceType == OPC_NS_HIERARCHIAL ) // show a tree
   {
      HTREEITEM Root = m_tree.InsertItem( _T("Root") );
      m_tree.SetItemData( Root, 1 );
      IEnumString* pEnumString = NULL;
      hr = browse.BrowseOPCItemIDs(OPC_FLAT,
                                  L"*",
                                  m_vt,
                                  0,  // no filtering (or OPC_READABLE|OPC_WRITEABLE)
                                  &pEnumString);
      if( SUCCEEDED(hr) )
      {
         LPWSTR pName[NEXT_COUNT];
         ULONG count = 0;
         do
         {
            hr = pEnumString->Next(NEXT_COUNT, &pName[0], &count);
            // CString does translation from UNICODE to native type
            // (depends on the way the application is built)
           
                CString name( pName[1] );
                HTREEITEM item = m_tree.InsertItem( name, Root );
                m_tree.SetItemData( item, 0 );
                m_tree.InsertItem( _T("Dummy"), item );
                CoTaskMemFree( pName[1] );
            
         }
         while( hr == S_OK );
         pEnumString->Release();
      }
      m_tree.SelectItem( Root );
      m_tree.Expand( Root, TVE_EXPAND );
   }
   else  // namespace must be flat, only display in one listbox
   {
      m_tree.ShowWindow( FALSE );
      m_tags.ShowWindow( FALSE );
      m_flat.ShowWindow( TRUE );
      UpdateFlat();
   }

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

/////////////////////////////////////////////////////////////////////////////
// AddItemDlg message handlers

void AddItemDlg::OnNative()
{
   m_vt = VT_EMPTY;
   if( nameSpaceType == OPC_NS_HIERARCHIAL )
      OnSelchangedTree( NULL, NULL );
   else
      UpdateFlat();
}

void AddItemDlg::OnBool()
{
   m_vt = VT_BOOL;
   if( nameSpaceType == OPC_NS_HIERARCHIAL )
      OnSelchangedTree( NULL, NULL );
   else
      UpdateFlat();
}

void AddItemDlg::OnShort()
{
   m_vt = VT_I2;
   if( nameSpaceType == OPC_NS_HIERARCHIAL )
      OnSelchangedTree( NULL, NULL );
   else
      UpdateFlat();
}

void AddItemDlg::OnLong()
{
   m_vt = VT_I4;
   if( nameSpaceType == OPC_NS_HIERARCHIAL )
      OnSelchangedTree( NULL, NULL );
   else
      UpdateFlat();
}

void AddItemDlg::OnDouble()
{
   m_vt = VT_R8;
   if( nameSpaceType == OPC_NS_HIERARCHIAL )
      OnSelchangedTree( NULL, NULL );
   else
      UpdateFlat();
}

void AddItemDlg::OnString()
{
   m_vt = VT_BSTR;
   if( nameSpaceType == OPC_NS_HIERARCHIAL )
      OnSelchangedTree( NULL, NULL );
   else
      UpdateFlat();
}

//**************************************************************************
// When the user selects a tag, put its name in the ItemID field
void AddItemDlg::OnSelchangeTags()
{
USES_CONVERSION;
   if( !browse.IsOk() )
      return;

   CWaitCursor wait;
   HTREEITEM item = m_tree.GetSelectedItem( );
   HRESULT hr = BrowseHere( item );    // move browse position here

   m_itemID.Empty();
   GetDlgItem(ID_OPC_ITEMPARAMETERS)->EnableWindow(FALSE);
   int nSel;
   if ((nSel = m_tags.GetCurSel()) != LB_ERR)
   {
      m_tags.GetText(nSel,m_itemID);
   }
   else
      return;

   // Ask the server for the itemID
   LPWSTR pName = NULL;
   hr = browse.GetItemID( T2OLE(m_itemID.GetBuffer(0)), &pName );
   if( SUCCEEDED(hr) )
   {
      m_itemID = pName;
      CoTaskMemFree( pName );
      GetDlgItem(ID_OPC_ITEMPARAMETERS)->EnableWindow(TRUE);
   }

   UpdateData( FALSE );

   // return browse position to root
   hr = S_OK;
   for( int i=0; i<10 && SUCCEEDED(hr); i++ )
      hr = browse.ChangeBrowsePosition( OPC_BROWSE_UP, empty );
}

//**************************************************************************
// When the user selects a branch, fill the list of tags
void AddItemDlg::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult)
{
USES_CONVERSION;
   if( !browse.IsOk() )
      return;

   CWaitCursor wait;
   HTREEITEM item = m_tree.GetSelectedItem( );
   HRESULT hr = BrowseHere( item );    // move browse position here
   if( SUCCEEDED(hr) )
   {
      // get the tags
      m_tags.ResetContent();
      IEnumString* pEnumString = NULL;
      hr = browse.BrowseOPCItemIDs(OPC_LEAF,
                                   T2OLE(m_filter.GetBuffer(0)),
                                   m_vt,
                                   0,  // no filtering (or OPC_READABLE|OPC_WRITEABLE)
                                   &pEnumString);
      if( hr == S_OK )
      {
         LPWSTR pName[NEXT_COUNT];
         ULONG count = 0;
         do
         {
            hr = pEnumString->Next(NEXT_COUNT, &pName[0], &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_tags.AddString( name );
               CoTaskMemFree( pName[index] );
            }
         }
         while( hr == S_OK );
         pEnumString->Release();
      }
   }
   hr = S_OK;
   for( int i=0; i<10 && SUCCEEDED(hr); i++ )
      hr = browse.ChangeBrowsePosition( OPC_BROWSE_UP, empty );

   if( pResult )
      *pResult = 0;
}

//**************************************************************************
// Recursive function that moves the browse position to this tree item
HRESULT AddItemDlg::BrowseHere( HTREEITEM item )
{
USES_CONVERSION;
   if( !browse.IsOk() )
      return E_FAIL;

   HRESULT hr = S_OK;
   if( item != NULL )
   {
      HTREEITEM parent = m_tree.GetParentItem( item );
      hr = BrowseHere( parent );
      if( SUCCEEDED( hr ) )
      {
         CString node( m_tree.GetItemText( item ) );
         if( node != _T("Root") )
         {
            hr = browse.ChangeBrowsePosition( OPC_BROWSE_DOWN, T2OLE(node.GetBuffer(0)) );
         }
      }
   }
   return hr;
}

//**************************************************************************
void AddItemDlg::OnSelchangeFlat()
{
USES_CONVERSION;
   if( !browse.IsOk() )
      return;

   CWaitCursor wait;
   m_itemID.Empty();
   GetDlgItem(ID_OPC_ITEMPARAMETERS)->EnableWindow(FALSE);
   int nSel = m_flat.GetCurSel();
   if ( nSel != LB_ERR )
   {
      m_flat.GetText(nSel,m_itemID);
   }
   else
      return;

   // Ask the server for the itemID
   LPWSTR pName = NULL;
   HRESULT hr = browse.GetItemID( T2OLE(m_itemID.GetBuffer(0)), &pName );
   if( SUCCEEDED(hr) )
   {
      m_itemID = pName;
      CoTaskMemFree( pName );
   GetDlgItem(ID_OPC_ITEMPARAMETERS)->EnableWindow(TRUE);
   }

   UpdateData( FALSE );
}

//**************************************************************************
void AddItemDlg::UpdateFlat()
{
USES_CONVERSION;
   if( !browse.IsOk() )
      return;

   CWaitCursor wait;
   // get the tags
   m_flat.ResetContent();
   IEnumString* pEnumString = NULL;
   HRESULT hr = browse.BrowseOPCItemIDs(OPC_FLAT,
                                      T2OLE(m_filter.GetBuffer(0)),
                                      m_vt,
                                      0,  // no filtering (or OPC_READABLE|OPC_WRITEABLE)
                                      &pEnumString);
   if( SUCCEEDED(hr) )
   {
      LPWSTR pName[NEXT_COUNT];
      ULONG count = 0;
      do
      {
         hr = pEnumString->Next(NEXT_COUNT, &pName[0], &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_flat.AddString( name );
            CoTaskMemFree( pName[index] );
         }
      }
      while( hr == S_OK );
      pEnumString->Release();
   }
   m_flat.SetCurSel( 0 );
}

//**************************************************************************
void AddItemDlg::OnAdditem()
{
   CWaitCursor wait;
   UpdateData();
   if( m_pView )
   {
      m_pView->AddItem( m_itemID, m_accessPath, m_vt );
   }
}

//**************************************************************************
void AddItemDlg::OnItemexpandingTree(NMHDR* pNMHDR, LRESULT* pResult)
{
USES_CONVERSION;
   if( !browse.IsOk() )
      return;

   CWaitCursor wait;
   NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
   HTREEITEM start = pNMTreeView->itemNew.hItem;
   DWORD expanded = m_tree.GetItemData( start );
   if( !expanded )
   {
      m_tree.SetItemData( start, 1 );  // mark this item expanded
      // remove existing children
      HTREEITEM hItem = m_tree.GetNextItem (start, TVGN_CHILD);
      while (hItem)
      {
         m_tree.DeleteItem( hItem );
         hItem = m_tree.GetNextItem(start, TVGN_CHILD);
      }
      // browse new children
      HRESULT hr = BrowseHere( start );    // move browse position here
      if( SUCCEEDED(hr) )
      {
         IEnumString* pEnumString = NULL;
         hr = browse.BrowseOPCItemIDs( OPC_BRANCH,
                                       L"*",
                                       VT_EMPTY,
                                       0,  // no filtering (or OPC_READABLE|OPC_WRITEABLE)
                                       &pEnumString);
         if( SUCCEEDED(hr) )
         {
            LPWSTR pName[NEXT_COUNT];
            ULONG count = 0;
            do
            {
               hr = pEnumString->Next(NEXT_COUNT, &pName[0], &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] );
                   HTREEITEM item = m_tree.InsertItem( name, start );
                   m_tree.SetItemData( item, 0 );
                   m_tree.InsertItem( _T("Dummy"), item );
                   CoTaskMemFree( pName[index] );
               }
            }
            while( hr == S_OK );
            pEnumString->Release();
         }
      }
      // return browse position to root
      hr = S_OK;
      for( int i=0; i<10 && SUCCEEDED(hr); i++ )
         hr = browse.ChangeBrowsePosition( OPC_BROWSE_UP, empty );
   }
   *pResult = 0;
}

void AddItemDlg::OnNewFilter()
{
   UpdateData( );
   if( nameSpaceType == OPC_NS_HIERARCHIAL )
      OnSelchangedTree( NULL, NULL );
   else
      UpdateFlat();
}

void AddItemDlg::OnDblclkTags()
{
    OnAdditem();
}

void AddItemDlg::OnDblclkFlat()
{
    OnAdditem();
}

void AddItemDlg::OnOpcItemparameters()
{
   UpdateData();
   if( m_itemID.IsEmpty() )
      return;
   CItemPropertiesDlg dlg(m_itemID);
   dlg.SetOPCPointer( (IUnknown*)((m_pView->m_pServerView)->opcServer) );
   dlg.DoModal();
}

⌨️ 快捷键说明

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