You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1442 lines
40 KiB
1442 lines
40 KiB
/*++
|
|
|
|
Copyright (c) 1989-2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
CompatAdmin.cpp
|
|
|
|
Abstract:
|
|
|
|
This module handles the code for handling the db tree used in the application
|
|
|
|
Author:
|
|
|
|
kinshu created October 15, 2001
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
|
|
//////////////////////// Function Declarations ////////////////////////////////
|
|
|
|
BOOL
|
|
DeleteFromContentsList(
|
|
HWND hwndList,
|
|
LPARAM lParam
|
|
);
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////// Extern variables //////////////////////////////////////
|
|
|
|
extern BOOL g_bIsContentListVisible;
|
|
extern HWND g_hwndContentsList;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
void
|
|
DatabaseTree::Init(
|
|
IN HWND hdlg,
|
|
IN INT iHeightToolbar,
|
|
IN INT iHeightStatusbar,
|
|
IN RECT* prcMainClient
|
|
)
|
|
/*++
|
|
|
|
DatabaseTree::Init
|
|
|
|
Desc: This sets up the system database tree item.
|
|
|
|
Params:
|
|
IN HWND hdlg: The parent of the tree view. This will be the
|
|
main app window
|
|
|
|
IN INT iHeightToolbar: Height of the tool bar
|
|
IN INT iHeightStatusbar: Height of the status bar
|
|
IN RECT* prcMainClient: The client rectangle for hdlg
|
|
--*/
|
|
{
|
|
RECT r;
|
|
GetWindowRect(hdlg, &r);
|
|
m_hLibraryTree = GetDlgItem(hdlg, IDC_LIBRARY);
|
|
|
|
//
|
|
// Resize it
|
|
//
|
|
GetWindowRect(m_hLibraryTree, &r);
|
|
MapWindowPoints(NULL, hdlg, (LPPOINT)&r, 2);
|
|
|
|
MoveWindow(m_hLibraryTree,
|
|
r.left,
|
|
r.top,
|
|
r.right - r.left,
|
|
prcMainClient->bottom - prcMainClient->top - iHeightStatusbar - iHeightToolbar - 20,
|
|
TRUE);
|
|
|
|
InvalidateRect(m_hLibraryTree, NULL, TRUE);
|
|
UpdateWindow(m_hLibraryTree);
|
|
|
|
//
|
|
// Make the System entry in the Tree
|
|
//
|
|
TVINSERTSTRUCT is;
|
|
|
|
is.hParent = TVI_ROOT;
|
|
is.hInsertAfter = TVI_SORT;
|
|
is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
|
|
is.item.stateMask = TVIS_EXPANDED;
|
|
is.item.lParam = (LPARAM)&GlobalDataBase;
|
|
is.item.pszText = GetString(IDS_SYSDB);
|
|
is.item.iImage = IMAGE_GLOBAL;
|
|
is.item.iSelectedImage = IMAGE_GLOBAL;
|
|
|
|
GlobalDataBase.hItemDB = m_hItemGlobal = TreeView_InsertItem(m_hLibraryTree, &is);
|
|
|
|
//
|
|
// Now add the applications item for the global database
|
|
//
|
|
is.hParent = m_hItemGlobal;
|
|
is.item.lParam = TYPE_GUI_APPS;
|
|
is.item.pszText = GetString(IDS_APPS);
|
|
is.item.iImage = IMAGE_APP;
|
|
is.item.iSelectedImage = IMAGE_APP;
|
|
|
|
GlobalDataBase.hItemAllApps = TreeView_InsertItem(m_hLibraryTree, &is);
|
|
|
|
//
|
|
// Dummy item. This is required to give a + button to the tree item.
|
|
// BUGBUG: There should be a proper way to do this.
|
|
//
|
|
is.hParent = GlobalDataBase.hItemAllApps;
|
|
is.item.pszText = TEXT(" 000");
|
|
|
|
|
|
TreeView_InsertItem(m_hLibraryTree, &is);
|
|
|
|
m_hItemAllInstalled = NULL;
|
|
m_hItemAllWorking = NULL;
|
|
m_hPerUserHead = NULL;
|
|
|
|
//
|
|
// Set the image list for the tree
|
|
//
|
|
TreeView_SetImageList(m_hLibraryTree, g_hImageList, TVSIL_NORMAL);
|
|
}
|
|
|
|
BOOL
|
|
DatabaseTree::PopulateLibraryTreeGlobal(
|
|
void
|
|
)
|
|
/*++
|
|
DatabaseTree::PopulateLibraryTreeGlobal
|
|
|
|
Desc: This function loads the shims and layers for the system database tree item. It does
|
|
not load the applications. The applications are loaded when the user first selects
|
|
or expand the "applications" item for the system database tree item
|
|
|
|
Warn: This function should be called only once.
|
|
|
|
--*/
|
|
{
|
|
BOOL bReturn = PopulateLibraryTree(m_hItemGlobal, &GlobalDataBase, TRUE);
|
|
|
|
TreeView_Expand(m_hLibraryTree, m_hItemGlobal, TVE_EXPAND);
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
BOOL
|
|
DatabaseTree::AddWorking(
|
|
IN PDATABASE pDataBase
|
|
)
|
|
/*++
|
|
|
|
DatabaseTree::AddWorking
|
|
|
|
Desc: Adds a new working database into the DB tree under the "Working Databases" entry
|
|
|
|
Params:
|
|
IN PDATABASE pDataBase: The database that we want to add into the list
|
|
|
|
Return:
|
|
TRUE: If successfully added
|
|
FALSE: Otherwise
|
|
--*/
|
|
{
|
|
|
|
TVINSERTSTRUCT is;
|
|
|
|
if (m_hPerUserHead) {
|
|
|
|
is.hInsertAfter = m_hPerUserHead;
|
|
} else if (m_hItemAllInstalled) {
|
|
|
|
is.hInsertAfter = m_hItemAllInstalled;
|
|
} else {
|
|
|
|
is.hInsertAfter = m_hItemGlobal;
|
|
}
|
|
|
|
is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE ;
|
|
is.item.stateMask = TVIS_EXPANDED;
|
|
|
|
if (m_hItemAllWorking == NULL) {
|
|
|
|
//
|
|
// Add the Parent tree item for all the working DBs tree items
|
|
//
|
|
is.hParent = TVI_ROOT;
|
|
is.item.lParam = TYPE_GUI_DATABASE_WORKING_ALL;
|
|
is.item.pszText = GetString(IDS_WORKDB);
|
|
is.item.iImage = IMAGE_WORKING;
|
|
is.item.iSelectedImage = IMAGE_WORKING;
|
|
|
|
m_hItemAllWorking = TreeView_InsertItem(m_hLibraryTree, &is);
|
|
}
|
|
|
|
//
|
|
// Now Add the Working database
|
|
//
|
|
is.item.iImage = IMAGE_DATABASE;
|
|
is.item.iSelectedImage = IMAGE_DATABASE;
|
|
is.hParent = m_hItemAllWorking;
|
|
is.item.lParam = (LPARAM)pDataBase;
|
|
is.item.pszText = pDataBase->strName;
|
|
|
|
HTREEITEM hItemDB = TreeView_InsertItem(m_hLibraryTree, &is);
|
|
|
|
//
|
|
// The other HTREEITEM for the database are set in the PopulateLibraryTree function
|
|
//
|
|
if (!PopulateLibraryTree(hItemDB, pDataBase)) {
|
|
return FALSE;
|
|
}
|
|
|
|
pDataBase->hItemDB = hItemDB;
|
|
|
|
//
|
|
// Now select the first application or the DB item if there is none
|
|
//
|
|
HTREEITEM hItemFirstApp = GetFirstAppItem(hItemDB);
|
|
|
|
if (hItemFirstApp) {
|
|
TreeView_SelectItem(m_hLibraryTree, hItemFirstApp);
|
|
} else {
|
|
TreeView_SelectItem(m_hLibraryTree, hItemDB);
|
|
}
|
|
|
|
LPARAM lParam;
|
|
|
|
//
|
|
// Set the app to be selected
|
|
//
|
|
if (GetLParam(hItemFirstApp, &lParam)) {
|
|
g_pEntrySelApp = (PDBENTRY)lParam;
|
|
} else {
|
|
g_pEntrySelApp = NULL;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
DatabaseTree::RemoveDataBase(
|
|
IN HTREEITEM hItemDB,
|
|
IN TYPE typeDB,
|
|
IN BOOL bSelectSibling
|
|
)
|
|
/*++
|
|
|
|
DatabaseTree::RemoveDataBase
|
|
|
|
Desc: Removes the item for the working or the installed database.
|
|
Sets focus to sibling or parent if no sibling exists.
|
|
|
|
Params:
|
|
IN HTREEITEM hItemDB: The tree item of the db to be removed
|
|
IN TYPE typeDB: The type of database
|
|
IN BOOL bSelectSibling (TRUE): When we call this
|
|
function from ID_CLOSE_ALL, we do not want unnecessary selections
|
|
--*/
|
|
{
|
|
if (hItemDB == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
HTREEITEM hItemSibling = TreeView_GetNextSibling(m_hLibraryTree, hItemDB);
|
|
|
|
if (hItemSibling == NULL) {
|
|
hItemSibling = TreeView_GetPrevSibling(m_hLibraryTree, hItemDB);
|
|
}
|
|
|
|
if (hItemSibling == NULL) {
|
|
//
|
|
// This was the last database, the database item gets deleted with the parent
|
|
//
|
|
HTREEITEM hItemParent = TreeView_GetParent(m_hLibraryTree, hItemDB);
|
|
|
|
assert(hItemParent);
|
|
|
|
TreeView_DeleteItem(m_hLibraryTree, hItemParent);
|
|
|
|
if (typeDB == DATABASE_TYPE_WORKING) {
|
|
|
|
m_hItemAllWorking = NULL;
|
|
g_uNextDataBaseIndex = 0;
|
|
|
|
} else {
|
|
m_hItemAllInstalled = NULL;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
TreeView_DeleteItem(m_hLibraryTree, hItemDB);
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
DatabaseTree::RemoveAllWorking(
|
|
void
|
|
)
|
|
/*++
|
|
|
|
DatabaseTree::RemoveAllWorking
|
|
|
|
Desc: Delete all the working databases tree items
|
|
|
|
--*/
|
|
{
|
|
TreeView_DeleteItem(m_hLibraryTree, m_hItemAllWorking);
|
|
}
|
|
|
|
BOOL
|
|
DatabaseTree::SetLParam(
|
|
IN HTREEITEM hItem,
|
|
IN LPARAM lParam
|
|
)
|
|
/*++
|
|
DatabaseTree::SetLParam
|
|
|
|
Desc: Sets the lParam of a tree item
|
|
|
|
Params:
|
|
IN HTREEITEM hItem: The hItem for the db tree item for which we want to
|
|
set the lParam
|
|
|
|
IN LPARAM lParam: The lParam to set
|
|
|
|
Return:
|
|
TRUE: Successful
|
|
FALSE: Error
|
|
--*/
|
|
{
|
|
TVITEM Item;
|
|
|
|
Item.mask = TVIF_PARAM;
|
|
Item.hItem = hItem;
|
|
Item.lParam = lParam;
|
|
|
|
return TreeView_SetItem(m_hLibraryTree, &Item);
|
|
}
|
|
|
|
BOOL
|
|
DatabaseTree::GetLParam(
|
|
IN HTREEITEM hItem,
|
|
OUT LPARAM* plParam
|
|
)
|
|
/*++
|
|
|
|
DatabaseTree::GetLParam
|
|
|
|
Desc: Gets the lParam of a tree item
|
|
|
|
Params:
|
|
IN HTREEITEM hItem: The hItem for which we want to get the lParam
|
|
OUT LPARAM* plParam: This will store the lParams for the tree item
|
|
|
|
Return:
|
|
TRUE: Successful
|
|
FALSE: Error
|
|
--*/
|
|
{
|
|
TVITEM Item;
|
|
|
|
if (plParam == NULL) {
|
|
assert(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
*plParam = 0;
|
|
|
|
Item.mask = TVIF_PARAM;
|
|
Item.hItem = hItem;
|
|
|
|
if (TreeView_GetItem(m_hLibraryTree, &Item)) {
|
|
*plParam = Item.lParam;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
HTREEITEM
|
|
DatabaseTree::FindChild(
|
|
IN HTREEITEM hItemParent,
|
|
IN LPARAM lParam
|
|
)
|
|
/*++
|
|
|
|
DatabaseTree::FindChild
|
|
|
|
Desc: Given a parent item and a lParam, finds the first child of the parent, with
|
|
that value of lParam. This function only searches in the next level and not all
|
|
the generations of the parent
|
|
|
|
Params:
|
|
IN HTREEITEM hItemParent: The tree item whose child we want to search
|
|
IN LPARAM lParam: The lParam of the child item should match this
|
|
|
|
Return: The handle to the child or NULL if it does not exist
|
|
|
|
--*/
|
|
{
|
|
HWND hwndTree = m_hLibraryTree;
|
|
HTREEITEM hItem = TreeView_GetChild(hwndTree, hItemParent);
|
|
|
|
while (hItem) {
|
|
|
|
LPARAM lParamOfItem;
|
|
|
|
if (!GetLParam (hItem, &lParamOfItem)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (lParamOfItem == lParam) {
|
|
return hItem;
|
|
} else {
|
|
hItem = TreeView_GetNextSibling(hwndTree, hItem);
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
HTREEITEM
|
|
DatabaseTree::GetAllAppsItem(
|
|
IN HTREEITEM hItemDataBase
|
|
)
|
|
/*++
|
|
|
|
DatabaseTree::GetAllAppsItem
|
|
|
|
Desc: Given the handle to the database item, finds the handle for the "Applications"
|
|
item.
|
|
|
|
Params:
|
|
IN HTREEITEM hItemDataBase: The handle to the database tree item
|
|
|
|
Return: The proper value of the handle or NULL if it does not exist.
|
|
|
|
--*/
|
|
{
|
|
HTREEITEM hItem = TreeView_GetChild(m_hLibraryTree, hItemDataBase);
|
|
TVITEM Item;
|
|
|
|
while (hItem) {
|
|
|
|
Item.mask = TVIF_PARAM;
|
|
Item.hItem = hItem;
|
|
|
|
if (!TreeView_GetItem(m_hLibraryTree, &Item)) {
|
|
assert(FALSE);
|
|
hItem = NULL;
|
|
break;
|
|
}
|
|
|
|
TYPE type = (TYPE)Item.lParam;
|
|
|
|
if (type == TYPE_GUI_APPS) {
|
|
break;
|
|
} else {
|
|
hItem = TreeView_GetNextSibling(m_hLibraryTree, hItem);
|
|
}
|
|
}
|
|
|
|
return hItem;
|
|
}
|
|
|
|
HTREEITEM
|
|
DatabaseTree::GetFirstAppItem(
|
|
IN HTREEITEM hItemDataBase
|
|
)
|
|
/*++
|
|
|
|
DatabaseTree::GetFirstAppItem
|
|
|
|
Desc: The handle to the first application's item; given the database tree item.
|
|
|
|
Params:
|
|
IN HTREEITEM hItemDataBase: The handle to the database tree item
|
|
|
|
Return: The proper value or NULL if there is no application for this database
|
|
|
|
--*/
|
|
{
|
|
HTREEITEM hItem = GetAllAppsItem(hItemDataBase);
|
|
|
|
if (hItem == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
return TreeView_GetChild(m_hLibraryTree, hItem);
|
|
}
|
|
|
|
void
|
|
DatabaseTree::AddNewLayer(
|
|
IN PDATABASE pDataBase,
|
|
IN PLAYER_FIX pLayer,
|
|
IN BOOL bShow //(FALSE)
|
|
)
|
|
/*++
|
|
|
|
DatabaseTree::AddNewLayer
|
|
|
|
Desc: Adds a new layer tree item in the tree for the database: pDatabase
|
|
The layer is specified by pLayer.
|
|
This routine might create the root of all layers: "Compatibility Modes", if
|
|
it does not exist.
|
|
|
|
Params:
|
|
IN PDATABASE pDataBase: The database for which we want to add the new layer
|
|
IN PLAYER_FIX pLayer: The layer
|
|
IN BOOL bShow (FALSE): Should we set the focus to the layer after it is created
|
|
|
|
Return:
|
|
void
|
|
--*/
|
|
{
|
|
TVINSERTSTRUCT is;
|
|
|
|
if (!pDataBase || !(pDataBase->hItemDB)) {
|
|
assert(FALSE);
|
|
return;
|
|
}
|
|
|
|
if (pDataBase->hItemAllLayers == NULL) {
|
|
|
|
//
|
|
// Create a new root of all layers: "Compatibility Modes".
|
|
//
|
|
is.hParent = pDataBase->hItemDB;
|
|
is.hInsertAfter = TVI_SORT;
|
|
is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE ;
|
|
is.item.stateMask = TVIS_EXPANDED;
|
|
is.item.lParam = TYPE_GUI_LAYERS;
|
|
is.item.pszText = GetString(IDS_COMPATMODES);
|
|
is.item.iImage = IMAGE_LAYERS;
|
|
is.item.iSelectedImage = IMAGE_LAYERS;
|
|
|
|
pDataBase->hItemAllLayers = TreeView_InsertItem(m_hLibraryTree, &is);
|
|
pDataBase->uLayerCount = 0;
|
|
}
|
|
|
|
pDataBase->uLayerCount++;
|
|
|
|
InsertLayerinTree(pDataBase->hItemAllLayers, pLayer, m_hLibraryTree, bShow);
|
|
}
|
|
|
|
void
|
|
DatabaseTree::RefreshAllLayers(
|
|
IN PDATABASE pDataBase
|
|
)
|
|
/*++
|
|
|
|
DatabaseTree::RefreshAllLayers
|
|
|
|
Desc: Redraws all the layer tree item for the database pDataBase.
|
|
This may be required when we have edited some layer
|
|
|
|
Params:
|
|
IN PDATABASE pDataBase: The database whose layers we want to refresh
|
|
|
|
Return:
|
|
void
|
|
--*/
|
|
{
|
|
if (pDataBase == NULL) {
|
|
assert(FALSE);
|
|
return;
|
|
}
|
|
|
|
PLAYER_FIX plfTemp = pDataBase->pLayerFixes;
|
|
|
|
SendMessage(m_hLibraryTree, WM_SETREDRAW, FALSE , 0);
|
|
|
|
while (plfTemp) {
|
|
RefreshLayer(pDataBase, plfTemp);
|
|
plfTemp = plfTemp->pNext;
|
|
}
|
|
|
|
SendMessage(m_hLibraryTree, WM_SETREDRAW, TRUE , 0);
|
|
}
|
|
|
|
HTREEITEM
|
|
DatabaseTree::RefreshLayer(
|
|
IN PDATABASE pDataBase,
|
|
IN PLAYER_FIX pLayer
|
|
)
|
|
/*++
|
|
|
|
DatabaseTree::RefreshLayer
|
|
|
|
Desc: Redraws the tree item for the layer: pLayer in database pDataBase.
|
|
First removes the tree item and adds it again
|
|
|
|
Params:
|
|
IN PDATABASE pDataBase: Database in which the layer exists
|
|
IN PLAYER_FIX pLayer: The layer to be refreshed
|
|
|
|
Return: The HTREEITEM for pLayer if it was found or NULL
|
|
|
|
--*/
|
|
{
|
|
if (!pDataBase || !(pDataBase->hItemAllLayers)) {
|
|
assert(FALSE);
|
|
return NULL;
|
|
}
|
|
|
|
HTREEITEM hItem = TreeView_GetChild(m_hLibraryTree, pDataBase->hItemAllLayers);
|
|
|
|
while (hItem) {
|
|
|
|
PLAYER_FIX pLayerExist;
|
|
LPARAM lParam;
|
|
|
|
if (GetLParam(hItem, &lParam)) {
|
|
|
|
pLayerExist = (PLAYER_FIX)lParam;
|
|
|
|
if (pLayerExist == pLayer) {
|
|
|
|
TreeView_DeleteItem(m_hLibraryTree, hItem);
|
|
|
|
InsertLayerinTree(pDataBase->hItemAllLayers,
|
|
pLayer,
|
|
m_hLibraryTree,
|
|
TRUE);
|
|
break;
|
|
|
|
} else {
|
|
hItem = TreeView_GetNextSibling(m_hLibraryTree, hItem);
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// Error:
|
|
//
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
return hItem;
|
|
}
|
|
|
|
|
|
BOOL
|
|
DatabaseTree::AddNewExe(
|
|
IN PDATABASE pDataBase,
|
|
IN PDBENTRY pEntry,
|
|
IN PDBENTRY pApp,
|
|
IN BOOL bRepaint // (TRUE)
|
|
)
|
|
/*++
|
|
|
|
DatabaseTree::AddNewExe
|
|
|
|
Desc: Adds a new exe entry in the apps Tree. First finds the database tree item
|
|
under the list of working database , then if pApp is NULL, checks if the Apps
|
|
htree item is there or not, If not creates a new item
|
|
If the pApp is not NULL, then we select that app. And add the exe in the EXE tree
|
|
and set the focus to it.
|
|
|
|
Params:
|
|
IN PDATABASE pDataBase: The database in which we wan to add the new entry
|
|
IN PDBENTRY pEntry: The entry to add
|
|
IN PDBENTRY pApp: The app of the entry
|
|
IN BOOL bRepaint (TRUE): <TODO>
|
|
|
|
Return:
|
|
TRUE: Added successfully
|
|
FALSE: There was some error
|
|
--*/
|
|
{
|
|
|
|
if (!pEntry || !pDataBase) {
|
|
assert(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
HTREEITEM hItemDB = pDataBase->hItemDB, hItem;
|
|
HTREEITEM hItemAllApps = pDataBase->hItemAllApps;
|
|
TVINSERTSTRUCT is;
|
|
|
|
SendMessage(g_hwndEntryTree, WM_SETREDRAW, TRUE, 0);
|
|
|
|
assert(m_hItemAllWorking);
|
|
assert(hItemDB);
|
|
|
|
if (hItemAllApps == NULL) {
|
|
|
|
is.hParent = hItemDB;
|
|
is.hInsertAfter = TVI_SORT;
|
|
is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
|
|
is.item.stateMask = TVIS_EXPANDED;
|
|
is.item.lParam = TYPE_GUI_APPS;
|
|
is.item.pszText = GetString(IDS_APPS);
|
|
is.item.iImage = IMAGE_APP;
|
|
is.item.iSelectedImage = IMAGE_APP;
|
|
|
|
HTREEITEM hItemApp = TreeView_InsertItem(m_hLibraryTree, &is);
|
|
|
|
g_pPresentDataBase->hItemAllApps = hItemApp;
|
|
}
|
|
|
|
if (pApp == NULL) {
|
|
|
|
is.hParent = g_pPresentDataBase->hItemAllApps;
|
|
is.hInsertAfter = TVI_SORT;
|
|
is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE ;
|
|
is.item.stateMask = TVIS_EXPANDED;
|
|
is.item.lParam = (LPARAM)pEntry;
|
|
is.item.pszText = pEntry->strAppName;
|
|
is.item.iImage = IMAGE_SINGLEAPP;
|
|
is.item.iSelectedImage = IMAGE_SINGLEAPP;
|
|
|
|
hItem = TreeView_InsertItem(m_hLibraryTree, &is);
|
|
g_pSelEntry = g_pEntrySelApp = pEntry;
|
|
|
|
TreeView_SelectItem(m_hLibraryTree, hItem);
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// Now loop through all the apps and then find the app for this exe
|
|
//
|
|
hItem = TreeView_GetChild(m_hLibraryTree, hItemAllApps);
|
|
|
|
while (hItem) {
|
|
|
|
LPARAM lParam;
|
|
|
|
if (!GetLParam(hItem, &lParam)) {
|
|
|
|
assert(FALSE);
|
|
break;
|
|
}
|
|
|
|
if ((PDBENTRY)lParam == pApp) {
|
|
|
|
TVITEM Item;
|
|
|
|
Item.mask = TVIF_PARAM;
|
|
Item.lParam = (LPARAM)pEntry;
|
|
Item.hItem = hItem;
|
|
|
|
TreeView_SetItem(m_hLibraryTree, &Item);
|
|
|
|
//
|
|
// This entry was added in the beginning of the list. TODO This can be removed
|
|
//
|
|
g_pEntrySelApp = pEntry;
|
|
|
|
if (TreeView_GetSelection(m_hLibraryTree) != hItem && bRepaint) {
|
|
|
|
//
|
|
// Focus is on some other App. Select this app
|
|
//
|
|
TreeView_SelectItem(m_hLibraryTree, hItem);
|
|
|
|
//
|
|
// The above will refresh the EXE Tree and call a UpdateEntryTreeView(). That will
|
|
// add the pEntry to the tree and set a valid pEntry->hItemExe, which we can now select
|
|
//
|
|
TreeView_SelectItem(g_hwndEntryTree, pEntry->hItemExe);
|
|
|
|
} else {
|
|
|
|
//
|
|
// Add the exe in the EXE tree and set the focus to it. The focus is on this app.
|
|
//
|
|
AddSingleEntry(g_hwndEntryTree, pEntry);
|
|
|
|
if (bRepaint) {
|
|
TreeView_SelectItem(g_hwndEntryTree, pEntry->hItemExe);
|
|
}
|
|
}
|
|
|
|
//
|
|
// This entry was added in the beginning of the list
|
|
//
|
|
g_pSelEntry = pEntry;
|
|
return TRUE;
|
|
}
|
|
|
|
hItem = TreeView_GetNextSibling(m_hLibraryTree, hItem);
|
|
}
|
|
|
|
if (bRepaint) {
|
|
SendMessage(g_hwndEntryTree, WM_SETREDRAW, TRUE, 0);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL
|
|
DatabaseTree::AddInstalled(
|
|
IN PDATABASE pDataBase
|
|
)
|
|
/*++
|
|
|
|
DatabaseTree::AddInstalled
|
|
|
|
Desc: Adds a New installed database under the "installed databases" tree item in the
|
|
database tree.
|
|
|
|
If the root of all installed databases: "Installed databases" is not present
|
|
this routine first of all adds that.
|
|
|
|
Params:
|
|
IN PDATABASE pDataBase: The installed database to be shown in the db tree
|
|
|
|
Return:
|
|
TRUE: Added successfully
|
|
FALSE: There was some error
|
|
--*/
|
|
{
|
|
TVINSERTSTRUCT is;
|
|
|
|
is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE ;
|
|
is.item.stateMask = TVIS_EXPANDED;
|
|
|
|
if (m_hItemAllInstalled == NULL) {
|
|
|
|
//
|
|
// Add the Parent tree item for all the Installed DBs tree items
|
|
//
|
|
is.hParent = TVI_ROOT;
|
|
is.hInsertAfter = m_hItemGlobal;
|
|
is.item.lParam = TYPE_GUI_DATABASE_INSTALLED_ALL;
|
|
is.item.pszText = GetString(IDS_INSTALLEDDB);
|
|
is.item.iImage = IMAGE_INSTALLED;
|
|
is.item.iSelectedImage = IMAGE_INSTALLED;
|
|
|
|
m_hItemAllInstalled = TreeView_InsertItem(m_hLibraryTree, &is);
|
|
}
|
|
|
|
is.hInsertAfter = TVI_SORT;
|
|
|
|
//
|
|
// Now Add the installed dataBase
|
|
//
|
|
is.hInsertAfter = TVI_SORT;
|
|
is.hParent = m_hItemAllInstalled;
|
|
is.item.lParam = (LPARAM)pDataBase;
|
|
is.item.pszText = pDataBase->strName;
|
|
is.item.iImage = IMAGE_DATABASE;
|
|
is.item.iSelectedImage = IMAGE_DATABASE;
|
|
|
|
HTREEITEM hItemDB = TreeView_InsertItem(m_hLibraryTree, &is);
|
|
|
|
if (!PopulateLibraryTree(hItemDB, pDataBase)) {
|
|
return FALSE;
|
|
}
|
|
|
|
pDataBase->hItemDB = hItemDB;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
DatabaseTree::DeleteAppLayer(
|
|
IN PDATABASE pDataBase,
|
|
IN BOOL bApp,
|
|
IN HTREEITEM hItemDelete,
|
|
IN BOOL bRepaint // (TRUE)
|
|
)
|
|
/*++
|
|
DatabaseTree::DeleteAppLayer
|
|
|
|
Desc: This function is to be used for deleting apps and layers.
|
|
Give the focus to the prev or the next sibling. If neither exist, delete the
|
|
parent and give the focus to the grandparent.
|
|
|
|
Params:
|
|
IN PDATABASE pDataBase: The database in which the app or layer to be deleted resides
|
|
IN BOOL bApp: Is it an app or a layer?
|
|
IN HTREEITEM hItemDelete: The tree item to be deleted
|
|
IN BOOL bRepaint (TRUE): Not used
|
|
|
|
Warning:
|
|
*************************************************************************
|
|
The actual layer or app has already been deleted before calling this function.
|
|
So do not get the lParam and do any stuff with it. Do not call GetItemType for
|
|
the hItemDelete
|
|
*************************************************************************
|
|
--*/
|
|
{
|
|
HTREEITEM hItemPrev = NULL,
|
|
hItemNext = NULL,
|
|
hParent = NULL,
|
|
hGrandParent = NULL;
|
|
|
|
LPARAM lParam = NULL;
|
|
TYPE type = TYPE_UNKNOWN;
|
|
|
|
hItemPrev = TreeView_GetPrevSibling(m_hLibraryTree, hItemDelete);
|
|
|
|
HTREEITEM hItemShow;
|
|
|
|
if (hItemPrev != NULL) {
|
|
hItemShow = hItemPrev;
|
|
} else {
|
|
|
|
hItemNext = TreeView_GetNextSibling(m_hLibraryTree, hItemDelete);
|
|
|
|
if (hItemNext != NULL) {
|
|
|
|
hItemShow = hItemNext;
|
|
} else {
|
|
|
|
//
|
|
// Now delete the parent and set the focus to the grandparent
|
|
//
|
|
if (bApp) {
|
|
|
|
pDataBase->hItemAllApps = NULL;
|
|
|
|
} else {
|
|
|
|
pDataBase->hItemAllLayers = NULL;
|
|
}
|
|
|
|
hParent = TreeView_GetParent(m_hLibraryTree, hItemDelete);
|
|
hGrandParent = TreeView_GetParent(m_hLibraryTree, hItemDelete);
|
|
|
|
hItemDelete = hParent;
|
|
hItemShow = hGrandParent;
|
|
}
|
|
}
|
|
|
|
SetStatusStringDBTree(TreeView_GetParent(m_hLibraryTree, hItemDelete));
|
|
|
|
TreeView_DeleteItem(m_hLibraryTree, hItemDelete);
|
|
|
|
if (bRepaint) {
|
|
//
|
|
// Tree view automatically selects the next element or the parent it there is no next.
|
|
//
|
|
SetFocus(m_hLibraryTree);
|
|
}
|
|
}
|
|
|
|
void
|
|
DatabaseTree::InsertLayerinTree(
|
|
IN HTREEITEM hItemLayers,
|
|
IN PLAYER_FIX plf,
|
|
IN HWND hwndTree, // (NULL)
|
|
IN BOOL bShow // (FALSE)
|
|
)
|
|
/*++
|
|
DatabaseTree::InsertLayerinTree
|
|
|
|
Desc: Given a single layer, it adds it under "Compatibility Modes" tree item for that database
|
|
It assumes that the parent "Compatibility Modes" tree item is already present
|
|
|
|
Params:
|
|
IN HTREEITEM hItemLayers: The all layers item for the database
|
|
IN PLAYER_FIX plf: The layer that we are adding
|
|
IN HWND hwndTree (NULL): The tree
|
|
IN BOOL bShow (FALSE): If true will select the newly added layer
|
|
--*/
|
|
{
|
|
if (hwndTree == NULL) {
|
|
hwndTree = m_hLibraryTree;
|
|
}
|
|
|
|
if (plf == NULL) {
|
|
assert(FALSE);
|
|
Dbg(dlError, "DatabaseTree::InsertLayerinTree Invalid parameter");
|
|
return;
|
|
}
|
|
|
|
TVINSERTSTRUCT is;
|
|
|
|
is.hInsertAfter = TVI_SORT;
|
|
is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
|
|
is.item.stateMask = TVIS_EXPANDED;
|
|
|
|
is.hParent = hItemLayers ;
|
|
is.item.lParam = (LPARAM)plf ;
|
|
is.item.pszText = plf->strName;
|
|
is.item.iImage = IMAGE_LAYERS;
|
|
is.item.iSelectedImage = IMAGE_LAYERS;
|
|
|
|
HTREEITEM hSingleLayer = TreeView_InsertItem(hwndTree, &is);
|
|
|
|
//
|
|
// Add the shims for this Layer
|
|
//
|
|
PSHIM_FIX_LIST pShimFixList = plf->pShimFixList;
|
|
PFLAG_FIX_LIST pFlagFixList = plf->pFlagFixList;
|
|
|
|
if (pShimFixList || pFlagFixList) {
|
|
|
|
while (pShimFixList) {
|
|
|
|
is.hInsertAfter = TVI_SORT;
|
|
|
|
assert(pShimFixList->pShimFix != NULL);
|
|
|
|
is.hParent = hSingleLayer;
|
|
is.item.pszText = pShimFixList->pShimFix->strName;
|
|
is.item.lParam = (LPARAM)pShimFixList->pShimFix;
|
|
is.item.iImage = IMAGE_SHIM;
|
|
is.item.iSelectedImage = IMAGE_SHIM;
|
|
|
|
HTREEITEM hSingleShimInLayer = TreeView_InsertItem(hwndTree, &is);
|
|
|
|
//
|
|
// Add the Include and Exclude list for this shim (Expert mode only)
|
|
//
|
|
if (!pShimFixList->strlInExclude.IsEmpty() && g_bExpert) {
|
|
|
|
is.hParent = hSingleShimInLayer;
|
|
is.hInsertAfter = TVI_LAST;
|
|
|
|
PSTRLIST listTemp = pShimFixList->strlInExclude.m_pHead;
|
|
|
|
while (listTemp) {
|
|
|
|
if (listTemp->data == INCLUDE) {
|
|
|
|
is.item.iImage = IMAGE_INCLUDE;
|
|
is.item.iSelectedImage = IMAGE_INCLUDE;
|
|
is.item.lParam = TYPE_GUI_INCLUDE;
|
|
} else {
|
|
|
|
is.item.iImage = IMAGE_EXCLUDE;
|
|
is.item.iSelectedImage = IMAGE_EXCLUDE;
|
|
is.item.lParam = TYPE_GUI_EXCLUDE;
|
|
}
|
|
|
|
is.item.pszText = listTemp->szStr;
|
|
listTemp = listTemp->pNext;
|
|
|
|
TreeView_InsertItem(m_hLibraryTree, &is);
|
|
}
|
|
}
|
|
|
|
if (pShimFixList->strCommandLine.Length() > 0 && g_bExpert) {
|
|
|
|
//
|
|
// Add the commandline for this shim in the layer.
|
|
//
|
|
CSTRING str;
|
|
|
|
str.Sprintf(CSTRING(IDS_COMMANDLINE), pShimFixList->strCommandLine);
|
|
|
|
is.hParent = hSingleShimInLayer;
|
|
is.item.lParam = TYPE_GUI_COMMANDLINE;
|
|
is.item.pszText = str;
|
|
is.item.iImage = IMAGE_COMMANDLINE;
|
|
is.item.iSelectedImage = IMAGE_COMMANDLINE;
|
|
|
|
TreeView_InsertItem(hwndTree, &is);
|
|
}
|
|
|
|
pShimFixList = pShimFixList->pNext;
|
|
}
|
|
}
|
|
|
|
is.hInsertAfter = TVI_SORT;
|
|
|
|
//
|
|
// Add the Flags for this Layer. Flags are also shown under the "Compatibility Fixes" parent
|
|
// and they have the same icon as the compatibility fixes.
|
|
//
|
|
if (pFlagFixList) {
|
|
|
|
while (pFlagFixList) {
|
|
|
|
assert(pFlagFixList->pFlagFix != NULL);
|
|
|
|
is.hParent = hSingleLayer;
|
|
is.item.iImage = IMAGE_SHIM;
|
|
is.item.iSelectedImage = IMAGE_SHIM;
|
|
|
|
is.item.pszText = pFlagFixList->pFlagFix->strName;
|
|
is.item.lParam = (LPARAM)pFlagFixList->pFlagFix;
|
|
|
|
HTREEITEM hSingleFlagInLayer = TreeView_InsertItem(hwndTree, &is);
|
|
|
|
if (g_bExpert && pFlagFixList->strCommandLine.Length() > 0) {
|
|
|
|
//
|
|
// Add the commandline for this flag in the layer.
|
|
//
|
|
CSTRING str;
|
|
|
|
str.Sprintf(CSTRING(IDS_COMMANDLINE), pFlagFixList->strCommandLine);
|
|
|
|
is.hParent = hSingleFlagInLayer;
|
|
is.item.lParam = TYPE_GUI_COMMANDLINE;
|
|
is.item.pszText = str;
|
|
is.item.iImage = IMAGE_COMMANDLINE;
|
|
is.item.iSelectedImage = IMAGE_COMMANDLINE;
|
|
|
|
TreeView_InsertItem(hwndTree, &is);
|
|
}
|
|
|
|
pFlagFixList = pFlagFixList->pNext;
|
|
}
|
|
}
|
|
|
|
if (bShow) {
|
|
TreeView_SelectItem(m_hLibraryTree, hSingleLayer);
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
DatabaseTree::PopulateLibraryTree(
|
|
IN HTREEITEM hRoot,
|
|
IN PDATABASE pDataBase,
|
|
IN BOOL bLoadOnlyLibrary, // (FALSE)
|
|
IN BOOL bLoadOnlyApps // (FALSE)
|
|
)
|
|
/*++
|
|
|
|
DatabaseTree::PopulateLibraryTree
|
|
|
|
Desc: This does the bulk of work of loading a database into the tree
|
|
|
|
Params:
|
|
IN HTREEITEM hRoot: This will be the handle for either the "System Database"
|
|
or the "Working Databases" or the "Installed Databases" tree item, depending upon where we want
|
|
to add the new database tree item. This is therefore the parent of the database tree item
|
|
that we are going to add
|
|
|
|
IN PDATABASE pDataBase: The database that is being loaded
|
|
IN BOOL bLoadOnlyLibrary (FALSE): We do not want the apps to be loaded into the tree
|
|
This is used, when we initially load the system DB
|
|
|
|
IN BOOL bLoadOnlyApps (FALSE): We only want the apps to be loaded into the tree.
|
|
This is used, when we load the apps for the sys DB
|
|
|
|
--*/
|
|
{
|
|
HTREEITEM hItemShims;
|
|
HTREEITEM hItemLayers;
|
|
TVINSERTSTRUCT is;
|
|
|
|
SendMessage(m_hLibraryTree, WM_SETREDRAW, FALSE, 0);
|
|
|
|
//
|
|
// Default settings
|
|
//
|
|
is.hInsertAfter = TVI_SORT;
|
|
is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
|
|
is.item.stateMask = 0;
|
|
is.item.lParam = 0;
|
|
|
|
if (bLoadOnlyApps == TRUE) {
|
|
goto LoadApps;
|
|
}
|
|
|
|
//
|
|
// Populate with the shims
|
|
//
|
|
if (pDataBase->pShimFixes != NULL || pDataBase->pFlagFixes != NULL) {
|
|
is.hParent = hRoot;
|
|
is.item.lParam = TYPE_GUI_SHIMS;
|
|
is.item.pszText = GetString(IDS_COMPATFIXES);
|
|
is.item.iImage = IMAGE_SHIM;
|
|
is.item.iSelectedImage = IMAGE_SHIM;
|
|
|
|
hItemShims = TreeView_InsertItem(m_hLibraryTree, &is);
|
|
|
|
PSHIM_FIX psf = pDataBase->pShimFixes;
|
|
|
|
while (psf) {
|
|
|
|
//
|
|
// Show only general shims
|
|
//
|
|
if (psf->bGeneral == FALSE && !g_bExpert) {
|
|
|
|
psf = psf->pNext;
|
|
continue;
|
|
}
|
|
|
|
is.hParent = hItemShims;
|
|
is.hInsertAfter = TVI_SORT;
|
|
is.item.lParam = (LPARAM)psf;
|
|
is.item.pszText = psf->strName;
|
|
is.item.iImage = IMAGE_SHIM;
|
|
is.item.iSelectedImage = IMAGE_SHIM;
|
|
|
|
HTREEITEM hItemSingleShim = TreeView_InsertItem(m_hLibraryTree, &is);
|
|
|
|
if (hItemSingleShim == NULL) {
|
|
Dbg(dlError, "Failed to add a individual shim in TreePopulate");
|
|
return FALSE;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Add the Include and Exclude list for this shim (Expert mode only)
|
|
//
|
|
if (!psf->strlInExclude.IsEmpty() && g_bExpert) {
|
|
|
|
is.hParent = hItemSingleShim;
|
|
is.hInsertAfter = TVI_LAST;
|
|
|
|
PSTRLIST listTemp = psf->strlInExclude.m_pHead;
|
|
|
|
while (listTemp) {
|
|
|
|
if (listTemp->data == INCLUDE) {
|
|
|
|
is.item.iImage = IMAGE_INCLUDE;
|
|
is.item.iSelectedImage = IMAGE_INCLUDE;
|
|
is.item.lParam = TYPE_GUI_INCLUDE;
|
|
} else {
|
|
|
|
is.item.iImage = IMAGE_EXCLUDE;
|
|
is.item.iSelectedImage = IMAGE_EXCLUDE;
|
|
is.item.lParam = TYPE_GUI_EXCLUDE;
|
|
}
|
|
|
|
is.item.pszText = listTemp->szStr;
|
|
listTemp = listTemp->pNext;
|
|
|
|
TreeView_InsertItem(m_hLibraryTree, &is);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Now add the command line
|
|
//
|
|
if (psf->strCommandLine.Length() > 0 && g_bExpert) {
|
|
|
|
is.hParent = hItemSingleShim;
|
|
is.item.lParam = TYPE_GUI_COMMANDLINE;
|
|
|
|
CSTRING str;
|
|
|
|
str.Sprintf(CSTRING(IDS_COMMANDLINE), psf->strCommandLine);
|
|
|
|
is.item.pszText = str;
|
|
is.item.iImage = IMAGE_COMMANDLINE;
|
|
is.item.iSelectedImage = IMAGE_COMMANDLINE;
|
|
|
|
TreeView_InsertItem(m_hLibraryTree, &is);
|
|
}
|
|
}
|
|
|
|
psf = psf->pNext;
|
|
}
|
|
|
|
//
|
|
// Put the Flags now, this time under the shims icon
|
|
//
|
|
is.hInsertAfter = TVI_SORT;
|
|
|
|
if (pDataBase->pFlagFixes != NULL) {
|
|
|
|
is.hParent = hItemShims;
|
|
is.item.iImage = IMAGE_SHIM;
|
|
is.item.iSelectedImage = IMAGE_SHIM;
|
|
|
|
PFLAG_FIX pff = pDataBase->pFlagFixes;
|
|
|
|
while (pff) {
|
|
|
|
if (pff->bGeneral || g_bExpert) {
|
|
|
|
is.item.lParam = (LPARAM)pff;
|
|
is.item.pszText = pff->strName;
|
|
TreeView_InsertItem(m_hLibraryTree, &is);
|
|
}
|
|
|
|
pff = pff->pNext;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Now populate the layers.
|
|
//
|
|
if (pDataBase->pLayerFixes != NULL) {
|
|
|
|
is.hParent = hRoot;
|
|
is.item.lParam = TYPE_GUI_LAYERS;
|
|
is.item.iImage = IMAGE_LAYERS;
|
|
is.item.iSelectedImage = IMAGE_LAYERS;
|
|
is.item.pszText = GetString(IDS_COMPATMODES);
|
|
|
|
hItemLayers = TreeView_InsertItem(m_hLibraryTree, &is);
|
|
|
|
pDataBase->hItemAllLayers = hItemLayers;
|
|
|
|
PLAYER_FIX plf = pDataBase->pLayerFixes;
|
|
|
|
while (plf) {
|
|
InsertLayerinTree(hItemLayers, plf, FALSE);
|
|
plf = plf->pNext;
|
|
}
|
|
}
|
|
|
|
LoadApps:
|
|
|
|
//
|
|
// Now add the Apps
|
|
//
|
|
if (pDataBase->pEntries && !bLoadOnlyLibrary) {
|
|
|
|
is.hParent = hRoot;
|
|
is.item.lParam = TYPE_GUI_APPS;
|
|
is.item.pszText = GetString(IDS_APPS);
|
|
is.item.iImage = IMAGE_APP;
|
|
is.item.iSelectedImage = IMAGE_APP;
|
|
|
|
if (pDataBase->type != DATABASE_TYPE_GLOBAL) {
|
|
pDataBase->hItemAllApps = TreeView_InsertItem(m_hLibraryTree, &is);
|
|
}
|
|
|
|
PDBENTRY pApps = pDataBase->pEntries;
|
|
|
|
while (pApps) {
|
|
|
|
is.hParent = pDataBase->hItemAllApps;
|
|
is.item.lParam = (LPARAM)pApps;
|
|
is.item.pszText = pApps->strAppName;
|
|
is.item.iImage = IMAGE_SINGLEAPP;
|
|
is.item.iSelectedImage = IMAGE_SINGLEAPP;
|
|
|
|
TreeView_InsertItem(m_hLibraryTree, &is);
|
|
|
|
pApps = pApps->pNext;
|
|
}
|
|
}
|
|
|
|
SendMessage(m_hLibraryTree, WM_SETREDRAW, TRUE, 0);
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
DatabaseTree::AddApp(
|
|
IN PDATABASE pDatabase,
|
|
IN PDBENTRY pApp,
|
|
IN BOOL bUpdate // (TRUE)
|
|
)
|
|
/*++
|
|
|
|
DatabaseTree::AddApp
|
|
|
|
Desc: If there is no app for
|
|
pApp->strApp: Adds a new app entry in the db tree for the database
|
|
Otherwise, it sets the lParam of the existing entry to pApp.
|
|
Calls UpdateEntryTree() after this
|
|
|
|
Params:
|
|
IN PDATABASE pDatabase: The database in which this app has been added
|
|
IN PDBENTRY pApp: The app that is to be added to the tree
|
|
IN BOOL bUpdate (TRUE): Should we set the focus to the new tree item
|
|
|
|
Return:
|
|
void
|
|
--*/
|
|
{
|
|
if (pDatabase == NULL) {
|
|
assert(FALSE);
|
|
return;
|
|
}
|
|
|
|
HTREEITEM hItem = pDatabase->hItemAllApps;
|
|
TVITEM tvitem;
|
|
TCHAR szBuffer[MAX_PATH];
|
|
|
|
|
|
if (pDatabase->hItemAllApps == NULL) {
|
|
|
|
AddNewExe(pDatabase, pApp, NULL, bUpdate);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Search for the app-name
|
|
//
|
|
hItem = TreeView_GetChild(m_hLibraryTree, hItem);
|
|
|
|
tvitem.mask = TVIF_TEXT;
|
|
tvitem.pszText = szBuffer;
|
|
tvitem.cchTextMax = ARRAYSIZE(szBuffer);
|
|
|
|
while (hItem) {
|
|
|
|
tvitem.hItem = hItem;
|
|
*szBuffer = 0;
|
|
|
|
if (!TreeView_GetItem(m_hLibraryTree, &tvitem)) {
|
|
assert(FALSE);
|
|
goto Next;
|
|
}
|
|
|
|
if (lstrcmpi(szBuffer, pApp->strAppName) == 0) {
|
|
|
|
//
|
|
// This is the app name
|
|
//
|
|
SetLParam(hItem, (LPARAM)pApp);
|
|
|
|
if (bUpdate) {
|
|
//
|
|
// This entry was added in the beginning of the list
|
|
//
|
|
TreeView_SelectItem(m_hLibraryTree, hItem);
|
|
|
|
g_pEntrySelApp = pApp;
|
|
g_pSelEntry = pApp;
|
|
|
|
UpdateEntryTreeView(pApp, g_hwndEntryTree);
|
|
}
|
|
|
|
return;
|
|
}
|
|
Next:
|
|
hItem = TreeView_GetNextSibling(m_hLibraryTree, hItem);
|
|
}
|
|
|
|
//
|
|
// There is no entry with this app-name uder the apps of the database
|
|
//
|
|
AddNewExe(pDatabase, pApp, NULL, bUpdate);
|
|
}
|
|
|
|
HTREEITEM
|
|
DatabaseTree::GetSelection(
|
|
void
|
|
)
|
|
/*++
|
|
DatabaseTree::GetSelection
|
|
|
|
Desc: Returns the selected item in the db tree.
|
|
|
|
Return: Returns the selected item in the db tree.
|
|
|
|
--*/
|
|
{
|
|
return TreeView_GetSelection(m_hLibraryTree);
|
|
}
|