[RAPPS] Build up a minimal UI for RAPPS started in AppWiz mode (#6655)

- Only the "Installed/Applications/Updates" items are shown.
- Delete the "Settings" item in the "File" menu.
- Remove unnecessary toolbar buttons: ID_INSTALL, ID_CHECK_ALL, ID_RESETDB.

- gui.cpp CMainWindow::ProcessWindowMessage():
  Forbid the "Install" tree-view section to collapse.

  However, there is currently a bug in Wine's comctl32, which ignores
  the value returned from the TVN_ITEMEXPANDING notification handler
  to control the collapse/expansion behaviour.

  https://bugs.winehq.org/show_bug.cgi?id=53727

  As a result, this feature doesn't work in ReactOS yet.
This commit is contained in:
Hermès Bélusca-Maïto 2024-03-22 18:20:35 +01:00
parent b1a3479500
commit 9835ea27d2
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
3 changed files with 123 additions and 6 deletions

View file

@ -16,6 +16,50 @@ using namespace Gdiplus;
HICON g_hDefaultPackageIcon = NULL;
static int g_DefaultPackageIconILIdx = I_IMAGENONE;
// **** Menu helpers ****
BOOL
DeleteMenuEx(
_In_ HMENU hMenu,
_In_ UINT uPosition,
_In_ UINT uFlags)
{
INT pos;
MENUITEMINFOW mii = { sizeof(mii), MIIM_FTYPE, 0 };
bool bIsValidItem1, bIsValidItem2;
bool bIsSep1, bIsSep2;
if (uFlags & MF_BYPOSITION)
pos = (INT)uPosition;
else
pos = ::GetMenuPosFromID(hMenu, uPosition);
if (pos < 0)
return FALSE;
bIsValidItem1 = ((pos > 0) && ::GetMenuItemInfoW(hMenu, pos - 1, TRUE, &mii));
bIsSep1 = bIsValidItem1 && !!(mii.fType & MFT_SEPARATOR);
bIsValidItem2 = ::GetMenuItemInfoW(hMenu, pos + 1, TRUE, &mii);
bIsSep2 = bIsValidItem2 && !!(mii.fType & MFT_SEPARATOR);
if (bIsSep1 && !bIsSep2 && !bIsValidItem2)
pos = pos - 1; // Delete separator only if pos+1 has no item
else if (!bIsSep1 && bIsSep2 && !bIsValidItem1)
pos = pos + 1; // Delete separator only if pos-1 has no item
else if (bIsSep1 && bIsSep2)
pos = pos + 1;
else
pos = -1;
// Delete one of the separators if necessary
if (pos != -1)
::DeleteMenu(hMenu, pos, MF_BYPOSITION);
// Finally, delete the menu item itself.
return ::DeleteMenu(hMenu, uPosition, uFlags);
}
// **** Menu helpers ****
// **** CMainToolbar ****
VOID
@ -1480,6 +1524,37 @@ CApplicationView::ProcessWindowMessage(
bSuccess &= CreateListView();
bSuccess &= CreateAppInfoDisplay();
/* APPWIZ-mode: Remove the unneeded menu items and toolbar buttons */
if (m_MainWindow->m_bAppwizMode)
{
HMENU hMenu;
/* Delete the "Settings" item in the "File" sub-menu */
hMenu = ::GetSubMenu(m_MainWindow->GetMenu(), 0);
DeleteMenuEx(hMenu, ID_SETTINGS, MF_BYCOMMAND);
/* Remove the menu items: ID_INSTALL, ID_RESETDB */
hMenu = GetMenu();
DeleteMenuEx(hMenu, ID_INSTALL, MF_BYCOMMAND);
DeleteMenuEx(hMenu, ID_RESETDB, MF_BYCOMMAND);
/* Remove the toolbar buttons:
* ID_INSTALL, ID_CHECK_ALL, ID_RESETDB
* We only keep:
* ID_UNINSTALL, ID_MODIFY, ID_REFRESH */
TBBUTTONINFO info = { sizeof(info), 0 };
int index;
index = m_Toolbar->GetButtonInfo(ID_INSTALL, &info);
if (index >= 0) m_Toolbar->DeleteButton(index);
index = m_Toolbar->GetButtonInfo(ID_CHECK_ALL, &info);
if (index >= 0) m_Toolbar->DeleteButton(index);
index = m_Toolbar->GetButtonInfo(ID_RESETDB, &info);
if (index >= 0) m_Toolbar->DeleteButton(index);
}
m_Toolbar->AutoSize();
RECT rTop;
@ -1927,26 +2002,35 @@ CApplicationView::SetDisplayAppType(APPLICATION_VIEW_TYPE AppType)
switch (AppType)
{
case AppViewTypeInstalledApps:
EnableMenuItem(hMenu, ID_REGREMOVE, MF_ENABLED);
{
EnableMenuItem(hMenu, ID_INSTALL, MF_GRAYED);
EnableMenuItem(hMenu, ID_UNINSTALL, MF_ENABLED);
EnableMenuItem(hMenu, ID_MODIFY, MF_ENABLED);
EnableMenuItem(hMenu, ID_REGREMOVE, MF_ENABLED);
m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_INSTALL, FALSE);
m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_UNINSTALL, TRUE);
m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_MODIFY, TRUE);
m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_CHECK_ALL, FALSE);
break;
}
case AppViewTypeAvailableApps:
EnableMenuItem(hMenu, ID_REGREMOVE, MF_GRAYED);
{
// We shouldn't get there in APPWIZ-mode.
ATLASSERT(!m_MainWindow->m_bAppwizMode);
EnableMenuItem(hMenu, ID_INSTALL, MF_ENABLED);
EnableMenuItem(hMenu, ID_UNINSTALL, MF_GRAYED);
EnableMenuItem(hMenu, ID_MODIFY, MF_GRAYED);
EnableMenuItem(hMenu, ID_REGREMOVE, MF_GRAYED);
m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_INSTALL, TRUE);
m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_UNINSTALL, FALSE);
m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_MODIFY, FALSE);
m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_CHECK_ALL, TRUE);
break;
}
}
return TRUE;
}

