mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
[DEVMGR]
- Add a separate class for the root node - Move creating the action menu items to a generic function so we can use it for both the context menu and the main menu - Create the main action menu as a dynamic popup menu. It doesn't work quite the same as the menus via the resources, so if any menu expects know how to fix this, be my guest svn path=/trunk/; revision=68342
This commit is contained in:
parent
f871bb9384
commit
b5e1b529b3
9 changed files with 174 additions and 104 deletions
|
@ -51,8 +51,7 @@ CDeviceView::CDeviceView(
|
|||
m_hMenu(NULL),
|
||||
m_ViewType(DevicesByType),
|
||||
m_ShowHidden(FALSE),
|
||||
m_RootClassImage(-1),
|
||||
m_RootDevInst(0)
|
||||
m_RootNode(NULL)
|
||||
{
|
||||
ZeroMemory(&m_ImageListData, sizeof(SP_CLASSIMAGELIST_DATA));
|
||||
}
|
||||
|
@ -162,14 +161,27 @@ CDeviceView::OnContextMenu(
|
|||
ScreenToClient(m_hTreeView, &pt) &&
|
||||
PtInRect(&rc, pt))
|
||||
{
|
||||
|
||||
INT xPos = GET_X_LPARAM(lParam);
|
||||
INT yPos = GET_Y_LPARAM(lParam);
|
||||
|
||||
CNode *Node = GetSelectedNode();
|
||||
if (Node)
|
||||
{
|
||||
BuildContextMenuForNode(Node, xPos, yPos);
|
||||
// Create the context menu
|
||||
HMENU hContextMenu = CreatePopupMenu();
|
||||
|
||||
// Add the actions for this node
|
||||
BuildActionMenuForNode(hContextMenu, Node);
|
||||
|
||||
INT xPos = GET_X_LPARAM(lParam);
|
||||
INT yPos = GET_Y_LPARAM(lParam);
|
||||
|
||||
// Display the menu
|
||||
TrackPopupMenuEx(hContextMenu,
|
||||
TPM_RIGHTBUTTON,
|
||||
xPos,
|
||||
yPos,
|
||||
m_hMainWnd,
|
||||
NULL);
|
||||
|
||||
DestroyMenu(hContextMenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -258,6 +270,22 @@ CDeviceView::SetFocus()
|
|||
{
|
||||
}
|
||||
|
||||
bool
|
||||
CDeviceView::CreateActionMenu(
|
||||
_In_ HMENU OwnerMenu,
|
||||
_In_ bool MainMenu
|
||||
)
|
||||
{
|
||||
CNode *Node = GetSelectedNode();
|
||||
if (Node)
|
||||
{
|
||||
BuildActionMenuForNode(OwnerMenu, Node);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CDeviceView::HasProperties(
|
||||
_In_ LPTV_ITEMW TvItem
|
||||
|
@ -336,54 +364,8 @@ CDeviceView::EnableSelectedDevice(
|
|||
bool
|
||||
CDeviceView::AddRootDevice()
|
||||
{
|
||||
// Check whether we've loaded the root bitmap into the imagelist (done on first run)
|
||||
if (m_RootClassImage == -1)
|
||||
{
|
||||
// Load the bitmap we'll be using as the root image
|
||||
HBITMAP hRootImage;
|
||||
hRootImage = LoadBitmapW(g_hInstance,
|
||||
MAKEINTRESOURCEW(IDB_ROOT_IMAGE));
|
||||
if (hRootImage == NULL) return FALSE;
|
||||
|
||||
// Add this bitmap to the device image list. This is a bit hacky, but it's safe
|
||||
m_RootClassImage = ImageList_Add(m_ImageListData.ImageList,
|
||||
hRootImage,
|
||||
NULL);
|
||||
DeleteObject(hRootImage);
|
||||
}
|
||||
|
||||
// Get the root instance
|
||||
CONFIGRET cr;
|
||||
cr = CM_Locate_DevNodeW(&m_RootDevInst,
|
||||
NULL,
|
||||
CM_LOCATE_DEVNODE_NORMAL);
|
||||
if (cr != CR_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// The root name is the computer name
|
||||
WCHAR RootDeviceName[ROOT_NAME_SIZE];
|
||||
DWORD Size = ROOT_NAME_SIZE;
|
||||
if (GetComputerNameW(RootDeviceName, &Size))
|
||||
_wcslwr_s(RootDeviceName);
|
||||
|
||||
TV_ITEMW tvi;
|
||||
TV_INSERTSTRUCT tvins;
|
||||
ZeroMemory(&tvi, sizeof(tvi));
|
||||
ZeroMemory(&tvins, sizeof(tvins));
|
||||
|
||||
// Insert the root / parent item into our treeview
|
||||
tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
|
||||
tvi.pszText = RootDeviceName;
|
||||
tvi.cchTextMax = wcslen(RootDeviceName);
|
||||
tvi.iImage = m_RootClassImage;
|
||||
tvi.iSelectedImage = m_RootClassImage;
|
||||
tvins.item = tvi;
|
||||
m_hTreeRoot = TreeView_InsertItem(m_hTreeView, &tvins);
|
||||
|
||||
m_hTreeRoot = InsertIntoTreeView(NULL, m_RootNode);
|
||||
return (m_hTreeRoot != NULL);
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -622,7 +604,7 @@ CDeviceView::ListDevicesByConnection()
|
|||
if (bSuccess == false) return false;
|
||||
|
||||
// Walk the device tree and add all the devices
|
||||
(void)RecurseChildDevices(m_RootDevInst, m_hTreeRoot);
|
||||
(void)RecurseChildDevices(m_RootNode->GetDeviceInst(), m_hTreeRoot);
|
||||
|
||||
// Expand the root item
|
||||
(void)TreeView_Expand(m_hTreeView,
|
||||
|
@ -755,11 +737,10 @@ CDeviceView::GetSiblingDevice(
|
|||
|
||||
HTREEITEM
|
||||
CDeviceView::InsertIntoTreeView(
|
||||
_In_ HTREEITEM hParent,
|
||||
_In_opt_ HTREEITEM hParent,
|
||||
_In_ CNode *Node
|
||||
)
|
||||
{
|
||||
|
||||
LPWSTR lpLabel;
|
||||
lpLabel = Node->GetDisplayName();
|
||||
|
||||
|
@ -791,15 +772,11 @@ CDeviceView::InsertIntoTreeView(
|
|||
}
|
||||
|
||||
void
|
||||
CDeviceView::BuildContextMenuForNode(
|
||||
_In_ CNode *Node,
|
||||
_In_ INT xPos,
|
||||
_In_ INT yPos
|
||||
CDeviceView::BuildActionMenuForNode(
|
||||
_In_ HMENU OwnerMenu,
|
||||
_In_ CNode *Node
|
||||
)
|
||||
{
|
||||
// Create the context menu
|
||||
HMENU hContextMenu = CreatePopupMenu();
|
||||
|
||||
// Create a seperator structure
|
||||
MENUITEMINFOW MenuSeperator = { 0 };
|
||||
MenuSeperator.cbSize = sizeof(MENUITEMINFOW);
|
||||
|
@ -824,7 +801,7 @@ CDeviceView::BuildContextMenuForNode(
|
|||
String.LoadStringW(g_hInstance, IDS_MENU_UPDATE);
|
||||
MenuItemInfo.wID = IDC_UPDATE_DRV;
|
||||
MenuItemInfo.dwTypeData = String.GetBuffer();
|
||||
InsertMenuItemW(hContextMenu, i, TRUE, &MenuItemInfo);
|
||||
InsertMenuItemW(OwnerMenu, i, TRUE, &MenuItemInfo);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
@ -833,7 +810,7 @@ CDeviceView::BuildContextMenuForNode(
|
|||
String.LoadStringW(g_hInstance, IDS_MENU_ENABLE);
|
||||
MenuItemInfo.wID = IDC_ENABLE_DRV;
|
||||
MenuItemInfo.dwTypeData = String.GetBuffer();
|
||||
InsertMenuItemW(hContextMenu, i, TRUE, &MenuItemInfo);
|
||||
InsertMenuItemW(OwnerMenu, i, TRUE, &MenuItemInfo);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
@ -842,7 +819,7 @@ CDeviceView::BuildContextMenuForNode(
|
|||
String.LoadStringW(g_hInstance, IDS_MENU_DISABLE);
|
||||
MenuItemInfo.wID = IDC_DISABLE_DRV;
|
||||
MenuItemInfo.dwTypeData = String.GetBuffer();
|
||||
InsertMenuItemW(hContextMenu, i, TRUE, &MenuItemInfo);
|
||||
InsertMenuItemW(OwnerMenu, i, TRUE, &MenuItemInfo);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
@ -851,11 +828,11 @@ CDeviceView::BuildContextMenuForNode(
|
|||
String.LoadStringW(g_hInstance, IDS_MENU_UNINSTALL);
|
||||
MenuItemInfo.wID = IDC_UNINSTALL_DRV;
|
||||
MenuItemInfo.dwTypeData = String.GetBuffer();
|
||||
InsertMenuItemW(hContextMenu, i, TRUE, &MenuItemInfo);
|
||||
InsertMenuItemW(OwnerMenu, i, TRUE, &MenuItemInfo);
|
||||
i++;
|
||||
}
|
||||
|
||||
InsertMenuItemW(hContextMenu, i, TRUE, &MenuSeperator);
|
||||
InsertMenuItemW(OwnerMenu, i, TRUE, &MenuSeperator);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
@ -863,32 +840,22 @@ CDeviceView::BuildContextMenuForNode(
|
|||
String.LoadStringW(g_hInstance, IDS_MENU_SCAN);
|
||||
MenuItemInfo.wID = IDC_SCAN_HARDWARE;
|
||||
MenuItemInfo.dwTypeData = String.GetBuffer();
|
||||
InsertMenuItemW(hContextMenu, i, TRUE, &MenuItemInfo);
|
||||
InsertMenuItemW(OwnerMenu, i, TRUE, &MenuItemInfo);
|
||||
i++;
|
||||
|
||||
if (Node->HasProperties())
|
||||
{
|
||||
InsertMenuItemW(hContextMenu, i, TRUE, &MenuSeperator);
|
||||
InsertMenuItemW(OwnerMenu, i, TRUE, &MenuSeperator);
|
||||
i++;
|
||||
|
||||
String.LoadStringW(g_hInstance, IDS_MENU_PROPERTIES);
|
||||
MenuItemInfo.wID = IDC_PROPERTIES;
|
||||
MenuItemInfo.dwTypeData = String.GetBuffer();
|
||||
InsertMenuItemW(hContextMenu, i, TRUE, &MenuItemInfo);
|
||||
InsertMenuItemW(OwnerMenu, i, TRUE, &MenuItemInfo);
|
||||
i++;
|
||||
|
||||
SetMenuDefaultItem(hContextMenu, IDC_PROPERTIES, FALSE);
|
||||
SetMenuDefaultItem(OwnerMenu, IDC_PROPERTIES, FALSE);
|
||||
}
|
||||
|
||||
// Display the menu
|
||||
TrackPopupMenuEx(hContextMenu,
|
||||
TPM_RIGHTBUTTON,
|
||||
xPos,
|
||||
yPos,
|
||||
m_hMainWnd,
|
||||
NULL);
|
||||
|
||||
DestroyMenu(hContextMenu);
|
||||
}
|
||||
|
||||
HTREEITEM
|
||||
|
@ -1097,6 +1064,9 @@ CDeviceView::RefreshDeviceList()
|
|||
|
||||
EmptyLists();
|
||||
|
||||
if (m_RootNode) delete m_RootNode;
|
||||
m_RootNode = new CRootNode(&m_ImageListData);
|
||||
m_RootNode->SetupNode();
|
||||
// Loop through all the classes
|
||||
do
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include "DeviceNode.h"
|
||||
#include "ClassNode.h"
|
||||
#include "RootNode.h"
|
||||
|
||||
enum ViewType
|
||||
{
|
||||
|
@ -13,6 +14,7 @@ enum ViewType
|
|||
|
||||
class CDeviceView
|
||||
{
|
||||
CRootNode *m_RootNode;
|
||||
CAtlList<CClassNode *> m_ClassNodeList;
|
||||
CAtlList<CDeviceNode *> m_DeviceNodeList;
|
||||
SP_CLASSIMAGELIST_DATA m_ImageListData;
|
||||
|
@ -22,9 +24,7 @@ class CDeviceView
|
|||
HMENU m_hMenu;
|
||||
ViewType m_ViewType;
|
||||
HTREEITEM m_hTreeRoot;
|
||||
DEVINST m_RootDevInst;
|
||||
bool m_ShowHidden;
|
||||
int m_RootClassImage;
|
||||
|
||||
public:
|
||||
CDeviceView(
|
||||
|
@ -68,6 +68,11 @@ public:
|
|||
|
||||
ViewType GetCurrentView() { return m_ViewType; }
|
||||
|
||||
bool CreateActionMenu(
|
||||
_In_ HMENU OwnerMenu,
|
||||
_In_ bool MainMenu
|
||||
);
|
||||
|
||||
bool HasProperties(
|
||||
_In_ LPTV_ITEMW TvItem
|
||||
);
|
||||
|
@ -123,14 +128,13 @@ private:
|
|||
);
|
||||
|
||||
HTREEITEM InsertIntoTreeView(
|
||||
_In_ HTREEITEM hParent,
|
||||
_In_opt_ HTREEITEM hParent,
|
||||
_In_ CNode *Node
|
||||
);
|
||||
|
||||
void BuildContextMenuForNode(
|
||||
_In_ CNode *Node,
|
||||
_In_ INT xPos,
|
||||
_In_ INT yPos
|
||||
void BuildActionMenuForNode(
|
||||
_In_ HMENU OwnerMenu,
|
||||
_In_ CNode *Node
|
||||
);
|
||||
|
||||
HTREEITEM RecurseFindDevice(
|
||||
|
|
|
@ -590,6 +590,29 @@ CMainWindow::OnCommand(WPARAM wParam,
|
|||
break;
|
||||
}
|
||||
|
||||
case IDC_ACTIONMENU:
|
||||
{
|
||||
// Create a popup menu with all the actions for the selected node
|
||||
HMENU hMenu = CreatePopupMenu();
|
||||
m_DeviceView->CreateActionMenu(hMenu, true);
|
||||
|
||||
RECT rc;
|
||||
GetMenuItemRect(m_hMainWnd, m_hMenu, 1, &rc);
|
||||
|
||||
LONG Height = rc.bottom - rc.top;
|
||||
|
||||
// Display the menu
|
||||
TrackPopupMenuEx(hMenu,
|
||||
TPM_RIGHTBUTTON,
|
||||
rc.left,
|
||||
rc.top + Height,
|
||||
m_hMainWnd,
|
||||
NULL);
|
||||
|
||||
DestroyMenu(hMenu);
|
||||
break;
|
||||
}
|
||||
|
||||
case IDC_DEVBYTYPE:
|
||||
{
|
||||
RefreshView(DevicesByType);
|
||||
|
|
|
@ -16,6 +16,7 @@ class CMainWindow
|
|||
HWND m_hToolBar;
|
||||
HIMAGELIST m_ToolbarhImageList;
|
||||
HMENU m_hMenu;
|
||||
HMENU m_hActionMenu;
|
||||
int m_CmdShow;
|
||||
|
||||
public:
|
||||
|
|
|
@ -22,6 +22,7 @@ CNode::CNode(_In_ NodeType Type,
|
|||
m_ClassImage(0)
|
||||
{
|
||||
m_DisplayName[0] = UNICODE_NULL;
|
||||
m_ClassGuid = GUID_NULL;
|
||||
}
|
||||
|
||||
CNode::~CNode()
|
||||
|
|
|
@ -21,8 +21,12 @@
|
|||
#define IDC_UPDATE_DRV 104
|
||||
#define IDC_UNINSTALL_DRV 105
|
||||
#define IDC_ADD_HARDWARE 106
|
||||
#define IDC_ABOUT 107
|
||||
#define IDC_EXIT 108
|
||||
|
||||
/* Menu items */
|
||||
#define IDC_ACTIONMENU 150
|
||||
#define IDC_ABOUT 151
|
||||
#define IDC_EXIT 152
|
||||
|
||||
|
||||
/* view menu */
|
||||
#define IDC_DEVBYTYPE 200
|
||||
|
|
61
reactos/dll/win32/devmgr/devmgmt/RootNode.cpp
Normal file
61
reactos/dll/win32/devmgr/devmgmt/RootNode.cpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Device Manager
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: dll/win32/devmgr/devmgr/RootNode.cpp
|
||||
* PURPOSE: Root object for
|
||||
* COPYRIGHT: Copyright 2015 Ged Murphy <gedmurphy@reactos.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "devmgmt.h"
|
||||
#include "RootNode.h"
|
||||
|
||||
|
||||
CRootNode::CRootNode(_In_ PSP_CLASSIMAGELIST_DATA ImageListData) :
|
||||
CNode(RootNode, ImageListData)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CRootNode::~CRootNode()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CRootNode::SetupNode()
|
||||
{
|
||||
|
||||
// Load the bitmap we'll be using as the root image
|
||||
HBITMAP hRootImage;
|
||||
hRootImage = LoadBitmapW(g_hInstance,
|
||||
MAKEINTRESOURCEW(IDB_ROOT_IMAGE));
|
||||
if (hRootImage == NULL) return FALSE;
|
||||
|
||||
// Add this bitmap to the device image list. This is a bit hacky, but it's safe
|
||||
m_ClassImage = ImageList_Add(m_ImageListData->ImageList,
|
||||
hRootImage,
|
||||
NULL);
|
||||
DeleteObject(hRootImage);
|
||||
|
||||
|
||||
// Get the root instance
|
||||
CONFIGRET cr;
|
||||
cr = CM_Locate_DevNodeW(&m_DevInst,
|
||||
NULL,
|
||||
CM_LOCATE_DEVNODE_NORMAL);
|
||||
if (cr != CR_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// The root name is the computer name
|
||||
DWORD Size = DISPLAY_NAME_LEN;
|
||||
if (GetComputerNameW(m_DisplayName, &Size))
|
||||
_wcslwr_s(m_DisplayName);
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
17
reactos/dll/win32/devmgr/devmgmt/RootNode.h
Normal file
17
reactos/dll/win32/devmgr/devmgmt/RootNode.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
#include "Node.h"
|
||||
|
||||
class CRootNode : public CNode
|
||||
{
|
||||
private:
|
||||
DEVINST m_DevInst;
|
||||
|
||||
public:
|
||||
CRootNode(_In_ PSP_CLASSIMAGELIST_DATA ImageListData);
|
||||
~CRootNode();
|
||||
|
||||
virtual bool SetupNode();
|
||||
|
||||
DEVINST GetDeviceInst() { return m_DevInst; }
|
||||
};
|
||||
|
|
@ -6,18 +6,7 @@ BEGIN
|
|||
BEGIN
|
||||
MENUITEM "E&xit", IDC_EXIT
|
||||
END
|
||||
POPUP "Action"
|
||||
BEGIN
|
||||
MENUITEM "Update driver software..." IDC_UPDATE_DRV
|
||||
MENUITEM "Enable" IDC_ENABLE_DRV
|
||||
MENUITEM "Disable" IDC_DISABLE_DRV
|
||||
MENUITEM "Uninstall" IDC_UNINSTALL_DRV
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Scan for hardware changes" IDC_SCAN_HARDWARE
|
||||
MENUITEM "Add hardware" IDC_ADD_HARDWARE, GRAYED
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Properties", IDC_PROPERTIES
|
||||
END
|
||||
MENUITEM "Action" IDC_ACTIONMENU
|
||||
POPUP "View"
|
||||
BEGIN
|
||||
MENUITEM "Devices by type", IDC_DEVBYTYPE
|
||||
|
|
Loading…
Reference in a new issue