www.pudn.com > 18900_netwall_lite.rar > NetWallView.cpp


/**************************************************************************/ 
/*  NetWallView.cpp : implementation of the CNetWallView class            */ 
/*                                                                        */ 
/*  这个文件实现一个树视图,在树上面显示适配器的相关信息,规则,日志等。  */ 
/*  当程序启动的时候,主框架从NetWall中间层驱动读取适配器的相关信息,然后 */ 
/*  主框架创建这个树视图,视图利用取回的适配器信息刷新树。                */  
/*                                                                        */         
/*	当用户点击该适配器项本身时,将发消息给主框架刷新右视图,列表显示适配  */ 
/*  的每一项信息。                                                        */ 
/*                                                                        */                                                              
/*	当用户点击该适配器的规则项时,将发消息给主框架将适配器的规则信息显示  */ 
/*  在树上,并且刷新右视图,列表显示每一项规则信息。                      */ 
/*                                                                        */ 
/*	当用户点击该适配器的日志项时,将发消息给主框架刷新右视图,列表显示该  */ 
/*  适配器的当天日志信息。                                                */ 
/*    */ 
/*	  */ 
/*    */ 
/*    */ 
/*	  */ 
/*    */ 
/**************************************************************************/ 
#include "stdafx.h" 
#include "NetWall.h" 
 
#include "NetWallDoc.h" 
#include "NetWallView.h" 
 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
// Image indexes 
#define ILI_HARD_DISK       0 
#define ILI_FLOPPY          1 
#define ILI_CD_ROM          2 
#define ILI_NET_DRIVE       3 
#define ILI_CLOSED_FOLDER   4 
#define ILI_OPEN_FOLDER     5 
 
const LPCTSTR  ADAPTER_NAME = _T("适配器"); 
const LPCTSTR  RULE_NAME    = _T("规则"); 
const LPCTSTR  LOG_NAME     = _T("日志"); 
 
///////////////////////////////////////////////////////////////////////////// 
// CNetWallView 
 
IMPLEMENT_DYNCREATE(CNetWallView, CTreeView) 
 
BEGIN_MESSAGE_MAP(CNetWallView, CTreeView) 
	//{{AFX_MSG_MAP(CNetWallView) 
	ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding) 
	ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged) 
	ON_WM_CREATE() 
	ON_NOTIFY_REFLECT(TVN_DELETEITEM, OnDeleteitem) 
	ON_WM_CONTEXTMENU() 
	ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick) 
	//}}AFX_MSG_MAP 
	// Standard printing commands 
	ON_COMMAND(ID_FILE_PRINT, CTreeView::OnFilePrint) 
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CTreeView::OnFilePrint) 
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CTreeView::OnFilePrintPreview) 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CNetWallView construction/destruction 
 
CNetWallView::CNetWallView() 
{ 
    m_pCurrentAdapter = NULL; 
	m_pAdapterList    = NULL; 
} 
 
CNetWallView::~CNetWallView() 
{ 
    m_pCurrentAdapter = NULL; 
    m_pAdapterList    = NULL; 
} 
 
BOOL CNetWallView::PreCreateWindow(CREATESTRUCT& cs) 
{     	 
    if (! CTreeView::PreCreateWindow(cs)) 
    { 
		return FALSE; 
    } 
 
    //  Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
    cs.style |= TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_SHOWSELALWAYS; 
	 
    return TRUE; 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CNetWallView drawing 
 
void CNetWallView::OnDraw(CDC* pDC) 
{ 
	CNetWallDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc);	 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CNetWallView diagnostics 
 
#ifdef _DEBUG 
void CNetWallView::AssertValid() const 
{ 
    CTreeView::AssertValid(); 
} 
 
void CNetWallView::Dump(CDumpContext& dc) const 
{ 
    CTreeView::Dump(dc); 
} 
 
CNetWallDoc* CNetWallView::GetDocument() // non-debug version is inline 
{ 
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CNetWallDoc))); 
    return (CNetWallDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CNetWallView message handlers 
 
int CNetWallView::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
    if (CTreeView::OnCreate(lpCreateStruct) == -1) 
    { 
        return -1; 
    } 
     
    // 
    // Initialize the image list. 
    // 
    m_ilAdapters.Create(IDB_NETWALL_IMAGES, 16, 1, RGB(255, 0, 255)); 
    m_ilAdapters.SetBkColor(GetSysColor(COLOR_WINDOW)); 
    GetTreeCtrl().SetImageList(&m_ilAdapters, TVSIL_NORMAL); 
         
    return 0; 
} 
 