View file

@ -82,7 +82,7 @@ CSideTreeView::~CSideTreeView()
// **** CMainWindow ****
CMainWindow::CMainWindow(CAppDB *db, BOOL bAppwiz) : m_ClientPanel(NULL), m_Db(db), bAppwizMode(bAppwiz), SelectedEnumType(ENUM_ALL_INSTALLED)
CMainWindow::CMainWindow(CAppDB *db, BOOL bAppwiz) : m_ClientPanel(NULL), m_Db(db), m_bAppwizMode(bAppwiz), SelectedEnumType(ENUM_ALL_INSTALLED)
{
}
@ -100,6 +100,10 @@ CMainWindow::InitCategoriesList()
m_TreeView->AddCategory(hRootItemInstalled, IDS_APPLICATIONS, IDI_APPS);
m_TreeView->AddCategory(hRootItemInstalled, IDS_UPDATES, IDI_APPUPD);
// Do not show any other categories in APPWIZ-mode.
if (m_bAppwizMode)
goto Finish;
m_TreeView->AddCategory(TVI_ROOT, IDS_SELECTEDFORINST, IDI_SELECTEDFORINST);
hRootItemAvailable = m_TreeView->AddCategory(TVI_ROOT, IDS_AVAILABLEFORINST, IDI_CATEGORY);
@ -120,10 +124,12 @@ CMainWindow::InitCategoriesList()
m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_THEMES, IDI_CAT_THEMES);
m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_OTHER, IDI_CAT_OTHER);
Finish:
m_TreeView->SetImageList();
m_TreeView->Expand(hRootItemInstalled, TVE_EXPAND);
m_TreeView->Expand(hRootItemAvailable, TVE_EXPAND);
m_TreeView->SelectItem(bAppwizMode ? hRootItemInstalled : hRootItemAvailable);
if (!m_bAppwizMode)
m_TreeView->Expand(hRootItemAvailable, TVE_EXPAND);
m_TreeView->SelectItem(m_bAppwizMode ? hRootItemInstalled : hRootItemAvailable);
}
BOOL
@ -337,6 +343,22 @@ CMainWindow::ProcessWindowMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lPa
switch (data->code)
{
case TVN_ITEMEXPANDING:
{
if (data->hwndFrom == m_TreeView->m_hWnd)
{
// APPWIZ-mode: forbid item collapse.
// FIXME: Prevent collapse (COMCTL32 is buggy)
// https://bugs.winehq.org/show_bug.cgi?id=53727
if (m_bAppwizMode && (((LPNMTREEVIEW)lParam)->action & TVE_TOGGLE) == TVE_COLLAPSE)
{
theResult = TRUE;
return TRUE; // Handled
}
}
break;
}
case TVN_SELCHANGED:
{
if (data->hwndFrom == m_TreeView->m_hWnd)
@ -612,6 +634,13 @@ CMainWindow::AddApplicationsToView(CAtlList<CAppInfo *> &List)
VOID
CMainWindow::UpdateApplicationsList(AppsCategories EnumType, BOOL bReload, BOOL bCheckAvailable)
{
// Only installed applications should be enumerated in APPWIZ-mode.
if (m_bAppwizMode && !IsInstalledEnum(EnumType))
{
ATLASSERT(FALSE && "Should not be called in APPWIZ-mode");
return;
}
bUpdating = TRUE;
if (HCURSOR hCursor = LoadCursor(NULL, IDC_APPSTARTING))
@ -650,6 +679,9 @@ CMainWindow::UpdateApplicationsList(AppsCategories EnumType, BOOL bReload, BOOL
}
else if (IsAvailableEnum(EnumType))
{
// We shouldn't get there in APPWIZ-mode.
ATLASSERT(!m_bAppwizMode);
if (bReload)
m_Db->UpdateAvailable();

View file

@ -52,12 +52,13 @@ class CMainWindow : public CWindowImpl<CMainWindow, CWindow, CFrameWinTraits>
CUiWindow<CStatusBar> *m_StatusBar = NULL;
CApplicationView *m_ApplicationView = NULL;
friend class CApplicationView;
CAppDB *m_Db;
CAtlList<CAppInfo *> m_Selected;
BOOL bUpdating = FALSE;
BOOL bAppwizMode;
BOOL m_bAppwizMode;
HTREEITEM hRootItemInstalled;
CStringW szSearchPattern;