[DEVMGR]
authorGed Murphy <gedmurphy@reactos.org>
Fri, 23 Oct 2015 12:45:41 +0000 (12:45 +0000)
committerGed Murphy <gedmurphy@reactos.org>
Fri, 23 Oct 2015 12:45:41 +0000 (12:45 +0000)
- When refreshing the view, reselect and expand the previously selected node in the tree. This allows to switch from 'by type' to 'by connection' and see where the selected device sits in the tree hierarchy (and vice versa)

svn path=/trunk/; revision=69658

reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp
reactos/dll/win32/devmgr/devmgmt/DeviceNode.h
reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp
reactos/dll/win32/devmgr/devmgmt/DeviceView.h
reactos/dll/win32/devmgr/devmgmt/Node.cpp
reactos/dll/win32/devmgr/devmgmt/Node.h

index 96d6a39..eff0d5c 100644 (file)
@@ -26,6 +26,24 @@ CDeviceNode::CDeviceNode(
     ZeroMemory(&m_DevinfoData, sizeof(SP_DEVINFO_DATA));
 }
 
+CDeviceNode::CDeviceNode(
+    _In_ const CDeviceNode &Node
+    ) :
+    CNode(Node)
+{
+    m_DevInst = Node.m_DevInst;
+    m_hDevInfo = Node.m_hDevInfo;
+    m_Status = Node.m_Status;
+    m_ProblemNumber = Node.m_ProblemNumber;
+    m_OverlayImage = Node.m_OverlayImage;
+    CopyMemory(&m_DevinfoData, &Node.m_DevinfoData, sizeof(SP_DEVINFO_DATA));
+
+    size_t size = wcslen(Node.m_DeviceId) + 1;
+    m_DeviceId = new WCHAR[size];
+    StringCbCopyW(m_DeviceId, size * sizeof(WCHAR), Node.m_DeviceId);
+
+}
+
 CDeviceNode::~CDeviceNode()
 {
     Cleanup();
@@ -290,7 +308,7 @@ CDeviceNode::EnableDevice(
     for (int i = 0; i < 2; i++)
     {
         // Check globally first, then check config specific
-        pcp.Scope = (i == 0) ? DICS_FLAG_GLOBAL : DICS_FLAG_CONFIGSPECIFIC;
+        pcp.Scope = (i == 0) ? DICS_FLAG_CONFIGGENERAL : DICS_FLAG_CONFIGSPECIFIC;
 
         if (SetupDiSetClassInstallParamsW(m_hDevInfo,
                                           &m_DevinfoData,
@@ -320,6 +338,7 @@ CDeviceNode::EnableDevice(
             SetupDiChangeState(m_hDevInfo, &m_DevinfoData);
         }
 
+
         if (Enable)
         {
             // config specific enabling first, then global enabling.
index 3c5ddc5..58520b6 100644 (file)
@@ -20,6 +20,10 @@ public:
 
     ~CDeviceNode();
 
+    CDeviceNode(
+        _In_ const CDeviceNode &Node
+        );
+
     virtual bool SetupNode();
 
     DEVINST GetDeviceInst() { return m_DevInst; }
index 388a258..13b14d4 100644 (file)
@@ -27,7 +27,6 @@ struct RefreshThreadData
     CDeviceView *This;
     BOOL ScanForChanges;
     BOOL UpdateView;
-    LPWSTR DeviceId;
 };
 
 
@@ -79,6 +78,10 @@ CDeviceView::Initialize()
 
         // Give the treeview arrows instead of +/- boxes (on Win7)
         SetWindowTheme(m_hTreeView, L"explorer", NULL);
+
+        // Create the root node
+        m_RootNode = new CRootNode(&m_ImageListData);
+        m_RootNode->SetupNode();
     }
 
 
@@ -198,15 +201,6 @@ CDeviceView::Refresh(
     ThreadData->This = this;
     ThreadData->ScanForChanges = ScanForChanges;
     ThreadData->UpdateView = UpdateView;
-    ThreadData->DeviceId = NULL;
-
-    if (DeviceId)
-    {
-        // Node gets deleted on refresh so we copy it to another block
-        size_t Length = wcslen(DeviceId) + 1;
-        ThreadData->DeviceId = new WCHAR[Length];
-        StringCbCopyW(ThreadData->DeviceId, Length, DeviceId);
-    }
 
 
     HANDLE hThread;
@@ -377,13 +371,29 @@ unsigned int __stdcall CDeviceView::RefreshThread(void *Param)
     RefreshThreadData *ThreadData = (RefreshThreadData *)Param;
     CDeviceView *This = ThreadData->This;
 
+    // Get a copy of the currently selected node
+    CNode *LastSelectedNode = This->GetSelectedNode();
+    if (LastSelectedNode == nullptr || (LastSelectedNode->GetNodeType() == RootNode))
+    {
+        LastSelectedNode = new CRootNode(*This->m_RootNode);
+    }
+    else if (LastSelectedNode->GetNodeType() == ClassNode)
+    {
+        LastSelectedNode = new CClassNode(*dynamic_cast<CClassNode *>(LastSelectedNode));
+    }
+    else if (LastSelectedNode->GetNodeType() == DeviceNode)
+    {
+        LastSelectedNode = new CDeviceNode(*dynamic_cast<CDeviceNode *>(LastSelectedNode));
+    }
 
     // Empty the treeview
     This->EmptyDeviceView();
-    This->m_hTreeRoot = NULL;
 
-    // Refresh the devices only if requested. This means
-    // switching views uses the cache and remains fast
+    // Re-add the root node to the tree
+    if (This->AddRootDevice() == false)
+        return 0;
+
+    // Refresh the devices only if requested
     if (ThreadData->ScanForChanges)
     {
         This->RefreshDeviceList();
@@ -408,10 +418,8 @@ unsigned int __stdcall CDeviceView::RefreshThread(void *Param)
     }
 
 
-    This->SelectNode(ThreadData->DeviceId);
+    This->SelectNode(LastSelectedNode);
 
-    if (ThreadData->DeviceId)
-        delete[] ThreadData->DeviceId;
     delete ThreadData;
 
     return 0;
@@ -429,10 +437,6 @@ CDeviceView::ListDevicesByType()
     INT ClassIndex;
     BOOL bClassSuccess, bSuccess;
 
-    // Start by adding the root node to the tree
-    bSuccess = AddRootDevice();
-    if (bSuccess == false) return false;
-
     ClassIndex = 0;
     do
     {
@@ -564,12 +568,6 @@ CDeviceView::ListDevicesByType()
 bool
 CDeviceView::ListDevicesByConnection()
 {
-    bool bSuccess;
-
-    // Start by adding the root node to the tree
-    bSuccess = AddRootDevice();
-    if (bSuccess == false) return false;
-
     // Walk the device tree and add all the devices 
     (void)RecurseChildDevices(m_RootNode->GetDeviceInst(), m_hTreeRoot);
 
@@ -928,13 +926,13 @@ CDeviceView::BuildActionMenuForNode(
 HTREEITEM
 CDeviceView::RecurseFindDevice(
     _In_ HTREEITEM hParentItem,
-    _In_ LPWSTR DeviceId
+    _In_ CNode *Node
     )
 {
     HTREEITEM FoundItem;
     HTREEITEM hItem;
     TVITEMW tvItem;
-    CNode *Node;
+    CNode *FoundNode;
 
     // Check if this node has any children
     hItem = TreeView_GetChild(m_hTreeView, hParentItem);
@@ -946,17 +944,22 @@ CDeviceView::RecurseFindDevice(
     if (TreeView_GetItem(m_hTreeView, &tvItem) &&
         tvItem.lParam != NULL)
     {
-        // check for a matching deviceid
-        Node = reinterpret_cast<CNode *>(tvItem.lParam);
-        if (Node->GetDeviceId() &&
-            (wcscmp(Node->GetDeviceId(), DeviceId) == 0))
+        // check for a matching node
+        FoundNode = reinterpret_cast<CNode *>(tvItem.lParam);
+        if ((FoundNode->GetNodeType() == Node->GetNodeType()) &&
+            (IsEqualGUID(*FoundNode->GetClassGuid(), *Node->GetClassGuid())))
         {
-            return hItem;
+            // check if this is a class node, or a device with matching ID's
+            if ((FoundNode->GetNodeType() == ClassNode) ||
+                (wcscmp(FoundNode->GetDeviceId(), Node->GetDeviceId()) == 0))
+            {
+                return hItem;
+            }
         }
     }
 
     // This node may have its own children
-    FoundItem = RecurseFindDevice(hItem, DeviceId);
+    FoundItem = RecurseFindDevice(hItem, Node);
     if (FoundItem) return FoundItem;
 
     // Loop all the siblings
@@ -971,17 +974,22 @@ CDeviceView::RecurseFindDevice(
         tvItem.mask = TVIF_PARAM;
         if (TreeView_GetItem(m_hTreeView, &tvItem))
         {
-            // check for a matching deviceid
-            Node = reinterpret_cast<CNode *>(tvItem.lParam);
-            if (Node->GetDeviceId() && 
-                wcscmp(Node->GetDeviceId(), DeviceId) == 0)
+            // check for a matching class
+            FoundNode = reinterpret_cast<CNode *>(tvItem.lParam);
+            if ((FoundNode->GetNodeType() == Node->GetNodeType()) &&
+                (IsEqualGUID(*FoundNode->GetClassGuid(), *Node->GetClassGuid())))
             {
-                return hItem;
+                // check if this is a class node, or a device with matching ID's
+                if ((FoundNode->GetNodeType() == ClassNode) ||
+                    (wcscmp(FoundNode->GetDeviceId(), Node->GetDeviceId()) == 0))
+                {
+                    return hItem;
+                }
             }
         }
 
         // This node may have its own children 
-        FoundItem = RecurseFindDevice(hItem, DeviceId);
+        FoundItem = RecurseFindDevice(hItem, Node);
         if (FoundItem) return FoundItem;
     }
 
@@ -990,7 +998,7 @@ CDeviceView::RecurseFindDevice(
 
 void
 CDeviceView::SelectNode(
-    _In_ LPWSTR DeviceId
+    _In_ CNode *Node
     )
 {
     HTREEITEM hRoot, hItem;
@@ -1000,18 +1008,17 @@ CDeviceView::SelectNode(
     if (hRoot == NULL) return;
 
     // If we don't want to set select a node, just select root
-    if (DeviceId == NULL)
+    if (Node == nullptr || Node->GetNodeType() == RootNode)
     {
         TreeView_SelectItem(m_hTreeView, hRoot);
         return;
     }
 
     // Scan the tree looking for the node we want
-    hItem = RecurseFindDevice(hRoot, DeviceId);
+    hItem = RecurseFindDevice(hRoot, Node);
     if (hItem)
     {
         TreeView_SelectItem(m_hTreeView, hItem);
-        TreeView_Expand(m_hTreeView, hItem, TVM_EXPAND);
     }
     else
     {
@@ -1033,7 +1040,7 @@ CDeviceView::GetClassNode(
     )
 {
     POSITION Pos;
-    CClassNode *Node;
+    CClassNode *Node = nullptr;
 
     Pos = m_ClassNodeList.GetHeadPosition();
     if (Pos == NULL) return nullptr;
@@ -1047,7 +1054,7 @@ CDeviceView::GetClassNode(
             break;
         }
 
-        Node = NULL;
+        Node = nullptr;
 
     } while (Pos != NULL);
 
@@ -1060,7 +1067,7 @@ CDeviceView::GetDeviceNode(
     )
 {
     POSITION Pos;
-    CDeviceNode *Node;
+    CDeviceNode *Node = nullptr;
 
     Pos = m_DeviceNodeList.GetHeadPosition();
     if (Pos == NULL) return nullptr;
@@ -1074,7 +1081,7 @@ CDeviceView::GetDeviceNode(
             break;
         }
 
-        Node = NULL;
+        Node = nullptr;
 
     } while (Pos != NULL);
 
@@ -1090,7 +1097,7 @@ CNode* CDeviceView::GetNode(
     {
         return (CNode *)TvItem->lParam;
     }
-    return NULL;
+    return nullptr;
 }
 
 void
index 24973f0..eb0383e 100644 (file)
@@ -148,11 +148,11 @@ private:
 
     HTREEITEM RecurseFindDevice(
         _In_ HTREEITEM hParentItem,
-        _In_ LPWSTR DeviceId
+        _In_ CNode *Node
         );
 
     void SelectNode(
-        _In_ LPWSTR DeviceId
+        _In_ CNode *Node
         );
 
     void EmptyDeviceView(
index 1925d2d..6e7d761 100644 (file)
@@ -25,6 +25,17 @@ CNode::CNode(_In_ NodeType Type,
     m_ClassGuid = GUID_NULL;
 }
 
-CNode::~CNode()
+CNode::CNode(const CNode &Node)
 {
+    m_NodeType = Node.m_NodeType;
+    m_ImageListData = Node.m_ImageListData;
+    m_DeviceId = Node.m_DeviceId;
+    m_ClassImage = Node.m_ClassImage;
+
+    StringCbCopyW(m_DisplayName, DISPLAY_NAME_LEN, Node.m_DisplayName);
+    CopyMemory(&m_ClassGuid, &Node.m_ClassGuid, sizeof(GUID));
 }
+
+CNode::~CNode()
+{
+}
\ No newline at end of file
index 373d27b..c511112 100644 (file)
@@ -25,6 +25,10 @@ public:
         _In_ PSP_CLASSIMAGELIST_DATA ImageListData
         );
 
+    CNode(
+        _In_ const CNode& Node
+        );
+
     virtual ~CNode();
 
     virtual bool SetupNode() = 0;