void CNetWallView::OnInitialUpdate()  
{ 
    CTreeView::OnInitialUpdate(); 
     
    Refresh(ADAPTER); 
} 
 
void CNetWallView::Refresh(NETWALL_LIST_TYPE eType, CAdapterInfo *pAdapterInfo) 
{ 
    GetTreeCtrl().DeleteAllItems(); 
 
    // 
    // Populate the tree view with adapters items. 
    // 
    m_pAdapterList = ((CMainFrame *)AfxGetMainWnd())->GetAdapters(); 
    if (NULL != m_pAdapterList) 
    { 
        AddAdapters(); 
    }     
     
    if (ADAPTER == eType) 
    { 
        // 
        // Show the items on the first adapter. 
        //	 
        HTREEITEM hItem = GetTreeCtrl().GetNextItem(NULL, TVGN_ROOT);	 
        if (hItem != NULL)  
        { 
            GetTreeCtrl().Expand(hItem, TVE_EXPAND); 
            GetTreeCtrl().Select(hItem, TVGN_CARET); 
        } 
     
        // 
        // Initialize the list view. 
        // 
        m_pCurrentAdapter = (CAdapterInfo *)GetTreeCtrl().GetItemData(GetTreeCtrl().GetSelectedItem()); 
        ((CMainFrame *)AfxGetMainWnd())->SetCurrentAdapter(m_pCurrentAdapter); 
        GetDocument()->UpdateAllViews(this, ADAPTER, (CObject *)m_pCurrentAdapter); 
    } 
    else if (RULE == eType) 
    { 
        // 
        // Show the rule items on the first adapter. 
        //	 
        HTREEITEM hItem = GetTreeCtrl().GetNextItem(NULL, TVGN_ROOT);	 
        while (hItem != NULL)  
        { 
            CAdapterInfo * pAdapter = (CAdapterInfo *)GetTreeCtrl().GetItemData(hItem); 
            if (pAdapter == pAdapterInfo) 
            { 
                GetTreeCtrl().Expand(hItem, TVE_EXPAND); 
                GetTreeCtrl().Select(hItem, TVGN_CARET); 
                                 
                HTREEITEM  hChildItem = GetTreeCtrl().GetChildItem(hItem); 
                 
                while (hChildItem != NULL) 
                { 
                    CString strItem = _T(""); 
                    strItem = GetTreeCtrl().GetItemText(hChildItem); 
                    if (! strItem.IsEmpty() && ! _tcscmp(strItem, RULE_NAME)) 
                    { 
                        GetTreeCtrl().Expand(hChildItem, TVE_EXPAND); 
                        GetTreeCtrl().Select(hChildItem, TVGN_CARET); 
                        break; 
                    }  
                     
                    hChildItem = GetTreeCtrl().GetNextSiblingItem(hChildItem); 
                } 
                 
                break; 
            } 
             
            hItem = GetTreeCtrl().GetNextSiblingItem(hItem);                        
        } 
    } 
    else if (LOG == eType) 
    { 
        // 
        // Show the log items on the adapter. 
        //	 
        HTREEITEM hItem = GetTreeCtrl().GetNextItem(NULL, TVGN_ROOT);	 
        while (hItem != NULL)  
        { 
            CAdapterInfo * pAdapter = (CAdapterInfo *)GetTreeCtrl().GetItemData(hItem); 
            if (pAdapter == pAdapterInfo) 
            { 
                GetTreeCtrl().Expand(hItem, TVE_EXPAND); 
                GetTreeCtrl().Select(hItem, TVGN_CARET); 
                 
                HTREEITEM  hChildItem = GetTreeCtrl().GetChildItem(hItem); 
                 
                while (hChildItem != NULL) 
                { 
                    CString strItem = _T(""); 
                    strItem = GetTreeCtrl().GetItemText(hChildItem); 
                    if (! strItem.IsEmpty() && ! _tcscmp(strItem, LOG_NAME)) 
                    { 
                        GetTreeCtrl().Expand(hChildItem, TVE_EXPAND); 
                        GetTreeCtrl().Select(hChildItem, TVGN_CARET); 
                        break; 
                    }  
                     
                    hChildItem = GetTreeCtrl().GetNextSiblingItem(hChildItem); 
                } 
                 
                break; 
            } 
             
            hItem = GetTreeCtrl().GetNextSiblingItem(hItem);                        
        }         
    } 
} 
 
