From 752f620e9ab90e7952faa3ece6ffb36ef7a786c7 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 13 Sep 2026 12:05:00 +0200 Subject: [PATCH] [MMC_NEW] Move the root of the snap-in tree to the main window - Fix File/New command. This command closes all views, deletes the snap-in tree, creates a new root folder snap-in and finally creates a new root view. - Implement the Windows/New Window command. This command just creates a new root view. - Update the main window title. - Adjust the options dialog accordingly. Hint: Running mmc_new might fail on ReactOS because of the missing folder snap-in. I will add some dummy/test snap-in skeletons including the folder snap-in next. --- base/applications/mmc_new/CConsoleWnd.cpp | 42 +++++++++- base/applications/mmc_new/CConsoleWnd.h | 8 +- base/applications/mmc_new/CMainWnd.cpp | 97 +++++++++++++++++++--- base/applications/mmc_new/CMainWnd.h | 27 ++++-- base/applications/mmc_new/COptionsDialog.h | 6 +- base/applications/mmc_new/lang/en-US.rc | 2 + base/applications/mmc_new/resource.h | 18 ++-- 7 files changed, 167 insertions(+), 33 deletions(-) diff --git a/base/applications/mmc_new/CConsoleWnd.cpp b/base/applications/mmc_new/CConsoleWnd.cpp index f3657d6940a..a982efb3512 100644 --- a/base/applications/mmc_new/CConsoleWnd.cpp +++ b/base/applications/mmc_new/CConsoleWnd.cpp @@ -4,13 +4,16 @@ * PURPOSE: Single 'console' window * COPYRIGHT: Copyright 2006-2007 Thomas Weidenmueller * Copyright 2017 Mark Jansen (mark.jansen@reactos.org) + * Copyright 2026 Eric Kohl (eric.kohl@reactos.org) */ #include "precomp.h" - CConsoleWnd::CConsoleWnd(CMainWnd *MainWnd) + CConsoleWnd::CConsoleWnd(CMainWnd *MainWnd, CSnapin *RootNode) { m_MainWnd = MainWnd; + m_ViewRootNode = RootNode; + m_ViewSelectedNode = RootNode; m_pfnSuperWindowProc = DefMDIChildProc; if (!m_thunk.Init(NULL, NULL)) @@ -61,6 +64,8 @@ m_ViewId = m_MainWnd->RegisterView(this); + UpdateTreeView(); + LPMDICREATESTRUCT mdicreate = reinterpret_cast(reinterpret_cast(lParam)->lpCreateParams); if (mdicreate->lParam) PostMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0); @@ -101,6 +106,41 @@ return TRUE; } + VOID CConsoleWnd::AddTreeViewItemRecursive(HTREEITEM hParentTreeItem, CSnapin *Node) + { + HTREEITEM hTreeItem; + + hTreeItem = m_TreeView.AddItem(hParentTreeItem, + (LPWSTR)Node->DisplayName().GetString(), + Node->GetCacheEntry()->NormalImageIndex(), + Node->GetCacheEntry()->OpenImageIndex(), + (LPARAM)Node); + if (hTreeItem) + { +#if 0 + int snapinCount = Node->GetNodeCount(); + for (int i = 0; i < snapinCount; i++) + { + CSnapinNode *ChildNode = Node->GetNode(i); + if (ChildNode) + AddTreeViewItemRecursive(hTreeItem, ChildNode); + } + + if (snapinCount > 0) + m_TreeView.Expand(hTreeItem, TVE_EXPAND); + + if (Node == m_SelectedNode) + m_TreeView.SelectItem(hTreeItem); +#endif + } + } + + VOID CConsoleWnd::UpdateTreeView() + { + m_TreeView.DeleteItem(TVI_ROOT); + AddTreeViewItemRecursive(TVI_ROOT, m_ViewRootNode); + } + BOOL CConsoleWnd::IsTreeViewVisible() { return m_bTreeViewVisible; diff --git a/base/applications/mmc_new/CConsoleWnd.h b/base/applications/mmc_new/CConsoleWnd.h index 584dc80245d..2d48f392235 100644 --- a/base/applications/mmc_new/CConsoleWnd.h +++ b/base/applications/mmc_new/CConsoleWnd.h @@ -4,6 +4,7 @@ * PURPOSE: Single 'console' window * COPYRIGHT: Copyright 2006-2007 Thomas Weidenmueller * Copyright 2017 Mark Jansen (mark.jansen@reactos.org) + * Copyright 2026 Eric Kohl (eric.kohl@reactos.org) */ #pragma once @@ -33,6 +34,9 @@ private: BOOL m_bStatusBarVisible; BOOL m_bDescriptionBarVisible; + CSnapin *m_ViewRootNode; + CSnapin *m_ViewSelectedNode; + public: CAtlString m_Filename; @@ -76,9 +80,11 @@ public: private: VOID UpdateLayout(); + VOID AddTreeViewItemRecursive(HTREEITEM hParentTreeItem, CSnapin *Node); + VOID UpdateTreeView(); public: - CConsoleWnd(CMainWnd *MainWnd); + CConsoleWnd(CMainWnd *MainWnd, CSnapin *RootNode); ~CConsoleWnd(); LRESULT OnCreate(UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled); diff --git a/base/applications/mmc_new/CMainWnd.cpp b/base/applications/mmc_new/CMainWnd.cpp index 6ca00429f88..efb63b090a9 100644 --- a/base/applications/mmc_new/CMainWnd.cpp +++ b/base/applications/mmc_new/CMainWnd.cpp @@ -24,11 +24,11 @@ static TBBUTTON TbButtons[] = }; CMainWnd::CMainWnd() - : m_NewConsoleCount(0) - , m_nConsoleCount(0) + : m_nConsoleNumber(0) , m_ConsoleMode(AuthorMode) , m_bToolBarVisible(true) , m_NextViewId(1) + , m_RootNode(NULL) { m_FrameThunk.Init(XDefFrameProc, this); m_pfnSuperWindowProc = m_FrameThunk.GetWNDPROC(); @@ -73,8 +73,6 @@ CMainWnd::OnCreate(UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled) RECT rect; m_bStandardMenusVisible = TRUE; - UpdateMenu(); - SetWindowTextW(L"ReactOS Management Console"); /* Create and initialize the Toolbar */ m_bToolBarVisible = TRUE; @@ -119,7 +117,7 @@ CMainWnd::OnSize(UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled) LRESULT CMainWnd::OnCloseChild(UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - m_nConsoleCount--; + UpdateTitle(); UpdateMenu(); return 0; } @@ -140,13 +138,42 @@ CMainWnd::OnClose(UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled) } LRESULT -CMainWnd::OnNewMDIChild(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) +CMainWnd::OnFileNew(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { MDICREATESTRUCT mcs; HWND hChild; - CAtlString title; - CreateNewConsoleTitle(title); - mcs.szTitle = title.GetString(); + CAtlString rootName(MAKEINTRESOURCE(IDS_CONSOLEROOT)); +// CAtlString nodeGuid(L"{C96401CC-0E17-11D3-885B-00C04F72C717}"); + + /* Close all views */ + POSITION pos = m_ViewList.GetHeadPosition(); + while (pos) + { + CConsoleWnd *console = (CConsoleWnd*)m_ViewList.GetNext(pos); + console->SendMessage(WM_CLOSE, 0, 0); + } + + /* Delete the snapin tree */ + delete m_RootNode; + m_RootNode = NULL; + + /* Create a new snapin root node */ + CSnapinCacheEntry *CacheEntry = GetSnapinCacheEntryByGuid((PWSTR)L"{C96401CC-0E17-11D3-885B-00C04F72C717}"); + if (!CacheEntry) + { + DPRINT1("No folder cache entry!\n"); + return 0; + } + + m_RootNode = new CSnapin(CacheEntry, rootName.GetString()); + if (!CacheEntry) + { + DPRINT1("No root folder!\n"); + return 0; + } + + /* Create a new view */ + mcs.szTitle = rootName.GetString(); mcs.szClass = CConsoleWnd::GetWndClassName(); mcs.hOwner = _AtlBaseModule.GetModuleInstance(); mcs.x = mcs.cx = CW_USEDEFAULT; @@ -156,18 +183,23 @@ CMainWnd::OnNewMDIChild(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled HWND hWndOld = (HWND)m_MDIClient.SendMessage(WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized); mcs.lParam = bMaximized || !hWndOld; /* This object registers itself in the _AtlWinModule to be assigned to the next window created */ - CConsoleWnd* child = new CConsoleWnd(this); + CConsoleWnd* child = new CConsoleWnd(this, m_RootNode); /* Ask for a new MDI Child window */ hChild = (HWND)m_MDIClient.SendMessage(WM_MDICREATE, 0, (LONG_PTR)&mcs); if (hChild) { - m_nConsoleCount++; + m_nConsoleNumber++; } else { delete child; + delete m_RootNode; + m_RootNode = NULL; } + + UpdateTitle(); UpdateMenu(); + return 1; } @@ -261,6 +293,34 @@ CMainWnd::OnViewCustomize(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandl return 0; } +LRESULT +CMainWnd::OnWindowsNew(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) +{ + MDICREATESTRUCT mcs; + HWND hChild; + + mcs.szTitle = m_RootNode->DisplayName().GetString(); + mcs.szClass = CConsoleWnd::GetWndClassName(); + mcs.hOwner = _AtlBaseModule.GetModuleInstance(); + mcs.x = mcs.cx = CW_USEDEFAULT; + mcs.y = mcs.cy = CW_USEDEFAULT; + mcs.style = MDIS_ALLCHILDSTYLES; + BOOL bMaximized = FALSE; + HWND hWndOld = (HWND)m_MDIClient.SendMessage(WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized); + mcs.lParam = bMaximized || !hWndOld; + /* This object registers itself in the _AtlWinModule to be assigned to the next window created */ + CConsoleWnd* child = new CConsoleWnd(this, m_RootNode); + /* Ask for a new MDI Child window */ + hChild = (HWND)m_MDIClient.SendMessage(WM_MDICREATE, 0, (LONG_PTR)&mcs); + if (!hChild) + { + delete child; + } + + UpdateMenu(); + return 0; +} + LRESULT CMainWnd::OnWindowsCascade(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { @@ -334,6 +394,17 @@ CMainWnd::OnMDIForward(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) return 0; } +CAtlString *CMainWnd::GetConsoleTitle() +{ + return &m_ConsoleTitle; +} + +void CMainWnd::SetConsoleTitle(CAtlString consoleTitle) +{ + m_ConsoleTitle = consoleTitle; + SetWindowTextW(consoleTitle.GetString()); +} + BOOL CMainWnd::IsToolBarVisible() { @@ -437,13 +508,13 @@ CMainWnd::UpdateViews() POSITION pos; pos = m_ViewList.GetHeadPosition(); - do + while (pos) { console = (CConsoleWnd*)m_ViewList.GetNext(pos); if (console) console->UpdateView(); - } while (pos != NULL); + } } void diff --git a/base/applications/mmc_new/CMainWnd.h b/base/applications/mmc_new/CMainWnd.h index d4b21c17d36..8298c87d6c9 100644 --- a/base/applications/mmc_new/CMainWnd.h +++ b/base/applications/mmc_new/CMainWnd.h @@ -24,8 +24,8 @@ class CMainWnd : private: CWndProcThunk m_FrameThunk; - int m_NewConsoleCount; - int m_nConsoleCount; + int m_nConsoleNumber; + CAtlString m_ConsoleTitle; HMENU m_hMenuConsoleSmall; HMENU m_hMenuConsoleLarge; CONSOLE_MODE m_ConsoleMode; @@ -42,6 +42,8 @@ private: CAtlList m_ViewList; int m_NextViewId; + CSnapin *m_RootNode; + public: CWindow m_MDIClient; @@ -54,7 +56,7 @@ public: MESSAGE_HANDLER(WM_SIZE, OnSize) MESSAGE_HANDLER(WM_USER_CLOSE_CHILD, OnCloseChild) - COMMAND_ID_HANDLER(IDM_FILE_NEW, OnNewMDIChild) + COMMAND_ID_HANDLER(IDM_FILE_NEW, OnFileNew) COMMAND_ID_HANDLER(IDM_FILE_SAVE, OnFileSave) COMMAND_ID_HANDLER(IDM_FILE_SAVEAS, OnFileSaveAs) COMMAND_ID_HANDLER(IDM_FILE_ADD, OnFileAdd) @@ -63,6 +65,7 @@ public: COMMAND_ID_HANDLER(IDM_VIEW_CUSTOMIZE, OnViewCustomize) + COMMAND_ID_HANDLER(IDM_WINDOWS_NEW, OnWindowsNew) COMMAND_ID_HANDLER(IDM_WINDOWS_CASCADE, OnWindowsCascade) COMMAND_ID_HANDLER(IDM_WINDOWS_TILE, OnWindowsTile) COMMAND_ID_HANDLER(IDM_WINDOWS_ARRANGE, OnWindowsArrange) @@ -113,12 +116,21 @@ private: void UpdateMenu() { - if (m_nConsoleCount == 0) + if (m_ViewList.IsEmpty()) SetMenu(m_hMenuConsoleSmall); else SetMenu(m_hMenuConsoleLarge); } + void UpdateTitle() + { + if (m_ViewList.IsEmpty()) + m_ConsoleTitle.LoadString(IDS_APPTITLE); + else + CreateNewConsoleTitle(m_ConsoleTitle); + SetWindowTextW(m_ConsoleTitle.GetString()); + } + CConsoleWnd* GetActiveChildInfo() { HWND hWndMDIChild; @@ -132,7 +144,7 @@ private: void CreateNewConsoleTitle(CAtlString& str) { - DWORD_PTR args[1] = { (DWORD_PTR)(++m_NewConsoleCount) }; + DWORD_PTR args[1] = { (DWORD_PTR)(m_nConsoleNumber) }; str.LoadString(IDS_CONSOLETITLE); LPTSTR lpTarget = NULL; @@ -157,13 +169,14 @@ public: LRESULT OnDestroy(UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnClose(UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnNewMDIChild(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); + LRESULT OnFileNew(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnFileSave(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnFileSaveAs(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnFileAdd(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnFileOptions(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnFileExit(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnViewCustomize(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); + LRESULT OnWindowsNew(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnWindowsCascade(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnWindowsTile(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); LRESULT OnWindowsArrange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); @@ -178,6 +191,8 @@ private: void UpdateViews(); public: + CAtlString *GetConsoleTitle(); + void SetConsoleTitle(CAtlString consoleTitle); BOOL IsToolBarVisible(); VOID SetToolBarVisible(BOOL bVisible); BOOL AreStandardMenusVisible(); diff --git a/base/applications/mmc_new/COptionsDialog.h b/base/applications/mmc_new/COptionsDialog.h index 3cd49d03fe1..0171527b3f0 100644 --- a/base/applications/mmc_new/COptionsDialog.h +++ b/base/applications/mmc_new/COptionsDialog.h @@ -63,9 +63,7 @@ public: // m_ConsoleIcon.SetIcon(); - CAtlString consoleTitle; - m_Console->GetWindowText(consoleTitle); - m_ConsoleName.SetWindowText(consoleTitle); + m_ConsoleName.SetWindowText(m_MainWnd->GetConsoleTitle()->GetString()); m_ConsoleSymbol.EnableWindow(FALSE); @@ -111,7 +109,7 @@ public: { CAtlString consoleTitle; m_ConsoleName.GetWindowText(consoleTitle); - m_Console->SetWindowText(consoleTitle); + m_MainWnd->SetConsoleTitle(consoleTitle); m_MainWnd->SetConsoleMode(m_consoleMode); EndDialog(IDOK); diff --git a/base/applications/mmc_new/lang/en-US.rc b/base/applications/mmc_new/lang/en-US.rc index a785b09780d..5b234876103 100644 --- a/base/applications/mmc_new/lang/en-US.rc +++ b/base/applications/mmc_new/lang/en-US.rc @@ -133,6 +133,8 @@ BEGIN IDS_VENDOR "Vendor" IDS_ABOUTTITLE "About" + IDS_CONSOLEROOT "Console Root" + IDS_AUTHORMODE "Author mode" IDS_USERMODE_FULL "User mode - full access" IDS_USERMODE_MULTIPLE "User mode - limited access, multiple window" diff --git a/base/applications/mmc_new/resource.h b/base/applications/mmc_new/resource.h index 55bdbe9064f..e110adbe317 100644 --- a/base/applications/mmc_new/resource.h +++ b/base/applications/mmc_new/resource.h @@ -88,15 +88,17 @@ #define IDC_CONSOLECUSTOM 3207 -#define IDS_AUTHORMODE 5000 -#define IDS_USERMODE_FULL 5001 -#define IDS_USERMODE_MULTIPLE 5002 -#define IDS_USERMODE_SINGLE 5003 +#define IDS_CONSOLEROOT 5010 -#define IDS_AUTHORMODE_DESC 5004 -#define IDS_USERMODE_FULL_DESC 5005 -#define IDS_USERMODE_MULTIPLE_DESC 5006 -#define IDS_USERMODE_SINGLE_DESC 5007 +#define IDS_AUTHORMODE 5100 +#define IDS_USERMODE_FULL 5101 +#define IDS_USERMODE_MULTIPLE 5102 +#define IDS_USERMODE_SINGLE 5103 + +#define IDS_AUTHORMODE_DESC 5104 +#define IDS_USERMODE_FULL_DESC 5105 +#define IDS_USERMODE_MULTIPLE_DESC 5106 +#define IDS_USERMODE_SINGLE_DESC 5107