// KRView.cpp : implementation of the CKeyRingView class // #include "stdafx.h" #include "KeyRing.h" #include "MainFrm.h" #include "KeyObjs.h" #include "machine.h" #include "KRDoc.h" #include "KeyDView.h" #include "KRView.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif extern CKeyDataView* g_pDataView; ///////////////////////////////////////////////////////////////////////////// // CKeyRingView IMPLEMENT_DYNCREATE(CKeyRingView, CTreeView) BEGIN_MESSAGE_MAP(CKeyRingView, CTreeView) //{{AFX_MSG_MAP(CKeyRingView) ON_WM_RBUTTONDOWN() ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged) ON_UPDATE_COMMAND_UI(ID_SERVER_DISCONNECT, OnUpdateServerDisconnect) ON_COMMAND(ID_SERVER_DISCONNECT, OnServerDisconnect) ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk) ON_WM_CHAR() //}}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() ///////////////////////////////////////////////////////////////////////////// // CKeyRingView construction/destruction CKeyRingView::CKeyRingView() { // TODO: add construction code here } CKeyRingView::~CKeyRingView() { } BOOL CKeyRingView::PreCreateWindow(CREATESTRUCT& cs) { cs.style |= (TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT); return CTreeView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CKeyRingView drawing void CKeyRingView::OnDraw(CDC* pDC) { CKeyRingDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here } ///////////////////////////////////////////////////////////////////////////// // CKeyRingView printing BOOL CKeyRingView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CKeyRingView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CKeyRingView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CKeyRingView diagnostics #ifdef _DEBUG void CKeyRingView::AssertValid() const { CTreeView::AssertValid(); } void CKeyRingView::Dump(CDumpContext& dc) const { CTreeView::Dump(dc); } CKeyRingDoc* CKeyRingView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CKeyRingDoc))); return (CKeyRingDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CKeyRingView message handlers //----------------------------------------------------------------------- void CKeyRingView::DestroyItems() { HTREEITEM hRoot; CTreeCtrl* pTree = (CTreeCtrl*)this; // make sure the items in the tree are deleted as well while ( hRoot = pTree->GetRootItem() ) { CMachine* pMachine = (CMachine*)pTree->GetItemData( hRoot ); ASSERT( pMachine->IsKindOf( RUNTIME_CLASS(CMachine) ) ); DisconnectMachine( pMachine ); delete pMachine; } } //----------------------------------------------------------------------- void CKeyRingView::DisconnectMachine( CMachine* pMachine ) { // loop through the services and disconnect them all CService* pService; while( pService = (CService*)pMachine->GetFirstChild() ) { ASSERT( pService->IsKindOf( RUNTIME_CLASS(CService) ) ); pService->CloseConnection(); pService->FRemoveFromTree(); delete pService; } // now remove the machine itself pMachine->FRemoveFromTree(); } //----------------------------------------------------------------------- BOOL CKeyRingView::FCommitMachinesNow() { CTreeCtrl* pTree = (CTreeCtrl*)this; // the success flag BOOL fSuccess = TRUE; // make sure the items in the tree are deleted as well HTREEITEM hItem = pTree->GetRootItem(); while ( hItem ) { CInternalMachine* pMachine = (CInternalMachine*)pTree->GetItemData( hItem ); ASSERT( pMachine->IsKindOf( RUNTIME_CLASS(CMachine) ) ); fSuccess &= pMachine->FCommitNow(); // get the next item hItem = pTree->GetNextSiblingItem( hItem ); } // return whether or not it succeeded return fSuccess; } //----------------------------------------------------------------------- BOOL CKeyRingView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) { BOOL f; // create the main object f = CTreeView::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); // assuming that worked, create the image list and set it into the tree view control if ( f ) { CTreeCtrl *pTree = (CTreeCtrl*)this;; // create the image list f = m_imageList.Create( IDB_TREEIMAGES, 16, 3, 0x00FF00FF ); // set the image list into the tree control pTree->SetImageList( &m_imageList, TVSIL_NORMAL ); } // return the answer return f; } //------------------------------------------------------------------------------ void CKeyRingView::OnContextMenu(CWnd*, CPoint point) { // lets see, what is that point in client coordinates..... CPoint ptClient = point; ScreenToClient( &ptClient ); // we need to start this by selecting the correct item that // is being clicked on. First, find the item CTreeCtrl* pTree = (CTreeCtrl*)this; UINT flagsHit; HTREEITEM hHit = pTree->HitTest( ptClient, &flagsHit ); // if nothing was hit, then don't bother with a context menu if ( !hHit ) return; // select the item that was hit pTree->SelectItem( hHit ); // double check that we have the right selection // now get that item's CTreeItem CTreeItem* pItem = PGetSelectedItem(); if ( !pItem ) return; // get on with the context menu... CMenu menu; VERIFY(menu.LoadMenu(IDR_KEYPROP)); // determine which sub menu to display WORD iSubMenu; if ( pItem->IsKindOf(RUNTIME_CLASS(CKey)) ) iSubMenu = 0; // key menu else if ( pItem->IsKindOf(RUNTIME_CLASS(CMachine)) ) iSubMenu = 1; // machine menu else if ( pItem->IsKindOf(RUNTIME_CLASS(CService)) ) iSubMenu = 2; // server menu else { ASSERT( FALSE ); return; // we can't handle it } CMenu* pPopup = menu.GetSubMenu(iSubMenu); 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); } //----------------------------------------------------------------------- BOOL CKeyRingView::PreTranslateMessage(MSG* pMsg) { short a; if ( pMsg->message == WM_KEYDOWN ) a = 0; // CG: This block was added by the Pop-up Menu component { // Shift+F10: show pop-up menu. if ((((pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN) && // If we hit a key and (pMsg->wParam == VK_F10) && (GetKeyState(VK_SHIFT) & ~1)) != 0) || // it's Shift+F10 OR (pMsg->message == WM_CONTEXTMENU)) // Natural keyboard key { // get the rect of the selected item and base the position of the menu // off of that. CRect rect; CTreeCtrl* pTree = (CTreeCtrl*)this; HTREEITEM hSelItem = pTree->GetSelectedItem(); // if no item is selected, bail if ( !hSelItem ) return TRUE; // now get that rect... if ( !pTree->GetItemRect( hSelItem, &rect, TRUE ) ) return TRUE; // finish prepping and call the menu ClientToScreen(rect); CPoint point = rect.BottomRight(); point.Offset(-10, -10); OnContextMenu(NULL, point); return TRUE; } } return CTreeView::PreTranslateMessage(pMsg); } //----------------------------------------------------------------------- void CKeyRingView::OnRButtonDown(UINT nFlags, CPoint point) { // let the sub class do its thing CTreeView::OnRButtonDown(nFlags, point); // convert the point to screen coordinates ClientToScreen( &point ); // run the context menu OnContextMenu(NULL, point); } //----------------------------------------------------------------------- CTreeItem* CKeyRingView::PGetSelectedItem() { CTreeCtrl* pTree = (CTreeCtrl*)this; HTREEITEM hHit = pTree->GetSelectedItem(); if ( !hHit ) return NULL; // now get that item's CTreeItem return (CTreeItem*)pTree->GetItemData( hHit ); } //----------------------------------------------------------------------- void CKeyRingView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; CKeyRingDoc* pDoc = GetDocument(); // make sure the key data view updates pDoc->UpdateAllViews( this, HINT_ChangeSelection, NULL ); *pResult = 0; } //----------------------------------------------------------------------- void CKeyRingView::OnUpdateServerDisconnect(CCmdUI* pCmdUI) { CTreeItem* pItem = PGetSelectedItem(); if ( pItem ) pCmdUI->Enable( pItem->IsKindOf(RUNTIME_CLASS(CRemoteMachine)) ); else pCmdUI->Enable( FALSE ); } //----------------------------------------------------------------------- void CKeyRingView::OnServerDisconnect() { CRemoteMachine* pMachine = (CRemoteMachine*)PGetSelectedItem(); ASSERT( pMachine->IsKindOf(RUNTIME_CLASS(CRemoteMachine)) ); // if the machine is dirty, try to commit it if ( pMachine->FGetDirty() ) { // ask the user if they want to commit switch( AfxMessageBox(IDS_SERVER_COMMIT, MB_YESNOCANCEL|MB_ICONQUESTION) ) { case IDYES: // yes, they do want to commit pMachine->FCommitNow(); break; case IDNO: // no, they don't want to commit break; case IDCANCEL: // whoa nellie! Stop this return; } } DisconnectMachine( pMachine ); delete pMachine; } //----------------------------------------------------------------------- // A double click on a key should bring up the properties dialog void CKeyRingView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) { CKey* pKey = (CKey*)PGetSelectedItem(); if ( pKey && pKey->IsKindOf(RUNTIME_CLASS(CKey)) ) pKey->OnProperties(); *pResult = 0; } //----------------------------------------------------------------------- // allow the user to tab to the data view void CKeyRingView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { if ( nChar == _T(' ') ) { // get the parental frame window CMainFrame* pFrame = (CMainFrame*)GetParentFrame(); // give the data view the focus pFrame->SetActiveView( g_pDataView ); } else CTreeView::OnChar(nChar, nRepCnt, nFlags); }