int CNetWallView::AddAdapters() 
{ 
    int nAdaptersAdded = 0; 
    CString strItem = _T(""); 
     
    for (CAdapterListIterator it = m_pAdapterList->begin(); 
         it != m_pAdapterList->end(); 
         it++) 
    { 
        HTREEITEM hItem; 
        strItem.Format(_T("适配器 %d"), ++nAdaptersAdded); 
         
        hItem = GetTreeCtrl().InsertItem(strItem, ILI_NET_DRIVE, ILI_NET_DRIVE); 
         
        GetTreeCtrl().SetItemData(hItem, (DWORD)(*it)); 
         
        GetTreeCtrl().InsertItem(_T(""), ILI_CLOSED_FOLDER, ILI_CLOSED_FOLDER, hItem); 
    } 
     
    return nAdaptersAdded; 
} 
 
BOOL CNetWallView::SetButtonState(HTREEITEM hItem, LPCTSTR lpszItem) 
{ 
    if (! _tcsnicmp(lpszItem, RULE_NAME, _tcslen(RULE_NAME))) 
    { 
        HTREEITEM hParentItem = GetTreeCtrl().GetParentItem(hItem); 
        if (NULL != hParentItem) 
        { 
            CAdapterInfo * pAdaterInfo = (CAdapterInfo *)GetTreeCtrl().GetItemData(hParentItem); 
            ASSERT(pAdaterInfo); 
 
            if (((CMainFrame *)AfxGetMainWnd())->HasRuleForAdapter(pAdaterInfo)) 
            {                 
                HTREEITEM  hNewItem = GetTreeCtrl().InsertItem(_T(""), ILI_CLOSED_FOLDER, ILI_CLOSED_FOLDER, hItem); 
                GetTreeCtrl().SetItemData(hNewItem, (DWORD)(0)); 
            } 
        }                 
    } 
 
    // Don't support logged now. 
    else if (! _tcsnicmp(lpszItem, LOG_NAME, _tcslen(LOG_NAME))) 
    { 
        // HTREEITEM  hNewItem = GetTreeCtrl().InsertItem(_T (""), ILI_CLOSED_FOLDER, ILI_CLOSED_FOLDER, hItem); 
        // GetTreeCtrl().SetItemData(hNewItem, (DWORD)(0));         
    } 
    else 
    { 
        return FALSE; 
    } 
 
    return TRUE; 
} 
 
void CNetWallView::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)  
{ 
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; 
    HTREEITEM hItem = pNMTreeView->itemNew.hItem; 
    CString strItem = GetTreeCtrl().GetItemText(hItem); 
     
    *pResult = FALSE; 
     
    if (pNMTreeView->action == TVE_EXPAND)  
    { 
        DeleteFirstChild(hItem); 
        if (AddAdapterItems(hItem, strItem) == 0) 
        { 
            *pResult = TRUE; 
        } 
    } 
    else // pNMTreeView->action == TVE_COLLAPSE 
    {  
        DeleteAllChildren(hItem); 
        if (GetTreeCtrl().GetParentItem(hItem) == NULL) 
        { 
            HTREEITEM  hNewItem = GetTreeCtrl().InsertItem(_T(""), ILI_CLOSED_FOLDER, ILI_CLOSED_FOLDER, hItem); 
            GetTreeCtrl().SetItemData(hNewItem, (DWORD)(0)); 
        } 
        else 
        { 
            SetButtonState(hItem, strItem); 
        } 
    }	 
} 
 
void CNetWallView::DeleteFirstChild(HTREEITEM hItem) 
{ 
    HTREEITEM   hChildItem; 
 
    if ((hChildItem = GetTreeCtrl().GetChildItem(hItem)) != NULL) 
    { 
        GetTreeCtrl().DeleteItem(hChildItem); 
    } 
} 
 
void CNetWallView::DeleteAllChildren(HTREEITEM hItem) 
{ 
    HTREEITEM   hChildItem; 
 
    if ((hChildItem = GetTreeCtrl().GetChildItem(hItem)) == NULL) 
    { 
        return; 
    } 
     
    do  
    { 
        HTREEITEM hNextItem = GetTreeCtrl ().GetNextSiblingItem(hChildItem); 
        GetTreeCtrl().DeleteItem(hChildItem); 
        hChildItem = hNextItem; 
         
    } while (hChildItem != NULL); 
} 
 
