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.

2248 lines
64 KiB

  1. /*++
  2. Copyright (c) 1989-2001 Microsoft Corporation
  3. Module Name:
  4. customlayer.cpp
  5. Abstract:
  6. Code for creating, removing and editing custom layers
  7. Author:
  8. kinshu created July 2, 2001
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. //////////////////////// Extern variables /////////////////////////////////////
  13. extern HWND g_hDlg;
  14. extern HINSTANCE g_hInstance;
  15. extern HIMAGELIST g_hImageList;
  16. extern DatabaseTree DBTree;
  17. extern struct DataBase GlobalDataBase;
  18. ///////////////////////////////////////////////////////////////////////////////
  19. //////////////////////// Global Variables /////////////////////////////////////
  20. // Pointer to the instance of CCustomLayer
  21. CCustomLayer* g_pCustomLayer;
  22. //
  23. // The layer that was passed to us through the lParam when we created the dialog.
  24. // If we are editing a layer, this will point to the layer being modified. If we want to
  25. // create a new layer, the caller of the dialog box, creates a new layer and passes the pointer
  26. // to that while calling the dialog box. If user presses cancel when creating a new layer, caller
  27. // must free the new layer.
  28. static PLAYER_FIX s_pLayerParam = NULL;
  29. ///////////////////////////////////////////////////////////////////////////////
  30. //////////////////////// Function Declarations ///////////////////////////////
  31. void
  32. ResizeControls(
  33. HWND hdlg
  34. );
  35. void
  36. RemoveAll(
  37. HWND hDlg
  38. );
  39. void
  40. SetOkParamsStatus(
  41. HWND hdlg
  42. );
  43. BOOL
  44. HandleNotifyShimList(
  45. HWND hDlg,
  46. LPARAM lParam
  47. );
  48. BOOL
  49. HandleNotifyLayerList(
  50. HWND hDlg,
  51. LPARAM lParam
  52. );
  53. void
  54. ShowParams(
  55. HWND hDlg,
  56. HWND hwndList
  57. );
  58. void
  59. RemoveSingleItem(
  60. HWND hdlg,
  61. INT iIndex,
  62. BOOL bOnlySelected
  63. );
  64. void
  65. OnCopy(
  66. HWND hdlg
  67. );
  68. void
  69. LoadCombo(
  70. HWND hdlg
  71. );
  72. INT_PTR
  73. CALLBACK
  74. CustomLayerProc(
  75. HWND hDlg,
  76. UINT uMsg,
  77. WPARAM wParam,
  78. LPARAM lParam
  79. );
  80. INT_PTR
  81. CALLBACK
  82. ChooseLayersProc(
  83. HWND hDlg,
  84. UINT uMsg,
  85. WPARAM wParam,
  86. LPARAM lParam
  87. );
  88. void
  89. OnDone(
  90. HWND hDlg,
  91. PLAYER_FIX pLayerParam
  92. );
  93. void
  94. PopulateLists(
  95. HWND hdlg,
  96. PLAYER_FIX pLayerParam,
  97. BOOL bSelChange
  98. );
  99. ///////////////////////////////////////////////////////////////////////////////
  100. BOOL
  101. CheckLayerInUse(
  102. IN PLAYER_FIX_LIST plfl,
  103. IN PLAYER_FIX plfArg
  104. )
  105. /*++
  106. CheckLayerInUse
  107. Desc: Checks if the layer plfArg is pointed to by plfl. This is used when we want to
  108. check if some layer list contains a particular layer
  109. Params:
  110. IN PLAYER_FIX_LIST plfl: The layer list in which to check
  111. IN PLAYER_FIX plfArg: The layer to check
  112. Return:
  113. TRUE: If the layer exists in the layer list
  114. FALSE: Otherwise
  115. --*/
  116. {
  117. if (plfl == NULL) {
  118. return FALSE;
  119. }
  120. //
  121. // For all the layer fix lists in the list headed by plfl, check if any one of
  122. // is for plfArg
  123. //
  124. while (plfl) {
  125. assert(plfl->pLayerFix);
  126. if (plfl->pLayerFix == plfArg) {
  127. return TRUE;
  128. }
  129. plfl = plfl->pNext;
  130. }
  131. return FALSE;
  132. }
  133. void
  134. OnRemove(
  135. IN HWND hDlg
  136. )
  137. /*++
  138. OnRemove
  139. Desc: Moves a selected list item from the layer list (RHS) to the shim list (LHS)
  140. Params:
  141. IN HWND hDlg: The handle to the customlayer dialog
  142. Return:
  143. void
  144. --*/
  145. {
  146. HWND hwndLayerList = GetDlgItem(hDlg, IDC_LAYERLIST);
  147. HWND hwndShimList = GetDlgItem(hDlg, IDC_SHIMLIST);
  148. LVITEM lvi;
  149. INT nCount;
  150. INT nTotal;
  151. PSHIM_FIX_LIST psflInLayerList = NULL;
  152. PFLAG_FIX_LIST pfflInLayerList = NULL;
  153. ZeroMemory(&lvi, sizeof(lvi));
  154. SendMessage(hwndLayerList, WM_SETREDRAW, FALSE, 0);
  155. SendMessage(hwndShimList, WM_SETREDRAW, FALSE, 0);
  156. //
  157. // Enumerate all the selected items and add them to the shim list
  158. //
  159. nTotal = ListView_GetItemCount(hwndLayerList);
  160. for (nCount= nTotal - 1; nCount >= 0; --nCount) {
  161. RemoveSingleItem(hDlg, nCount, TRUE); // Remove only if selected
  162. }
  163. SendMessage(hwndLayerList, WM_SETREDRAW, TRUE, 0);
  164. SendMessage(hwndShimList, WM_SETREDRAW, TRUE, 0);
  165. InvalidateRect(hwndShimList, NULL, TRUE);
  166. InvalidateRect(hwndLayerList, NULL, TRUE);
  167. UpdateWindow(hwndShimList);
  168. UpdateWindow(hwndLayerList);
  169. }
  170. void
  171. OnAdd(
  172. IN HWND hDlg
  173. )
  174. /*++
  175. OnAdd
  176. Desc: Moves a selected list item from the shim list (LHS) to the layer list (RHS)
  177. Params:
  178. IN HWND hDlg: The handle to the customlayer dialog
  179. Return:
  180. void
  181. --*/
  182. {
  183. HWND hwndShimList = GetDlgItem(hDlg, IDC_SHIMLIST);
  184. HWND hwndLayerList = GetDlgItem(hDlg, IDC_LAYERLIST);
  185. PSHIM_FIX_LIST psflInShimList = NULL;
  186. PFLAG_FIX_LIST pfflInShimList = NULL;
  187. LVITEM lvi;
  188. INT nCount;
  189. INT nTotal;
  190. ZeroMemory(&lvi, sizeof(lvi));
  191. SendMessage(hwndShimList, WM_SETREDRAW, FALSE, 0);
  192. SendMessage(hwndLayerList, WM_SETREDRAW, FALSE, 0);
  193. nTotal = ListView_GetItemCount(hwndShimList);
  194. //
  195. // Enumerate all the selected items and add them to the layer list
  196. //
  197. for (nCount= nTotal - 1; nCount >= 0; --nCount) {
  198. lvi.mask = LVIF_PARAM | LVIF_STATE ;
  199. lvi.stateMask = LVIS_SELECTED;
  200. lvi.iItem = nCount;
  201. lvi.iSubItem = 0;
  202. if (!ListView_GetItem(hwndShimList, &lvi)) {
  203. assert(FALSE);
  204. continue;
  205. }
  206. if (lvi.state & LVIS_SELECTED) {
  207. TYPE type = ConvertLparam2Type(lvi.lParam);
  208. if (type == FIX_LIST_SHIM) {
  209. //
  210. // This is a shim
  211. //
  212. psflInShimList = (PSHIM_FIX_LIST)lvi.lParam;
  213. if (psflInShimList->pShimFix == NULL) {
  214. assert(FALSE);
  215. continue;
  216. }
  217. lvi.mask = LVIF_PARAM | LVIF_TEXT;
  218. lvi.pszText = psflInShimList->pShimFix->strName.pszString;
  219. lvi.iImage = IMAGE_SHIM;
  220. lvi.iItem = 0;
  221. lvi.iSubItem = 0;
  222. lvi.lParam = (LPARAM)psflInShimList;
  223. INT iIndex = ListView_InsertItem(hwndLayerList, &lvi);
  224. //
  225. // Add the command line and the params in the expert mode
  226. //
  227. if (g_bExpert) {
  228. //
  229. // We need to set the commandline in the list view, if we are in
  230. // expert mode. Unlike flags, shims can have include-exclude params
  231. // in addition to command line parameter
  232. //
  233. ListView_SetItemText(hwndLayerList,
  234. iIndex,
  235. 1,
  236. psflInShimList->strCommandLine);
  237. ListView_SetItemText(hwndLayerList,
  238. iIndex,
  239. 2,
  240. psflInShimList->strlInExclude.IsEmpty() ?
  241. GetString(IDS_NO) : GetString(IDS_YES));
  242. }
  243. } else if (type == FIX_LIST_FLAG) {
  244. //
  245. // This is a flag
  246. //
  247. pfflInShimList = (PFLAG_FIX_LIST)lvi.lParam;
  248. if (pfflInShimList->pFlagFix == NULL) {
  249. assert(FALSE);
  250. continue;
  251. }
  252. lvi.mask = LVIF_PARAM | LVIF_TEXT;
  253. lvi.pszText = pfflInShimList->pFlagFix->strName.pszString;
  254. lvi.iImage = IMAGE_SHIM;
  255. lvi.iItem = 0;
  256. lvi.iSubItem = 0;
  257. lvi.lParam = (LPARAM)pfflInShimList;
  258. INT iIndex = ListView_InsertItem(hwndLayerList, &lvi);
  259. if (g_bExpert) {
  260. //
  261. // We need to set the commandline in the list view, if we are in
  262. // expert mode. Unlike shims flags can only have command lines, they
  263. // do not have any include-exclude params
  264. //
  265. ListView_SetItemText(hwndLayerList,
  266. iIndex,
  267. 1,
  268. pfflInShimList->strCommandLine);
  269. ListView_SetItemText(hwndLayerList, iIndex, 2, GetString(IDS_NO));
  270. }
  271. }
  272. //
  273. // Remove the shim or flag from the shim list (LHS)
  274. //
  275. ListView_DeleteItem(hwndShimList, nCount);
  276. }
  277. }
  278. SendMessage(hwndShimList, WM_SETREDRAW, TRUE, 0);
  279. SendMessage(hwndLayerList, WM_SETREDRAW, TRUE, 0);
  280. InvalidateRect(hwndLayerList, NULL, TRUE);
  281. InvalidateRect(hwndShimList, NULL, TRUE);
  282. UpdateWindow(hwndLayerList);
  283. UpdateWindow(hwndShimList);
  284. }
  285. BOOL
  286. CCustomLayer::AddCustomLayer(
  287. OUT PLAYER_FIX pLayer,
  288. IN PDATABASE pDatabase
  289. )
  290. /*++
  291. CCustomLayer::AddCustomLayer
  292. Desc: Sets the shims and/or flags for a new layer
  293. Params:
  294. OUT PLAYER_FIX pLayer: The pointer to the layer for which we have to
  295. set the shims and/or flags. If we return FALSE, the caller should delete
  296. it.
  297. IN PDATABASE pDatabase: The presently selected database
  298. Return:
  299. TRUE: If the shims and/or flags have been properly set, the user pressed OK on the
  300. custom layer dialog
  301. FALSE: Otherwise
  302. --*/
  303. {
  304. g_pCustomLayer = this;
  305. m_uMode = LAYERMODE_ADD;
  306. m_pCurrentSelectedDB = pDatabase;
  307. return DialogBoxParam(g_hInstance,
  308. MAKEINTRESOURCE(IDD_CUSTOMLAYER),
  309. g_hDlg,
  310. CustomLayerProc,
  311. (LPARAM)pLayer);
  312. }
  313. BOOL
  314. CCustomLayer::EditCustomLayer(
  315. IN OUT PLAYER_FIX pLayer,
  316. IN PDATABASE pDatabase
  317. )
  318. /*++
  319. CCustomLayer::EditCustomLayer
  320. Desc: Modifies the shims and/or flags for an existing layer
  321. Params:
  322. IN OUT PLAYER_FIX pLayer: The pointer to the layer for which we have to
  323. set the shims and/or flags. If we return FALSE this means that the layer
  324. was not modified
  325. IN PDATABASE pDatabase: The presnntly selected database
  326. Return:
  327. TRUE: If the shims and/or flags have been modified, the user pressed OK on the
  328. custom layer dialog
  329. FALSE: Otherwise
  330. --*/
  331. {
  332. g_pCustomLayer = this;
  333. m_uMode = LAYERMODE_EDIT;
  334. m_pCurrentSelectedDB = pDatabase;
  335. return DialogBoxParam(g_hInstance,
  336. MAKEINTRESOURCE(IDD_CUSTOMLAYER),
  337. g_hDlg,
  338. CustomLayerProc,
  339. (LPARAM)pLayer);
  340. }
  341. void
  342. OnCustomLayerInitDialog(
  343. IN HWND hDlg,
  344. IN LPARAM lParam
  345. )
  346. /*++
  347. DoInitDialog
  348. Desc: Handles the WM_INITDIALOG message for the custom layer dialog box
  349. If we are in non-expert mode, calls ResizeControls() so that the sizes
  350. of both the list views is same
  351. Params:
  352. IN HWND hdlg: The custom layer dialog.
  353. IN LPARAM lParam: This will contain the pointer to a LAYER_FIX
  354. This is the layer that was passed to us through the lParam when we created the
  355. dialog. If we are editing a layer, this will point to the layer being
  356. modified. If we want to create a new layer, the caller of the dialog box,
  357. creates a new layer and passes the pointer to that while calling the
  358. dialog box. If user presses cancel when creating a new layer, caller
  359. must free the new layer.
  360. Return:
  361. void
  362. --*/
  363. {
  364. if (lParam == NULL) {
  365. assert(FALSE);
  366. return;
  367. }
  368. HWND hwndLayerList = GetDlgItem(hDlg, IDC_LAYERLIST);
  369. HWND hwndShimList = GetDlgItem(hDlg, IDC_SHIMLIST);
  370. //
  371. // Add the columns for the list views and set the image lists. The layer list
  372. // will have columns for the commandline and the include-exclude params only
  373. // in expert mode
  374. //
  375. ListView_SetImageList(hwndLayerList, g_hImageList, LVSIL_SMALL);
  376. ListView_SetImageList(hwndShimList, g_hImageList, LVSIL_SMALL);
  377. InsertColumnIntoListView(hwndShimList,
  378. CSTRING(IDS_COL_FIXNAME),
  379. 0,
  380. 100);
  381. InsertColumnIntoListView(hwndLayerList,
  382. CSTRING(IDS_COL_FIXNAME),
  383. 0,
  384. g_bExpert ? 50 : 100);
  385. if (g_bExpert) {
  386. InsertColumnIntoListView(hwndLayerList, CSTRING(IDS_COL_CMDLINE), 1, 30);
  387. InsertColumnIntoListView(hwndLayerList, CSTRING(IDS_COL_MODULE), 2, 20);
  388. ListView_SetColumnWidth(hwndLayerList, 2, LVSCW_AUTOSIZE_USEHEADER);
  389. } else {
  390. //
  391. // We do not allow to configure parameters in non-expert mode
  392. //
  393. ShowWindow(GetDlgItem(hDlg, IDC_PARAMS), SW_HIDE);
  394. ListView_SetColumnWidth(hwndLayerList, 0, LVSCW_AUTOSIZE_USEHEADER);
  395. }
  396. ListView_SetExtendedListViewStyleEx(hwndShimList,
  397. 0,
  398. LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT);
  399. ListView_SetExtendedListViewStyleEx(hwndLayerList,
  400. 0,
  401. LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT);
  402. //
  403. // When this dialog is called, it is passed a PLAYER_FIX. This will be either a
  404. // new PLAYER_FIX if want to create a new layer or an existing one in case
  405. // we are trying to modify an existing one
  406. //
  407. s_pLayerParam = (PLAYER_FIX)lParam;
  408. if (g_pCustomLayer->m_uMode == LAYERMODE_ADD) {
  409. //
  410. // We are creating a new layer
  411. //
  412. ENABLEWINDOW(GetDlgItem(hDlg, IDC_NAME), TRUE);
  413. ShowWindow(GetDlgItem(hDlg, IDC_NAME), SW_SHOW);
  414. SendMessage(GetDlgItem(hDlg, IDC_NAME),
  415. EM_LIMITTEXT,
  416. (WPARAM)
  417. LIMIT_LAYER_NAME,
  418. (LPARAM)0);
  419. ENABLEWINDOW(GetDlgItem(hDlg, IDOK), FALSE);
  420. SetFocus(GetDlgItem(hDlg, IDC_NAME));
  421. } else {
  422. //
  423. // We want to edit an existing layer
  424. //
  425. int iPos = -1;
  426. ENABLEWINDOW(GetDlgItem(hDlg, IDC_COMBO), TRUE);
  427. ShowWindow (GetDlgItem(hDlg, IDC_COMBO), SW_SHOW);
  428. //
  429. // Load the combo box with the names of the existing layers
  430. // for the present database.
  431. //
  432. LoadCombo(hDlg);
  433. //
  434. // Set the selection in the combo box to the layer that was passed to us
  435. //
  436. if (s_pLayerParam) {
  437. iPos = SendMessage(GetDlgItem(hDlg, IDC_COMBO),
  438. CB_SELECTSTRING,
  439. (WPARAM)0,
  440. (LPARAM)(s_pLayerParam->strName.pszString));
  441. assert(iPos != CB_ERR);
  442. }
  443. SetFocus(GetDlgItem(hDlg, IDC_COMBO));
  444. SetWindowText (hDlg, GetString(IDS_EDITCUSTOMCOMPATDLG));
  445. }
  446. //
  447. // Populate both the shim list and the layer lust. Since we are
  448. // editing a layer here, the layer list will contain the fixes for
  449. // the layer being edited
  450. //
  451. PopulateLists(hDlg, s_pLayerParam, FALSE);
  452. if (g_bExpert == FALSE) {
  453. //
  454. // We are in non-expert mode, so we must make the sizes of both the list view
  455. // controls equal as we will now not show the command lines and the params of
  456. // the shims in the layer list view(RHS). We will also need to move the buttons
  457. //
  458. ResizeControls(hDlg);
  459. }
  460. SetFocus(GetDlgItem(hDlg, IDC_SHIMLIST));
  461. }
  462. BOOL
  463. CALLBACK
  464. CustomLayerProc(
  465. IN HWND hDlg,
  466. IN UINT uMsg,
  467. IN WPARAM wParam,
  468. IN LPARAM lParam
  469. )
  470. /*++
  471. CustomLayerProc
  472. Desc: The dialog proc for the custom layer
  473. Params: Standard dialog handler parameters
  474. IN HWND hDlg
  475. IN UINT uMsg
  476. IN WPARAM wParam
  477. IN LPARAM lParam: This will contain the pointer to a LAYER_FIX
  478. This is the layer that was passed to us thorugh the lParam when we created the
  479. dialog. If we are editing a layer, this will point to the layer being
  480. modified. If we want to create a new layer, the caller of the dialog box,
  481. creates a new layer and passes the pointer to that while calling the
  482. dialog box. If user presses cancel when creating a new layer, caller
  483. must free the new layer.
  484. Return: Standard dialog handler return
  485. --*/
  486. {
  487. switch (uMsg) {
  488. case WM_INITDIALOG:
  489. OnCustomLayerInitDialog(hDlg, lParam);
  490. break;
  491. case WM_NOTIFY:
  492. {
  493. LPNMHDR lpnmhdr = (LPNMHDR)lParam;
  494. if (lpnmhdr == NULL) {
  495. break;
  496. }
  497. if (lpnmhdr->idFrom == IDC_SHIMLIST) {
  498. return HandleNotifyShimList(hDlg, lParam);
  499. } else if (lpnmhdr->idFrom == IDC_LAYERLIST) {
  500. return HandleNotifyLayerList(hDlg, lParam);
  501. } else {
  502. return FALSE;
  503. }
  504. break;
  505. }
  506. case WM_DESTROY:
  507. {
  508. HWND hwndLayerList = GetDlgItem(hDlg, IDC_SHIMLIST);
  509. int nTotal = ListView_GetItemCount(hwndLayerList);
  510. LVITEM lvi;
  511. ZeroMemory(&lvi, sizeof(lvi));
  512. lvi.mask = LVIF_PARAM;
  513. lvi.iSubItem = 0;
  514. //
  515. // Enumerate all the shims/flags listed on the shim side and delete
  516. // their corresponding PSHIM_FIX_LIST
  517. // or PFLAG_FIX_LIST
  518. //
  519. for (int nCount = 0; nCount < nTotal; ++nCount) {
  520. lvi.iItem = nCount;
  521. if (!ListView_GetItem(hwndLayerList, &lvi)) {
  522. assert(FALSE);
  523. continue;
  524. }
  525. TYPE type = ConvertLparam2Type(lvi.lParam);
  526. if (type == FIX_LIST_SHIM) {
  527. DeleteShimFixList((PSHIM_FIX_LIST)lvi.lParam);
  528. } else if (type == FIX_LIST_FLAG) {
  529. DeleteFlagFixList((PFLAG_FIX_LIST)lvi.lParam);
  530. } else {
  531. //
  532. // Invalid type for this operation
  533. //
  534. assert(FALSE);
  535. }
  536. }
  537. break;
  538. }
  539. case WM_COMMAND:
  540. switch (LOWORD(wParam)) {
  541. case IDC_NAME:
  542. {
  543. //
  544. // The Ok button will be enabled only if the IDC_NAME, text box is non-empty and the
  545. // the number of elements in the IDC_LAYERLIST is > 0
  546. //
  547. if (EN_UPDATE == HIWORD(wParam)) {
  548. TCHAR szText[MAX_PATH_BUFFSIZE];
  549. UINT uTotal = ListView_GetItemCount(GetDlgItem(hDlg,
  550. IDC_LAYERLIST));
  551. BOOL bEnable = TRUE;
  552. *szText = 0;
  553. GetDlgItemText(hDlg,
  554. IDC_NAME,
  555. szText,
  556. ARRAYSIZE(szText));
  557. bEnable = (uTotal > 0) && CSTRING::Trim(szText);
  558. ENABLEWINDOW(GetDlgItem(hDlg, IDOK), bEnable);
  559. }
  560. }
  561. break;
  562. case IDC_REMOVEALL:
  563. RemoveAll(hDlg);
  564. break;
  565. case IDC_COPY:
  566. OnCopy(hDlg);
  567. SetOkParamsStatus(hDlg);
  568. break;
  569. case IDC_ADD:
  570. OnAdd(hDlg);
  571. SetOkParamsStatus(hDlg);
  572. break;
  573. case IDC_REMOVE:
  574. OnRemove(hDlg);
  575. SetOkParamsStatus(hDlg);
  576. break;
  577. case IDOK://DONE Button
  578. OnDone(hDlg, s_pLayerParam);
  579. break;
  580. case IDC_PARAMS:
  581. ShowParams(hDlg, GetDlgItem(hDlg, IDC_LAYERLIST));
  582. break;
  583. case IDCANCEL:
  584. case IDC_CANCEL:
  585. {
  586. //
  587. // Note: We only free the items for the layer list here.
  588. // The items for the shim list will be freed up in destroy
  589. //
  590. HWND hwndLayerList = GetDlgItem(hDlg, IDC_LAYERLIST);
  591. int nTotal = ListView_GetItemCount(hwndLayerList);
  592. LVITEM lvi;
  593. ZeroMemory(&lvi, sizeof(lvi));
  594. lvi.mask = LVIF_PARAM;
  595. lvi.iSubItem = 0;
  596. //
  597. // Enumerate all the shims/flags listed on the layer side and delete
  598. // their corresponding PSHIM_FIX_LIST
  599. // or PFLAG_FIX_LIST
  600. //
  601. for (int nCount = 0; nCount < nTotal; ++nCount) {
  602. lvi.iItem = nCount;
  603. if (!ListView_GetItem(hwndLayerList, &lvi)) {
  604. assert(FALSE);
  605. continue;
  606. }
  607. TYPE type = ConvertLparam2Type(lvi.lParam);
  608. if (type == FIX_LIST_SHIM) {
  609. DeleteShimFixList((PSHIM_FIX_LIST)lvi.lParam);
  610. } else if (type == FIX_LIST_FLAG) {
  611. DeleteFlagFixList((PFLAG_FIX_LIST)lvi.lParam);
  612. } else {
  613. //
  614. // Invalid type for this operation
  615. //
  616. assert(FALSE);
  617. }
  618. }
  619. EndDialog(hDlg, FALSE);
  620. }
  621. break;
  622. case IDC_COMBO:
  623. {
  624. HWND hwndCombo = GetDlgItem(hDlg, IDC_COMBO);
  625. if (HIWORD(wParam) == CBN_SELCHANGE) {
  626. int iPos = SendMessage(hwndCombo,
  627. CB_GETCURSEL,
  628. 0,
  629. 0);
  630. if (iPos == CB_ERR) {
  631. break;
  632. }
  633. s_pLayerParam = (PLAYER_FIX)SendMessage(hwndCombo,
  634. CB_GETITEMDATA,
  635. iPos,
  636. 0);
  637. //
  638. // We need to repopulate the lists with the new layer that was selected
  639. //
  640. PopulateLists(hDlg, s_pLayerParam, TRUE);
  641. } else {
  642. return FALSE;
  643. }
  644. }
  645. break;
  646. default:
  647. return FALSE;
  648. break;
  649. }
  650. default:return FALSE;
  651. }
  652. return TRUE;
  653. }
  654. INT_PTR
  655. CALLBACK
  656. ChooseLayersProc(
  657. IN HWND hDlg,
  658. IN UINT uMsg,
  659. IN WPARAM wParam,
  660. IN LPARAM lParam
  661. )
  662. /*++
  663. ChooseLayersProc
  664. Desc: The dialog proc for the dialog that allows us to choose a layer, when we do a Copy
  665. layer operation from the custom layer dialog
  666. Params: Standard dialog handler parameters
  667. IN HWND hDlg
  668. IN UINT uMsg
  669. IN WPARAM wParam
  670. IN LPARAM lParam
  671. Return:
  672. PLAYER_FIX of selected layer, if OK is pressed
  673. NULL, otherwise
  674. --*/
  675. {
  676. switch (uMsg) {
  677. case WM_INITDIALOG:
  678. {
  679. PLAYER_FIX pLayerFix = NULL;
  680. //
  681. // Add the global layers
  682. //
  683. pLayerFix = GlobalDataBase.pLayerFixes;
  684. while (NULL != pLayerFix) {
  685. int nIndex = SendDlgItemMessage(hDlg,
  686. IDC_LIST,
  687. LB_ADDSTRING,
  688. 0,
  689. (LPARAM)(LPCTSTR)pLayerFix->strName);
  690. if (LB_ERR != nIndex) {
  691. SendDlgItemMessage(hDlg,
  692. IDC_LIST,
  693. LB_SETITEMDATA,
  694. nIndex,
  695. (LPARAM)pLayerFix);
  696. }
  697. pLayerFix = pLayerFix->pNext;
  698. }
  699. //
  700. // Add the custom layers
  701. //
  702. pLayerFix = g_pCustomLayer->m_pCurrentSelectedDB->pLayerFixes;
  703. while (NULL != pLayerFix) {
  704. int nIndex = SendDlgItemMessage(hDlg,
  705. IDC_LIST,
  706. LB_ADDSTRING,
  707. 0,
  708. (LPARAM)(LPCTSTR)pLayerFix->strName);
  709. if (LB_ERR != nIndex) {
  710. SendDlgItemMessage(hDlg,
  711. IDC_LIST,
  712. LB_SETITEMDATA,
  713. nIndex,
  714. (LPARAM)pLayerFix);
  715. }
  716. pLayerFix = pLayerFix->pNext;
  717. }
  718. SendMessage(GetDlgItem(hDlg, IDC_LIST), LB_SETCURSEL, (WPARAM)0, (LPARAM)0);
  719. SetFocus(GetDlgItem (hDlg, IDC_LIST));
  720. }
  721. break;
  722. case WM_COMMAND:
  723. {
  724. switch (LOWORD(wParam)) {
  725. case IDC_LIST:
  726. if (LB_ERR == SendMessage(GetDlgItem(hDlg, IDC_LIST), LB_GETCURSEL, 0, 0)) {
  727. ENABLEWINDOW(GetDlgItem(hDlg, IDOK), FALSE);
  728. } else {
  729. ENABLEWINDOW(GetDlgItem(hDlg, IDOK), TRUE);
  730. }
  731. break;
  732. case IDOK:
  733. {
  734. int nIndex = SendMessage(GetDlgItem(hDlg, IDC_LIST), LB_GETCURSEL, 0, 0);
  735. PLAYER_FIX pLayerTemp = (PLAYER_FIX) SendDlgItemMessage(hDlg,
  736. IDC_LIST,
  737. LB_GETITEMDATA,
  738. nIndex,
  739. 0);
  740. if (pLayerTemp == NULL) {
  741. assert(FALSE);
  742. break;
  743. }
  744. EndDialog(hDlg, (INT_PTR)pLayerTemp);
  745. }
  746. break;
  747. case IDCANCEL:
  748. EndDialog(hDlg, NULL);
  749. break;
  750. }
  751. }
  752. break;
  753. }
  754. return FALSE;
  755. }
  756. BOOL
  757. RemoveLayer(
  758. IN PDATABASE pDataBase,
  759. IN PLAYER_FIX pLayerToRemove,
  760. OUT HTREEITEM* pHItem
  761. )
  762. /*++
  763. RemoveLayer
  764. Desc: Removes a layer from a database
  765. Params:
  766. IN PDATABASE pDataBase: The database in which the layer resides
  767. IN PLAYER_FIX pLayerToRemove: The layer to remove
  768. OUT HTREEITEM* pHItem: If this not null, then we can save the hitem
  769. for the layer in the db tree in this variable
  770. Warn: Before removing a layer we must make sure that this layer is not in use
  771. Return:
  772. TRUE: We managed to remove the layer
  773. FALSE: Otherwise
  774. --*/
  775. {
  776. HTREEITEM hItem;
  777. LPARAM lParam;
  778. PDBENTRY pEntry = NULL, pApp = NULL;
  779. PLAYER_FIX plfTemp = NULL;
  780. PLAYER_FIX plfPrev = NULL;
  781. CSTRING strMessage;
  782. if (pDataBase == NULL || pLayerToRemove == NULL) {
  783. assert(FALSE);
  784. return FALSE;
  785. }
  786. pApp = pEntry = pDataBase->pEntries;
  787. //
  788. // Check if the layer is in use by any entry
  789. //
  790. while (NULL != pEntry) {
  791. if (CheckLayerInUse(pEntry->pFirstLayer, pLayerToRemove)) {
  792. //
  793. // This layer is applied to some app and cannot be removed
  794. //
  795. strMessage.Sprintf(GetString(IDS_UNABLETOREMOVE_MODE),
  796. (LPCTSTR)pLayerToRemove->strName,
  797. (LPCTSTR)pEntry->strExeName,
  798. (LPCTSTR)pEntry->strAppName);
  799. MessageBox(g_hDlg,
  800. (LPCTSTR)strMessage,
  801. g_szAppName,
  802. MB_ICONWARNING);
  803. return FALSE;
  804. }
  805. if (pEntry->pSameAppExe) {
  806. pEntry = pEntry->pSameAppExe;
  807. } else {
  808. pEntry = pApp->pNext;
  809. pApp = pApp->pNext;
  810. }
  811. }
  812. plfTemp = pDataBase->pLayerFixes, plfPrev = NULL;
  813. while (plfTemp) {
  814. if (plfTemp == pLayerToRemove) {
  815. break;
  816. }
  817. plfPrev = plfTemp;
  818. plfTemp = plfTemp->pNext;
  819. }
  820. if (plfTemp) {
  821. //
  822. // The layer was found
  823. //
  824. if (plfPrev) {
  825. plfPrev->pNext = plfTemp->pNext;
  826. } else {
  827. //
  828. // This was the first layer of the database
  829. //
  830. pDataBase->pLayerFixes = plfTemp->pNext;
  831. }
  832. }
  833. hItem = pDataBase->hItemAllLayers;
  834. //
  835. // Set the phItem properly if asked to. This is the hItem of the layer in the Lib Tree. This can be used to
  836. // remove the item directly.
  837. //
  838. if (pHItem) {
  839. *pHItem = NULL;
  840. while (hItem) {
  841. DBTree.GetLParam(hItem, &lParam);
  842. if ((PLAYER_FIX)lParam == pLayerToRemove) {
  843. *pHItem = hItem;
  844. break;
  845. }
  846. hItem = TreeView_GetNextSibling(DBTree.m_hLibraryTree, hItem);
  847. }
  848. }
  849. ValidateClipBoard(NULL, (LPVOID)plfTemp);
  850. if (plfTemp) {
  851. delete plfTemp;
  852. plfTemp = NULL;
  853. }
  854. pDataBase->uLayerCount--;
  855. return TRUE;
  856. }
  857. void
  858. PopulateLists(
  859. IN HWND hdlg,
  860. IN PLAYER_FIX pLayerParam,
  861. IN BOOL bSelChange
  862. )
  863. /*++
  864. PopulateLists
  865. Desc: Populates both the shim list (LHS) and the layer list (RHS)
  866. Params:
  867. IN HWND hdlg: The custom layer dialog proc
  868. IN PLAYER_FIX pLayerParam: The layer that has to be shown in the layer list
  869. IN BOOL bSelChange: Is this because of a selchange in the combo box
  870. Return:
  871. void
  872. --*/
  873. {
  874. HWND hwndShimList = GetDlgItem(hdlg, IDC_SHIMLIST);
  875. HWND hwndLayerList = GetDlgItem(hdlg, IDC_LAYERLIST);
  876. PSHIM_FIX psf = GlobalDataBase.pShimFixes;
  877. PFLAG_FIX pff = GlobalDataBase.pFlagFixes;
  878. INT iIndex = 0;
  879. LVITEM lvi;
  880. ZeroMemory(&lvi, sizeof (lvi));
  881. //
  882. // Turn off repaints
  883. //
  884. SendDlgItemMessage(hdlg, IDC_SHIMLIST, WM_SETREDRAW, FALSE, 0);
  885. SendDlgItemMessage(hdlg, IDC_LAYERLIST, WM_SETREDRAW, FALSE, 0);
  886. //
  887. // This is because of a selchange in the combo box. So we must
  888. // remove all the shims that are shown in the layer list. This means that we
  889. // will move the entries from the layer list to the shim list
  890. //
  891. if (bSelChange) {
  892. RemoveAll(hdlg);
  893. }
  894. lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
  895. if (!bSelChange) {
  896. //
  897. // The function has been called because of the initialization of the dialog box
  898. // If we are editing a layer, pLayerParam will be the pointer to the layer
  899. // being edited
  900. //
  901. //
  902. // Add the shims first
  903. //
  904. while (psf != NULL) {
  905. if ((psf->bGeneral || g_bExpert) &&
  906. !ShimFlagExistsInLayer(psf, pLayerParam, FIX_SHIM)) {
  907. //
  908. // Add a new shim item to the shim list view
  909. //
  910. PSHIM_FIX_LIST psfl = new SHIM_FIX_LIST;
  911. if (psfl == NULL) {
  912. MEM_ERR;
  913. return;
  914. }
  915. psfl->pShimFix = psf;
  916. lvi.pszText = psf->strName;
  917. lvi.iSubItem = 0;
  918. lvi.lParam = (LPARAM)psfl;
  919. lvi.iImage = IMAGE_SHIM;
  920. lvi.iItem = 0;
  921. ListView_InsertItem(hwndShimList, &lvi);
  922. }
  923. psf = psf->pNext;
  924. }
  925. //
  926. // Add the flags next
  927. //
  928. while (pff != NULL) {
  929. if ((pff->bGeneral || g_bExpert) &&
  930. !ShimFlagExistsInLayer(pff, pLayerParam, FIX_FLAG)) {
  931. //
  932. // Add a new flag item to the shim list view
  933. //
  934. PFLAG_FIX_LIST pffl = new FLAG_FIX_LIST;
  935. if (pffl == NULL) {
  936. MEM_ERR;
  937. return;
  938. }
  939. pffl->pFlagFix = pff;
  940. lvi.pszText = pff->strName;
  941. lvi.iSubItem = 0;
  942. lvi.lParam = (LPARAM)pffl;
  943. lvi.iItem = 0;
  944. lvi.iImage = IMAGE_SHIM;
  945. ListView_InsertItem(hwndShimList, &lvi);
  946. }
  947. pff = pff->pNext;
  948. }
  949. }
  950. if (NULL != pLayerParam) {
  951. PSHIM_FIX_LIST psflInLayer = pLayerParam->pShimFixList;
  952. PFLAG_FIX_LIST pfflInLayer = pLayerParam->pFlagFixList;
  953. //
  954. // Copy the shims to the layer list
  955. //
  956. while (psflInLayer) {
  957. if (psflInLayer->pShimFix == NULL) {
  958. assert(FALSE);
  959. goto Next_Shim;
  960. }
  961. //
  962. // Add a new shim item to the layer list view
  963. //
  964. PSHIM_FIX_LIST psfl = new SHIM_FIX_LIST;
  965. if (psfl == NULL) {
  966. MEM_ERR;
  967. break;
  968. }
  969. psfl->pShimFix = psflInLayer->pShimFix;
  970. //
  971. // Add the command lines for this shim
  972. //
  973. psfl->strCommandLine = psflInLayer->strCommandLine;
  974. //
  975. // Add the inclusion-exclusion list for this shim
  976. //
  977. psfl->strlInExclude = psflInLayer->strlInExclude;
  978. //
  979. // Copy the LUA data
  980. //
  981. if (psflInLayer->pLuaData) {
  982. psfl->pLuaData = new LUADATA;
  983. if (psfl->pLuaData == NULL) {
  984. MEM_ERR;
  985. return;
  986. }
  987. psfl->pLuaData->Copy(psflInLayer->pLuaData);
  988. }
  989. lvi.pszText = psflInLayer->pShimFix->strName;
  990. lvi.iSubItem = 0;
  991. lvi.lParam = (LPARAM)psfl;
  992. lvi.iItem = 0;
  993. lvi.iImage = IMAGE_SHIM;
  994. iIndex = ListView_InsertItem(hwndLayerList, &lvi);
  995. if (g_bExpert) {
  996. ListView_SetItemText(hwndLayerList,
  997. iIndex,
  998. 1,
  999. psfl->strCommandLine);
  1000. ListView_SetItemText(hwndLayerList,
  1001. iIndex,
  1002. 2,
  1003. psfl->strlInExclude.IsEmpty() ? GetString(IDS_NO) : GetString(IDS_YES));
  1004. }
  1005. Next_Shim:
  1006. psflInLayer = psflInLayer->pNext;
  1007. }
  1008. //
  1009. // Copy the flags to the layer list
  1010. //
  1011. while (pfflInLayer) {
  1012. if (pfflInLayer->pFlagFix == NULL) {
  1013. assert(FALSE);
  1014. goto Next_Flag;
  1015. }
  1016. //
  1017. // Add a new flag item to the layer list view
  1018. //
  1019. PFLAG_FIX_LIST pffl = new FLAG_FIX_LIST;
  1020. if (pffl == NULL) {
  1021. MEM_ERR;
  1022. return;
  1023. }
  1024. pffl->pFlagFix = pfflInLayer->pFlagFix;
  1025. //
  1026. // Add the command lines for this flag
  1027. //
  1028. pffl->strCommandLine = pfflInLayer->strCommandLine;
  1029. lvi.pszText = pfflInLayer->pFlagFix->strName;
  1030. lvi.iSubItem = 0;
  1031. lvi.lParam = (LPARAM)pffl;
  1032. lvi.iItem = 0;
  1033. lvi.iImage = IMAGE_SHIM;
  1034. INT iIndexFlag = ListView_InsertItem(hwndLayerList, &lvi);
  1035. if (g_bExpert) {
  1036. ListView_SetItemText(hwndLayerList,
  1037. iIndexFlag,
  1038. 1,
  1039. pffl->strCommandLine);
  1040. }
  1041. Next_Flag:
  1042. pfflInLayer = pfflInLayer->pNext;
  1043. }
  1044. SendDlgItemMessage(hdlg, IDC_SHIMLIST, WM_SETREDRAW, TRUE, 0);
  1045. InvalidateRect(GetDlgItem(hdlg, IDC_SHIMLIST), NULL, TRUE);
  1046. UpdateWindow(GetDlgItem(hdlg, IDC_SHIMLIST));
  1047. SendDlgItemMessage(hdlg, IDC_LAYERLIST, WM_SETREDRAW, TRUE, 0);
  1048. InvalidateRect(GetDlgItem(hdlg, IDC_LAYERLIST), NULL, TRUE);
  1049. UpdateWindow(GetDlgItem(hdlg, IDC_LAYERLIST));
  1050. } else {
  1051. assert(FALSE);
  1052. }
  1053. }
  1054. void
  1055. LoadCombo(
  1056. IN HWND hdlg
  1057. )
  1058. /*++
  1059. LoadCombo
  1060. Desc: Loads the combo box with the names of the existing layers for the present database.
  1061. Sets the lParam to the PLAYER_FIX for the layer
  1062. Should be called when editing layers only
  1063. Params:
  1064. IN HWND hdlg: The custom layer dialog proc
  1065. --*/
  1066. {
  1067. PLAYER_FIX plf = g_pCustomLayer->m_pCurrentSelectedDB->pLayerFixes;
  1068. int iPos = -1;
  1069. HWND hwndCombo = GetDlgItem(hdlg, IDC_COMBO);
  1070. //
  1071. // Add all the layers for the database to the combo-box
  1072. //
  1073. while (plf) {
  1074. iPos = SendMessage(hwndCombo, CB_ADDSTRING, 0,(LPARAM)plf->strName.pszString);
  1075. if (iPos != CB_ERR) {
  1076. SendMessage(hwndCombo, CB_SETITEMDATA, (WPARAM)iPos, (LPARAM)plf);
  1077. }
  1078. plf = plf->pNext;
  1079. }
  1080. }
  1081. void
  1082. OnCopy(
  1083. IN HWND hDlg
  1084. )
  1085. /*++
  1086. OnCopy
  1087. Desc: Handles the case when the user presses "Copy" button in the dialog box
  1088. This routine allows us to make shim combinations based on existing layers
  1089. The commandline and the in-ex list of the shims in the layers are also copied
  1090. Params:
  1091. IN HWND hdlg: The custom layer dialog proc
  1092. --*/
  1093. {
  1094. LVITEM lvi;
  1095. INT iIndex;
  1096. HWND hwndShimList = GetDlgItem(hDlg, IDC_SHIMLIST);
  1097. HWND hwndLayerList = GetDlgItem(hDlg, IDC_LAYERLIST);
  1098. ZeroMemory(&lvi, sizeof(lvi));
  1099. HWND hwndFocus = GetFocus();
  1100. //
  1101. // Get the layer whose shims/flags we want to copy
  1102. //
  1103. PLAYER_FIX plfSelected = (PLAYER_FIX)DialogBox(g_hInstance,
  1104. MAKEINTRESOURCE(IDD_SELECTLAYER),
  1105. hDlg,
  1106. ChooseLayersProc);
  1107. if (plfSelected) {
  1108. PSHIM_FIX_LIST psfl = plfSelected->pShimFixList;
  1109. PFLAG_FIX_LIST pffl = plfSelected->pFlagFixList;
  1110. PSHIM_FIX_LIST psflInShimList = NULL;
  1111. PFLAG_FIX_LIST pfflInShimList = NULL;
  1112. LVFINDINFO lvfind;
  1113. SendDlgItemMessage(hDlg, IDC_SHIMLIST, WM_SETREDRAW, FALSE, 0);
  1114. SendDlgItemMessage(hDlg, IDC_LAYERLIST, WM_SETREDRAW, FALSE, 0);
  1115. lvfind.flags = LVFI_STRING;
  1116. //
  1117. // Add over all the shims for this layer that we want to copy
  1118. //
  1119. while (psfl) {
  1120. if (psfl->pShimFix == NULL) {
  1121. assert(FALSE);
  1122. goto Next_Shim;
  1123. }
  1124. lvfind.psz = psfl->pShimFix->strName.pszString;
  1125. iIndex = ListView_FindItem(hwndShimList, -1, &lvfind);
  1126. if (iIndex != -1) {
  1127. //
  1128. // This was a general shim, we have to add this to the layer list
  1129. //
  1130. lvi.mask = LVIF_PARAM;
  1131. lvi.iItem = iIndex;
  1132. lvi.iSubItem = 0;
  1133. if (!ListView_GetItem(hwndShimList, &lvi)) {
  1134. assert(FALSE);
  1135. goto Next_Shim;
  1136. }
  1137. psflInShimList = (PSHIM_FIX_LIST)lvi.lParam;
  1138. psflInShimList->strCommandLine = psfl->strCommandLine;
  1139. psflInShimList->strlInExclude = psfl->strlInExclude;
  1140. //
  1141. // LUA data. This will be not required but just in case ...
  1142. //
  1143. if (psflInShimList->pLuaData) {
  1144. delete psflInShimList->pLuaData;
  1145. psflInShimList->pLuaData = NULL;
  1146. }
  1147. if (psfl->pLuaData) {
  1148. psflInShimList->pLuaData = new LUADATA;
  1149. if (psflInShimList->pLuaData == NULL) {
  1150. MEM_ERR;
  1151. return;
  1152. }
  1153. psflInShimList->pLuaData->Copy(psfl->pLuaData);
  1154. }
  1155. //
  1156. // Remove the item from the shim list and add it to the layer list
  1157. //
  1158. ListView_DeleteItem(hwndShimList, iIndex);
  1159. } else {
  1160. //
  1161. // The shim may be present in the layer list, if yes we can remove it now
  1162. //
  1163. assert(psfl->pShimFix);
  1164. lvfind.psz = psfl->pShimFix->strName.pszString;
  1165. iIndex = ListView_FindItem(hwndLayerList, -1, &lvfind);
  1166. if (iIndex != -1) {
  1167. lvi.mask = LVIF_PARAM;
  1168. lvi.iItem = iIndex;
  1169. lvi.iSubItem = 0;
  1170. if (!ListView_GetItem(hwndLayerList, &lvi)) {
  1171. assert(FALSE);
  1172. goto Next_Shim;
  1173. }
  1174. //
  1175. // This is the PSHIM_FIX_LIST that was present in the
  1176. // layer list view
  1177. //
  1178. psflInShimList = (PSHIM_FIX_LIST)lvi.lParam;
  1179. psflInShimList->strCommandLine = psfl->strCommandLine;
  1180. psflInShimList->strlInExclude = psfl->strlInExclude;
  1181. //
  1182. // LUA data. This will be not required but just in case ...
  1183. //
  1184. if (psflInShimList->pLuaData) {
  1185. delete psflInShimList->pLuaData;
  1186. psflInShimList->pLuaData = NULL;
  1187. }
  1188. if (psfl->pLuaData) {
  1189. psflInShimList->pLuaData = new LUADATA;
  1190. if (psflInShimList->pLuaData) {
  1191. psflInShimList->pLuaData->Copy(psfl->pLuaData);
  1192. } else {
  1193. MEM_ERR;
  1194. return;
  1195. }
  1196. }
  1197. //
  1198. // Remove the item from the layer list view. We will add it again soon.
  1199. //
  1200. ListView_DeleteItem(hwndLayerList, iIndex);
  1201. } else {
  1202. //
  1203. // We have to create new as this is a non-general shim
  1204. //
  1205. psflInShimList = new SHIM_FIX_LIST;
  1206. if (psflInShimList == NULL) {
  1207. MEM_ERR;
  1208. return;
  1209. }
  1210. psflInShimList->pShimFix = psfl->pShimFix;
  1211. psflInShimList->strCommandLine = psfl->strCommandLine;
  1212. psflInShimList->strlInExclude = psfl->strlInExclude;
  1213. if (psfl->pLuaData) {
  1214. psflInShimList->pLuaData = new LUADATA;
  1215. if (psflInShimList->pLuaData) {
  1216. MEM_ERR;
  1217. return;
  1218. }
  1219. psflInShimList->pLuaData->Copy(psfl->pLuaData);
  1220. }
  1221. }
  1222. }
  1223. //
  1224. // Add this psflInshimList to the layer list now
  1225. //
  1226. lvi.mask = LVIF_PARAM | LVIF_TEXT | LVIF_IMAGE;
  1227. lvi.pszText = psflInShimList->pShimFix->strName;
  1228. lvi.iSubItem = 0;
  1229. lvi.lParam = (LPARAM)psflInShimList;
  1230. lvi.iImage = IMAGE_SHIM;
  1231. lvi.iItem = 0;
  1232. iIndex = ListView_InsertItem(hwndLayerList, &lvi);
  1233. if (g_bExpert) {
  1234. ListView_SetItemText(hwndLayerList,
  1235. iIndex,
  1236. 1,
  1237. psflInShimList->strCommandLine);
  1238. ListView_SetItemText(hwndLayerList,
  1239. iIndex,
  1240. 2,
  1241. psflInShimList->strlInExclude.IsEmpty() ?
  1242. GetString(IDS_NO) : GetString(IDS_YES));
  1243. }
  1244. Next_Shim:
  1245. psfl = psfl->pNext;
  1246. }
  1247. //
  1248. // Now add the flags for the layer
  1249. //
  1250. while (pffl) {
  1251. if (pffl->pFlagFix == NULL) {
  1252. assert(FALSE);
  1253. goto Next_Flag;
  1254. }
  1255. lvfind.psz = pffl->pFlagFix->strName.pszString;
  1256. iIndex = ListView_FindItem(hwndShimList, -1, &lvfind);
  1257. if (iIndex != -1) {
  1258. //
  1259. // This was a general flag, we have to add this to the layer lit
  1260. //
  1261. lvi.mask = LVIF_PARAM;
  1262. lvi.iItem = iIndex;
  1263. lvi.iSubItem = 0;
  1264. if (!ListView_GetItem(hwndShimList, &lvi)) {
  1265. assert(FALSE);
  1266. goto Next_Flag;
  1267. }
  1268. pfflInShimList = (PFLAG_FIX_LIST)lvi.lParam;
  1269. //
  1270. // Add the command lines for this shim
  1271. //
  1272. pfflInShimList->strCommandLine = pffl->strCommandLine;
  1273. //
  1274. // Remove the item from the flag list and add it to the layer list
  1275. //
  1276. ListView_DeleteItem(hwndShimList, iIndex);
  1277. } else {
  1278. //
  1279. // The flag may be present in the layer list, if yes we can remove it now
  1280. //
  1281. if (pffl->pFlagFix == NULL) {
  1282. assert(FALSE);
  1283. goto Next_Flag;
  1284. }
  1285. lvfind.psz = pffl->pFlagFix->strName.pszString;
  1286. iIndex = ListView_FindItem(hwndLayerList, -1, &lvfind);
  1287. if (iIndex != -1) {
  1288. lvi.mask = LVIF_PARAM;
  1289. lvi.iItem = iIndex;
  1290. lvi.iSubItem = 0;
  1291. if (!ListView_GetItem(hwndLayerList, &lvi)) {
  1292. assert(FALSE);
  1293. goto Next_Flag;
  1294. }
  1295. //
  1296. // This is the PFLAG_FIX_LIST that was present in the
  1297. // layer list view
  1298. //
  1299. pfflInShimList = (PFLAG_FIX_LIST)lvi.lParam;
  1300. pfflInShimList->strCommandLine = pffl->strCommandLine;
  1301. //
  1302. // Remove the item from the layer list. We will add it again soon.
  1303. //
  1304. ListView_DeleteItem(hwndLayerList, iIndex);
  1305. } else {
  1306. //
  1307. // We have to create new
  1308. //
  1309. pfflInShimList = new FLAG_FIX_LIST;
  1310. if (pfflInShimList == NULL) {
  1311. MEM_ERR;
  1312. return;
  1313. }
  1314. pfflInShimList->pFlagFix = pffl->pFlagFix;
  1315. pfflInShimList->strCommandLine = pffl->strCommandLine;
  1316. }
  1317. }
  1318. //
  1319. // Add this pfflInflagList to the layer list now
  1320. //
  1321. lvi.mask = LVIF_PARAM | LVIF_TEXT;
  1322. lvi.pszText = pfflInShimList->pFlagFix->strName;
  1323. lvi.iSubItem = 0;
  1324. lvi.lParam = (LPARAM)pfflInShimList;
  1325. lvi.iImage = IMAGE_SHIM;
  1326. lvi.iItem = 0;
  1327. iIndex = ListView_InsertItem(hwndLayerList, &lvi);
  1328. if (g_bExpert) {
  1329. ListView_SetItemText(hwndLayerList,
  1330. iIndex,
  1331. 1,
  1332. pfflInShimList->strCommandLine);
  1333. ListView_SetItemText(hwndLayerList,
  1334. iIndex,
  1335. 2,
  1336. GetString(IDS_NO));
  1337. }
  1338. Next_Flag:
  1339. pffl = pffl->pNext;
  1340. }
  1341. SendDlgItemMessage(hDlg, IDC_SHIMLIST, WM_SETREDRAW, TRUE, 0);
  1342. SendDlgItemMessage(hDlg, IDC_LAYERLIST, WM_SETREDRAW, TRUE, 0);
  1343. InvalidateRect(GetDlgItem(hDlg, IDC_SHIMLIST), NULL, TRUE);
  1344. UpdateWindow(GetDlgItem(hDlg, IDC_SHIMLIST));
  1345. InvalidateRect(GetDlgItem(hDlg, IDC_LAYERLIST), NULL, TRUE);
  1346. UpdateWindow(GetDlgItem(hDlg, IDC_LAYERLIST));
  1347. }
  1348. SetFocus(hwndFocus);
  1349. }
  1350. void
  1351. OnDone(
  1352. IN HWND hDlg,
  1353. IN OUT PLAYER_FIX pLayerParam
  1354. )
  1355. /*++
  1356. OnDone
  1357. Desc: Removes all the existing shims and flags from pLayerParam and then
  1358. adds the selected shims and flags (those in the layerlist (RHS)) to pLayerParam
  1359. Params:
  1360. IN HWND hDlg: The custom layer dialog proc
  1361. IN OUT PLAYER_FIX pLayerParam: The layer that has to be populated with the
  1362. selected shims and flags
  1363. --*/
  1364. {
  1365. TCHAR szText[MAX_PATH_BUFFSIZE];
  1366. LVITEM lvi;
  1367. HWND hwndLayerList;
  1368. ZeroMemory(&lvi, sizeof(lvi));
  1369. *szText = 0;
  1370. hwndLayerList = GetDlgItem(hDlg, IDC_LAYERLIST);
  1371. if (g_pCustomLayer->m_uMode == LAYERMODE_EDIT) {
  1372. GetDlgItemText(hDlg, IDC_COMBO, szText, ARRAYSIZE(szText));
  1373. } else {
  1374. GetDlgItemText(hDlg, IDC_NAME, szText, ARRAYSIZE(szText));
  1375. }
  1376. if (CSTRING::Trim(szText) == 0) {
  1377. MessageBox(hDlg,
  1378. GetString(IDS_INVALID_LAYER_NAME),
  1379. g_szAppName,
  1380. MB_ICONWARNING);
  1381. return;
  1382. }
  1383. CSTRING strLayerName = szText;
  1384. //
  1385. // Check if the new name already exists, if yes give error.
  1386. //
  1387. if (g_pCustomLayer->m_uMode == LAYERMODE_ADD
  1388. && FindFix((LPCTSTR)strLayerName, FIX_LAYER, g_pCustomLayer->m_pCurrentSelectedDB)) {
  1389. //
  1390. // Since we have a read only combo box when we are editing a fix, the user
  1391. // cannot change the name, so we only check for whether we have an existing layer of the
  1392. // same name when we are creating a new layer
  1393. //
  1394. MessageBox(hDlg, GetString(IDS_LAYEREXISTS), g_szAppName, MB_ICONWARNING);
  1395. return;
  1396. }
  1397. //
  1398. // Remove all the shims.
  1399. //
  1400. DeleteShimFixList(pLayerParam->pShimFixList);
  1401. pLayerParam->pShimFixList = NULL;
  1402. //
  1403. // Remove all the Flags.
  1404. //
  1405. DeleteFlagFixList (pLayerParam->pFlagFixList);
  1406. pLayerParam->pFlagFixList = NULL;
  1407. pLayerParam->uShimCount = 0;
  1408. int nCount;
  1409. int nTotal;
  1410. pLayerParam->strName = szText;
  1411. nTotal = ListView_GetItemCount(hwndLayerList);
  1412. //
  1413. // Enumerate all the shims listed and add to the layer.
  1414. //
  1415. for (nCount=0; nCount < nTotal; ++nCount) {
  1416. lvi.mask = LVIF_PARAM;
  1417. lvi.iItem = nCount;
  1418. lvi.iSubItem = 0;
  1419. if (!ListView_GetItem(hwndLayerList, &lvi)) {
  1420. assert(FALSE);
  1421. continue;
  1422. }
  1423. TYPE type = ConvertLparam2Type(lvi.lParam);
  1424. if (type == FIX_LIST_SHIM) {
  1425. //
  1426. // Add this shim to the layer
  1427. //
  1428. PSHIM_FIX_LIST pShimFixList = (PSHIM_FIX_LIST)lvi.lParam;
  1429. assert(pShimFixList);
  1430. if (pLayerParam->pShimFixList == NULL) {
  1431. pLayerParam->pShimFixList = pShimFixList;
  1432. pLayerParam->pShimFixList->pNext = NULL;
  1433. } else {
  1434. pShimFixList->pNext = pLayerParam->pShimFixList->pNext;
  1435. pLayerParam->pShimFixList->pNext = pShimFixList;
  1436. }
  1437. } else if (FIX_LIST_FLAG) {
  1438. //
  1439. // Add this flag to the layer
  1440. //
  1441. PFLAG_FIX_LIST pFlagFixList = (PFLAG_FIX_LIST) lvi.lParam;
  1442. assert(pFlagFixList);
  1443. if (pLayerParam->pFlagFixList == NULL) {
  1444. pLayerParam->pFlagFixList = pFlagFixList;
  1445. pLayerParam->pFlagFixList->pNext = NULL;
  1446. } else {
  1447. pFlagFixList->pNext = pLayerParam->pFlagFixList->pNext;
  1448. pLayerParam->pFlagFixList->pNext = pFlagFixList;
  1449. }
  1450. }
  1451. //
  1452. // Count of both shims and flags, we do not use this variable now
  1453. // BUBUG: remove this variable from the structure
  1454. //
  1455. pLayerParam->uShimCount++;
  1456. }
  1457. EndDialog(hDlg, TRUE);
  1458. }
  1459. void
  1460. RemoveSingleItem(
  1461. IN HWND hdlg,
  1462. IN INT iIndex,
  1463. IN BOOL bOnlySelected
  1464. )
  1465. /*++
  1466. RemoveSingleItem
  1467. Desc: Moves a single item from the layer list to the shim list
  1468. Params:
  1469. IN HWND hdlg: The custom layer dialog
  1470. IN INT iIndex: The index of the item that has to be removed
  1471. IN BOOL bOnlySelected: We should remove the item only if it selected
  1472. --*/
  1473. {
  1474. LVITEM lvi;
  1475. HWND hwndLayerList = GetDlgItem(hdlg, IDC_LAYERLIST);
  1476. HWND hwndShimList = GetDlgItem(hdlg, IDC_SHIMLIST);
  1477. PSHIM_FIX_LIST psflInLayerList = NULL;
  1478. PFLAG_FIX_LIST pfflInLayerList = NULL;
  1479. ZeroMemory(&lvi, sizeof(lvi));
  1480. lvi.mask = LVIF_PARAM | LVIF_STATE ;
  1481. lvi.stateMask = LVIS_SELECTED;
  1482. lvi.iItem = iIndex;
  1483. lvi.iSubItem = 0;
  1484. if (!ListView_GetItem(hwndLayerList, &lvi)) {
  1485. assert(FALSE);
  1486. return;
  1487. }
  1488. if (!bOnlySelected ||(lvi.state & LVIS_SELECTED)) {
  1489. TYPE type = ConvertLparam2Type(lvi.lParam);
  1490. if (type == FIX_LIST_SHIM) {
  1491. psflInLayerList = (PSHIM_FIX_LIST)lvi.lParam;
  1492. assert(psflInLayerList->pShimFix);
  1493. lvi.mask = LVIF_PARAM | LVIF_TEXT;
  1494. lvi.pszText = psflInLayerList->pShimFix->strName;
  1495. lvi.iImage = IMAGE_SHIM;
  1496. lvi.iItem = 0;
  1497. lvi.iSubItem = 0;
  1498. lvi.lParam = (LPARAM)psflInLayerList;
  1499. } else if (type == FIX_LIST_FLAG) {
  1500. pfflInLayerList = (PFLAG_FIX_LIST)lvi.lParam;
  1501. assert(pfflInLayerList->pFlagFix);
  1502. lvi.mask = LVIF_PARAM | LVIF_STATE | LVIF_TEXT;
  1503. lvi.pszText = pfflInLayerList->pFlagFix->strName;
  1504. lvi.iImage = IMAGE_SHIM;
  1505. lvi.iItem = 0;
  1506. lvi.iSubItem = 0;
  1507. lvi.lParam = (LPARAM)pfflInLayerList;
  1508. }
  1509. ListView_InsertItem(hwndShimList, &lvi);
  1510. ListView_DeleteItem(hwndLayerList, iIndex);
  1511. }
  1512. }
  1513. BOOL
  1514. HandleNotifyLayerList(
  1515. IN HWND hDlg,
  1516. IN LPARAM lParam
  1517. )
  1518. /*++
  1519. HandleNotifyLayerList
  1520. Desc: Handles the notification messages for the layer list. This is the RHS list view
  1521. Params:
  1522. IN HWND hDlg: The custom layer dialog proc
  1523. IN LPARAM lParam: The lParam with WM_NOTIFY
  1524. --*/
  1525. {
  1526. NMHDR * pHdr = (NMHDR*)lParam;
  1527. switch (pHdr->code) {
  1528. case NM_DBLCLK:
  1529. OnRemove(hDlg);
  1530. SetOkParamsStatus(hDlg);
  1531. break;
  1532. case NM_CLICK:
  1533. if (ListView_GetSelectedCount(GetDlgItem(hDlg, IDC_LAYERLIST)) == 0) {
  1534. ENABLEWINDOW(GetDlgItem(hDlg, IDC_PARAMS), FALSE);
  1535. } else {
  1536. ENABLEWINDOW(GetDlgItem(hDlg, IDC_PARAMS), TRUE);
  1537. }
  1538. break;
  1539. case LVN_ITEMCHANGED:
  1540. {
  1541. LPNMLISTVIEW lpnmlv;
  1542. lpnmlv = (LPNMLISTVIEW)lParam;
  1543. if (lpnmlv && (lpnmlv->uChanged & LVIF_STATE)) {
  1544. if (lpnmlv->uNewState & LVIS_SELECTED) {
  1545. ENABLEWINDOW(GetDlgItem(hDlg, IDC_PARAMS), TRUE);
  1546. }
  1547. }
  1548. break;
  1549. }
  1550. default: return FALSE;
  1551. }
  1552. return TRUE;
  1553. }
  1554. BOOL
  1555. HandleNotifyShimList(
  1556. IN HWND hDlg,
  1557. IN LPARAM lParam
  1558. )
  1559. /*++
  1560. HandleNotifyShimList
  1561. Desc: Handles the notification messages for the ShimList. This is the LHS list view
  1562. Params:
  1563. IN HWND hDlg: The custom layer dialog proc
  1564. IN LPARAM lParam: The lParam with WM_NOTIFY
  1565. --*/
  1566. {
  1567. NMHDR* pHdr = (NMHDR*)lParam;
  1568. switch (pHdr->code) {
  1569. case NM_DBLCLK:
  1570. OnAdd(hDlg);
  1571. SetOkParamsStatus(hDlg);
  1572. break;
  1573. default: return FALSE;
  1574. }
  1575. return TRUE;
  1576. }
  1577. void
  1578. SetOkParamsStatus(
  1579. IN HWND hdlg
  1580. )
  1581. /*++
  1582. SetOkParamsStatus
  1583. Desc: Sets the status of the ok button and the params button
  1584. Params:
  1585. IN HWND hDlg: The custom layer dialog proc
  1586. --*/
  1587. {
  1588. INT iTotalCount = ListView_GetItemCount(GetDlgItem(hdlg, IDC_LAYERLIST));
  1589. if (g_pCustomLayer->m_uMode == LAYERMODE_ADD) {
  1590. SendMessage(hdlg, WM_COMMAND, MAKELONG(IDC_NAME, EN_UPDATE), 0);
  1591. } else {
  1592. ENABLEWINDOW(GetDlgItem(hdlg, IDOK), iTotalCount > 0);
  1593. }
  1594. //
  1595. // Enable the params button only if we have some selection in the layer list view(RHS)
  1596. //
  1597. ENABLEWINDOW(GetDlgItem(hdlg, IDC_PARAMS),
  1598. ListView_GetNextItem(GetDlgItem(hdlg, IDC_LAYERLIST), -1, LVNI_SELECTED) != -1);
  1599. }
  1600. void
  1601. RemoveAll(
  1602. IN HWND hDlg
  1603. )
  1604. /*++
  1605. RemoveAll
  1606. Desc: Removes all the shims/flags from the layer list and adds them
  1607. to the shim list
  1608. Params:
  1609. IN HWND hDlg: The custom layer dialog
  1610. Return:
  1611. --*/
  1612. {
  1613. SendDlgItemMessage(hDlg, IDC_SHIMLIST, WM_SETREDRAW, FALSE, 0);
  1614. SendDlgItemMessage(hDlg, IDC_LAYERLIST, WM_SETREDRAW, FALSE, 0);
  1615. int nCount;
  1616. nCount = ListView_GetItemCount(GetDlgItem(hDlg, IDC_LAYERLIST)) - 1;
  1617. for (;nCount >= 0; --nCount) {
  1618. //
  1619. // Remove all either selected or not
  1620. //
  1621. RemoveSingleItem(hDlg, nCount, FALSE);
  1622. }
  1623. SendDlgItemMessage(hDlg, IDC_SHIMLIST, WM_SETREDRAW, TRUE, 0);
  1624. SendDlgItemMessage(hDlg, IDC_LAYERLIST, WM_SETREDRAW, TRUE, 0);
  1625. InvalidateRect(GetDlgItem(hDlg, IDC_SHIMLIST), NULL, TRUE);
  1626. UpdateWindow(GetDlgItem(hDlg, IDC_SHIMLIST));
  1627. InvalidateRect(GetDlgItem(hDlg, IDC_LAYERLIST), NULL, TRUE);
  1628. UpdateWindow(GetDlgItem(hDlg, IDC_LAYERLIST));
  1629. SetOkParamsStatus(hDlg);
  1630. }
  1631. void
  1632. ResizeControls(
  1633. IN HWND hdlg
  1634. )
  1635. /*++
  1636. ResizeControls
  1637. Desc: Make the sizes of both the list view controls equal as we will now
  1638. not show the command lines and the params of the shims in the layer
  1639. list view(RHS) in non-expert mode. We will also need to move the buttons
  1640. Params:
  1641. IN HWND hdlg: The custom layer dialog box
  1642. Return:
  1643. void
  1644. --*/
  1645. {
  1646. HWND hwndTemp;
  1647. RECT rcTemp;
  1648. INT iWidthShimList;
  1649. INT iWidthLayerList;
  1650. INT iWidthDiff;
  1651. HDWP hdwp = BeginDeferWindowPos(3);
  1652. //
  1653. // Note: DeferWindowPos: All windows in a multiple-window position structure must
  1654. // have the same parent.
  1655. //
  1656. hwndTemp = GetDlgItem(hdlg, IDC_SHIMLIST);
  1657. GetWindowRect(hwndTemp, &rcTemp);
  1658. MapWindowPoints(NULL, hdlg, (LPPOINT)&rcTemp, 2);
  1659. iWidthShimList = rcTemp.right - rcTemp.left;
  1660. hwndTemp = GetDlgItem(hdlg, IDC_LAYERLIST);
  1661. GetWindowRect(hwndTemp, &rcTemp);
  1662. MapWindowPoints(NULL, hdlg, (LPPOINT)&rcTemp, 2);
  1663. iWidthLayerList = rcTemp.right - rcTemp.left;
  1664. iWidthDiff = iWidthLayerList - iWidthShimList;
  1665. //
  1666. // Make the width of the layer list equal to the width of the shim list
  1667. //
  1668. DeferWindowPos(hdwp,
  1669. hwndTemp,
  1670. NULL,
  1671. 0,
  1672. 0,
  1673. iWidthShimList,
  1674. rcTemp.bottom - rcTemp.top,
  1675. SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  1676. //
  1677. // Move the OK button to the left
  1678. //
  1679. hwndTemp = GetDlgItem(hdlg, IDOK);
  1680. GetWindowRect(hwndTemp, &rcTemp);
  1681. MapWindowPoints(NULL, hdlg, (LPPOINT)&rcTemp, 2);
  1682. DeferWindowPos(hdwp,
  1683. hwndTemp,
  1684. NULL,
  1685. rcTemp.left - iWidthDiff,
  1686. rcTemp.top,
  1687. 0,
  1688. 0,
  1689. SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
  1690. //
  1691. // Move the Cancel button to the left
  1692. //
  1693. hwndTemp = GetDlgItem(hdlg, IDC_CANCEL);
  1694. GetWindowRect(hwndTemp, &rcTemp);
  1695. MapWindowPoints(NULL, hdlg, (LPPOINT)&rcTemp, 2);
  1696. DeferWindowPos(hdwp,
  1697. hwndTemp,
  1698. NULL,
  1699. rcTemp.left - iWidthDiff,
  1700. rcTemp.top,
  1701. 0,
  1702. 0,
  1703. SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
  1704. EndDeferWindowPos(hdwp);
  1705. //
  1706. // Now we must reduce the size of the main dialog as well
  1707. //
  1708. GetWindowRect(hdlg, &rcTemp);
  1709. MoveWindow(hdlg,
  1710. rcTemp.left,
  1711. rcTemp.top,
  1712. rcTemp.right - rcTemp.left - iWidthDiff,
  1713. rcTemp.bottom - rcTemp.top,
  1714. TRUE);
  1715. //
  1716. // Make the last column fit in the list view
  1717. //
  1718. hwndTemp = GetDlgItem(hdlg, IDC_LAYERLIST);
  1719. ListView_SetColumnWidth(hwndTemp, 0, LVSCW_AUTOSIZE_USEHEADER);
  1720. }