Source code of Windows XP (NT5)
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.

908 lines
23 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1996.
  5. //
  6. // File: wizsel.cxx
  7. //
  8. // Contents: Task wizard Onestop selection property page implementation.
  9. //
  10. // Classes: CSelectItemsPage
  11. //
  12. // History: 11-21-1997 SusiA
  13. //
  14. //---------------------------------------------------------------------------
  15. #include "precomp.h"
  16. // temporariy define new mstask flag in case hasn't
  17. // propogated to sdk\inc
  18. //for CS help
  19. extern TCHAR szSyncMgrHelp[];
  20. extern ULONG g_aContextHelpIds[];
  21. extern DWORD g_dwPlatformId;
  22. extern OSVERSIONINFOA g_OSVersionInfo; // osVersionInfo,
  23. extern LANGID g_LangIdSystem; // LangId of system we are running on.
  24. CSelectItemsPage *g_pSelectItemsPage = NULL;
  25. //+-------------------------------------------------------------------------------
  26. // FUNCTION: SchedWizardConnectionDlgProc(HWND, UINT, WPARAM, LPARAM)
  27. //
  28. // PURPOSE: Callback dialog procedure for the property page
  29. //
  30. // PARAMETERS:
  31. // hDlg - Dialog box window handle
  32. // uMessage - current message
  33. // wParam - depends on message
  34. // lParam - depends on message
  35. //
  36. // RETURN VALUE:
  37. //
  38. // Depends on message. In general, return TRUE if we process it.
  39. //
  40. // COMMENTS:
  41. //
  42. //--------------------------------------------------------------------------------
  43. BOOL CALLBACK SchedWizardConnectionDlgProc(HWND hDlg, UINT uMessage, WPARAM wParam, LPARAM lParam)
  44. {
  45. WORD wNotifyCode = HIWORD(wParam); // notification code
  46. switch (uMessage)
  47. {
  48. case WM_INITDIALOG:
  49. if (g_pSelectItemsPage)
  50. g_pSelectItemsPage->Initialize(hDlg);
  51. InitPage(hDlg,lParam);
  52. break;
  53. case WM_DESTROY:
  54. if (g_pSelectItemsPage)
  55. {
  56. g_pSelectItemsPage->FreeItemsFromListView();
  57. g_pSelectItemsPage->FreeRas();
  58. if (g_pSelectItemsPage->m_pListView)
  59. {
  60. delete g_pSelectItemsPage->m_pListView;
  61. }
  62. }
  63. break;
  64. case WM_HELP:
  65. {
  66. LPHELPINFO lphi = (LPHELPINFO)lParam;
  67. if (lphi->iContextType == HELPINFO_WINDOW)
  68. {
  69. WinHelp ( (HWND) lphi->hItemHandle,
  70. szSyncMgrHelp,
  71. HELP_WM_HELP,
  72. (ULONG_PTR) g_aContextHelpIds);
  73. }
  74. return TRUE;
  75. }
  76. case WM_CONTEXTMENU:
  77. {
  78. WinHelp ((HWND)wParam,
  79. szSyncMgrHelp,
  80. HELP_CONTEXTMENU,
  81. (ULONG_PTR)g_aContextHelpIds);
  82. return TRUE;
  83. }
  84. case WM_PAINT:
  85. WmPaint(hDlg, uMessage, wParam, lParam);
  86. break;
  87. case WM_PALETTECHANGED:
  88. WmPaletteChanged(hDlg, wParam);
  89. break;
  90. case WM_QUERYNEWPALETTE:
  91. return( WmQueryNewPalette(hDlg) );
  92. break;
  93. case WM_ACTIVATE:
  94. return( WmActivate(hDlg, wParam, lParam) );
  95. break;
  96. case WM_NOTIFYLISTVIEWEX:
  97. if (g_pSelectItemsPage)
  98. {
  99. int idCtrl = (int) wParam;
  100. LPNMHDR pnmhdr = (LPNMHDR) lParam;
  101. if ( (IDC_SCHEDUPDATELIST != idCtrl) || (NULL == g_pSelectItemsPage->m_pListView))
  102. {
  103. Assert(IDC_SCHEDUPDATELIST == idCtrl);
  104. Assert(g_pSelectItemsPage->m_pListView);
  105. break;
  106. }
  107. switch (pnmhdr->code)
  108. {
  109. case LVNEX_ITEMCHECKCOUNT:
  110. {
  111. LPNMLISTVIEWEXITEMCHECKCOUNT pnmvCheckCount = (LPNMLISTVIEWEXITEMCHECKCOUNT) lParam;
  112. g_pSelectItemsPage->SetItemCheckState(pnmvCheckCount->iCheckCount);
  113. break;
  114. }
  115. default:
  116. break;
  117. }
  118. }
  119. break;
  120. case WM_NOTIFY:
  121. if (g_pSelectItemsPage)
  122. {
  123. int idCtrl = (int) wParam;
  124. LPNMHDR pnmhdr = (LPNMHDR) lParam;
  125. // if notification for UpdateListPass it on.
  126. if ((IDC_SCHEDUPDATELIST == idCtrl) && g_pSelectItemsPage->m_pListView)
  127. {
  128. g_pSelectItemsPage->m_pListView->OnNotify(pnmhdr);
  129. break;
  130. }
  131. }
  132. switch (((NMHDR FAR *)lParam)->code)
  133. {
  134. case PSN_KILLACTIVE:
  135. break;
  136. case PSN_RESET:
  137. break;
  138. case PSN_SETACTIVE:
  139. if (g_pSelectItemsPage->m_pListView
  140. && (0 == g_pSelectItemsPage->m_pListView->GetCheckedItemsCount()) )
  141. {
  142. PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK ) ;
  143. }
  144. else
  145. {
  146. PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK | PSWIZB_NEXT);
  147. }
  148. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0);
  149. break;
  150. case PSN_WIZNEXT:
  151. //shouldn't save this until finish
  152. //this guy is only called if the dialog is a wizard
  153. break;
  154. default:
  155. break;
  156. }
  157. break;
  158. case WM_COMMAND:
  159. switch (LOWORD(wParam))
  160. {
  161. case IDC_SCHEDUPDATECOMBO:
  162. {
  163. if (wNotifyCode == CBN_SELCHANGE)
  164. {
  165. HWND hwndCombo = (HWND) lParam;
  166. if (g_pSelectItemsPage)
  167. {
  168. g_pSelectItemsPage->SetConnectionDirty();
  169. g_pSelectItemsPage->ShowItemsOnThisConnection
  170. (ComboBox_GetCurSel(hwndCombo), FALSE);
  171. }
  172. }
  173. }
  174. break;
  175. case IDC_AUTOCONNECT:
  176. {
  177. if (wNotifyCode == BN_CLICKED)
  178. {
  179. PropSheet_Changed(GetParent(hDlg), hDlg);
  180. HWND hwndCtrl = (HWND) lParam;
  181. g_pSelectItemsPage->SetCheck(LOWORD(wParam),
  182. Button_GetCheck(hwndCtrl));
  183. }
  184. }
  185. break;
  186. default:
  187. break;
  188. }
  189. break;
  190. default:
  191. return FALSE;
  192. }
  193. return TRUE;
  194. }
  195. //+--------------------------------------------------------------------------
  196. //
  197. // Member: CSelectItemsPage::CSelectItemsPage
  198. //
  199. // Synopsis: ctor
  200. //
  201. // [phPSP] - filled with prop page handle
  202. //
  203. // History: 11-21-1997 SusiA
  204. //
  205. //---------------------------------------------------------------------------
  206. CSelectItemsPage::CSelectItemsPage(
  207. HINSTANCE hinst,
  208. BOOL *pfSaved,
  209. ISyncSchedule *pISyncSched,
  210. HPROPSHEETPAGE *phPSP,
  211. int iDialogResource)
  212. {
  213. ZeroMemory(&m_psp, sizeof(PROPSHEETPAGE));
  214. Assert(pISyncSched);
  215. m_psp.dwSize = sizeof (PROPSHEETPAGE);
  216. m_psp.dwFlags = PSH_DEFAULT;
  217. m_psp.hInstance = hinst;
  218. m_psp.pszTemplate = MAKEINTRESOURCE(iDialogResource);
  219. m_psp.pszIcon = NULL;
  220. m_psp.pfnDlgProc = (DLGPROC) SchedWizardConnectionDlgProc;
  221. m_psp.lParam = 0;
  222. m_iCreationKind = iDialogResource;
  223. g_pSelectItemsPage = this;
  224. m_pISyncSched = pISyncSched;
  225. m_pISyncSched->AddRef();
  226. m_pfSaved = pfSaved;
  227. *m_pfSaved = FALSE;
  228. m_pListView = NULL;
  229. m_fItemsChanged = FALSE;
  230. m_fConnectionFlagChanged = FALSE;
  231. m_fConnectionChanged = FALSE;
  232. // attempt to get our private interface
  233. if (NOERROR != pISyncSched->QueryInterface(IID_ISyncSchedulep,(void **) &m_pISyncSchedp))
  234. {
  235. m_pISyncSchedp = NULL;
  236. }
  237. #ifdef WIZARD97
  238. m_psp.dwFlags |= PSP_HIDEHEADER;
  239. #endif // WIZARD97
  240. *phPSP = CreatePropertySheetPage(&m_psp);
  241. }
  242. CSelectItemsPage::~CSelectItemsPage()
  243. {
  244. if (m_pISyncSchedp)
  245. {
  246. m_pISyncSchedp->Release();
  247. }
  248. }
  249. //+--------------------------------------------------------------------------
  250. //
  251. // Member: CSelectItemsPage::FreeRas()
  252. //
  253. // History: 12-Mar-1998 SusiA
  254. //
  255. //---------------------------------------------------------------------------
  256. void CSelectItemsPage::FreeRas()
  257. {
  258. if (m_pRas)
  259. delete m_pRas;
  260. }
  261. //+--------------------------------------------------------------------------
  262. //
  263. // Member: CSelectItemsPage::Initialize(HWND hwnd)
  264. //
  265. // Synopsis: initialize the item selection page and set the task name to a unique
  266. // new onestop name
  267. //
  268. // History: 11-21-1997 SusiA
  269. //
  270. //---------------------------------------------------------------------------
  271. BOOL CSelectItemsPage::Initialize(HWND hwnd)
  272. {
  273. m_hwnd = hwnd;
  274. // Initialize Ras Combo box
  275. m_pRas= new CRasUI();
  276. if (NULL == m_pRas || FALSE == m_pRas->Initialize())
  277. {
  278. if (m_pRas)
  279. delete m_pRas;
  280. return FALSE;
  281. }
  282. m_hwndRasCombo = GetDlgItem(m_hwnd,IDC_SCHEDUPDATECOMBO);
  283. m_pRas->FillRasCombo(m_hwndRasCombo,FALSE,TRUE);
  284. InitializeItems();
  285. //initialize the item list
  286. HWND hwndList = GetDlgItem(m_hwnd,IDC_SCHEDUPDATELIST);
  287. LV_COLUMN columnInfo;
  288. HIMAGELIST himage;
  289. INT iItem = -1;
  290. UINT ImageListflags;
  291. m_pListView = new CListView(hwndList,m_hwnd,IDC_SCHEDUPDATELIST,WM_NOTIFYLISTVIEWEX);
  292. if (NULL == m_pListView)
  293. {
  294. return FALSE;
  295. }
  296. m_pListView->SetExtendedListViewStyle(LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP );
  297. ImageListflags = ILC_COLOR | ILC_MASK;
  298. if (IsHwndRightToLeft(hwnd))
  299. {
  300. ImageListflags |= ILC_MIRROR;
  301. }
  302. // create an imagelist
  303. himage = ImageList_Create( GetSystemMetrics(SM_CXSMICON),
  304. GetSystemMetrics(SM_CYSMICON),ImageListflags,5,20);
  305. if (himage)
  306. {
  307. m_pListView->SetImageList(himage,LVSIL_SMALL);
  308. }
  309. // Insert the Proper columns
  310. columnInfo.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
  311. columnInfo.fmt = LVCFMT_LEFT;
  312. columnInfo.cx = CalcListViewWidth(hwndList,295);
  313. columnInfo .pszText = TEXT("");
  314. columnInfo.cchTextMax = 1;
  315. columnInfo.iSubItem = 0;
  316. m_pListView->InsertColumn(0,&columnInfo);
  317. ShowItemsOnThisConnection(ComboBox_GetCurSel(m_hwndRasCombo), FALSE);
  318. //Wizard creation
  319. if (m_iCreationKind != IDD_SCHEDPAGE_ITEMS)
  320. {
  321. SetConnectionDirty();
  322. }
  323. ShowWindow(m_hwnd, /* nCmdShow */ SW_SHOWNORMAL );
  324. UpdateWindow(m_hwnd);
  325. return TRUE;
  326. }
  327. //+-------------------------------------------------------------------------------
  328. //
  329. // FUNCTION: BOOL CSelectItemsPage::InitializeItems()
  330. //
  331. // PURPOSE: initialize the handler for the schedule wizard page
  332. //
  333. // RETURN VALUE: return TRUE if we process it ok.
  334. //
  335. //+-------------------------------------------------------------------------------
  336. BOOL CSelectItemsPage::InitializeItems()
  337. {
  338. int i,
  339. iConnectionCount;
  340. TCHAR ptszComboConnName[RAS_MaxEntryName + 1];
  341. TCHAR ptszConnectionName[RAS_MaxEntryName + 1];
  342. WCHAR pwszConnectionName[RAS_MaxEntryName + 1];
  343. DWORD dwSize = RAS_MaxEntryName + 1;
  344. DWORD dwConnType;
  345. m_fItemsChanged = FALSE;
  346. m_fConnectionFlagChanged = FALSE;
  347. m_fConnectionChanged = FALSE;
  348. if (FAILED(m_pISyncSched->GetConnection(&dwSize,pwszConnectionName, &dwConnType)))
  349. {
  350. return FALSE;
  351. }
  352. ConvertString(ptszConnectionName,pwszConnectionName,ARRAY_SIZE(ptszConnectionName));
  353. iConnectionCount= ComboBox_GetCount(m_hwndRasCombo);
  354. //Initialize the Schedule connection settings
  355. COMBOBOXEXITEM comboItem;
  356. for (i=0; i< iConnectionCount; i++)
  357. {
  358. comboItem.mask = CBEIF_TEXT;
  359. comboItem.cchTextMax = ARRAY_SIZE(ptszComboConnName);
  360. comboItem.pszText = ptszComboConnName;
  361. comboItem.iItem = i;
  362. // Review, handle failures.
  363. ComboEx_GetItem(m_hwndRasCombo,&comboItem);
  364. m_SchedConnectionNum = 0;
  365. if (lstrcmp(ptszComboConnName, ptszConnectionName) == 0)
  366. {
  367. //Current connection to sync over for the schedule.
  368. m_SchedConnectionNum = i;
  369. ComboBox_SetCurSel(m_hwndRasCombo, i);
  370. break;
  371. }
  372. }
  373. //Set the default autoconnect check state
  374. m_pISyncSched->GetFlags(&m_dwFlags);
  375. Button_SetCheck(GetDlgItem(m_hwnd,IDC_AUTOCONNECT),
  376. m_dwFlags & SYNCSCHEDINFO_FLAGS_AUTOCONNECT);
  377. return TRUE;
  378. }
  379. //--------------------------------------------------------------------------------
  380. //
  381. // FUNCTION: CSelectItemsPage::SetConnectionDirty()
  382. //
  383. // PURPOSE: we have changed the connection info
  384. //
  385. // COMMENTS: Only called frm prop sheet; not wizard
  386. //
  387. //--------------------------------------------------------------------------------
  388. void CSelectItemsPage::SetConnectionDirty()
  389. {
  390. m_fConnectionChanged = TRUE;
  391. }
  392. //--------------------------------------------------------------------------------
  393. //
  394. // FUNCTION: CSelectItemsPage::CommitChanges()
  395. //
  396. // PURPOSE: Write all the current Schedule Settings to the registry
  397. //
  398. // COMMENTS: Implemented on main thread.
  399. //
  400. //--------------------------------------------------------------------------------
  401. HRESULT CSelectItemsPage::CommitChanges()
  402. {
  403. HRESULT hr = S_OK;
  404. if (m_fConnectionFlagChanged)
  405. {
  406. m_pISyncSched->SetFlags(m_dwFlags);
  407. }
  408. if (m_fConnectionChanged)
  409. {
  410. m_pISyncSched->SetConnection(m_pwszConnectionName, m_dwConnType);
  411. }
  412. if (m_fItemsChanged)
  413. {
  414. int iTotalItems = m_pListView->GetItemCount();
  415. //Now set the check state with ISyncSched
  416. BOOL fChecked;
  417. int iItem;
  418. for (iItem=0;iItem < iTotalItems;iItem++)
  419. {
  420. fChecked = (LVITEMEXSTATE_CHECKED == m_pListView->GetCheckState(iItem)) ? TRUE : FALSE;
  421. LVITEMEX lvItem;
  422. ZeroMemory(&lvItem, sizeof(lvItem));
  423. lvItem.mask = LVIF_PARAM;
  424. lvItem.maskEx = 0;
  425. lvItem.iItem = iItem;
  426. lvItem.lParam = 0;
  427. if (m_pListView->GetItem(&lvItem) && lvItem.lParam) // lparam is zero for toplevel items
  428. {
  429. LPSYNC_HANDLER_ITEM_INFO pHandlerItem = (LPSYNC_HANDLER_ITEM_INFO) lvItem.lParam;
  430. if (fChecked)
  431. {
  432. m_pISyncSched->SetItemCheck(pHandlerItem->handlerID,
  433. &(pHandlerItem->itemID),
  434. SYNCMGRITEMSTATE_CHECKED);
  435. }
  436. else
  437. {
  438. m_pISyncSched->SetItemCheck(pHandlerItem->handlerID,
  439. &(pHandlerItem->itemID),
  440. SYNCMGRITEMSTATE_UNCHECKED);
  441. }
  442. }
  443. }
  444. }
  445. hr = m_pISyncSched->Save();
  446. if (hr == S_OK)
  447. {
  448. *m_pfSaved = TRUE;
  449. }
  450. return hr;
  451. }
  452. //+-------------------------------------------------------------------------------
  453. //
  454. // FUNCTION: BOOL CSelectItemsPage::SetItemCheckState()
  455. //
  456. // PURPOSE: set the selected check state
  457. //
  458. // RETURN VALUE: return TRUE if we process it ok.
  459. //
  460. //+-------------------------------------------------------------------------------
  461. BOOL CSelectItemsPage::SetItemCheckState(int iCheckCount)
  462. {
  463. int iConnectionItem = ComboBox_GetCurSel(m_hwndRasCombo);
  464. //The check state is message is getting flagged by us programmatically setting it,
  465. // until after we are done initializing.
  466. if (m_Initialized)
  467. {
  468. BOOL fAnyChecked = iCheckCount ? TRUE : FALSE;
  469. //Enable the prompt me first according to what items selected
  470. //EnableWindow(GetDlgItem(m_hwnd,IDC_AUTOPROMPT_ME_FIRST), m_fAnyChecked);
  471. PropSheet_Changed(GetParent(m_hwnd), m_hwnd);
  472. //Enable the next button according to what items are selected
  473. // should only be disabled iff ALL connection items are
  474. // unselected, not just the current connections selection's
  475. if (fAnyChecked)
  476. PropSheet_SetWizButtons(GetParent(m_hwnd), PSWIZB_BACK | PSWIZB_NEXT);
  477. else
  478. PropSheet_SetWizButtons(GetParent(m_hwnd), PSWIZB_BACK);
  479. m_fItemsChanged = TRUE;
  480. }
  481. return TRUE;
  482. }
  483. //+-------------------------------------------------------------------------------
  484. //
  485. // FUNCTION: BOOL CSelectItemsPage::SetCheck(WORD wParam,DWORD dwCheckState)
  486. //
  487. // PURPOSE: set the selected check state
  488. //
  489. // RETURN VALUE: return TRUE if we process it ok.
  490. //
  491. //+-------------------------------------------------------------------------------
  492. BOOL CSelectItemsPage::SetCheck(WORD wParam,DWORD dwCheckState)
  493. {
  494. if (wParam == IDC_AUTOCONNECT)
  495. {
  496. int iConnectionItem = ComboBox_GetCurSel(m_hwndRasCombo);
  497. //preserve Readonly state
  498. m_dwFlags &= SYNCSCHEDINFO_FLAGS_READONLY;
  499. //set new autoconnect state
  500. if (dwCheckState)
  501. {
  502. m_dwFlags |= SYNCSCHEDINFO_FLAGS_AUTOCONNECT;
  503. }
  504. if (m_Initialized)
  505. {
  506. m_fConnectionFlagChanged = TRUE;
  507. }
  508. }
  509. return TRUE;
  510. }
  511. //+-------------------------------------------------------------------------------
  512. //
  513. // FUNCTION: BOOL CSelectItemsPage::FreeItemsFromListView()
  514. //
  515. // PURPOSE: free the items on this Schedule
  516. //
  517. // RETURN VALUE: return TRUE if we process it ok.
  518. //
  519. //+-------------------------------------------------------------------------------
  520. BOOL CSelectItemsPage::FreeItemsFromListView()
  521. {
  522. int iItem;
  523. int iItemCount;
  524. HWND hwndListView = GetDlgItem(m_hwnd,IDC_SCHEDUPDATELIST);
  525. iItemCount = m_pListView->GetItemCount();
  526. for(iItem = 0; iItem < iItemCount; iItem++)
  527. {
  528. LPSYNC_HANDLER_ITEM_INFO pHandlerItem;
  529. LVITEMEX lvItem;
  530. ZeroMemory(&lvItem, sizeof(lvItem));
  531. lvItem.mask = LVIF_PARAM;
  532. lvItem.maskEx = 0;
  533. lvItem.iItem = iItem;
  534. if (m_pListView->GetItem(&lvItem) && lvItem.lParam)
  535. {
  536. pHandlerItem = (LPSYNC_HANDLER_ITEM_INFO) lvItem.lParam;
  537. FREE(pHandlerItem);
  538. }
  539. }
  540. return TRUE;
  541. }
  542. //+-------------------------------------------------------------------------------
  543. //
  544. // FUNCTION: BOOL CSelectItemsPage::ShowItemsOnThisConnection()
  545. //
  546. // PURPOSE: List the items on this connection for the Schedule page
  547. //
  548. // RETURN VALUE: return TRUE if we process it ok.
  549. //
  550. //+-------------------------------------------------------------------------------
  551. BOOL CSelectItemsPage::ShowItemsOnThisConnection(int iItem, BOOL fClear)
  552. {
  553. TCHAR ptszConnectionName[RAS_MaxEntryName + 1];
  554. // set up the list view
  555. if (!m_pListView || !m_pISyncSchedp)
  556. {
  557. return FALSE;
  558. }
  559. HIMAGELIST himage;
  560. LVITEMEX itemInfo;
  561. m_Initialized = FALSE;
  562. //Note: Use text to "uniquely" identify connection on RAS
  563. //change to using GUID on connection objects
  564. int iNumConnections = ComboBox_GetCount(m_hwndRasCombo);
  565. m_SchedConnectionNum = iItem;
  566. COMBOBOXEXITEM comboItem;
  567. comboItem.mask = CBEIF_TEXT | CBEIF_LPARAM;
  568. comboItem.cchTextMax = ARRAY_SIZE(ptszConnectionName);
  569. comboItem.pszText = ptszConnectionName;
  570. comboItem.iItem = iItem;
  571. // Review, handle failures.
  572. ComboEx_GetItem(m_hwndRasCombo,&comboItem);
  573. //SetConnectionName
  574. ConvertString(m_pwszConnectionName, ptszConnectionName,ARRAY_SIZE(ptszConnectionName));
  575. m_dwConnType = (DWORD) comboItem.lParam;
  576. // if don't need to clear and listview contains items then we are done
  577. if (!fClear && m_pListView->GetItemCount())
  578. {
  579. m_Initialized = TRUE;
  580. return TRUE;
  581. }
  582. //first clear out the list view
  583. FreeItemsFromListView();
  584. m_pListView->DeleteAllItems();
  585. // Review, dont' clear ImageList so just keeps getting bigger as change connections.
  586. himage = m_pListView->GetImageList(LVSIL_SMALL );
  587. //Enumerate the Items
  588. IEnumSyncItems *pIEnum;
  589. LPSYNC_HANDLER_ITEM_INFO pHandlerItem = (LPSYNC_HANDLER_ITEM_INFO)
  590. ALLOC(sizeof(SYNC_HANDLER_ITEM_INFO));
  591. ULONG ulFetched;
  592. if (FAILED(m_pISyncSchedp->EnumItems(GUID_NULL, &pIEnum)))
  593. {
  594. return FALSE;
  595. }
  596. while (pHandlerItem && S_OK == pIEnum->Next(1,pHandlerItem, &ulFetched))
  597. {
  598. LVHANDLERITEMBLOB lvHandlerItemBlob;
  599. int iParentItemId;
  600. BOOL fHandlerParent = TRUE; // always have a parent for now.
  601. // Check if item is already in the ListView and if so
  602. // go on
  603. lvHandlerItemBlob.cbSize = sizeof(LVHANDLERITEMBLOB);
  604. lvHandlerItemBlob.clsidServer = pHandlerItem->handlerID;
  605. lvHandlerItemBlob.ItemID = pHandlerItem->itemID;
  606. if (-1 != m_pListView->FindItemFromBlob((LPLVBLOB) &lvHandlerItemBlob))
  607. {
  608. // already in ListView, go on to the next item.
  609. continue;
  610. }
  611. if (!fHandlerParent)
  612. {
  613. iParentItemId = LVI_ROOT;
  614. }
  615. else
  616. {
  617. // need to add to list so find parent and if one doesn't exist, create it.
  618. lvHandlerItemBlob.cbSize = sizeof(LVHANDLERITEMBLOB);
  619. lvHandlerItemBlob.clsidServer = pHandlerItem->handlerID;
  620. lvHandlerItemBlob.ItemID = GUID_NULL;
  621. iParentItemId = m_pListView->FindItemFromBlob((LPLVBLOB) &lvHandlerItemBlob);
  622. if (-1 == iParentItemId)
  623. {
  624. LVITEMEX itemInfoParent;
  625. SYNCMGRHANDLERINFO *pSyncMgrHandlerInfo;
  626. // if can't get the ParentInfo then don't add the Item
  627. if (NOERROR != m_pISyncSchedp->GetHandlerInfo(pHandlerItem->handlerID,&pSyncMgrHandlerInfo) )
  628. {
  629. continue;
  630. }
  631. // Insert the Parent.
  632. itemInfoParent.mask = LVIF_TEXT | LVIF_PARAM;
  633. itemInfoParent.iItem = LVI_LAST;
  634. itemInfoParent.iSubItem = 0;
  635. itemInfoParent.lParam = 0;
  636. itemInfoParent.iImage = -1;
  637. itemInfoParent.pszText = pSyncMgrHandlerInfo->wszHandlerName;
  638. if (himage)
  639. {
  640. HICON hIcon = pSyncMgrHandlerInfo->hIcon ? pSyncMgrHandlerInfo->hIcon : pHandlerItem->hIcon;
  641. // if have toplevel handler info icon use this else use the
  642. // items icon
  643. if (hIcon && (itemInfoParent.iImage =
  644. ImageList_AddIcon(himage,hIcon)) )
  645. {
  646. itemInfoParent.mask |= LVIF_IMAGE ;
  647. }
  648. }
  649. // save the blob
  650. itemInfoParent.maskEx = LVIFEX_BLOB;
  651. itemInfoParent.pBlob = (LPLVBLOB) &lvHandlerItemBlob;
  652. iParentItemId = m_pListView->InsertItem(&itemInfoParent);
  653. CoTaskMemFree(pSyncMgrHandlerInfo);
  654. // if parent insert failed go onto the next item
  655. if (-1 == iParentItemId)
  656. {
  657. continue;
  658. }
  659. }
  660. }
  661. itemInfo.mask = LVIF_TEXT | LVIF_PARAM;
  662. itemInfo.maskEx = LVIFEX_PARENT | LVIFEX_BLOB;
  663. itemInfo.iItem = LVI_LAST;
  664. itemInfo.iSubItem = 0;
  665. itemInfo.lParam = (LPARAM)pHandlerItem;
  666. itemInfo.pszText = pHandlerItem->wszItemName;
  667. itemInfo.iImage = -1; // index of the list view item?s icon
  668. if (himage && pHandlerItem->hIcon)
  669. {
  670. itemInfo.iImage =
  671. ImageList_AddIcon(himage,pHandlerItem->hIcon);
  672. itemInfo.mask |= LVIF_IMAGE;
  673. }
  674. itemInfo.iParent = iParentItemId;
  675. // setup the blob
  676. lvHandlerItemBlob.ItemID = pHandlerItem->itemID;
  677. itemInfo.pBlob = (LPLVBLOB) &lvHandlerItemBlob;
  678. itemInfo.iItem = m_pListView->InsertItem(&itemInfo);
  679. if (-1 == itemInfo.iItem)
  680. {
  681. continue;
  682. }
  683. //Set the check state of the item
  684. itemInfo.mask = LVIF_STATE;
  685. itemInfo.stateMask= LVIS_STATEIMAGEMASK;
  686. if (fClear)
  687. {
  688. itemInfo.state = LVIS_STATEIMAGEMASK_UNCHECK;
  689. m_fItemsChanged = TRUE;
  690. }
  691. else
  692. {
  693. itemInfo.state = pHandlerItem->dwCheckState == SYNCMGRITEMSTATE_UNCHECKED ?
  694. LVIS_STATEIMAGEMASK_UNCHECK : LVIS_STATEIMAGEMASK_CHECK ;
  695. }
  696. m_pListView->SetItem(&itemInfo);
  697. pHandlerItem = (LPSYNC_HANDLER_ITEM_INFO) ALLOC(sizeof(SYNC_HANDLER_ITEM_INFO));
  698. }
  699. if (m_pListView->GetItemCount())
  700. {
  701. m_pListView->SetItemState(0,
  702. LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED );
  703. }
  704. //free the last one we created, we didn't use it.
  705. if (pHandlerItem)
  706. {
  707. FREE(pHandlerItem);
  708. }
  709. pIEnum->Release();
  710. m_Initialized = TRUE;
  711. if (m_pListView->GetCheckedItemsCount())
  712. {
  713. PropSheet_SetWizButtons(GetParent(m_hwnd), PSWIZB_BACK | PSWIZB_NEXT);
  714. }
  715. else
  716. {
  717. PropSheet_SetWizButtons(GetParent(m_hwnd), PSWIZB_BACK);
  718. }
  719. return TRUE;
  720. }