int CNetWallView::AddAdapterItems(HTREEITEM hItem, CString strItem) 
{ 
    HTREEITEM   hNewItem; 
    int         nCount = 0; 
     
    try 
    {     
        // Add Adapter's sub item 
        if (! _tcsnicmp(strItem, ADAPTER_NAME, _tcslen(ADAPTER_NAME))) 
        {         
            hNewItem = GetTreeCtrl().InsertItem(RULE_NAME, ILI_CLOSED_FOLDER, ILI_OPEN_FOLDER, hItem); 
            GetTreeCtrl().SetItemData(hNewItem, (DWORD)(0)); 
            SetButtonState(hNewItem, RULE_NAME); 
            nCount++; 
         
            hNewItem = GetTreeCtrl().InsertItem(LOG_NAME, ILI_CLOSED_FOLDER, ILI_OPEN_FOLDER, hItem); 
            GetTreeCtrl().SetItemData(hNewItem, (DWORD)(0)); 
            SetButtonState(hNewItem, LOG_NAME); 
            nCount++; 
        } 
     
        else if (! _tcsnicmp(strItem, RULE_NAME, _tcslen(RULE_NAME)))  
        { 
            CString strItem = _T(""); 
         
            if (0 < m_pCurrentAdapter->m_dwNumberOfRules) 
            { 
                RULE_ITEM * pItem = ((CMainFrame *)AfxGetMainWnd())->GetAdapterRuleItem(); 
 
                for (nCount = 0; nCount < m_pCurrentAdapter->m_dwNumberOfRules; nCount++)         
                { 
                    strItem.Format(_T("规则 %d"), nCount + 1); 
                     
                    hNewItem = GetTreeCtrl().InsertItem(strItem, ILI_NET_DRIVE, ILI_NET_DRIVE, hItem);   
                                         
                    RULE_ITEM * pNode = (PRULE_ITEM)new BYTE[pItem->cbSize]; 
                    ASSERT(pItem && pNode);                           
                     
                    RtlCopyMemory(pNode, pItem, pItem->cbSize); 
                     
                    GetTreeCtrl().SetItemData(hNewItem, (DWORD)(pNode));   
                     
                    pItem = (RULE_ITEM *)((LPBYTE)pItem + pItem->cbSize); 
                }     
            }                 
        }         
 
        else if (! _tcsnicmp(strItem, LOG_NAME, _tcslen(LOG_NAME)))  
        { 
            // Don't support Logged now. 
        } 
    } 
    catch (...) 
    { 
        AfxMessageBox(_T("刷新树视图失败!")); 
        throw; 
    } 
 
    return nCount; 
} 
 
