Author: gedmurphy Date: Fri Jul 3 06:56:58 2015 New Revision: 68334
URL: http://svn.reactos.org/svn/reactos?rev=68334&view=rev Log: [DEVMGR] - Implement dynamic context menu for device and class nodes - Fix CanUninstall to return correct results - Strings hardcoded for now, will fix soon
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/ClassNode.cpp trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.h trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.h trunk/reactos/dll/win32/devmgr/devmgmt/Node.cpp trunk/reactos/dll/win32/devmgr/devmgmt/Node.h
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/ClassNode.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/Cl... ============================================================================== --- trunk/reactos/dll/win32/devmgr/devmgmt/ClassNode.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/devmgr/devmgmt/ClassNode.cpp [iso-8859-1] Fri Jul 3 06:56:58 2015 @@ -16,7 +16,7 @@ _In_ LPGUID ClassGuid, _In_ PSP_CLASSIMAGELIST_DATA ImageListData ) : - CNode(ImageListData) + CNode(ClassNode, ImageListData) { CopyMemory(&m_ClassGuid, ClassGuid, sizeof(GUID)); }
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/De... ============================================================================== --- trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp [iso-8859-1] Fri Jul 3 06:56:58 2015 @@ -16,7 +16,7 @@ _In_opt_ DEVINST Device, _In_ PSP_CLASSIMAGELIST_DATA ImageListData ) : - CNode(ImageListData), + CNode(DeviceNode, ImageListData), m_DevInst(Device), m_hDevInfo(NULL), m_Status(0), @@ -260,11 +260,12 @@ NULL); if (cr == CR_SUCCESS) { - return ((m_Status & DN_DISABLEABLE) != 0 && - (m_Status & DN_ROOT_ENUMERATED) == 0); - } - - return false; + if ((m_Status & DN_ROOT_ENUMERATED) != 0 && + (m_Status & DN_DISABLEABLE) == 0) + return false; + } + + return true; }
bool
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/De... ============================================================================== --- trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.h [iso-8859-1] Fri Jul 3 06:56:58 2015 @@ -27,10 +27,11 @@ bool HasProblem(); bool IsHidden(); bool CanDisable(); - bool IsDisabled(); + virtual bool IsDisabled(); bool IsStarted(); bool IsInstalled(); bool CanUninstall(); + virtual bool CanUpdate() { return true; } // unimplemented
bool EnableDevice( _In_ bool Enable,
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/De... ============================================================================== --- trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp [iso-8859-1] Fri Jul 3 06:56:58 2015 @@ -49,7 +49,6 @@ m_hTreeView(NULL), m_hPropertyDialog(NULL), m_hMenu(NULL), - m_hContextMenu(NULL), m_ViewType(DevicesByType), m_ShowHidden(FALSE), m_RootClassImage(-1), @@ -92,9 +91,7 @@ SetWindowTheme(m_hTreeView, L"explorer", NULL); }
- // Create the context menu and make properties the default item - m_hContextMenu = CreatePopupMenu(); - SetMenuDefaultItem(m_hContextMenu, IDC_PROPERTIES, FALSE); +
return !!(m_hTreeView); } @@ -109,8 +106,6 @@ SetupDiDestroyClassImageList(&m_ImageListData); ZeroMemory(&m_ImageListData, sizeof(SP_CLASSIMAGELIST_DATA)); } - - DestroyMenu(m_hContextMenu);
return true; } @@ -168,26 +163,14 @@ PtInRect(&rc, pt)) {
- CNode *Node = GetSelectedNode(); - if (Node && Node->HasProperties()) - { - - } - - - - - - INT xPos = GET_X_LPARAM(lParam); INT yPos = GET_Y_LPARAM(lParam);
- TrackPopupMenuEx(m_hContextMenu, - TPM_RIGHTBUTTON, - xPos, - yPos, - m_hMainWnd, - NULL); + CNode *Node = GetSelectedNode(); + if (Node) + { + BuildContextMenuForNode(Node, xPos, yPos); + } } }
@@ -807,6 +790,100 @@ return TreeView_InsertItem(m_hTreeView, &tvins); }
+void +CDeviceView::BuildContextMenuForNode( + _In_ CNode *Node, + _In_ INT xPos, + _In_ INT yPos + ) +{ + // Create the context menu + HMENU hContextMenu = CreatePopupMenu(); + + // Create a seperator structure + MENUITEMINFOW MenuSeperator = { 0 }; + MenuSeperator.cbSize = sizeof(MENUITEMINFOW); + MenuSeperator.fType = MFT_SEPARATOR; + + // Setup the + MENUITEMINFOW MenuItemInfo = { 0 }; + MenuItemInfo.cbSize = sizeof(MENUITEMINFOW); + MenuItemInfo.fMask = MIIM_ID | MIIM_STRING | MIIM_DATA | MIIM_SUBMENU; + MenuItemInfo.fType = MFT_STRING; + + int i = 0; + + // Device nodes have extra data + if (Node->GetNodeType() == DeviceNode) + { + CDeviceNode *DeviceNode = dynamic_cast<CDeviceNode *>(Node); + + if (DeviceNode->CanUpdate()) + { + MenuItemInfo.wID = IDC_UPDATE_DRV; + MenuItemInfo.dwTypeData = L"Update driver software..."; + InsertMenuItemW(hContextMenu, i, TRUE, &MenuItemInfo); + i++; + } + + if (DeviceNode->IsDisabled()) + { + MenuItemInfo.wID = IDC_ENABLE_DRV; + MenuItemInfo.dwTypeData = L"Enable"; + InsertMenuItemW(hContextMenu, i, TRUE, &MenuItemInfo); + i++; + } + + if (DeviceNode->CanDisable() && !DeviceNode->IsDisabled()) + { + MenuItemInfo.wID = IDC_DISABLE_DRV; + MenuItemInfo.dwTypeData = L"Disable"; + InsertMenuItemW(hContextMenu, i, TRUE, &MenuItemInfo); + i++; + } + + if (DeviceNode->CanUninstall()) + { + MenuItemInfo.wID = IDC_UNINSTALL_DRV; + MenuItemInfo.dwTypeData = L"Uninstall"; + InsertMenuItemW(hContextMenu, i, TRUE, &MenuItemInfo); + i++; + } + + InsertMenuItemW(hContextMenu, i, TRUE, &MenuSeperator); + i++; + } + + // All nodes have the scan option + MenuItemInfo.wID = IDC_SCAN_HARDWARE; + MenuItemInfo.dwTypeData = L"Scan for hardware changes"; + InsertMenuItemW(hContextMenu, i, TRUE, &MenuItemInfo); + i++; + + if (Node->HasProperties()) + { + InsertMenuItemW(hContextMenu, i, TRUE, &MenuSeperator); + i++; + + MenuItemInfo.wID = IDC_PROPERTIES; + MenuItemInfo.dwTypeData = L"Properties"; + InsertMenuItemW(hContextMenu, i, TRUE, &MenuItemInfo); + i++; + + SetMenuDefaultItem(hContextMenu, IDC_PROPERTIES, FALSE); + } + + // Display the menu + TrackPopupMenuEx(hContextMenu, + TPM_RIGHTBUTTON, + xPos, + yPos, + m_hMainWnd, + NULL); + + DestroyMenu(hContextMenu); +} + HTREEITEM CDeviceView::RecurseFindDevice( _In_ HTREEITEM hParentItem, @@ -828,6 +905,7 @@ 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)) @@ -840,7 +918,7 @@ FoundItem = RecurseFindDevice(hItem, DeviceId); if (FoundItem) return FoundItem;
- // Delete all the siblings + // Loop all the siblings for (;;) { // Get the next item at this level @@ -852,6 +930,7 @@ 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) @@ -879,14 +958,19 @@ hRoot = TreeView_GetRoot(m_hTreeView); if (hRoot == NULL) return;
- if (DeviceId) - { - hItem = RecurseFindDevice(hRoot, DeviceId); - if (hItem) - { - TreeView_SelectItem(m_hTreeView, hItem); - TreeView_Expand(m_hTreeView, hItem, TVM_EXPAND); - } + // If we don't want to set select a node, just select root + if (DeviceId == NULL) + { + TreeView_SelectItem(m_hTreeView, hRoot); + return; + } + + // Scan the tree looking for the node we want + hItem = RecurseFindDevice(hRoot, DeviceId); + if (hItem) + { + TreeView_SelectItem(m_hTreeView, hItem); + TreeView_Expand(m_hTreeView, hItem, TVM_EXPAND); } else {
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/De... ============================================================================== --- trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.h [iso-8859-1] Fri Jul 3 06:56:58 2015 @@ -20,7 +20,6 @@ HWND m_hTreeView; HWND m_hPropertyDialog; HMENU m_hMenu; - HMENU m_hContextMenu; ViewType m_ViewType; HTREEITEM m_hTreeRoot; DEVINST m_RootDevInst; @@ -128,6 +127,12 @@ _In_ CNode *Node );
+ void BuildContextMenuForNode( + _In_ CNode *Node, + _In_ INT xPos, + _In_ INT yPos + ); + HTREEITEM RecurseFindDevice( _In_ HTREEITEM hParentItem, _In_ LPWSTR DeviceId
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/Node.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/No... ============================================================================== --- trunk/reactos/dll/win32/devmgr/devmgmt/Node.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/devmgr/devmgmt/Node.cpp [iso-8859-1] Fri Jul 3 06:56:58 2015 @@ -14,7 +14,9 @@
/* PUBLIC METHODS *******************************************/
-CNode::CNode(_In_ PSP_CLASSIMAGELIST_DATA ImageListData) : +CNode::CNode(_In_ NodeType Type, + _In_ PSP_CLASSIMAGELIST_DATA ImageListData) : + m_NodeType(Type), m_ImageListData(ImageListData), m_DeviceId(NULL), m_ClassImage(0)
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/Node.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/No... ============================================================================== --- trunk/reactos/dll/win32/devmgr/devmgmt/Node.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/devmgr/devmgmt/Node.h [iso-8859-1] Fri Jul 3 06:56:58 2015 @@ -1,6 +1,13 @@ #pragma once
#define DISPLAY_NAME_LEN 256 + +enum NodeType +{ + RootNode, + ClassNode, + DeviceNode +};
class CNode { @@ -10,9 +17,11 @@ WCHAR m_DisplayName[DISPLAY_NAME_LEN]; GUID m_ClassGuid; INT m_ClassImage; + NodeType m_NodeType;
public: CNode( + _In_ NodeType Type, _In_ PSP_CLASSIMAGELIST_DATA ImageListData );
@@ -20,6 +29,7 @@
virtual bool SetupNode() = 0;
+ NodeType GetNodeType() { return m_NodeType; } LPGUID GetClassGuid() { return &m_ClassGuid; } LPWSTR GetDisplayName() { return m_DisplayName; } INT GetClassImage() { return m_ClassImage; }