Leaked source code of windows server 2003
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

  1. /*++
  2. Copyright (c) 1989-2000 Microsoft Corporation
  3. Module Name:
  4. CompatAdmin.cpp
  5. Abstract:
  6. This module handles the code for handling the db tree used in the application
  7. Author:
  8. kinshu created October 15, 2001
  9. --*/
  10. #include "precomp.h"
  11. //////////////////////// Function Declarations ////////////////////////////////
  12. BOOL
  13. DeleteFromContentsList(
  14. HWND hwndList,
  15. LPARAM lParam
  16. );
  17. ///////////////////////////////////////////////////////////////////////////////
  18. /////////////////////// Extern variables //////////////////////////////////////
  19. extern BOOL g_bIsContentListVisible;
  20. extern HWND g_hwndContentsList;
  21. ///////////////////////////////////////////////////////////////////////////////
  22. void
  23. DatabaseTree::Init(
  24. IN HWND hdlg,
  25. IN INT iHeightToolbar,
  26. IN INT iHeightStatusbar,
  27. IN RECT* prcMainClient
  28. )
  29. /*++
  30. DatabaseTree::Init
  31. Desc: This sets up the system database tree item.
  32. Params:
  33. IN HWND hdlg: The parent of the tree view. This will be the
  34. main app window
  35. IN INT iHeightToolbar: Height of the tool bar
  36. IN INT iHeightStatusbar: Height of the status bar
  37. IN RECT* prcMainClient: The client rectangle for hdlg
  38. --*/
  39. {
  40. RECT r;
  41. GetWindowRect(hdlg, &r);
  42. m_hLibraryTree = GetDlgItem(hdlg, IDC_LIBRARY);
  43. //
  44. // Resize it
  45. //
  46. GetWindowRect(m_hLibraryTree, &r);
  47. MapWindowPoints(NULL, hdlg, (LPPOINT)&r, 2);
  48. MoveWindow(m_hLibraryTree,
  49. r.left,
  50. r.top,
  51. r.right - r.left,
  52. prcMainClient->bottom - prcMainClient->top - iHeightStatusbar - iHeightToolbar - 20,
  53. TRUE);
  54. InvalidateRect(m_hLibraryTree, NULL, TRUE);
  55. UpdateWindow(m_hLibraryTree);
  56. //
  57. // Make the System entry in the Tree
  58. //
  59. TVINSERTSTRUCT is;
  60. is.hParent = TVI_ROOT;
  61. is.hInsertAfter = TVI_SORT;
  62. is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  63. is.item.stateMask = TVIS_EXPANDED;
  64. is.item.lParam = (LPARAM)&GlobalDataBase;
  65. is.item.pszText = GetString(IDS_SYSDB);
  66. is.item.iImage = IMAGE_GLOBAL;
  67. is.item.iSelectedImage = IMAGE_GLOBAL;
  68. GlobalDataBase.hItemDB = m_hItemGlobal = TreeView_InsertItem(m_hLibraryTree, &is);
  69. //
  70. // Now add the applications item for the global database
  71. //
  72. is.hParent = m_hItemGlobal;
  73. is.item.lParam = TYPE_GUI_APPS;
  74. is.item.pszText = GetString(IDS_APPS);
  75. is.item.iImage = IMAGE_APP;
  76. is.item.iSelectedImage = IMAGE_APP;
  77. GlobalDataBase.hItemAllApps = TreeView_InsertItem(m_hLibraryTree, &is);
  78. //
  79. // Dummy item. This is required to give a + button to the tree item.
  80. // BUGBUG: There should be a proper way to do this.
  81. //
  82. is.hParent = GlobalDataBase.hItemAllApps;
  83. is.item.pszText = TEXT(" 000");
  84. TreeView_InsertItem(m_hLibraryTree, &is);
  85. m_hItemAllInstalled = NULL;
  86. m_hItemAllWorking = NULL;
  87. m_hPerUserHead = NULL;
  88. //
  89. // Set the image list for the tree
  90. //
  91. TreeView_SetImageList(m_hLibraryTree, g_hImageList, TVSIL_NORMAL);
  92. }
  93. BOOL
  94. DatabaseTree::PopulateLibraryTreeGlobal(
  95. void
  96. )
  97. /*++
  98. DatabaseTree::PopulateLibraryTreeGlobal
  99. Desc: This function loads the shims and layers for the system database tree item. It does
  100. not load the applications. The applications are loaded when the user first selects
  101. or expand the "applications" item for the system database tree item
  102. Warn: This function should be called only once.
  103. --*/
  104. {
  105. BOOL bReturn = PopulateLibraryTree(m_hItemGlobal, &GlobalDataBase, TRUE);
  106. TreeView_Expand(m_hLibraryTree, m_hItemGlobal, TVE_EXPAND);
  107. return bReturn;
  108. }
  109. BOOL
  110. DatabaseTree::AddWorking(
  111. IN PDATABASE pDataBase
  112. )
  113. /*++
  114. DatabaseTree::AddWorking
  115. Desc: Adds a new working database into the DB tree under the "Working Databases" entry
  116. Params:
  117. IN PDATABASE pDataBase: The database that we want to add into the list
  118. Return:
  119. TRUE: If successfully added
  120. FALSE: Otherwise
  121. --*/
  122. {
  123. TVINSERTSTRUCT is;
  124. if (m_hPerUserHead) {
  125. is.hInsertAfter = m_hPerUserHead;
  126. } else if (m_hItemAllInstalled) {
  127. is.hInsertAfter = m_hItemAllInstalled;
  128. } else {
  129. is.hInsertAfter = m_hItemGlobal;
  130. }
  131. is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE ;
  132. is.item.stateMask = TVIS_EXPANDED;
  133. if (m_hItemAllWorking == NULL) {
  134. //
  135. // Add the Parent tree item for all the working DBs tree items
  136. //
  137. is.hParent = TVI_ROOT;
  138. is.item.lParam = TYPE_GUI_DATABASE_WORKING_ALL;
  139. is.item.pszText = GetString(IDS_WORKDB);
  140. is.item.iImage = IMAGE_WORKING;
  141. is.item.iSelectedImage = IMAGE_WORKING;
  142. m_hItemAllWorking = TreeView_InsertItem(m_hLibraryTree, &is);
  143. }
  144. //
  145. // Now Add the Working database
  146. //
  147. is.item.iImage = IMAGE_DATABASE;
  148. is.item.iSelectedImage = IMAGE_DATABASE;
  149. is.hParent = m_hItemAllWorking;
  150. is.item.lParam = (LPARAM)pDataBase;
  151. is.item.pszText = pDataBase->strName;
  152. HTREEITEM hItemDB = TreeView_InsertItem(m_hLibraryTree, &is);
  153. //
  154. // The other HTREEITEM for the database are set in the PopulateLibraryTree function
  155. //
  156. if (!PopulateLibraryTree(hItemDB, pDataBase)) {
  157. return FALSE;
  158. }
  159. pDataBase->hItemDB = hItemDB;
  160. //
  161. // Now select the first application or the DB item if there is none
  162. //
  163. HTREEITEM hItemFirstApp = GetFirstAppItem(hItemDB);
  164. if (hItemFirstApp) {
  165. TreeView_SelectItem(m_hLibraryTree, hItemFirstApp);
  166. } else {
  167. TreeView_SelectItem(m_hLibraryTree, hItemDB);
  168. }
  169. LPARAM lParam;
  170. //
  171. // Set the app to be selected
  172. //
  173. if (GetLParam(hItemFirstApp, &lParam)) {
  174. g_pEntrySelApp = (PDBENTRY)lParam;
  175. } else {
  176. g_pEntrySelApp = NULL;
  177. }
  178. return TRUE;
  179. }
  180. BOOL
  181. DatabaseTree::RemoveDataBase(
  182. IN HTREEITEM hItemDB,
  183. IN TYPE typeDB,
  184. IN BOOL bSelectSibling
  185. )
  186. /*++
  187. DatabaseTree::RemoveDataBase
  188. Desc: Removes the item for the working or the installed database.
  189. Sets focus to sibling or parent if no sibling exists.
  190. Params:
  191. IN HTREEITEM hItemDB: The tree item of the db to be removed
  192. IN TYPE typeDB: The type of database
  193. IN BOOL bSelectSibling (TRUE): When we call this
  194. function from ID_CLOSE_ALL, we do not want unnecessary selections
  195. --*/
  196. {
  197. if (hItemDB == NULL) {
  198. return FALSE;
  199. }
  200. HTREEITEM hItemSibling = TreeView_GetNextSibling(m_hLibraryTree, hItemDB);
  201. if (hItemSibling == NULL) {
  202. hItemSibling = TreeView_GetPrevSibling(m_hLibraryTree, hItemDB);
  203. }
  204. if (hItemSibling == NULL) {
  205. //
  206. // This was the last database, the database item gets deleted with the parent
  207. //
  208. HTREEITEM hItemParent = TreeView_GetParent(m_hLibraryTree, hItemDB);
  209. assert(hItemParent);
  210. TreeView_DeleteItem(m_hLibraryTree, hItemParent);
  211. if (typeDB == DATABASE_TYPE_WORKING) {
  212. m_hItemAllWorking = NULL;
  213. g_uNextDataBaseIndex = 0;
  214. } else {
  215. m_hItemAllInstalled = NULL;
  216. }
  217. return TRUE;
  218. }
  219. TreeView_DeleteItem(m_hLibraryTree, hItemDB);
  220. return TRUE;
  221. }
  222. void
  223. DatabaseTree::RemoveAllWorking(
  224. void
  225. )
  226. /*++
  227. DatabaseTree::RemoveAllWorking
  228. Desc: Delete all the working databases tree items
  229. --*/
  230. {
  231. TreeView_DeleteItem(m_hLibraryTree, m_hItemAllWorking);
  232. }
  233. BOOL
  234. DatabaseTree::SetLParam(
  235. IN HTREEITEM hItem,
  236. IN LPARAM lParam
  237. )
  238. /*++
  239. DatabaseTree::SetLParam
  240. Desc: Sets the lParam of a tree item
  241. Params:
  242. IN HTREEITEM hItem: The hItem for the db tree item for which we want to
  243. set the lParam
  244. IN LPARAM lParam: The lParam to set
  245. Return:
  246. TRUE: Successful
  247. FALSE: Error
  248. --*/
  249. {
  250. TVITEM Item;
  251. Item.mask = TVIF_PARAM;
  252. Item.hItem = hItem;
  253. Item.lParam = lParam;
  254. return TreeView_SetItem(m_hLibraryTree, &Item);
  255. }
  256. BOOL
  257. DatabaseTree::GetLParam(
  258. IN HTREEITEM hItem,
  259. OUT LPARAM* plParam
  260. )
  261. /*++
  262. DatabaseTree::GetLParam
  263. Desc: Gets the lParam of a tree item
  264. Params:
  265. IN HTREEITEM hItem: The hItem for which we want to get the lParam
  266. OUT LPARAM* plParam: This will store the lParams for the tree item
  267. Return:
  268. TRUE: Successful
  269. FALSE: Error
  270. --*/
  271. {
  272. TVITEM Item;
  273. if (plParam == NULL) {
  274. assert(FALSE);
  275. return FALSE;
  276. }
  277. *plParam = 0;
  278. Item.mask = TVIF_PARAM;
  279. Item.hItem = hItem;
  280. if (TreeView_GetItem(m_hLibraryTree, &Item)) {
  281. *plParam = Item.lParam;
  282. return TRUE;
  283. }
  284. return FALSE;
  285. }
  286. HTREEITEM
  287. DatabaseTree::FindChild(
  288. IN HTREEITEM hItemParent,
  289. IN LPARAM lParam
  290. )
  291. /*++
  292. DatabaseTree::FindChild
  293. Desc: Given a parent item and a lParam, finds the first child of the parent, with
  294. that value of lParam. This function only searches in the next level and not all
  295. the generations of the parent
  296. Params:
  297. IN HTREEITEM hItemParent: The tree item whose child we want to search
  298. IN LPARAM lParam: The lParam of the child item should match this
  299. Return: The handle to the child or NULL if it does not exist
  300. --*/
  301. {
  302. HWND hwndTree = m_hLibraryTree;
  303. HTREEITEM hItem = TreeView_GetChild(hwndTree, hItemParent);
  304. while (hItem) {
  305. LPARAM lParamOfItem;
  306. if (!GetLParam (hItem, &lParamOfItem)) {
  307. return NULL;
  308. }
  309. if (lParamOfItem == lParam) {
  310. return hItem;
  311. } else {
  312. hItem = TreeView_GetNextSibling(hwndTree, hItem);
  313. }
  314. }
  315. return NULL;
  316. }
  317. HTREEITEM
  318. DatabaseTree::GetAllAppsItem(
  319. IN HTREEITEM hItemDataBase
  320. )
  321. /*++
  322. DatabaseTree::GetAllAppsItem
  323. Desc: Given the handle to the database item, finds the handle for the "Applications"
  324. item.
  325. Params:
  326. IN HTREEITEM hItemDataBase: The handle to the database tree item
  327. Return: The proper value of the handle or NULL if it does not exist.
  328. --*/
  329. {
  330. HTREEITEM hItem = TreeView_GetChild(m_hLibraryTree, hItemDataBase);
  331. TVITEM Item;
  332. while (hItem) {
  333. Item.mask = TVIF_PARAM;
  334. Item.hItem = hItem;
  335. if (!TreeView_GetItem(m_hLibraryTree, &Item)) {
  336. assert(FALSE);
  337. hItem = NULL;
  338. break;
  339. }
  340. TYPE type = (TYPE)Item.lParam;
  341. if (type == TYPE_GUI_APPS) {
  342. break;
  343. } else {
  344. hItem = TreeView_GetNextSibling(m_hLibraryTree, hItem);
  345. }
  346. }
  347. return hItem;
  348. }
  349. HTREEITEM
  350. DatabaseTree::GetFirstAppItem(
  351. IN HTREEITEM hItemDataBase
  352. )
  353. /*++
  354. DatabaseTree::GetFirstAppItem
  355. Desc: The handle to the first application's item; given the database tree item.
  356. Params:
  357. IN HTREEITEM hItemDataBase: The handle to the database tree item
  358. Return: The proper value or NULL if there is no application for this database
  359. --*/
  360. {
  361. HTREEITEM hItem = GetAllAppsItem(hItemDataBase);
  362. if (hItem == NULL) {
  363. return NULL;
  364. }
  365. return TreeView_GetChild(m_hLibraryTree, hItem);
  366. }
  367. void
  368. DatabaseTree::AddNewLayer(
  369. IN PDATABASE pDataBase,
  370. IN PLAYER_FIX pLayer,
  371. IN BOOL bShow //(FALSE)
  372. )
  373. /*++
  374. DatabaseTree::AddNewLayer
  375. Desc: Adds a new layer tree item in the tree for the database: pDatabase
  376. The layer is specified by pLayer.
  377. This routine might create the root of all layers: "Compatibility Modes", if
  378. it does not exist.
  379. Params:
  380. IN PDATABASE pDataBase: The database for which we want to add the new layer
  381. IN PLAYER_FIX pLayer: The layer
  382. IN BOOL bShow (FALSE): Should we set the focus to the layer after it is created
  383. Return:
  384. void
  385. --*/
  386. {
  387. TVINSERTSTRUCT is;
  388. if (!pDataBase || !(pDataBase->hItemDB)) {
  389. assert(FALSE);
  390. return;
  391. }
  392. if (pDataBase->hItemAllLayers == NULL) {
  393. //
  394. // Create a new root of all layers: "Compatibility Modes".
  395. //
  396. is.hParent = pDataBase->hItemDB;
  397. is.hInsertAfter = TVI_SORT;
  398. is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE ;
  399. is.item.stateMask = TVIS_EXPANDED;
  400. is.item.lParam = TYPE_GUI_LAYERS;
  401. is.item.pszText = GetString(IDS_COMPATMODES);
  402. is.item.iImage = IMAGE_LAYERS;
  403. is.item.iSelectedImage = IMAGE_LAYERS;
  404. pDataBase->hItemAllLayers = TreeView_InsertItem(m_hLibraryTree, &is);
  405. pDataBase->uLayerCount = 0;
  406. }
  407. pDataBase->uLayerCount++;
  408. InsertLayerinTree(pDataBase->hItemAllLayers, pLayer, m_hLibraryTree, bShow);
  409. }
  410. void
  411. DatabaseTree::RefreshAllLayers(
  412. IN PDATABASE pDataBase
  413. )
  414. /*++
  415. DatabaseTree::RefreshAllLayers
  416. Desc: Redraws all the layer tree item for the database pDataBase.
  417. This may be required when we have edited some layer
  418. Params:
  419. IN PDATABASE pDataBase: The database whose layers we want to refresh
  420. Return:
  421. void
  422. --*/
  423. {
  424. if (pDataBase == NULL) {
  425. assert(FALSE);
  426. return;
  427. }
  428. PLAYER_FIX plfTemp = pDataBase->pLayerFixes;
  429. SendMessage(m_hLibraryTree, WM_SETREDRAW, FALSE , 0);
  430. while (plfTemp) {
  431. RefreshLayer(pDataBase, plfTemp);
  432. plfTemp = plfTemp->pNext;
  433. }
  434. SendMessage(m_hLibraryTree, WM_SETREDRAW, TRUE , 0);
  435. }
  436. HTREEITEM
  437. DatabaseTree::RefreshLayer(
  438. IN PDATABASE pDataBase,
  439. IN PLAYER_FIX pLayer
  440. )
  441. /*++
  442. DatabaseTree::RefreshLayer
  443. Desc: Redraws the tree item for the layer: pLayer in database pDataBase.
  444. First removes the tree item and adds it again
  445. Params:
  446. IN PDATABASE pDataBase: Database in which the layer exists
  447. IN PLAYER_FIX pLayer: The layer to be refreshed
  448. Return: The HTREEITEM for pLayer if it was found or NULL
  449. --*/
  450. {
  451. if (!pDataBase || !(pDataBase->hItemAllLayers)) {
  452. assert(FALSE);
  453. return NULL;
  454. }
  455. HTREEITEM hItem = TreeView_GetChild(m_hLibraryTree, pDataBase->hItemAllLayers);
  456. while (hItem) {
  457. PLAYER_FIX pLayerExist;
  458. LPARAM lParam;
  459. if (GetLParam(hItem, &lParam)) {
  460. pLayerExist = (PLAYER_FIX)lParam;
  461. if (pLayerExist == pLayer) {
  462. TreeView_DeleteItem(m_hLibraryTree, hItem);
  463. InsertLayerinTree(pDataBase->hItemAllLayers,
  464. pLayer,
  465. m_hLibraryTree,
  466. TRUE);
  467. break;
  468. } else {
  469. hItem = TreeView_GetNextSibling(m_hLibraryTree, hItem);
  470. }
  471. } else {
  472. //
  473. // Error:
  474. //
  475. return NULL;
  476. }
  477. }
  478. return hItem;
  479. }
  480. BOOL
  481. DatabaseTree::AddNewExe(
  482. IN PDATABASE pDataBase,
  483. IN PDBENTRY pEntry,
  484. IN PDBENTRY pApp,
  485. IN BOOL bRepaint // (TRUE)
  486. )
  487. /*++
  488. DatabaseTree::AddNewExe
  489. Desc: Adds a new exe entry in the apps Tree. First finds the database tree item
  490. under the list of working database , then if pApp is NULL, checks if the Apps
  491. htree item is there or not, If not creates a new item
  492. If the pApp is not NULL, then we select that app. And add the exe in the EXE tree
  493. and set the focus to it.
  494. Params:
  495. IN PDATABASE pDataBase: The database in which we wan to add the new entry
  496. IN PDBENTRY pEntry: The entry to add
  497. IN PDBENTRY pApp: The app of the entry
  498. IN BOOL bRepaint (TRUE): <TODO>
  499. Return:
  500. TRUE: Added successfully
  501. FALSE: There was some error
  502. --*/
  503. {
  504. if (!pEntry || !pDataBase) {
  505. assert(FALSE);
  506. return FALSE;
  507. }
  508. HTREEITEM hItemDB = pDataBase->hItemDB, hItem;
  509. HTREEITEM hItemAllApps = pDataBase->hItemAllApps;
  510. TVINSERTSTRUCT is;
  511. SendMessage(g_hwndEntryTree, WM_SETREDRAW, TRUE, 0);
  512. assert(m_hItemAllWorking);
  513. assert(hItemDB);
  514. if (hItemAllApps == NULL) {
  515. is.hParent = hItemDB;
  516. is.hInsertAfter = TVI_SORT;
  517. is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  518. is.item.stateMask = TVIS_EXPANDED;
  519. is.item.lParam = TYPE_GUI_APPS;
  520. is.item.pszText = GetString(IDS_APPS);
  521. is.item.iImage = IMAGE_APP;
  522. is.item.iSelectedImage = IMAGE_APP;
  523. HTREEITEM hItemApp = TreeView_InsertItem(m_hLibraryTree, &is);
  524. g_pPresentDataBase->hItemAllApps = hItemApp;
  525. }
  526. if (pApp == NULL) {
  527. is.hParent = g_pPresentDataBase->hItemAllApps;
  528. is.hInsertAfter = TVI_SORT;
  529. is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE ;
  530. is.item.stateMask = TVIS_EXPANDED;
  531. is.item.lParam = (LPARAM)pEntry;
  532. is.item.pszText = pEntry->strAppName;
  533. is.item.iImage = IMAGE_SINGLEAPP;
  534. is.item.iSelectedImage = IMAGE_SINGLEAPP;
  535. hItem = TreeView_InsertItem(m_hLibraryTree, &is);
  536. g_pSelEntry = g_pEntrySelApp = pEntry;
  537. TreeView_SelectItem(m_hLibraryTree, hItem);
  538. return TRUE;
  539. }
  540. //
  541. // Now loop through all the apps and then find the app for this exe
  542. //
  543. hItem = TreeView_GetChild(m_hLibraryTree, hItemAllApps);
  544. while (hItem) {
  545. LPARAM lParam;
  546. if (!GetLParam(hItem, &lParam)) {
  547. assert(FALSE);
  548. break;
  549. }
  550. if ((PDBENTRY)lParam == pApp) {
  551. TVITEM Item;
  552. Item.mask = TVIF_PARAM;
  553. Item.lParam = (LPARAM)pEntry;
  554. Item.hItem = hItem;
  555. TreeView_SetItem(m_hLibraryTree, &Item);
  556. //
  557. // This entry was added in the beginning of the list. TODO This can be removed
  558. //
  559. g_pEntrySelApp = pEntry;
  560. if (TreeView_GetSelection(m_hLibraryTree) != hItem && bRepaint) {
  561. //
  562. // Focus is on some other App. Select this app
  563. //
  564. TreeView_SelectItem(m_hLibraryTree, hItem);
  565. //
  566. // The above will refresh the EXE Tree and call a UpdateEntryTreeView(). That will
  567. // add the pEntry to the tree and set a valid pEntry->hItemExe, which we can now select
  568. //
  569. TreeView_SelectItem(g_hwndEntryTree, pEntry->hItemExe);
  570. } else {
  571. //
  572. // Add the exe in the EXE tree and set the focus to it. The focus is on this app.
  573. //
  574. AddSingleEntry(g_hwndEntryTree, pEntry);
  575. if (bRepaint) {
  576. TreeView_SelectItem(g_hwndEntryTree, pEntry->hItemExe);
  577. }
  578. }
  579. //
  580. // This entry was added in the beginning of the list
  581. //
  582. g_pSelEntry = pEntry;
  583. return TRUE;
  584. }
  585. hItem = TreeView_GetNextSibling(m_hLibraryTree, hItem);
  586. }
  587. if (bRepaint) {
  588. SendMessage(g_hwndEntryTree, WM_SETREDRAW, TRUE, 0);
  589. }
  590. return FALSE;
  591. }
  592. BOOL
  593. DatabaseTree::AddInstalled(
  594. IN PDATABASE pDataBase
  595. )
  596. /*++
  597. DatabaseTree::AddInstalled
  598. Desc: Adds a New installed database under the "installed databases" tree item in the
  599. database tree.
  600. If the root of all installed databases: "Installed databases" is not present
  601. this routine first of all adds that.
  602. Params:
  603. IN PDATABASE pDataBase: The installed database to be shown in the db tree
  604. Return:
  605. TRUE: Added successfully
  606. FALSE: There was some error
  607. --*/
  608. {
  609. TVINSERTSTRUCT is;
  610. is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE ;
  611. is.item.stateMask = TVIS_EXPANDED;
  612. if (m_hItemAllInstalled == NULL) {
  613. //
  614. // Add the Parent tree item for all the Installed DBs tree items
  615. //
  616. is.hParent = TVI_ROOT;
  617. is.hInsertAfter = m_hItemGlobal;
  618. is.item.lParam = TYPE_GUI_DATABASE_INSTALLED_ALL;
  619. is.item.pszText = GetString(IDS_INSTALLEDDB);
  620. is.item.iImage = IMAGE_INSTALLED;
  621. is.item.iSelectedImage = IMAGE_INSTALLED;
  622. m_hItemAllInstalled = TreeView_InsertItem(m_hLibraryTree, &is);
  623. }
  624. is.hInsertAfter = TVI_SORT;
  625. //
  626. // Now Add the installed dataBase
  627. //
  628. is.hInsertAfter = TVI_SORT;
  629. is.hParent = m_hItemAllInstalled;
  630. is.item.lParam = (LPARAM)pDataBase;
  631. is.item.pszText = pDataBase->strName;
  632. is.item.iImage = IMAGE_DATABASE;
  633. is.item.iSelectedImage = IMAGE_DATABASE;
  634. HTREEITEM hItemDB = TreeView_InsertItem(m_hLibraryTree, &is);
  635. if (!PopulateLibraryTree(hItemDB, pDataBase)) {
  636. return FALSE;
  637. }
  638. pDataBase->hItemDB = hItemDB;
  639. return TRUE;
  640. }
  641. void
  642. DatabaseTree::DeleteAppLayer(
  643. IN PDATABASE pDataBase,
  644. IN BOOL bApp,
  645. IN HTREEITEM hItemDelete,
  646. IN BOOL bRepaint // (TRUE)
  647. )
  648. /*++
  649. DatabaseTree::DeleteAppLayer
  650. Desc: This function is to be used for deleting apps and layers.
  651. Give the focus to the prev or the next sibling. If neither exist, delete the
  652. parent and give the focus to the grandparent.
  653. Params:
  654. IN PDATABASE pDataBase: The database in which the app or layer to be deleted resides
  655. IN BOOL bApp: Is it an app or a layer?
  656. IN HTREEITEM hItemDelete: The tree item to be deleted
  657. IN BOOL bRepaint (TRUE): Not used
  658. Warning:
  659. *************************************************************************
  660. The actual layer or app has already been deleted before calling this function.
  661. So do not get the lParam and do any stuff with it. Do not call GetItemType for
  662. the hItemDelete
  663. *************************************************************************
  664. --*/
  665. {
  666. HTREEITEM hItemPrev = NULL,
  667. hItemNext = NULL,
  668. hParent = NULL,
  669. hGrandParent = NULL;
  670. LPARAM lParam = NULL;
  671. TYPE type = TYPE_UNKNOWN;
  672. hItemPrev = TreeView_GetPrevSibling(m_hLibraryTree, hItemDelete);
  673. HTREEITEM hItemShow;
  674. if (hItemPrev != NULL) {
  675. hItemShow = hItemPrev;
  676. } else {
  677. hItemNext = TreeView_GetNextSibling(m_hLibraryTree, hItemDelete);
  678. if (hItemNext != NULL) {
  679. hItemShow = hItemNext;
  680. } else {
  681. //
  682. // Now delete the parent and set the focus to the grandparent
  683. //
  684. if (bApp) {
  685. pDataBase->hItemAllApps = NULL;
  686. } else {
  687. pDataBase->hItemAllLayers = NULL;
  688. }
  689. hParent = TreeView_GetParent(m_hLibraryTree, hItemDelete);
  690. hGrandParent = TreeView_GetParent(m_hLibraryTree, hItemDelete);
  691. hItemDelete = hParent;
  692. hItemShow = hGrandParent;
  693. }
  694. }
  695. SetStatusStringDBTree(TreeView_GetParent(m_hLibraryTree, hItemDelete));
  696. TreeView_DeleteItem(m_hLibraryTree, hItemDelete);
  697. if (bRepaint) {
  698. //
  699. // Tree view automatically selects the next element or the parent it there is no next.
  700. //
  701. SetFocus(m_hLibraryTree);
  702. }
  703. }
  704. void
  705. DatabaseTree::InsertLayerinTree(
  706. IN HTREEITEM hItemLayers,
  707. IN PLAYER_FIX plf,
  708. IN HWND hwndTree, // (NULL)
  709. IN BOOL bShow // (FALSE)
  710. )
  711. /*++
  712. DatabaseTree::InsertLayerinTree
  713. Desc: Given a single layer, it adds it under "Compatibility Modes" tree item for that database
  714. It assumes that the parent "Compatibility Modes" tree item is already present
  715. Params:
  716. IN HTREEITEM hItemLayers: The all layers item for the database
  717. IN PLAYER_FIX plf: The layer that we are adding
  718. IN HWND hwndTree (NULL): The tree
  719. IN BOOL bShow (FALSE): If true will select the newly added layer
  720. --*/
  721. {
  722. if (hwndTree == NULL) {
  723. hwndTree = m_hLibraryTree;
  724. }
  725. if (plf == NULL) {
  726. assert(FALSE);
  727. Dbg(dlError, "DatabaseTree::InsertLayerinTree Invalid parameter");
  728. return;
  729. }
  730. TVINSERTSTRUCT is;
  731. is.hInsertAfter = TVI_SORT;
  732. is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  733. is.item.stateMask = TVIS_EXPANDED;
  734. is.hParent = hItemLayers ;
  735. is.item.lParam = (LPARAM)plf ;
  736. is.item.pszText = plf->strName;
  737. is.item.iImage = IMAGE_LAYERS;
  738. is.item.iSelectedImage = IMAGE_LAYERS;
  739. HTREEITEM hSingleLayer = TreeView_InsertItem(hwndTree, &is);
  740. //
  741. // Add the shims for this Layer
  742. //
  743. PSHIM_FIX_LIST pShimFixList = plf->pShimFixList;
  744. PFLAG_FIX_LIST pFlagFixList = plf->pFlagFixList;
  745. if (pShimFixList || pFlagFixList) {
  746. while (pShimFixList) {
  747. is.hInsertAfter = TVI_SORT;
  748. assert(pShimFixList->pShimFix != NULL);
  749. is.hParent = hSingleLayer;
  750. is.item.pszText = pShimFixList->pShimFix->strName;
  751. is.item.lParam = (LPARAM)pShimFixList->pShimFix;
  752. is.item.iImage = IMAGE_SHIM;
  753. is.item.iSelectedImage = IMAGE_SHIM;
  754. HTREEITEM hSingleShimInLayer = TreeView_InsertItem(hwndTree, &is);
  755. //
  756. // Add the Include and Exclude list for this shim (Expert mode only)
  757. //
  758. if (!pShimFixList->strlInExclude.IsEmpty() && g_bExpert) {
  759. is.hParent = hSingleShimInLayer;
  760. is.hInsertAfter = TVI_LAST;
  761. PSTRLIST listTemp = pShimFixList->strlInExclude.m_pHead;
  762. while (listTemp) {
  763. if (listTemp->data == INCLUDE) {
  764. is.item.iImage = IMAGE_INCLUDE;
  765. is.item.iSelectedImage = IMAGE_INCLUDE;
  766. is.item.lParam = TYPE_GUI_INCLUDE;
  767. } else {
  768. is.item.iImage = IMAGE_EXCLUDE;
  769. is.item.iSelectedImage = IMAGE_EXCLUDE;
  770. is.item.lParam = TYPE_GUI_EXCLUDE;
  771. }
  772. is.item.pszText = listTemp->szStr;
  773. listTemp = listTemp->pNext;
  774. TreeView_InsertItem(m_hLibraryTree, &is);
  775. }
  776. }
  777. if (pShimFixList->strCommandLine.Length() > 0 && g_bExpert) {
  778. //
  779. // Add the commandline for this shim in the layer.
  780. //
  781. CSTRING str;
  782. str.Sprintf(CSTRING(IDS_COMMANDLINE), pShimFixList->strCommandLine);
  783. is.hParent = hSingleShimInLayer;
  784. is.item.lParam = TYPE_GUI_COMMANDLINE;
  785. is.item.pszText = str;
  786. is.item.iImage = IMAGE_COMMANDLINE;
  787. is.item.iSelectedImage = IMAGE_COMMANDLINE;
  788. TreeView_InsertItem(hwndTree, &is);
  789. }
  790. pShimFixList = pShimFixList->pNext;
  791. }
  792. }
  793. is.hInsertAfter = TVI_SORT;
  794. //
  795. // Add the Flags for this Layer. Flags are also shown under the "Compatibility Fixes" parent
  796. // and they have the same icon as the compatibility fixes.
  797. //
  798. if (pFlagFixList) {
  799. while (pFlagFixList) {
  800. assert(pFlagFixList->pFlagFix != NULL);
  801. is.hParent = hSingleLayer;
  802. is.item.iImage = IMAGE_SHIM;
  803. is.item.iSelectedImage = IMAGE_SHIM;
  804. is.item.pszText = pFlagFixList->pFlagFix->strName;
  805. is.item.lParam = (LPARAM)pFlagFixList->pFlagFix;
  806. HTREEITEM hSingleFlagInLayer = TreeView_InsertItem(hwndTree, &is);
  807. if (g_bExpert && pFlagFixList->strCommandLine.Length() > 0) {
  808. //
  809. // Add the commandline for this flag in the layer.
  810. //
  811. CSTRING str;
  812. str.Sprintf(CSTRING(IDS_COMMANDLINE), pFlagFixList->strCommandLine);
  813. is.hParent = hSingleFlagInLayer;
  814. is.item.lParam = TYPE_GUI_COMMANDLINE;
  815. is.item.pszText = str;
  816. is.item.iImage = IMAGE_COMMANDLINE;
  817. is.item.iSelectedImage = IMAGE_COMMANDLINE;
  818. TreeView_InsertItem(hwndTree, &is);
  819. }
  820. pFlagFixList = pFlagFixList->pNext;
  821. }
  822. }
  823. if (bShow) {
  824. TreeView_SelectItem(m_hLibraryTree, hSingleLayer);
  825. }
  826. }
  827. BOOL
  828. DatabaseTree::PopulateLibraryTree(
  829. IN HTREEITEM hRoot,
  830. IN PDATABASE pDataBase,
  831. IN BOOL bLoadOnlyLibrary, // (FALSE)
  832. IN BOOL bLoadOnlyApps // (FALSE)
  833. )
  834. /*++
  835. DatabaseTree::PopulateLibraryTree
  836. Desc: This does the bulk of work of loading a database into the tree
  837. Params:
  838. IN HTREEITEM hRoot: This will be the handle for either the "System Database"
  839. or the "Working Databases" or the "Installed Databases" tree item, depending upon where we want
  840. to add the new database tree item. This is therefore the parent of the database tree item
  841. that we are going to add
  842. IN PDATABASE pDataBase: The database that is being loaded
  843. IN BOOL bLoadOnlyLibrary (FALSE): We do not want the apps to be loaded into the tree
  844. This is used, when we initially load the system DB
  845. IN BOOL bLoadOnlyApps (FALSE): We only want the apps to be loaded into the tree.
  846. This is used, when we load the apps for the sys DB
  847. --*/
  848. {
  849. HTREEITEM hItemShims;
  850. HTREEITEM hItemLayers;
  851. TVINSERTSTRUCT is;
  852. SendMessage(m_hLibraryTree, WM_SETREDRAW, FALSE, 0);
  853. //
  854. // Default settings
  855. //
  856. is.hInsertAfter = TVI_SORT;
  857. is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  858. is.item.stateMask = 0;
  859. is.item.lParam = 0;
  860. if (bLoadOnlyApps == TRUE) {
  861. goto LoadApps;
  862. }
  863. //
  864. // Populate with the shims
  865. //
  866. if (pDataBase->pShimFixes != NULL || pDataBase->pFlagFixes != NULL) {
  867. is.hParent = hRoot;
  868. is.item.lParam = TYPE_GUI_SHIMS;
  869. is.item.pszText = GetString(IDS_COMPATFIXES);
  870. is.item.iImage = IMAGE_SHIM;
  871. is.item.iSelectedImage = IMAGE_SHIM;
  872. hItemShims = TreeView_InsertItem(m_hLibraryTree, &is);
  873. PSHIM_FIX psf = pDataBase->pShimFixes;
  874. while (psf) {
  875. //
  876. // Show only general shims
  877. //
  878. if (psf->bGeneral == FALSE && !g_bExpert) {
  879. psf = psf->pNext;
  880. continue;
  881. }
  882. is.hParent = hItemShims;
  883. is.hInsertAfter = TVI_SORT;
  884. is.item.lParam = (LPARAM)psf;
  885. is.item.pszText = psf->strName;
  886. is.item.iImage = IMAGE_SHIM;
  887. is.item.iSelectedImage = IMAGE_SHIM;
  888. HTREEITEM hItemSingleShim = TreeView_InsertItem(m_hLibraryTree, &is);
  889. if (hItemSingleShim == NULL) {
  890. Dbg(dlError, "Failed to add a individual shim in TreePopulate");
  891. return FALSE;
  892. } else {
  893. //
  894. // Add the Include and Exclude list for this shim (Expert mode only)
  895. //
  896. if (!psf->strlInExclude.IsEmpty() && g_bExpert) {
  897. is.hParent = hItemSingleShim;
  898. is.hInsertAfter = TVI_LAST;
  899. PSTRLIST listTemp = psf->strlInExclude.m_pHead;
  900. while (listTemp) {
  901. if (listTemp->data == INCLUDE) {
  902. is.item.iImage = IMAGE_INCLUDE;
  903. is.item.iSelectedImage = IMAGE_INCLUDE;
  904. is.item.lParam = TYPE_GUI_INCLUDE;
  905. } else {
  906. is.item.iImage = IMAGE_EXCLUDE;
  907. is.item.iSelectedImage = IMAGE_EXCLUDE;
  908. is.item.lParam = TYPE_GUI_EXCLUDE;
  909. }
  910. is.item.pszText = listTemp->szStr;
  911. listTemp = listTemp->pNext;
  912. TreeView_InsertItem(m_hLibraryTree, &is);
  913. }
  914. }
  915. //
  916. // Now add the command line
  917. //
  918. if (psf->strCommandLine.Length() > 0 && g_bExpert) {
  919. is.hParent = hItemSingleShim;
  920. is.item.lParam = TYPE_GUI_COMMANDLINE;
  921. CSTRING str;
  922. str.Sprintf(CSTRING(IDS_COMMANDLINE), psf->strCommandLine);
  923. is.item.pszText = str;
  924. is.item.iImage = IMAGE_COMMANDLINE;
  925. is.item.iSelectedImage = IMAGE_COMMANDLINE;
  926. TreeView_InsertItem(m_hLibraryTree, &is);
  927. }
  928. }
  929. psf = psf->pNext;
  930. }
  931. //
  932. // Put the Flags now, this time under the shims icon
  933. //
  934. is.hInsertAfter = TVI_SORT;
  935. if (pDataBase->pFlagFixes != NULL) {
  936. is.hParent = hItemShims;
  937. is.item.iImage = IMAGE_SHIM;
  938. is.item.iSelectedImage = IMAGE_SHIM;
  939. PFLAG_FIX pff = pDataBase->pFlagFixes;
  940. while (pff) {
  941. if (pff->bGeneral || g_bExpert) {
  942. is.item.lParam = (LPARAM)pff;
  943. is.item.pszText = pff->strName;
  944. TreeView_InsertItem(m_hLibraryTree, &is);
  945. }
  946. pff = pff->pNext;
  947. }
  948. }
  949. }
  950. //
  951. // Now populate the layers.
  952. //
  953. if (pDataBase->pLayerFixes != NULL) {
  954. is.hParent = hRoot;
  955. is.item.lParam = TYPE_GUI_LAYERS;
  956. is.item.iImage = IMAGE_LAYERS;
  957. is.item.iSelectedImage = IMAGE_LAYERS;
  958. is.item.pszText = GetString(IDS_COMPATMODES);
  959. hItemLayers = TreeView_InsertItem(m_hLibraryTree, &is);
  960. pDataBase->hItemAllLayers = hItemLayers;
  961. PLAYER_FIX plf = pDataBase->pLayerFixes;
  962. while (plf) {
  963. InsertLayerinTree(hItemLayers, plf, FALSE);
  964. plf = plf->pNext;
  965. }
  966. }
  967. LoadApps:
  968. //
  969. // Now add the Apps
  970. //
  971. if (pDataBase->pEntries && !bLoadOnlyLibrary) {
  972. is.hParent = hRoot;
  973. is.item.lParam = TYPE_GUI_APPS;
  974. is.item.pszText = GetString(IDS_APPS);
  975. is.item.iImage = IMAGE_APP;
  976. is.item.iSelectedImage = IMAGE_APP;
  977. if (pDataBase->type != DATABASE_TYPE_GLOBAL) {
  978. pDataBase->hItemAllApps = TreeView_InsertItem(m_hLibraryTree, &is);
  979. }
  980. PDBENTRY pApps = pDataBase->pEntries;
  981. while (pApps) {
  982. is.hParent = pDataBase->hItemAllApps;
  983. is.item.lParam = (LPARAM)pApps;
  984. is.item.pszText = pApps->strAppName;
  985. is.item.iImage = IMAGE_SINGLEAPP;
  986. is.item.iSelectedImage = IMAGE_SINGLEAPP;
  987. TreeView_InsertItem(m_hLibraryTree, &is);
  988. pApps = pApps->pNext;
  989. }
  990. }
  991. SendMessage(m_hLibraryTree, WM_SETREDRAW, TRUE, 0);
  992. return TRUE;
  993. }
  994. void
  995. DatabaseTree::AddApp(
  996. IN PDATABASE pDatabase,
  997. IN PDBENTRY pApp,
  998. IN BOOL bUpdate // (TRUE)
  999. )
  1000. /*++
  1001. DatabaseTree::AddApp
  1002. Desc: If there is no app for
  1003. pApp->strApp: Adds a new app entry in the db tree for the database
  1004. Otherwise, it sets the lParam of the existing entry to pApp.
  1005. Calls UpdateEntryTree() after this
  1006. Params:
  1007. IN PDATABASE pDatabase: The database in which this app has been added
  1008. IN PDBENTRY pApp: The app that is to be added to the tree
  1009. IN BOOL bUpdate (TRUE): Should we set the focus to the new tree item
  1010. Return:
  1011. void
  1012. --*/
  1013. {
  1014. if (pDatabase == NULL) {
  1015. assert(FALSE);
  1016. return;
  1017. }
  1018. HTREEITEM hItem = pDatabase->hItemAllApps;
  1019. TVITEM tvitem;
  1020. TCHAR szBuffer[MAX_PATH];
  1021. if (pDatabase->hItemAllApps == NULL) {
  1022. AddNewExe(pDatabase, pApp, NULL, bUpdate);
  1023. return;
  1024. }
  1025. //
  1026. // Search for the app-name
  1027. //
  1028. hItem = TreeView_GetChild(m_hLibraryTree, hItem);
  1029. tvitem.mask = TVIF_TEXT;
  1030. tvitem.pszText = szBuffer;
  1031. tvitem.cchTextMax = ARRAYSIZE(szBuffer);
  1032. while (hItem) {
  1033. tvitem.hItem = hItem;
  1034. *szBuffer = 0;
  1035. if (!TreeView_GetItem(m_hLibraryTree, &tvitem)) {
  1036. assert(FALSE);
  1037. goto Next;
  1038. }
  1039. if (lstrcmpi(szBuffer, pApp->strAppName) == 0) {
  1040. //
  1041. // This is the app name
  1042. //
  1043. SetLParam(hItem, (LPARAM)pApp);
  1044. if (bUpdate) {
  1045. //
  1046. // This entry was added in the beginning of the list
  1047. //
  1048. TreeView_SelectItem(m_hLibraryTree, hItem);
  1049. g_pEntrySelApp = pApp;
  1050. g_pSelEntry = pApp;
  1051. UpdateEntryTreeView(pApp, g_hwndEntryTree);
  1052. }
  1053. return;
  1054. }
  1055. Next:
  1056. hItem = TreeView_GetNextSibling(m_hLibraryTree, hItem);
  1057. }
  1058. //
  1059. // There is no entry with this app-name uder the apps of the database
  1060. //
  1061. AddNewExe(pDatabase, pApp, NULL, bUpdate);
  1062. }
  1063. HTREEITEM
  1064. DatabaseTree::GetSelection(
  1065. void
  1066. )
  1067. /*++
  1068. DatabaseTree::GetSelection
  1069. Desc: Returns the selected item in the db tree.
  1070. Return: Returns the selected item in the db tree.
  1071. --*/
  1072. {
  1073. return TreeView_GetSelection(m_hLibraryTree);
  1074. }