/************************************************************************/ 
/* 当用户选择树上某项时,发消息给MainFrame更新右视图,并刷新右视图。    */ 
/************************************************************************/ 
void CNetWallView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)  
{ 
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;	 
 
    ((CMainFrame *)AfxGetMainWnd())->m_nIndex = -1; 
     
    HTREEITEM  hItem = pNMTreeView->itemNew.hItem;     
    if (NULL == hItem) 
    { 
        return; 
    } 
 
    // Get Adapter  
    HTREEITEM hParent, hTempItem; 
    hTempItem = hItem; 
    while ((hParent = GetTreeCtrl().GetParentItem(hTempItem)) != NULL)  
    {         
        hTempItem = hParent; 
    } 
 
    m_pCurrentAdapter = (CAdapterInfo *)GetTreeCtrl().GetItemData(hParent == NULL ? hTempItem : hParent); 
     
    ((CMainFrame *)AfxGetMainWnd())->SetCurrentAdapter(m_pCurrentAdapter); 
     
    // Set Data 
    CString strItem = GetTreeCtrl().GetItemText(pNMTreeView->itemNew.hItem); 
 
    // 在 RuleListView 中显示适配器的信息 
    if (! _tcsnicmp(strItem, ADAPTER_NAME, _tcslen(ADAPTER_NAME))) 
    { 
        AfxGetMainWnd()->SendMessage(WM_USER_DISPLAY_RULEITEM, ADAPTER, 0); 
        GetDocument()->UpdateAllViews(this, ADAPTER, (CObject *)m_pCurrentAdapter); 
        ((CMainFrame *)AfxGetMainWnd())->UpdateStatusBar(ADAPTER); 
    } 
    else if (! _tcsnicmp(strItem, RULE_NAME, _tcslen(RULE_NAME)))  
    { 
        // 在 RuleListView 中显示当前适配器的所有规则信息 
        if (strItem == RULE_NAME) 
        { 
            AfxGetMainWnd()->SendMessage(WM_USER_DISPLAY_RULEITEM, RULE, 0); 
            GetDocument()->UpdateAllViews(this, RULE, (CObject *)m_pCurrentAdapter); 
            ((CMainFrame *)AfxGetMainWnd())->UpdateStatusBar(RULE); 
        } 
         
        // 在 DisplayRuleView 中显示当前适配器的一条规则的详细信息 
        else 
        { 
            RULE_ITEM  *pNode = (PRULE_ITEM)GetTreeCtrl().GetItemData(hItem); 
            ASSERT(pNode); 
            if (NULL != pNode) 
            {            
                ((CMainFrame *)AfxGetMainWnd())->m_nIndex = atoi(strItem.Mid(strItem.Find(_T(' ')) + 1)) - 1; 
                 
                AfxGetMainWnd()->SendMessage(WM_USER_DISPLAY_RULEITEM, RULEITEM, (LPARAM)pNode); 
                GetDocument()->UpdateAllViews(this, RULEITEM, (CObject *)pNode); 
                ((CMainFrame *)AfxGetMainWnd())->UpdateStatusBar(RULEITEM); 
            } 
        } 
    } 
 
    // 在 RuleListView 中显示当前适配器当天的日志信息 
    else if (! _tcsnicmp(strItem, LOG_NAME, _tcslen(LOG_NAME)))  
    { 
        AfxGetMainWnd()->SendMessage(WM_USER_DISPLAY_RULEITEM, LOG, 0); 
        GetDocument()->UpdateAllViews(this, LOG, (CObject *)m_pCurrentAdapter); 
    } 
     
    *pResult = 0; 
} 
 
void CNetWallView::OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult)  
{ 
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; 
 
	HTREEITEM hItem = (pNMTreeView->itemOld).hItem; 
 
    CString strItem = GetTreeCtrl().GetItemText(hItem); 
    if (! strItem.IsEmpty()  
        && strItem.GetLength() > _tcslen(RULE_NAME)  
        && ! _tcsnicmp(strItem, RULE_NAME, _tcslen(RULE_NAME))) 
    {     
        RULE_ITEM  *pNode = (PRULE_ITEM)GetTreeCtrl().GetItemData(hItem); 
        if (NULL != pNode) 
        { 
            delete	[](LPBYTE)pNode; 
            pNode = NULL; 
        } 
    } 
     
    *pResult = 0; 
} 
 
 
void CNetWallView::OnContextMenu(CWnd* pWnd, CPoint point)  
{     
    if (point.x == -1 && point.y == -1) 
    { 
        //keystroke invocation 
        CRect rect; 
        GetClientRect(rect); 
        ClientToScreen(rect); 
         
        point = rect.TopLeft(); 
        point.Offset(5, 5); 
    } 
     
    CMenu menu; 
    VERIFY(menu.LoadMenu(IDR_POPUP_ADAPTER_VIEW)); 
     
    CMenu* pPopup = menu.GetSubMenu(0); 
    ASSERT(pPopup != NULL); 
    CWnd* pWndPopupOwner = this; 
     
    while (pWndPopupOwner->GetStyle() & WS_CHILD) 
    { 
        pWndPopupOwner = pWndPopupOwner->GetParent(); 
    } 
     
    pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, 
        pWndPopupOwner); 
     
} 
 
void CNetWallView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult)  
{	    
    CPoint curPoint; 
    GetCursorPos(&curPoint); 
 
    ScreenToClient(&curPoint); 
     
    // Select the item that is at the point myPoint. 
    UINT uFlags; 
    HTREEITEM hItem = GetTreeCtrl().HitTest(curPoint, &uFlags); 
     
    if ((hItem != NULL) && (TVHT_ONITEM & uFlags)) 
    { 
        GetTreeCtrl().Select(hItem, TVGN_CARET); 
        SendMessage(WM_CONTEXTMENU, 0, MAKELPARAM(curPoint.x, curPoint.y)); 
    } 
     
	*pResult = 0; 
}