// *************************************************************************** // // Copyright (c) 1996-2001 Microsoft Corporation, All Rights Reserved // // File: CClassTree.cpp // // Description: // This file implements the CClassTree class which is a part of the Class // Navigator OCX, it is a subclass of the Microsoft CTreeCtrl common // control and performs the following functions: // a. Insertion of individual classes // b. Allows classes to be "expanded" by going out to the database // to get its subclasses // c. Allows classes to be renamed. // d. Supports operations to add and delete tree branches. // e. Supports OLE drag and drop (disabled for ALPHA) // // Part of: // ClassNav.ocx // // Used by: // // // History: // Judith Ann Powell 10-08-96 Created. // // // ************************************************************************** // =========================================================================== // // Includes // // =========================================================================== #include "precomp.h" #include "resource.h" #include "afxpriv.h" #include "AFXCONV.H" #include "wbemidl.h" #include "olemsclient.h" #include "CClassTree.h" #include "RenameClassDIalog.h" #include "TreeDropTarget.h" #include "CContainedToolBar.h" #include "Banner.h" #include "ClassNavCtl.h" #include "resource.h" #define KBSelectionTimer 1000 #define ExpansionOrSelectionTimer 1001 #define UPDATESELECTEDITEM WM_USER + 450 #define SELECTITEMONFOCUS WM_USER + 451 void CALLBACK EXPORT SelectItemAfterDelay(HWND hWnd,UINT nMsg, WPARAM nIDEvent, ULONG dwTime) { ::PostMessage(hWnd,UPDATESELECTEDITEM,0,0); } // Only has a valid value for the interval between a double click. CClassTree *gpTreeTmp; void CALLBACK EXPORT ExpansionOrSelection(HWND hWnd,UINT nMsg,WPARAM nIDEvent, ULONG dwTime) { CClassTree *pTree = gpTreeTmp; if (!pTree) { return; } if (pTree->m_uiSelectionTimer) { pTree->KillTimer(pTree->m_uiSelectionTimer ); pTree-> m_uiSelectionTimer= 0; } if (InterlockedDecrement(&pTree->m_lSelection) == 0) { CPoint point(0,0); pTree->ContinueProcessSelection(TRUE,point ); gpTreeTmp = NULL; } } // =========================================================================== // // Message Map // // =========================================================================== BEGIN_MESSAGE_MAP(CClassTree,CTreeCtrl) ON_WM_CONTEXTMENU() //{{AFX_MSG_MAP(CClassTree) ON_WM_CREATE() ON_WM_LBUTTONUP() ON_WM_MOUSEMOVE() ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged) ON_WM_HSCROLL() ON_WM_VSCROLL() ON_WM_SIZE() ON_WM_DESTROY() ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnEndlabeledit) ON_WM_LBUTTONDOWN() ON_WM_RBUTTONDOWN() ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemexpanded) ON_NOTIFY_REFLECT(TVN_BEGINLABELEDIT, OnBeginlabeledit) ON_NOTIFY_REFLECT(TVN_KEYDOWN, OnKeydown) ON_WM_CONTEXTMENU() ON_NOTIFY_REFLECT(NM_KILLFOCUS, OnKillfocus) ON_NOTIFY_REFLECT(NM_SETFOCUS, OnSetfocus) ON_NOTIFY_REFLECT(TVN_SELCHANGING, OnSelchanging) //}}AFX_MSG_MAP ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING,OnItemExpanding) ON_MESSAGE( UPDATESELECTEDITEM,SelectTreeItem) ON_MESSAGE( SELECTITEMONFOCUS,SelectTreeItemOnFocus) END_MESSAGE_MAP() // *************************************************************************** // // CClassTree::PreCreateWindow // // Description: // This VIRTUAL member function returns Initializes create struct values // for the custom tree control. // // Parameters: // CREATESTRUCT& cs A reference to a CREATESTRUCT with default control // creation values. // // Returns: // BOOL Nonzero if the window creation should continue; // 0 to indicate creation failure. // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** BOOL CClassTree::PreCreateWindow(CREATESTRUCT& cs) { if (!CTreeCtrl::PreCreateWindow(cs)) return FALSE; cs.style = WS_CHILD | WS_VISIBLE | CS_DBLCLKS | TVS_SHOWSELALWAYS | TVS_HASLINES | TVS_LINESATROOT |TVS_HASBUTTONS; return TRUE; } // *************************************************************************** // // CClassTree::CClassTree // // Description: // Class constructor. // // Parameters: // NONE // // Returns: // NONE // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** CClassTree::CClassTree() : m_bInDrag (FALSE), m_prevDropEffect (DROPEFFECT_NONE), m_bDropTargetRegistered (FALSE), m_bDragAndDropState (FALSE), m_dragSize (1,1), m_dragPoint (-1,-1), m_lClickTime(0), m_bDeleting(FALSE), m_bMouseDown(FALSE), m_bKeyDown(FALSE), m_uiTimer(0), m_bFirstSetFocus(TRUE), m_bUseItem(FALSE), m_hItemToUse(NULL) { } //============================================================================ // // CClassTree::InitTreeState // // Description: // This function initializes processing state for the custom tree control. // // Parameters: // CClassNavCtrl *pParent A CClassNavCtrl pointer to the tree controls // parent window. // // Returns: // VOID . // // Globals accessed: // NONE // // Globals modified: // NONE // //============================================================================ void CClassTree::InitTreeState (CClassNavCtrl *pParent) { if (m_uiTimer) { KillTimer( m_uiTimer ); m_uiTimer = 0; } m_bMouseDown = FALSE; m_bKeyDown = FALSE; m_bUseItem = FALSE; m_hItemToUse = NULL; m_pParent = pParent; } // *************************************************************************** // // CClassTree::AddTreeObject // // Description: // Adds an IWbemClassObject instance to the tree. // // Parameters: // HTREEITEM hParent Tree item parent. // IWbemClassObject *pimcoNew Class object // BOOL bNewClass If a new class add to tree and class // roots. // // Returns: // HTREEITEM Tree item handle of added class. // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** HTREEITEM CClassTree::AddNewClass(HTREEITEM hParent,IWbemClassObject *pimcoNew) { CSchemaInfo::CClassInfo &info= m_schema.AddClass(pimcoNew); HTREEITEM hObject = AddTreeObject2(hParent, info); if (hObject) EnsureVisible(hObject); // Update parent's icons if(hParent) RefreshIcons(hParent); else { m_pParent->GetTreeRoots()->Add(hObject); m_pParent->GetClassRoots()->Add(pimcoNew); } return hObject; } void CClassTree::RefreshIcons(HTREEITEM hItem) { while(hItem) { int nImage = m_schema[GetItemText(hItem)].GetImage(); SetItemImage(hItem, nImage, nImage); hItem = GetParentItem(hItem); } } HTREEITEM CClassTree::AddTreeObject2(HTREEITEM hParent, CSchemaInfo::CClassInfo &info) { HTREEITEM hObject = NULL; int nImage = info.GetImage(); hObject = InsertTreeItem(hParent, (LPARAM) info.m_pObject, nImage, nImage, info.m_szClass, FALSE, info.m_rgszSubs.GetSize()>0); return hObject; } // *************************************************************************** // // CClassTree::OnItemExpanding // // Description: // Special processing associated with expanding or callapsing a // tree branch. // // Parameters: // NMHDR *pNMHDR Notification message structure. // LRESULT *pResult Set to TRUE to prevent the list from // expanding or collapsing. // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::OnItemExpanding (NMHDR *pNMHDR, LRESULT *pResult) { SetFocus(); NM_TREEVIEW* pnmtv = (NM_TREEVIEW*)pNMHDR; HTREEITEM hItem = pnmtv->itemNew.hItem; *pResult = 0; m_pParent -> InvalidateControl(); } // *************************************************************************** // // CClassTree::InsertTreeItem // // Description: // Construct TV_INSERTSTRUCT for insertion into the CTreeCtrl and insert // item. // // Parameters: // HTREEITEM hParent Parent tree item. // LPARAM lparam Data to store in tree item data. // int iBitmap Index to bitmap. // int iSelectedBitmap Index to selected bitmap. // LPCTSTR pszText Tree item label. // BOOL bBold If TRUE label in bold. // BOOL bChildren If TRUE tree item has children. // // Returns: // HTREEITEM Tree item handle of new item. // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** HTREEITEM CClassTree::InsertTreeItem (HTREEITEM hParent, LPARAM lparam, int iBitmap, int iSelectedBitmap, LPCTSTR pszText, BOOL bBold, BOOL bChildren) { // If we are in select all mode we open the tree items // with a check (see tvis.item.state) TVINSERTSTRUCT tvis; tvis.hParent = hParent; tvis.hInsertAfter = TVI_LAST; tvis.item.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_CHILDREN | TVIF_PARAM | TVIF_IMAGE | TVIF_STATE; tvis.item.cChildren = bChildren?1:0; tvis.item.pszText = (LPTSTR) pszText; tvis.item.iImage = iBitmap; tvis.item.iSelectedImage = iBitmap; tvis.item.state = INDEXTOSTATEIMAGEMASK((m_pParent->m_bSelectAllMode)?2:1);; tvis.item.stateMask = TVIS_STATEIMAGEMASK; tvis.item.lParam = lparam; return InsertItem(&tvis); } // *************************************************************************** // // CClassTree::OnRButtonDown // // Description: // Do not pass on to the base class so the context menu can be // invoked. // // Parameters: // UINT nFlags Indicates whether various virtual keys are down. // CPoint point Specifies the x and y coordinates of the cursor. // // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::OnRButtonDown(UINT nFlags, CPoint point) { // Do not want to pass on to tree control. UINT hitFlags ; HTREEITEM hItem ; hItem = HitTest( point, &hitFlags ) ; if (hitFlags & (TVHT_ONITEM | TVHT_ONITEMBUTTON)) { // m_pParent->m_hContextSelection = hItem; } else { // m_pParent->m_hContextSelection = NULL; } } // *************************************************************************** // // CClassTree::OnContextMenu // // Description: // Initialize the context menu. See PSS ID Q141199. // // Parameters: // CWnd* pWnd CWnd parent. // CPoint point Specifies the x and y coordinates of the cursor. // // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::OnContextMenu(CWnd* pWnd, CPoint point) { // CG: This function was added by the Pop-up Menu component // See for PSS ID Number: Q141199 for explanation of modifications // required for COleControl UINT hitFlags ; HTREEITEM hItem ; CPoint cpClient; if (point.x == -1 && point.y == -1) { CRect crClient; GetClientRect(&crClient); hItem = GetSelectedItem(); if (hItem) { RECT rect; BOOL bRect = GetItemRect(hItem,&rect, TRUE ); POINT p; p.x = rect.left + 2; p.y = rect.top + 2; if (bRect && crClient.PtInRect(p)) { cpClient.x = rect.left + 2; cpClient.y = rect.top + 2; } else { cpClient.x = 0; cpClient.y = 0; } } m_pParent->m_hContextSelection = hItem; point = cpClient; ClientToScreen(&point); } else { cpClient = point; ScreenToClient(&cpClient); hItem = HitTest( cpClient, &hitFlags ) ; if (hitFlags & (TVHT_ONITEM | TVHT_ONITEMBUTTON)) { m_pParent->m_hContextSelection = hItem; } else { m_pParent->m_hContextSelection = NULL; } } VERIFY(m_cmContext.LoadMenu(CG_IDR_POPUP_A_TREE_CTRL)); CMenu* pPopup = m_cmContext.GetSubMenu(0); CWnd* pWndPopupOwner = m_pParent; HWND hwndFocus = ::GetFocus(); pPopup->TrackPopupMenu (TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, pWndPopupOwner); m_cmContext.DestroyMenu(); if (::IsWindow(hwndFocus) && ::IsWindowVisible(hwndFocus)) { ::SetFocus(hwndFocus); } } // *************************************************************************** // // CClassTree::OnCreate // // Description: // Called by the framework after the window is being created but before // the window is shown. // // Parameters: // LPCREATESTRUCT lpCreateStruct Pointer to the structure which contains // default parameters. // // Returns: // BOOL 0 if continue; -1 if the window should be destroyed. // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** int CClassTree::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CTreeCtrl::OnCreate(lpCreateStruct) == -1) return -1; m_uTreeCF = RegisterClipboardFormat(_T("ATREECONTROL_CF")); return 0; } // *************************************************************************** // // CClassTree::OnLButtonDown // // Description: // Process things that need to happen on a left button down. // // Parameters: // UINT nFlags Indicates whether various virtual keys are down. // CPoint point Specifies the x and y coordinates of the cursor. // // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::OnLButtonDown(UINT nFlags, CPoint point) { UINT m_nLBDFlags; CPoint m_cpLBDPoint = point; HTREEITEM hItem = HitTest( m_cpLBDPoint, &m_nLBDFlags ) ; // Toggle tree item image if the state icon was selected. if (hItem && (m_nLBDFlags & (TVHT_ONITEMSTATEICON)) ) { UINT nStateMask = TVIS_STATEIMAGEMASK; UINT uState = GetItemState( hItem, nStateMask ); UINT uImage1 = INDEXTOSTATEIMAGEMASK (1); UINT uImage2 = INDEXTOSTATEIMAGEMASK (2); if (uState & INDEXTOSTATEIMAGEMASK (1)) { uState = INDEXTOSTATEIMAGEMASK (2); } else { if (m_pParent->m_bSelectAllMode) { m_pParent->m_bItemUnselected = TRUE; } else { m_pParent->m_bItemUnselected = FALSE; } uState = INDEXTOSTATEIMAGEMASK (1); } SetItemState(hItem, uState, TVIS_STATEIMAGEMASK); } CTreeCtrl::OnLButtonDown(nFlags, point); } // *************************************************************************** // // CClassTree::OnLButtonUp // // Description: // Process things that need to happen on a left button up. // // Parameters: // UINT nFlags Indicates whether various virtual keys are down. // CPoint point Specifies the x and y coordinates of the cursor. // // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::OnLButtonUp(UINT nFlags, CPoint point) { m_bMouseDown = TRUE; m_bKeyDown = FALSE; CTreeCtrl::OnLButtonUp(nFlags, point); m_pParent -> OnActivateInPlace(TRUE,NULL); } // *************************************************************************** // // CClassTree::OnMouseMove // // Description: // Process things that need to happen when the mouse moves. // // Parameters: // UINT nFlags Indicates whether various virtual keys are down. // CPoint point Specifies the x and y coordinates of the cursor. // // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::OnMouseMove(UINT nFlags, CPoint point) { if (m_bInDrag) { CTreeCtrl::OnMouseMove(nFlags, point); return; } if ((nFlags & MK_LBUTTON) == MK_LBUTTON) { UINT m_nLBDFlags; CPoint m_cpLBDPoint = point; HTREEITEM hItem = HitTest( m_cpLBDPoint, &m_nLBDFlags ) ; m_bInDrag = TRUE; // This disables beginning a drag // Maybe will be enabled post alpha return; } CTreeCtrl::OnMouseMove(nFlags, point); } // *************************************************************************** // // CClassTree::OnSelchanged // // Description: // Process things that need to happen when the selected tree item // has changed. // // Parameters: // NMHDR *pNMHDR Notification message structure. // LRESULT *pResult Set to TRUE to prevent the selection from // changing. // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) { *pResult = 0; m_pParent -> PostMessage(SETFOCUSTREE,0,0); } void CClassTree::ContinueProcessSelection(UINT nFlags, CPoint point) { if (m_pParent->m_bOpeningNamespace) { return; } UINT uFlags = 0; HTREEITEM hItem; if (m_bUseItem) { hItem = m_hItemToUse; m_bUseItem = FALSE; m_hItemToUse = NULL; } else { hItem= HitTest( point, &uFlags ); } if (!hItem || m_bKeyDown) { m_bUseItem = FALSE; m_hItemToUse = NULL; m_pParent -> PostMessage(SETFOCUSTREE,0,0); return; } IWbemClassObject *pItem = reinterpret_cast(GetItemData(hItem)); if (m_bUseItem) { m_bUseItem = FALSE; m_hItemToUse = NULL; } if (!pItem) { m_pParent -> PostMessage(SETFOCUSTREE,0,0); return; } CString csClass = _T("__Class"); m_csSelection = ::GetProperty(pItem, &csClass); if (m_csSelection[0] == '_' && m_csSelection[1] == '_') { // Disable the delete button. m_pParent->m_cbBannerWindow.m_cctbToolBar. GetToolBarCtrl().EnableButton(ID_BUTTONDELETE,FALSE); m_pParent->m_cbBannerWindow.m_cctbToolBar. GetToolBarCtrl().EnableButton(ID_BUTTONADD,TRUE); } else { m_pParent->m_cbBannerWindow.m_cctbToolBar. GetToolBarCtrl().EnableButton(ID_BUTTONDELETE,TRUE); m_pParent->m_cbBannerWindow.m_cctbToolBar. GetToolBarCtrl().EnableButton(ID_BUTTONADD,TRUE); } if (!m_bDeleting) { CString csItem; COleVariant covClass; // Fire events. csItem = GetIWbemFullPath(m_pParent->GetServices(),pItem); covClass = csItem; if (!m_pParent->m_bOpenedInitialNamespace) { m_pParent->m_bOpenedInitialNamespace = TRUE; if (m_pParent->m_bReadySignal) { m_pParent->FireNotifyOpenNameSpace(m_pParent->m_csNameSpace); } } #ifdef _DEBUG afxDump <<"CClassTree::OnSelchanged: Before m_pParent -> FireEditExistingClass(covNewClass); \n"; afxDump << " " << csItem << "\n"; #endif if (m_pParent->m_bReadySignal) { m_pParent -> FireEditExistingClass(covClass); } #ifdef _DEBUG afxDump <<"CClassTree::OnSelchanged: After m_pParent -> FireEditExistingClass(covNewClass); \n"; afxDump << " " << csItem << "\n"; #endif } m_pParent -> PostMessage(SETFOCUSTREE,0,0); } // *************************************************************************** // // CClassTree::OnHScroll // // Description: // Process things that need to happen when the tree has been scrolled. // // Parameters: // UINT nSBCode Scroll-bar code for scrolling request. // UINT nPos Scroll-box position. // CScrollBar* pScrollBar Scroll bar control or NULL. // // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: Add your message handler code here and/or call default CTreeCtrl::OnHScroll(nSBCode, nPos, pScrollBar); } // *************************************************************************** // // CClassTree::OnVScroll // // Description: // Process things that need to happen when the tree has been scrolled. // // Parameters: // UINT nSBCode Scroll-bar code for scrolling request. // UINT nPos Scroll-box position. // CScrollBar* pScrollBar Scroll bar control or NULL. // // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: Add your message handler code here and/or call default CTreeCtrl::OnVScroll(nSBCode, nPos, pScrollBar); } // *************************************************************************** // // CClassTree::OnSize // // Description: // Called by the framework after the window is being resized. // // Parameters: // UINT nType Specifies the type of resizing requested. // int cx Specifies the new width of the client area. // int cy Specifies the new height of the client area. // // Returns: // void // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::OnSize(UINT nType, int cx, int cy) { CTreeCtrl::OnSize(nType, cx, cy); } // *************************************************************************** // // CClassTree::OnDestroy // // Description: // Process things that need to happen when the tree is going away, // before the tree is actually destroyed. Is is no longer visible // but still exists. // // Parameters: // NONE // // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::OnDestroy() { if (m_uiTimer) { KillTimer( m_uiTimer ); m_uiTimer = 0; } m_bMouseDown = FALSE; m_bKeyDown = FALSE; m_bUseItem = FALSE; m_hItemToUse = NULL; CPtrArray *pcpaTreeRoots = m_pParent -> GetTreeRoots(); int nRoots = (int) pcpaTreeRoots -> GetSize( ); HTREEITEM hItem; for (int i = 0; i < nRoots; i++) { hItem = reinterpret_cast(pcpaTreeRoots -> GetAt(i)); if (hItem) { ReleaseClassObjects(hItem); } } CTreeCtrl::OnDestroy(); } // *************************************************************************** // // CClassTree::GetSelectionPath // // Description: // Returns a CString which contains the current tree selection. // // Parameters: // VOID // // Returns: // CString Full path of selection. // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** CString CClassTree::GetSelectionPath(HTREEITEM hIn) { CString csPath = _T(""); HTREEITEM hItem = hIn ? hIn :GetSelectedItem(); if (hItem) { IWbemClassObject *pimcoSel = reinterpret_cast (GetItemData(hItem)); if (pimcoSel) { csPath = GetIWbemFullPath (NULL, pimcoSel); } } return csPath; } // *************************************************************************** // // CClassTree::NumExtendedSelection // // Description: // Returns the number of extended selections for specified state. // // Parameters: // int nState Selected or not selected // // Returns: // int Number of items with state. // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** int CClassTree::NumExtendedSelection(int nState) { CPtrArray cpaExtendedSelection; int nExtendedSelection = ExtendedSelectionFromTree(cpaExtendedSelection,nState); CString *pcs; for (int i = 0; i < nExtendedSelection; i++) { pcs = reinterpret_cast (cpaExtendedSelection.GetAt(i)); delete pcs; } return nExtendedSelection; } // *************************************************************************** // // CClassTree::GetExtendedSelection // // Description: // Return a SAFEARRAY which contains the class names of classes selected // via the extended selection mechanism. [Extended selection is via // selection of the tree items icon.] // // Parameters: // int nState Selected or not selected // // Returns: // SAFEARRAY * Of type VT_BSTR // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** SAFEARRAY *CClassTree::GetExtendedSelection(int nState) { SAFEARRAY *psaSelections; int i; CPtrArray cpaExtendedSelection; int nExtendedSelection = ExtendedSelectionFromTree(cpaExtendedSelection,nState); if (nExtendedSelection == 0) { MakeSafeArray (&psaSelections, VT_BSTR, 1); PutStringInSafeArray (psaSelections, &m_pParent->m_csNameSpace, 0); } else { MakeSafeArray (&psaSelections, VT_BSTR, nExtendedSelection + 1); int n = 0; PutStringInSafeArray (psaSelections, &m_pParent->m_csNameSpace , n++); for (i = 0; i < nExtendedSelection; i++) { CString *pcs = reinterpret_cast(cpaExtendedSelection.GetAt(i)); PutStringInSafeArray (psaSelections, pcs , n++); } } int nSelections = (int) cpaExtendedSelection.GetSize( ); CString *pcs; for (i = 0; i < nSelections; i++) { pcs = reinterpret_cast (cpaExtendedSelection.GetAt(i)); delete pcs; } return psaSelections; } // *************************************************************************** // // CClassTree::ExtendedSelectionFromTree // // Description: // Return a CPtrArray which contains the class names of classes selected // via the extended selection mechanism with state (either selected or not // selected. For whole tree. // // Parameters: // CPtrArray &cpaExtendedSelection The items with state. // int nState Selected or not selected // // Returns: // int Number of items with state in tree. // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** int CClassTree::ExtendedSelectionFromTree (CPtrArray &cpaExtendedSelection,int nState) { CPtrArray *pcpaTreeRoots = m_pParent -> GetTreeRoots(); int nRoots = (int) pcpaTreeRoots -> GetSize( ); HTREEITEM hItem; for (int i = 0; i < nRoots; i++) { hItem = reinterpret_cast(pcpaTreeRoots -> GetAt(i)); if (hItem) { ExtendedSelectionFromRoot(hItem,cpaExtendedSelection,nState); } } return (int) cpaExtendedSelection.GetSize( ); } // *************************************************************************** // // CClassTree::ExtendedSelectionFromRoot // // Description: // Return a CPtrArray which contains the class names of classes selected // via the extended selection mechanism with state (either selected or not // selected. For a branch. // // Parameters: // HTREEITEM hItem Branch root to get selection from. // CPtrArray &cpaExtendedSelection The items with state. // int nState Selected or not selected // // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::ExtendedSelectionFromRoot (HTREEITEM hItem, CPtrArray &cpaExtendedSelection, int nState) { UINT nStateMask = TVIS_STATEIMAGEMASK; UINT uState = GetItemState( hItem, nStateMask ); if (uState & INDEXTOSTATEIMAGEMASK (nState)) { IWbemClassObject *pItem = (IWbemClassObject*) GetItemData(hItem) ; if (pItem) { CString csClass = _T("__Path"); csClass = ::GetProperty(pItem, &csClass); CString *pcsClass = new CString(csClass); cpaExtendedSelection.Add (reinterpret_cast(pcsClass)); } } // now rip thru the children if (!ItemHasChildren (hItem)) { return ; } HTREEITEM hChild = GetChildItem(hItem); while (hChild) { ExtendedSelectionFromRoot(hChild, cpaExtendedSelection,nState); hChild = GetNextSiblingItem(hChild); } return; } // *************************************************************************** // // CClassTree::ClearExtendedSelection // // Description: // Clears extended selection for the whole tree. // // Parameters: // NONE // // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::ClearExtendedSelection() { CPtrArray *pcpaTreeRoots = m_pParent -> GetTreeRoots(); int nRoots = (int) pcpaTreeRoots -> GetSize( ); HTREEITEM hItem; for (int i = 0; i < nRoots; i++) { hItem = reinterpret_cast(pcpaTreeRoots -> GetAt(i)); if (hItem) { ClearExtendedSelectionFromRoot(hItem); } } m_pParent -> InvalidateControl(); } // *************************************************************************** // // CClassTree::ClearExtendedSelection // // Description: // Clears extended selection for a branch. // // Parameters: // HTREEITEM hItem Branch root to clear selection from. // // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::ClearExtendedSelectionFromRoot (HTREEITEM hItem) { UINT nStateMask = TVIS_STATEIMAGEMASK; UINT uState = GetItemState( hItem, nStateMask ); if (uState & INDEXTOSTATEIMAGEMASK (2)) { SetItemState(hItem, INDEXTOSTATEIMAGEMASK (1), TVIS_STATEIMAGEMASK); } // now rip thru the children if (!ItemHasChildren (hItem)) { return ; } HTREEITEM hChild = GetChildItem(hItem); while (hChild) { ClearExtendedSelectionFromRoot(hChild); hChild = GetNextSiblingItem(hChild); } return; } // *************************************************************************** // // CClassTree::SetExtendedSelection // // Description: // Sets extended selection for the whole tree. // // Parameters: // NONE // // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::SetExtendedSelection() { CPtrArray *pcpaTreeRoots = m_pParent -> GetTreeRoots(); int nRoots = (int) pcpaTreeRoots -> GetSize( ); HTREEITEM hItem; for (int i = 0; i < nRoots; i++) { hItem = reinterpret_cast(pcpaTreeRoots -> GetAt(i)); if (hItem) { SetExtendedSelectionFromRoot(hItem); } } m_pParent -> InvalidateControl(); } // *************************************************************************** // // CClassTree::SetExtendedSelectionFromRoot // // Description: // Sets extended selection for a branch. // // Parameters: // HTREEITEM hItem Branch root to set selection for. // // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::SetExtendedSelectionFromRoot (HTREEITEM hItem) { SetItemState(hItem, INDEXTOSTATEIMAGEMASK (2), TVIS_STATEIMAGEMASK); // now rip thru the children if (!ItemHasChildren (hItem)) { return ; } HTREEITEM hChild = GetChildItem(hItem); while (hChild) { SetExtendedSelectionFromRoot(hChild); hChild = GetNextSiblingItem(hChild); } return; } // *************************************************************************** // // CClassTree::OnItemexpanded // // Description: // Invoked to let the tree know one of its tree items has been // expanded or contracted. // // Parameters: // NMHDR *pNMHDR Notification message structure. // LRESULT *pResult Return value ignored. // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pnmtv = (NM_TREEVIEW*)pNMHDR; *pResult = 0; } // *************************************************************************** // // CClassTree::FindObjectinChildren // // Description: // Finds the tree item in a branch that represents a class object // // Parameters: // HTREEITEM hItem Root of branch // IWbemClassObject *pClassObject Class to search for. // // Returns: // HTREEITEM Tree item; or NULL if not found. // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** HTREEITEM CClassTree::FindObjectinChildren (HTREEITEM hItem, IWbemClassObject *pClassObject) { HTREEITEM hChild = GetChildItem(hItem); if (!hChild) { return NULL; } IWbemClassObject *pChild; while (hChild) { pChild = reinterpret_cast (GetItemData(hChild)); if (ClassIdentity(pClassObject,pChild)) { return hChild; } hChild = GetNextSiblingItem(hChild); } return NULL; } // *************************************************************************** // // CClassTree::OnEndlabeledit // // Description: // Invoked to let the tree know one of its tree item labels // has been changed. Semantics for us is a class rename. // // Parameters: // NMHDR *pNMHDR Notification message structure. // LRESULT *pResult Set to FALSE to prevent the label from // changing; otherwise non-zero. // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult) { TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR; HTREEITEM hItem = pTVDispInfo -> item.hItem; UpdateItemData(hItem); IWbemClassObject *pimcoEdit = reinterpret_cast(GetItemData(hItem)); CString csClass = _T("__Class"); CString csClassName = pimcoEdit ? ::GetProperty (pimcoEdit, &csClass) : ""; CString csNew = pTVDispInfo -> item.pszText; if (csNew.GetLength() == 0) { *pResult = 0; SelectItem(hItem); // 1-29-99 SetFocus(); // 1-29-99 return; } // Check to see if the class already exists IWbemClassObject *pimcoMaybe = NULL; BSTR bstrTemp = csNew.AllocSysString(); SCODE sc = m_pParent -> GetServices() -> GetObject(bstrTemp, 0, NULL, &pimcoMaybe, NULL); ::SysFreeString(bstrTemp); // Class already exists so cannot rename. if (pimcoMaybe && sc == S_OK) { CString csUserMsg = _T("An error occured renaming a class: "); csUserMsg += _T("The class already exists."); ErrorMsg (&csUserMsg, sc, NULL, TRUE, &csUserMsg, __FILE__, __LINE__ - 11); pimcoMaybe -> Release(); *pResult = 0; SelectItem(hItem); // 1-29-99 SetFocus(); // 1-29-99 return; } // Must delete pimcoEdit after its children have been // reparented. IWbemClassObject *pimcoNew = RenameAClass (m_pParent -> GetServices(), pimcoEdit, &csNew, FALSE); if (!pimcoNew) { CString csUserMsg = _T("Cannot rename class: ") + csClassName; ErrorMsg (&csUserMsg, S_OK, NULL, TRUE, &csUserMsg, __FILE__, __LINE__ - 7); SelectItem(hItem); // 1-29-99 SetFocus(); // 1-29-99 *pResult = 0; // 1-29-99 return; } csClass = GetIWbemFullPath(m_pParent->GetServices(),pimcoNew); COleVariant covClass(csClass); if (m_pParent->m_bReadySignal) { m_pParent -> FireEditExistingClass(covClass); } #ifdef _DEBUG afxDump <<"CBanner::OnEndlabeledit: m_pParent -> FireEditExistingClass(covNewClass); \n"; afxDump << " " << csClass << "\n"; #endif pimcoEdit->Release(); SetItemData(hItem,(LPARAM)(pimcoNew)); HTREEITEM hChild = GetChildItem(hItem); while (hChild) { IWbemClassObject *pimcoChild = reinterpret_cast(GetItemData(hChild)); ReparentAClass(m_pParent -> GetServices(),pimcoNew, pimcoChild); hChild = GetNextSiblingItem(hChild); } BOOL bReturn = DeleteAClass (m_pParent -> GetServices(), &csClassName ); SelectItem(hItem); // 1-29-99 SetFocus(); // 1-29-99 *pResult = 1; } void CClassTree::UpdateItemData(HTREEITEM hItem) { IWbemClassObject *pimcoItemData = reinterpret_cast(GetItemData(hItem)); if (!pimcoItemData) { return; } CString csClass = GetIWbemClass(pimcoItemData); pimcoItemData->Release(); pimcoItemData = NULL; pimcoItemData = GetClassObject (m_pParent -> GetServices(),&csClass,FALSE); if (!pimcoItemData) { return; } SetItemData(hItem,(LPARAM)(pimcoItemData)); } // *************************************************************************** // // CClassTree::OnBeginlabeledit // // Description: // Invoked to let the tree know one of its tree item labels // is being changed. Semantics for us is a class rename. // // Parameters: // NMHDR *pNMHDR Notification message structure. // LRESULT *pResult Set to non-zero to prevent the label from // being edited; otherwise zero. // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::OnBeginlabeledit(NMHDR* pNMHDR, LRESULT* pResult) { HTREEITEM hSelection = GetSelectedItem( ); if (hSelection) { CString csSelection = GetSelectionPath(hSelection); BOOL bCanChangeSelection = m_pParent->QueryCanChangeSelection(csSelection); if (!bCanChangeSelection) { SetFocus(); *pResult = 1; return; } } TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR; HTREEITEM hItem = pTVDispInfo -> item.hItem; IWbemClassObject *pimcoEdit = reinterpret_cast(GetItemData(hItem)); if (!pimcoEdit) { *pResult = 1; return; } CString csClass = _T("__Class"); m_csSelection = ::GetProperty(pimcoEdit, &csClass); if (m_csSelection[0] == '_' && m_csSelection[1] == '_') { *pResult = 1; CString csPrompt = _T("You cannot rename a system class."); int nReturn = m_pParent -> MessageBox ( csPrompt, _T("Class Rename Error"), MB_OK | MB_ICONSTOP | MB_DEFBUTTON1 | MB_APPLMODAL); SetFocus(); return; } if (ItemHasChildren(hItem)) { *pResult = 1; CString csPrompt = _T("You cannot rename a class which has subclasses."); int nReturn = m_pParent -> MessageBox ( csPrompt, _T("Class Rename Error"), MB_OK | MB_ICONSTOP | MB_DEFBUTTON1 | MB_APPLMODAL); SetFocus(); return; } else { BOOL bSubClasses = HasSubclasses (m_pParent->GetServices(), pimcoEdit,m_pParent->m_csNameSpace); if (bSubClasses) { *pResult = 1; return; } else { BOOL bReturn; CString csQual = _T("dynamic"); SCODE sc = GetAttribBool (pimcoEdit,NULL, &csQual,bReturn); CString csProvider; CString csPrompt; if (bReturn) { csQual = _T("provider"); sc = GetAttribBSTR (pimcoEdit,NULL, &csQual, csProvider); csPrompt = _T("The dynamic provider for this class \""); csPrompt += csProvider + _T("\""); csPrompt += _T(" may need to be updated. Do you want to continue renaming the class?"); } else { csPrompt = _T("If this class has static instances renaming the class will result in the instances being deleted. Do you want to continue renaming the class?"); } int nReturn = m_pParent -> MessageBox ( csPrompt, _T("Class Rename Warning"), MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON1 | MB_APPLMODAL); SetFocus(); if (nReturn == IDYES) { *pResult = 0; } else { *pResult = 1; } } } } // *************************************************************************** // // CClassTree::FindAndOpenObject // // Description: // Find an object in the tree or grow the tree to object. // // Parameters: // IWbemClassObject *pClass Class object; // // Returns: // HTREEITEM Tree item or NULL. // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** HTREEITEM CClassTree::FindAndOpenObject(IWbemClassObject *pClass) { CString csClass = _T("__Class"); csClass = ::GetProperty(pClass,&csClass); CStringArray *pcsaPath = PathFromRoot (pClass); HTREEITEM hRoot; HTREEITEM hItem = NULL; if (pcsaPath->GetSize() > 1) { HTREEITEM hChild; hChild = hRoot = m_pParent->FindObjectinClassRoots (&pcsaPath->GetAt(0)); for (int i = 1; i < pcsaPath->GetSize(); i++) { IWbemClassObject *pObject = NULL; IWbemClassObject *pErrorObject = NULL; BSTR bstrTemp = pcsaPath->GetAt(i).AllocSysString(); SCODE sc = m_pParent->GetServices() -> GetObject (bstrTemp,0, NULL, &pObject, NULL); ::SysFreeString(bstrTemp); if (sc == S_OK) { hChild = FindObjectinChildren (hRoot, pObject); if (hChild) { hRoot = hChild; } else { Expand(hRoot,TVE_EXPAND); hRoot = hChild = FindObjectinChildren (hRoot, pObject); } ReleaseErrorObject(pErrorObject); pObject ->Release(); } else { ErrorMsg (NULL, sc, pErrorObject, TRUE, NULL, __FILE__, __LINE__ - 40); ReleaseErrorObject(pErrorObject); } } hItem = hChild; } else { hRoot = m_pParent->FindObjectinClassRoots (&csClass); hItem = hRoot; } delete pcsaPath; if (hItem) { SelectSetFirstVisible(hItem); SelectItem(hItem); SetFocus(); Expand(hItem,TVE_EXPAND); } return hItem; } BOOL CClassTree::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point) { return TRUE; } DROPEFFECT CClassTree::OnDropEx(COleDataObject* pDataObject, DROPEFFECT dropEffect, DROPEFFECT dropEffectList, CPoint point) { return DROPEFFECT_NONE; } DROPEFFECT CClassTree::OnDragEnter(COleDataObject* pDataObject, DWORD grfKeyState, CPoint point) { return DROPEFFECT_NONE; } DROPEFFECT CClassTree::OnDragOver(COleDataObject* pDataObject, DWORD grfKeyState, CPoint point) { return DROPEFFECT_NONE; } DROPEFFECT CClassTree::OnDragScroll(DWORD grfKeyState, CPoint point) { return DROPEFFECT_NONE; } void CClassTree::OnDragLeave() { } // *************************************************************************** // // CClassTree::IsChildNodeOf // // Description: // Predicate to see if a tree item is a parent or grand ... parent // of a another tree item. // // Parameters: // HTREEITEM hitemChild Item to test. // HTREEITEM hitemSuspectedParent Maybe a parent. // // Returns: // BOOL TRUE if a child; otherwise FALSE // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** BOOL CClassTree::IsChildNodeOf (HTREEITEM hitemChild, HTREEITEM hitemSuspectedParent) { do { if (hitemChild == hitemSuspectedParent) break; } while ((hitemChild = GetParentItem(hitemChild)) != NULL); return (hitemChild != NULL); } // *************************************************************************** // // CClassTree::DeleteBranch // // Description: // Delete a branch of the tree and conditionally release the // class objects assoiciated with the tree items. // // Parameters: // HTREEITEM hItem Root of branch to transfer. // // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::DeleteBranch(HTREEITEM &hItem) { HTREEITEM hParent = GetParentItem(hItem); IWbemClassObject *pClassObject; pClassObject = reinterpret_cast (GetItemData( hItem )); if (!hParent) // item is a root { if (pClassObject) { m_pParent -> RemoveObjectFromClassRoots(pClassObject); } m_pParent -> RemoveItemFromTreeItemRoots(hItem); } if (pClassObject) { pClassObject -> Release(); } if (!ItemHasChildren (hItem)) { DeleteItem(hItem); HTREEITEM hChild = NULL; hChild = GetChildItem(hParent); if (!hChild) { TV_INSERTSTRUCT tvstruct; tvstruct.item.hItem = hParent; tvstruct.item.mask = TVIF_CHILDREN | TVIF_STATE; tvstruct.item.stateMask = TVIS_EXPANDEDONCE; tvstruct.item.state = TVIS_EXPANDEDONCE; tvstruct.item.cChildren = 0; SetItem(&tvstruct.item); EnsureVisible (hParent); // 10-26-96 force parent to update } hItem = 0; return; } HTREEITEM hChild = GetChildItem(hItem); while (hChild) { DeleteBranch(hChild); if (hChild) hChild = GetNextSiblingItem(hChild); } DeleteItem(hItem); hChild = NULL; hChild = GetChildItem(hParent); if (!hChild) { TV_INSERTSTRUCT tvstruct; tvstruct.item.hItem = hParent; tvstruct.item.mask = TVIF_CHILDREN | TVIF_STATE; tvstruct.item.stateMask = TVIS_EXPANDEDONCE; tvstruct.item.state = TVIS_EXPANDEDONCE; tvstruct.item.cChildren = 0; SetItem(&tvstruct.item); EnsureVisible (hParent); // 10-26-96 force parent to update } hItem = 0; } // *************************************************************************** // // CClassTree::OnScroll // // Description: // Scroll the window by a line only. Called only by the drop target // when it detects that a drag operation is in the scrolling region. // // Parameters: // UINT nScrollCode Scrolling request. // UINT nPos Not used. // BOOL bDoScroll If TRUE do the scroll; otherwise just // return whither or not a scroll could occur. // // Returns: // BOOL TRUE if could scroll; otherwise FALSE. // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** BOOL CClassTree::OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll) { // Read the docs on CView::OnScroll to understand the semantics of // bDoScroll. // calc new x position int x = GetScrollPos(SB_HORZ); switch (LOBYTE(nScrollCode)) { case SB_LINEUP: x = -1; break; case SB_LINEDOWN: x = 1; break; } // calc new y position int y = GetScrollPos(SB_VERT); switch (HIBYTE(nScrollCode)) { case SB_LINEUP: y = -1; break; case SB_LINEDOWN: y = 1; break; } BOOL bResult = OnScrollBy(CSize(x, y ), bDoScroll); return bResult; } //*************************************************************************** // // CClassTree::OnScrollBy // // Purpose: // // This is work in progress. // //*************************************************************************** // *************************************************************************** // // CClassTree::OnScrollBy // // Description: // Actually scrolls the window if bDoScroll it TRUE. If bDSoScroll // is FALSE test to see if a scroll could be done. // // Parameters: // CSize sizeScroll Number of pixels scrolled horizontally // and vertically. // BOOL bDoScroll If TRUE do the scroll; otherwise just // return whither or not a scroll could occur. // // Returns: // BOOL TRUE if could scroll; otherwise FALSE. // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** BOOL CClassTree::OnScrollBy(CSize sizeScroll, BOOL bDoScroll) { int nScrollH = sizeScroll.cx; int nScrollV = sizeScroll.cy; int xOrig; int yOrig; int x = sizeScroll.cx; int y = sizeScroll.cy; CRect rControl; GetClientRect(&rControl); CDC *pdc = GetDC( ); pdc -> LPtoDP(&rControl); ClientToScreen(&rControl); ReleaseDC(pdc); SCROLLINFO siHInfo; SCROLLINFO siVInfo; siHInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE; siVInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE; BOOL bReturn; bReturn = GetScrollInfo(SB_HORZ, &siHInfo, SIF_ALL); bReturn = GetScrollInfo(SB_VERT, &siVInfo ,SIF_ALL); long lStyle = GetWindowLong(GetSafeHwnd(), GWL_STYLE); BOOL bHScroll = lStyle & WS_HSCROLL; BOOL bVScroll = lStyle & WS_VSCROLL; // don't scroll if there is no valid scroll range (ie. no scroll bar) if (!bVScroll) { // vertical scroll bar not enabled sizeScroll.cy = 0; } if (!bHScroll) { // horizontal scroll bar not enabled sizeScroll.cx = 0; } // adjust current x position xOrig = GetScrollPos(SB_HORZ); int xMax = GetScrollLimit(SB_HORZ); x += xOrig; if (x < 0) x = 0; else if (x > xMax) x = xMax; // adjust current y position yOrig = GetScrollPos(SB_VERT); int yMax = GetScrollLimit(SB_VERT); y += yOrig; if (y < 0) y = 0; else if (y > yMax) y = yMax; //did anything change? if (x == xOrig && y == yOrig) return FALSE; if (bDoScroll) { bReturn; WPARAM wParam; LPARAM lParam; wParam = MAKEWPARAM((nScrollV < 0) ? SB_LINEUP : SB_LINEDOWN, yOrig); lParam = NULL; this -> SendMessage(WM_VSCROLL, wParam, lParam); wParam = MAKEWPARAM((nScrollH < 0) ? SB_LINEUP : SB_LINEDOWN, xOrig); lParam = NULL; this -> SendMessage(WM_HSCROLL, wParam, lParam); bReturn = ::UpdateWindow(GetSafeHwnd()); bReturn = GetScrollInfo(SB_VERT, &siVInfo ,SIF_ALL); m_pParent -> InvalidateControl(); m_pParent -> SetModifiedFlag( TRUE ); } return TRUE; } // *************************************************************************** // // CClassTree::ReleaseClassObjects // // Description: // Release (in OLE sense) the IWbemClassobject instances. // // Parameters: // HTREEITEM hItem Tree root to start releasing from. // // Returns: // VOID // // Globals accessed: // NONE // // Globals modified: // NONE // // *************************************************************************** void CClassTree::ReleaseClassObjects(HTREEITEM hItem) { IWbemClassObject *pClassObject = reinterpret_cast(GetItemData( hItem )); if (pClassObject) { pClassObject -> Release(); SetItemData(hItem,NULL); } if (!ItemHasChildren (hItem)) { return; } HTREEITEM hChild = GetChildItem(hItem); while (hChild) { ReleaseClassObjects(hChild); hChild = GetNextSiblingItem(hChild); } } LRESULT CClassTree::SelectTreeItemOnFocus(WPARAM, LPARAM) { if (m_nSpinFocus < 1) { m_nSpinFocus++; HTREEITEM hItem = GetSelectedItem(); if (hItem) { m_nSelectedItem = hItem; } PostMessage(SELECTITEMONFOCUS,0,0); return 0; } HTREEITEM hSelectedItem = GetSelectedItem(); if (hSelectedItem && m_nSelectedItem && GetCount() != -1) { SelectItem(m_nSelectedItem); SetFocus(); IWbemClassObject *pItem = (IWbemClassObject*)GetItemData(m_nSelectedItem); if (pItem) { if (m_pParent->m_bReadySignal) { COleVariant covClass; CString csItem = GetIWbemFullPath(m_pParent->GetServices(),pItem); covClass = csItem; m_pParent -> FireEditExistingClass(covClass); #ifdef _DEBUG afxDump <<"CClassTree::SelectTreeItemOnFocus: m_pParent -> FireEditExistingClass(covClass); \n"; afxDump << " " << csItem << "\n"; #endif } } } m_pParent->InvalidateControl(); m_pParent -> PostMessage(SETFOCUSTREE,0,0); return 0; } LRESULT CClassTree::SelectTreeItem(WPARAM, LPARAM) { m_bMouseDown = FALSE; m_bKeyDown = FALSE; m_bUseItem = FALSE; m_hItemToUse = NULL; if (m_uiTimer) { KillTimer( m_uiTimer ); m_uiTimer = 0; } HTREEITEM hItem = GetSelectedItem(); if (!hItem) { return 0; } m_bUseItem = TRUE; m_hItemToUse = hItem; CPoint point(0,0); ContinueProcessSelection(0, point); return 0; } void CClassTree::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult) { TV_KEYDOWN* pTVKeyDown = (TV_KEYDOWN*)pNMHDR; switch (pTVKeyDown->wVKey) { case VK_LEFT: case VK_RIGHT: case VK_UP: case VK_DOWN: case VK_NEXT: case VK_PRIOR: case VK_HOME: case VK_END: if (m_uiTimer) { KillTimer( m_uiTimer ); m_uiTimer = 0; } m_uiTimer = (UINT) SetTimer(KBSelectionTimer, 250, SelectItemAfterDelay); m_bKeyDown = TRUE; m_bMouseDown = FALSE; break; default: m_bKeyDown = FALSE; m_bMouseDown = TRUE; break; }; // TODO: Add your control notification handler code here *pResult = 0; } void CClassTree::OnKillfocus(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here #ifdef _DEBUG afxDump << _T("CClassTree::OnKillfocus\n"); #endif m_pParent->m_bRestoreFocusToTree = TRUE; *pResult = 0; } void CClassTree::OnSetfocus(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here #ifdef _DEBUG afxDump << _T("Before COleControl::OnActivateInPlace in CClassTree::OnSetFocus\n"); #endif // TODO: Add your message handler code here m_pParent->OnActivateInPlace(TRUE,NULL); #ifdef _DEBUG afxDump << _T("After COleControl::OnActivateInPlace in CClassTree::OnSetFocus\n"); #endif m_pParent->m_bRestoreFocusToTree = TRUE; *pResult = 0; } void CClassTree::OnSelchanging(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; // TODO: Add your control notification handler code here m_pParent -> OnActivateInPlace(TRUE,NULL); HTREEITEM hOld = pNMTreeView->itemOld.hItem; CString csSelection = GetSelectionPath(hOld); BOOL bCanChangeSelection = m_pParent->QueryCanChangeSelection(csSelection); if (!bCanChangeSelection) { SetFocus(); *pResult = TRUE; return; } *pResult = 0; UINT uInterval = GetDoubleClickTime(); if (uInterval > 0) { if (m_uiSelectionTimer) { KillTimer( m_uiSelectionTimer ); m_uiSelectionTimer = 0; } gpTreeTmp = this; m_lSelection = 1; m_uiSelectionTimer =(UINT) ::SetTimer (this->m_hWnd, ExpansionOrSelectionTimer, /*uInterval + */50, ExpansionOrSelection); NM_TREEVIEW* pnmtv = (NM_TREEVIEW*)pNMHDR; HTREEITEM hItem = pnmtv->itemNew.hItem; m_bUseItem = TRUE; m_hItemToUse = hItem; } *pResult = 0; } /* EOF: CClassTree.cpp */