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.

1990 lines
52 KiB

  1. //==========================================================================
  2. //
  3. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. // PURPOSE.
  7. //
  8. // Copyright 1998 - 1999 Microsoft Corporation. All Rights Reserved.
  9. //
  10. //--------------------------------------------------------------------------
  11. // global settings class created in DLLMain
  12. // manages user settings and keeps track of what items are synchronizing
  13. // between all instances.
  14. #include "precomp.h"
  15. extern HINSTANCE g_hmodThisDll; // Handle to this DLL itself.
  16. extern CSettings *g_pSettings; // ptr to global settings class.
  17. //+---------------------------------------------------------------------------
  18. //
  19. // Member: CSettings::CSettings, public
  20. //
  21. // Synopsis:
  22. //
  23. // Returns:
  24. //
  25. // Modifies:
  26. //
  27. //----------------------------------------------------------------------------
  28. CSettings::CSettings()
  29. {
  30. m_cRefs = 1;
  31. m_pHandlerItems = NULL;
  32. }
  33. //+---------------------------------------------------------------------------
  34. //
  35. // Member: CSettings::~CSettings, public
  36. //
  37. // Synopsis: Destructor
  38. //
  39. // Arguments:
  40. //
  41. // Returns:
  42. //
  43. // Modifies:
  44. //
  45. //----------------------------------------------------------------------------
  46. CSettings::~CSettings()
  47. {
  48. Assert(0 == m_cRefs);
  49. if (m_pHandlerItems)
  50. {
  51. LPGENERICITEMLIST pHandlerItems = m_pHandlerItems;
  52. m_pHandlerItems = NULL;
  53. Release_ItemList(pHandlerItems);
  54. }
  55. }
  56. //+---------------------------------------------------------------------------
  57. //
  58. // Member: CSettings::AddRef, public
  59. //
  60. // Synopsis:
  61. //
  62. // Arguments:
  63. //
  64. // Returns:
  65. //
  66. // Modifies:
  67. //
  68. //----------------------------------------------------------------------------
  69. STDMETHODIMP_(ULONG) CSettings::AddRef()
  70. {
  71. DWORD cRefs;
  72. Assert(m_cRefs >= 1); // should never zero bounce.
  73. cRefs = InterlockedIncrement((LONG *)& m_cRefs);
  74. return cRefs;
  75. }
  76. //+---------------------------------------------------------------------------
  77. //
  78. // Member: CSettings::Release, public
  79. //
  80. // Synopsis:
  81. //
  82. // Arguments:
  83. //
  84. // Returns:
  85. //
  86. // Modifies:
  87. //
  88. //----------------------------------------------------------------------------
  89. STDMETHODIMP_(ULONG) CSettings::Release()
  90. {
  91. DWORD cRefs;
  92. cRefs = InterlockedDecrement( (LONG *) &m_cRefs);
  93. Assert(cRefs >= 0); // should never go negative.
  94. if (0 == cRefs)
  95. {
  96. delete this;
  97. }
  98. return cRefs;
  99. }
  100. //+---------------------------------------------------------------------------
  101. //
  102. // Member: CSettings::EnumSyncMgrItems, public
  103. //
  104. // Synopsis: Returns a SyncMgrEnum enumerator of current items
  105. //
  106. // Arguments:
  107. //
  108. // Returns:
  109. //
  110. // Modifies:
  111. //
  112. //----------------------------------------------------------------------------
  113. STDMETHODIMP CSettings::EnumSyncMgrItems(ISyncMgrEnumItems** ppenumOffineItems)
  114. {
  115. CLock clock(this);
  116. clock.Enter();
  117. ReadSettings(FALSE /* fForce */); // make sure settings have been read in
  118. *ppenumOffineItems = NULL;
  119. if (m_pHandlerItems)
  120. {
  121. LPGENERICITEMLIST pDupList;
  122. // snapshot itemlist for enum so don't have to
  123. // worry about changes.
  124. pDupList = DuplicateItemList(m_pHandlerItems);
  125. if (pDupList)
  126. {
  127. *ppenumOffineItems = new CEnumSyncMgrItems(pDupList,0);
  128. Release_ItemList(pDupList);
  129. }
  130. }
  131. clock.Leave();
  132. return *ppenumOffineItems ? NOERROR: E_OUTOFMEMORY;
  133. }
  134. //+---------------------------------------------------------------------------
  135. //
  136. // Member: CSettings::ShowProperties, public
  137. //
  138. // Synopsis: Displays the property page for the requested item.
  139. // it ItemID == GUID_NULL the top-level property page
  140. // is shown.
  141. //
  142. // Arguments:
  143. //
  144. // Returns:
  145. //
  146. // Modifies:
  147. //
  148. //----------------------------------------------------------------------------
  149. STDMETHODIMP CSettings::ShowProperties(HWND hWndParent,REFSYNCMGRITEMID ItemID)
  150. {
  151. HRESULT hr = NOERROR;
  152. DWORD dwResult;
  153. CLock clock(this);
  154. clock.Enter();
  155. ReadSettings(FALSE /* fForce */); // make sure settings are read in.a
  156. clock.Leave();
  157. if (GUID_NULL == ItemID)
  158. {
  159. PROPSHEETPAGE psp [1];
  160. HPROPSHEETPAGE hpsp [1];
  161. PROPSHEETHEADER psh;
  162. CONFIGSETTINGSLPARAM configlParam;
  163. configlParam.pSettings = this;
  164. configlParam.hr = NOERROR;
  165. memset(psp,0,sizeof(psp));
  166. memset(&psh,0,sizeof(psh));
  167. psp[0].dwSize = sizeof (psp[0]);
  168. psp[0].dwFlags = PSP_DEFAULT | PSP_USETITLE;
  169. psp[0].hInstance = g_hmodThisDll;
  170. psp[0].pszTemplate = MAKEINTRESOURCE(IDD_CONFIGDIALOG);
  171. psp[0].pszIcon = NULL;
  172. psp[0].pfnDlgProc = (DLGPROC) ConfigureDlgProc;
  173. psp[0].pszTitle = MAKEINTRESOURCE(IDS_CONFIG_TAB);
  174. psp[0].lParam = (LPARAM) &configlParam;
  175. if (hpsp[0] = CreatePropertySheetPage(&(psp[0])))
  176. {
  177. psh.dwSize = sizeof (psh);
  178. psh.dwFlags = PSH_DEFAULT | PSH_USEHICON;
  179. psh.hwndParent = hWndParent;
  180. psh.hInstance = g_hmodThisDll;
  181. psh.pszIcon = NULL;
  182. psh.hIcon = LoadIcon(g_hmodThisDll, MAKEINTRESOURCE(IDI_SAMPLEHANDLERICON));
  183. psh.pszCaption = MAKEINTRESOURCE(IDS_CONFIG_TITLE);
  184. psh.nPages = 1;
  185. psh.phpage = hpsp;
  186. psh.pfnCallback = NULL;
  187. psh.nStartPage = 0;
  188. dwResult = PropertySheet(&psh);
  189. hr = configlParam.hr;
  190. }
  191. }
  192. else
  193. {
  194. if (S_OK == ShowItemProperties(hWndParent,FALSE /*fNewItem */,
  195. NULL,ItemID))
  196. {
  197. hr = S_SYNCMGR_ENUMITEMS;
  198. }
  199. }
  200. return hr;
  201. }
  202. //+---------------------------------------------------------------------------
  203. //
  204. // Member: CSettings::RequestItemLock, public
  205. //
  206. // Synopsis: Called by handler Requests a Lock on the Item
  207. // once given the lock no other handler instance
  208. // can obtain it. This ensures only one handler
  209. // instance is synchronizing an item at a time.
  210. //
  211. // Arguments:
  212. //
  213. // Returns:
  214. //
  215. // Modifies:
  216. //
  217. //----------------------------------------------------------------------------
  218. BOOL CSettings::RequestItemLock(CSyncMgrHandler *pLockHandler,REFSYNCMGRITEMID ItemID)
  219. {
  220. LPSAMPLEITEMSETTINGS pItemSettings;
  221. CLock clock(this);
  222. clock.Enter();
  223. pItemSettings = FindItemSettings(ItemID);
  224. if (pItemSettings && !(pItemSettings->fSyncLock))
  225. {
  226. Assert(NULL == pItemSettings->pLockHandler);
  227. pItemSettings->fSyncLock = TRUE;
  228. pItemSettings->pLockHandler = pLockHandler;
  229. clock.Leave();
  230. return TRUE;
  231. }
  232. clock.Leave();
  233. return FALSE;
  234. }
  235. //+---------------------------------------------------------------------------
  236. //
  237. // Member: CSettings::ReleaseItemLock, public
  238. //
  239. // Synopsis: Called by Handler to inform settings that it is
  240. // done synchronizing an Item and no longer needs the lock.
  241. // Filetime field request the last update time be upated.
  242. //
  243. // Arguments:
  244. //
  245. // Returns:
  246. //
  247. // Modifies:
  248. //
  249. //----------------------------------------------------------------------------
  250. BOOL CSettings::ReleaseItemLock(CSyncMgrHandler *pLockHandler,REFSYNCMGRITEMID ItemID
  251. ,FILETIME *pftLastUpdate)
  252. {
  253. return ReleaseItemLockX(pLockHandler,ItemID,TRUE,pftLastUpdate);
  254. }
  255. //+---------------------------------------------------------------------------
  256. //
  257. // Member: CSettings::ReleaseItemLock, public
  258. //
  259. // Synopsis: Called by Handler to inform settings that it is
  260. // done synchronizing an Item and no longer needs the lock.
  261. //
  262. // Arguments:
  263. //
  264. // Returns:
  265. //
  266. // Modifies:
  267. //
  268. //----------------------------------------------------------------------------
  269. BOOL CSettings::ReleaseItemLock(CSyncMgrHandler *pLockHandler,REFSYNCMGRITEMID ItemID)
  270. {
  271. return ReleaseItemLockX(pLockHandler,ItemID,FALSE,NULL);
  272. }
  273. //+---------------------------------------------------------------------------
  274. //
  275. // Member: CSettings::ReleaseItemLockX, private
  276. //
  277. // Synopsis: private call to release synchronize call and update filetime
  278. // if necessary.
  279. //
  280. // Arguments:
  281. //
  282. // Returns:
  283. //
  284. // Modifies:
  285. //
  286. //----------------------------------------------------------------------------
  287. BOOL CSettings::ReleaseItemLockX(CSyncMgrHandler *pLockHandler,REFSYNCMGRITEMID ItemID,
  288. BOOL fUpdateft,FILETIME *pftLastUpdate)
  289. {
  290. LPSAMPLEITEMSETTINGS pItemSettings;
  291. CLock clock(this);
  292. clock.Enter();
  293. pItemSettings = FindItemSettings(ItemID);
  294. if (pItemSettings)
  295. {
  296. Assert(TRUE == pItemSettings->fSyncLock);
  297. Assert(pLockHandler == pItemSettings->pLockHandler);
  298. if (pItemSettings->pLockHandler == pLockHandler)
  299. {
  300. pItemSettings->fSyncLock = FALSE;
  301. pItemSettings->pLockHandler = NULL;
  302. if (fUpdateft)
  303. {
  304. pItemSettings->syncmgrItem.ftLastUpdate = *pftLastUpdate;
  305. // write out item to registry to update the last update time.
  306. WriteItemSettings(pItemSettings);
  307. }
  308. }
  309. clock.Leave();
  310. return TRUE;
  311. }
  312. clock.Leave();
  313. return FALSE;
  314. }
  315. //+---------------------------------------------------------------------------
  316. //
  317. // Member: CSettings::CopyHandlerSyncInfo, public
  318. //
  319. // Synopsis: Called by handler to obtain information it
  320. // needs on an item to perform a synchronization.
  321. //
  322. // Arguments:
  323. //
  324. // Returns:
  325. //
  326. // Modifies:
  327. //
  328. //----------------------------------------------------------------------------
  329. BOOL CSettings::CopyHandlerSyncInfo(REFSYNCMGRITEMID ItemID,
  330. /* [in,out] */ LPHANDLERITEMSETTINGS pHandlerSyncItem)
  331. {
  332. LPSAMPLEITEMSETTINGS pItemSettings;
  333. BOOL fReturn = FALSE;
  334. CLock clock(this);
  335. clock.Enter();
  336. pItemSettings = FindItemSettings(ItemID);
  337. Assert(pHandlerSyncItem);
  338. if (pItemSettings && pHandlerSyncItem)
  339. {
  340. pHandlerSyncItem->ItemID = ItemID;
  341. pHandlerSyncItem->ft = pItemSettings->syncmgrItem.ftLastUpdate;
  342. pHandlerSyncItem->fRecursive = pItemSettings->fRecursive;
  343. lstrcpyn(pHandlerSyncItem->dir1,pItemSettings->dir1,
  344. sizeof(pHandlerSyncItem->dir1)/sizeof(TCHAR));
  345. lstrcpyn(pHandlerSyncItem->dir2,pItemSettings->dir2,
  346. sizeof(pHandlerSyncItem->dir2)/sizeof(TCHAR));
  347. #ifndef _UNICODE
  348. WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
  349. pItemSettings->syncmgrItem.wszItemName,
  350. -1, pHandlerSyncItem->szItemName,
  351. sizeof(pHandlerSyncItem->szItemName)/sizeof(TCHAR), NULL, NULL);
  352. #else
  353. lstrcpyn(pHandlerSyncItem->szItemName,
  354. pItemSettings->syncmgrItem.wszItemName,
  355. sizeof(pHandlerSyncItem->szItemName));
  356. #endif // _UNICODE
  357. fReturn = TRUE;
  358. }
  359. clock.Leave();
  360. return fReturn;
  361. }
  362. //+---------------------------------------------------------------------------
  363. //
  364. // Member: CSettings::ReadSettings, private
  365. //
  366. // Synopsis: Called to Read in Settings from Registry
  367. //
  368. // Arguments:
  369. //
  370. // Returns:
  371. //
  372. // Modifies:
  373. //
  374. //----------------------------------------------------------------------------
  375. STDMETHODIMP CSettings::ReadSettings(BOOL fForce)
  376. {
  377. HKEY hkeyHandlerPerf;
  378. ASSERT_LOCKHELD(this);
  379. // if not forced to refresh and already have a list just re-use it.
  380. if (!fForce && m_pHandlerItems)
  381. {
  382. return NOERROR;
  383. }
  384. Assert(NULL == m_pHandlerItems);
  385. m_pHandlerItems = CreateItemList();
  386. if (!m_pHandlerItems)
  387. {
  388. return E_OUTOFMEMORY;
  389. }
  390. // loop through registered items loading them in.
  391. if (hkeyHandlerPerf = CreateHandlerPrefKey(CLSID_SyncMgrHandler))
  392. {
  393. TCHAR lpName[256];
  394. WCHAR *pszName;
  395. DWORD cbName = 256;
  396. CLSID clsid;
  397. DWORD dwIndex = 0;
  398. while ( ERROR_SUCCESS == RegEnumKey(hkeyHandlerPerf,dwIndex,
  399. lpName,cbName) )
  400. {
  401. #ifndef _UNICODE
  402. WCHAR pwszItemID[MAX_SYNCMGRITEMNAME];
  403. MultiByteToWideChar(CP_ACP, 0,
  404. lpName,
  405. -1, pwszItemID,MAX_SYNCMGRITEMNAME);
  406. pszName = pwszItemID;
  407. #else
  408. pszName = lpName;
  409. #endif // _UNICODE
  410. if (NOERROR == CLSIDFromString(pszName,&clsid) )
  411. {
  412. LPSAMPLEITEMSETTINGS pSampleItem;
  413. // set up item list,
  414. pSampleItem = (LPSAMPLEITEMSETTINGS) AddNewItemToList(m_pHandlerItems,sizeof(SAMPLEITEMSETTINGS));
  415. if (!pSampleItem)
  416. {
  417. continue;
  418. }
  419. // setup values we don't get from preferences.
  420. pSampleItem->syncmgrItem.cbSize = sizeof(SYNCMGRITEM);
  421. pSampleItem->syncmgrItem.dwItemState = SYNCMGRITEMSTATE_CHECKED;
  422. pSampleItem->syncmgrItem.hIcon =
  423. LoadIcon(g_hmodThisDll,MAKEINTRESOURCE(IDI_SAMPLEHANDLERICON));
  424. pSampleItem->syncmgrItem.dwFlags =
  425. SYNCMGRITEM_HASPROPERTIES | SYNCMGRITEM_LASTUPDATETIME;
  426. // read in items from preferences
  427. Reg_GetItemSettingsForHandlerItem(hkeyHandlerPerf,
  428. clsid,
  429. pSampleItem);
  430. }
  431. dwIndex++;
  432. }
  433. RegCloseKey(hkeyHandlerPerf);
  434. }
  435. return NOERROR;
  436. }
  437. //+---------------------------------------------------------------------------
  438. //
  439. // Member: CSettings::WriteItemSettings, private
  440. //
  441. // Synopsis: Called to write out settings to the Registry
  442. //
  443. // Arguments:
  444. //
  445. // Returns:
  446. //
  447. // Modifies:
  448. //
  449. //----------------------------------------------------------------------------
  450. BOOL CSettings::WriteItemSettings(LPSAMPLEITEMSETTINGS pSampleItemSettings)
  451. {
  452. ASSERT_LOCKHELD(this);
  453. Reg_SetItemSettingsForHandlerItem(CLSID_SyncMgrHandler,
  454. pSampleItemSettings->syncmgrItem.ItemID,
  455. pSampleItemSettings);
  456. return TRUE;
  457. }
  458. // deletes item settings from the registry
  459. BOOL CSettings::DeleteItemSettings(LPSAMPLEITEMSETTINGS pSampleItemSettings)
  460. {
  461. ASSERT_LOCKHELD(this);
  462. Reg_DeleteItemIdForHandlerItem(CLSID_SyncMgrHandler,
  463. pSampleItemSettings->syncmgrItem.ItemID);
  464. return TRUE;
  465. }
  466. //+---------------------------------------------------------------------------
  467. //
  468. // Member: CSettings::WriteItemSettings, private
  469. //
  470. // Synopsis: Finds item settings in list for the specified ItemID
  471. // caller must have put a lock on the settings list
  472. // and not release it until it is done using the
  473. // structure pointed to by the return value.
  474. //
  475. // Arguments:
  476. //
  477. // Returns:
  478. //
  479. // Modifies:
  480. //
  481. //----------------------------------------------------------------------------
  482. LPSAMPLEITEMSETTINGS CSettings::FindItemSettings(REFSYNCMGRITEMID ItemID)
  483. {
  484. LPSAMPLEITEMSETTINGS pItemSettings = NULL;
  485. ASSERT_LOCKHELD(this);
  486. ReadSettings(FALSE /* fForce */); // make sure settings are read in.a
  487. if (m_pHandlerItems)
  488. {
  489. pItemSettings = (LPSAMPLEITEMSETTINGS) m_pHandlerItems->pFirstGenericItem;
  490. while (pItemSettings)
  491. {
  492. Assert(sizeof(SAMPLEITEMSETTINGS) == pItemSettings->genericItem.cbSize);
  493. if (ItemID == pItemSettings->syncmgrItem.ItemID)
  494. {
  495. break;
  496. }
  497. pItemSettings = (LPSAMPLEITEMSETTINGS) pItemSettings->genericItem.pNextGenericItem;
  498. }
  499. }
  500. AssertSz(pItemSettings,"Item not Found");
  501. return pItemSettings;
  502. }
  503. //+---------------------------------------------------------------------------
  504. //
  505. // Member: CSettings::ShowItemProperties, private
  506. //
  507. // Synopsis: called internally by class to show item properties
  508. // if fNewItem is set to true then the pItemSettings
  509. // argument is used. else need to lookup pItemSettings
  510. // from ItemID each time it is needed.
  511. //
  512. // Arguments:
  513. //
  514. // Returns:
  515. //
  516. // Modifies:
  517. //
  518. //----------------------------------------------------------------------------
  519. STDMETHODIMP CSettings::ShowItemProperties(HWND hWndParent,BOOL fNewItem,
  520. LPSAMPLEITEMSETTINGS pItemSettings,
  521. SYNCMGRITEMID ItemID)
  522. {
  523. HRESULT hr = NOERROR;
  524. PROPSHEETPAGE psp [1];
  525. HPROPSHEETPAGE hpsp [1];
  526. PROPSHEETHEADER psh;
  527. ITEMCONFIGSETTINGSLPARAM ItemConfiglParam;
  528. TCHAR szLocalDisplayNameBuf[MAX_SYNCMGRITEMNAME];
  529. TCHAR *pDisplayName;
  530. WCHAR *pwszDisplayName = NULL;
  531. CLock clock(this);
  532. ItemConfiglParam.pSettings = this;
  533. ItemConfiglParam.hr = NOERROR;
  534. ItemConfiglParam.fNewItem = fNewItem;
  535. // if new item save to use settings, else use ItemID and look up
  536. // in list when need in case item deleted by someone else.
  537. clock.Enter(); // setup lock to get the display Name.
  538. if (fNewItem)
  539. {
  540. Assert(pItemSettings);
  541. ItemConfiglParam.pItemSettings = pItemSettings;
  542. ItemConfiglParam.ItemID = GUID_NULL;
  543. pwszDisplayName = pItemSettings->syncmgrItem.wszItemName;
  544. }
  545. else
  546. {
  547. LPSAMPLEITEMSETTINGS pTempItemSettings;
  548. Assert(NULL == pItemSettings);
  549. ItemConfiglParam.pItemSettings = NULL;
  550. ItemConfiglParam.ItemID = ItemID;
  551. if (pTempItemSettings = FindItemSettings(ItemID))
  552. {
  553. pwszDisplayName = pTempItemSettings->syncmgrItem.wszItemName;
  554. }
  555. }
  556. // convert the display name before release lock to properly handler
  557. // existing items.
  558. pDisplayName = szLocalDisplayNameBuf;
  559. *szLocalDisplayNameBuf = NULL;
  560. if (pwszDisplayName)
  561. {
  562. #if _UNICODE
  563. lstrcpy(szLocalDisplayNameBuf,pwszDisplayName);
  564. #else
  565. WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
  566. pwszDisplayName,
  567. -1, szLocalDisplayNameBuf,MAX_SYNCMGRITEMNAME, NULL, NULL);
  568. #endif // _UNICODE
  569. }
  570. clock.Leave();
  571. memset(psp,0,sizeof(psp));
  572. memset(&psh,0,sizeof(psh));
  573. psp[0].dwSize = sizeof (psp[0]);
  574. psp[0].dwFlags = PSP_DEFAULT | PSP_USETITLE;
  575. psp[0].hInstance = g_hmodThisDll;
  576. psp[0].pszTemplate = MAKEINTRESOURCE(IDD_ITEMCONFIGDIALOG);
  577. psp[0].pszIcon = NULL;
  578. psp[0].pfnDlgProc = (DLGPROC) ItemConfigDlgProc;
  579. psp[0].pszTitle = MAKEINTRESOURCE(IDS_ITEMCONFIG_TAB);
  580. psp[0].lParam = (LPARAM) &ItemConfiglParam;
  581. if (hpsp[0] = CreatePropertySheetPage(&(psp[0])))
  582. {
  583. psh.dwSize = sizeof (psh);
  584. psh.dwFlags = PSH_DEFAULT | PSH_USEHICON;
  585. psh.hwndParent = hWndParent;
  586. psh.hInstance = g_hmodThisDll;
  587. psh.pszIcon = NULL;
  588. psh.hIcon = LoadIcon(g_hmodThisDll, MAKEINTRESOURCE(IDI_SAMPLEHANDLERITEMICON));
  589. psh.pszCaption = pDisplayName;
  590. psh.nPages = 1;
  591. psh.phpage = hpsp;
  592. psh.pfnCallback = NULL;
  593. psh.nStartPage = 0;
  594. PropertySheet(&psh);
  595. hr = ItemConfiglParam.hr;
  596. }
  597. return hr;
  598. }
  599. //+---------------------------------------------------------------------------
  600. //
  601. // Member: CSettings::Alert, private
  602. //
  603. // Synopsis: Simple helper to show a message box.
  604. //
  605. // Arguments:
  606. //
  607. // Returns:
  608. //
  609. // Modifies:
  610. //
  611. //----------------------------------------------------------------------------
  612. int CSettings::Alert(HWND hWnd,LPCTSTR lpText)
  613. {
  614. return ::MessageBox(hWnd,lpText,TEXT("Sample Handler"),MB_OK | MB_ICONERROR);
  615. }
  616. //+---------------------------------------------------------------------------
  617. //
  618. // Member: CSettings::ConfigDlgAddListViewItem, private
  619. //
  620. // Synopsis: Adds a ListViewItem to the Config Dialog.
  621. //
  622. // Arguments:
  623. //
  624. // Returns: -1 on falure
  625. //
  626. // Modifies:
  627. //
  628. //----------------------------------------------------------------------------
  629. int CSettings::ConfigDlgAddListViewItem(HWND hWndList,SYNCMGRITEM syncMgrItem,int iItem
  630. ,int iIconIndex)
  631. {
  632. LV_ITEM lvItem;
  633. CONFIGITEMLISTVIEWLPARAM *pConfigItemListViewlParam;
  634. int iResult = -1;
  635. lvItem.mask = LVIF_TEXT | LVIF_PARAM;
  636. lvItem.iItem = iItem;
  637. lvItem.iSubItem = 0;
  638. #ifdef _UNICODE
  639. lvItem.pszText = syncMgrItem.wszItemName;
  640. #else
  641. char TextBuf[MAX_PATH];
  642. *TextBuf = NULL;
  643. WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, syncMgrItem.wszItemName,
  644. -1, TextBuf,MAX_PATH, NULL, NULL);
  645. lvItem.pszText = TextBuf;
  646. #endif // _UNICODE
  647. if (iIconIndex >= 0)
  648. {
  649. lvItem.mask |= LVIF_IMAGE;
  650. lvItem.iImage = iIconIndex;
  651. }
  652. // need to store somethin in lParam so can get Item from it.
  653. pConfigItemListViewlParam = (CONFIGITEMLISTVIEWLPARAM *) ALLOC(sizeof(CONFIGITEMLISTVIEWLPARAM));
  654. if (pConfigItemListViewlParam)
  655. {
  656. pConfigItemListViewlParam->ItemID = syncMgrItem.ItemID;
  657. lvItem.lParam = (LPARAM) pConfigItemListViewlParam;
  658. //add the item to the list
  659. iResult = ListView_InsertItem(hWndList, &lvItem);
  660. if (-1 == iResult)
  661. {
  662. FREE(pConfigItemListViewlParam);
  663. }
  664. }
  665. return iResult;
  666. }
  667. //+---------------------------------------------------------------------------
  668. //
  669. // Member: CSettings::OnConfigDlgInit, private
  670. //
  671. // Synopsis: Initializes the Config Dialog.
  672. //
  673. // Arguments:
  674. //
  675. // Returns:
  676. //
  677. // Modifies:
  678. //
  679. //----------------------------------------------------------------------------
  680. void CSettings::OnConfigDlgInit(HWND hWnd,CONFIGSETTINGSLPARAM *pConfigSettingslParam,
  681. UINT uMessage, WPARAM wParam,LPARAM lParam)
  682. {
  683. HWND hwndList = GetDlgItem(hWnd,IDC_CONFIGDIALOG_ITEMLIST);
  684. if (hwndList)
  685. {
  686. int iItem = 0;
  687. LV_COLUMN columnInfo;
  688. HIMAGELIST himage;
  689. int iIconIndex = -1;
  690. ISyncMgrEnumItems *pEnumItems;
  691. ListView_SetExtendedListViewStyle(hwndList, LVS_EX_FULLROWSELECT);
  692. // Insert the Proper columns
  693. columnInfo.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
  694. columnInfo.fmt = LVCFMT_LEFT;
  695. columnInfo.cx = CalcListViewWidth(hwndList,300);
  696. columnInfo .pszText = TEXT("Items");
  697. columnInfo.iSubItem = 0;
  698. ListView_InsertColumn(hwndList,0,&columnInfo);
  699. // create an imagelist
  700. himage = ImageList_Create( GetSystemMetrics(SM_CXSMICON),
  701. GetSystemMetrics(SM_CYSMICON),ILC_COLOR | ILC_MASK,5,20);
  702. if (himage)
  703. {
  704. ListView_SetImageList(hwndList,himage,LVSIL_SMALL);
  705. }
  706. HICON hIcon = LoadIcon(g_hmodThisDll,MAKEINTRESOURCE(IDI_SAMPLEHANDLERITEMICON));
  707. if (hIcon)
  708. {
  709. iIconIndex = ImageList_AddIcon(himage,hIcon);
  710. }
  711. // loop though item enumerator adding the info.
  712. if (NOERROR == EnumSyncMgrItems(&pEnumItems))
  713. {
  714. SYNCMGRITEM syncMgrItem;
  715. ULONG fetched;
  716. while (NOERROR == pEnumItems->Next(1,&syncMgrItem,&fetched))
  717. {
  718. if (-1 != ConfigDlgAddListViewItem(hwndList,syncMgrItem,iItem,iIconIndex))
  719. {
  720. iItem++;
  721. }
  722. }
  723. pEnumItems->Release();
  724. }
  725. }
  726. }
  727. //+---------------------------------------------------------------------------
  728. //
  729. // Member: CSettings::DeleteListViewItem, private
  730. //
  731. // Synopsis: deletes an Item from the Config Dialog ListView
  732. //
  733. // Arguments:
  734. //
  735. // Returns:
  736. //
  737. // Modifies:
  738. //
  739. //----------------------------------------------------------------------------
  740. BOOL CSettings::ConfigDlgDeleteListViewItem(HWND hWndList,int iItem)
  741. {
  742. LV_ITEM lvItem;
  743. CONFIGITEMLISTVIEWLPARAM *pConfigItemListViewlParam;
  744. BOOL fResult = FALSE;
  745. lvItem.mask = LVIF_PARAM;
  746. lvItem.iItem = iItem;
  747. if (ListView_GetItem(hWndList, &lvItem))
  748. {
  749. pConfigItemListViewlParam = (CONFIGITEMLISTVIEWLPARAM *) lvItem.lParam;
  750. if (ListView_DeleteItem(hWndList,iItem))
  751. {
  752. fResult = TRUE;
  753. if (pConfigItemListViewlParam)
  754. {
  755. FREE(pConfigItemListViewlParam);
  756. }
  757. }
  758. }
  759. return fResult;
  760. }
  761. //+---------------------------------------------------------------------------
  762. //
  763. // Member: CSettings::OnConfigDlgDestroy, private
  764. //
  765. // Synopsis: called to cleanup the dialog
  766. //
  767. // Arguments:
  768. //
  769. // Returns:
  770. //
  771. // Modifies:
  772. //
  773. //----------------------------------------------------------------------------
  774. void CSettings::OnConfigDlgDestroy(HWND hWnd,CONFIGSETTINGSLPARAM *pConfigSettingslParam,
  775. UINT uMessage, WPARAM wParam,LPARAM lParam)
  776. {
  777. HWND hwndListView = GetDlgItem(hWnd,IDC_CONFIGDIALOG_ITEMLIST);
  778. int iItemCount;
  779. int iItem;
  780. if (!hwndListView)
  781. {
  782. return;
  783. }
  784. iItemCount = ListView_GetItemCount(hwndListView);
  785. for(iItem = 0; iItem < iItemCount; iItem++)
  786. {
  787. ConfigDlgDeleteListViewItem(hwndListView,0); // delete list view items to cleanup lParam
  788. }
  789. }
  790. //+---------------------------------------------------------------------------
  791. //
  792. // Member: CSettings::OnConfigDlgNotify, private
  793. //
  794. // Synopsis: handles WM_NOTIFY messages for the Config Dialog
  795. //
  796. // Arguments:
  797. //
  798. // Returns:
  799. //
  800. // Modifies:
  801. //
  802. //----------------------------------------------------------------------------
  803. void CSettings::OnConfigDlgNotify(HWND hWnd,CONFIGSETTINGSLPARAM *pConfigSettingslParam,
  804. UINT uMessage, WPARAM wParam,LPARAM lParam)
  805. {
  806. LPNMHDR pnmhdr = (LPNMHDR)lParam;
  807. int iCtrlId = wParam;
  808. // enable/disable edit and remove button based on listview selection.
  809. if (IDC_CONFIGDIALOG_ITEMLIST == iCtrlId)
  810. {
  811. LPNMLISTVIEW pnmv = (LPNMLISTVIEW) pnmhdr;
  812. switch (pnmhdr->code)
  813. {
  814. case LVN_ITEMCHANGED:
  815. {
  816. if ( (pnmv->uChanged == LVIF_STATE) &&
  817. ((pnmv->uNewState ^ pnmv->uOldState) & LVIS_SELECTED))
  818. {
  819. BOOL fEnable = FALSE;
  820. if (pnmv->uNewState & LVIS_SELECTED)
  821. {
  822. fEnable = TRUE;
  823. }
  824. EnableWindow(GetDlgItem(hWnd,IDC_CONFIGDIALOG_REMOVE),fEnable);
  825. EnableWindow(GetDlgItem(hWnd,IDC_CONFIGDIALOG_EDIT),fEnable);
  826. }
  827. break;
  828. }
  829. case NM_DBLCLK:
  830. {
  831. LV_ITEM lvItem;
  832. CONFIGITEMLISTVIEWLPARAM *pConfigItemListViewlParam;
  833. SYNCMGRITEMID ItemID;
  834. // grab itemid out of the lParam.
  835. lvItem.mask = LVIF_PARAM;
  836. lvItem.iItem = pnmv->iItem;
  837. if (FALSE == ListView_GetItem(GetDlgItem(hWnd,IDC_CONFIGDIALOG_ITEMLIST),&lvItem))
  838. {
  839. return;
  840. }
  841. pConfigItemListViewlParam = (CONFIGITEMLISTVIEWLPARAM *) lvItem.lParam;
  842. if (NULL == pConfigItemListViewlParam)
  843. {
  844. return;
  845. }
  846. ItemID = pConfigItemListViewlParam->ItemID;
  847. OnConfigDlgEdit(hWnd,pConfigSettingslParam,ItemID,pnmv->iItem);
  848. break;
  849. }
  850. default:
  851. break;
  852. }
  853. }
  854. }
  855. //+---------------------------------------------------------------------------
  856. //
  857. // Member: CSettings::OnConfigDlgAdd, private
  858. //
  859. // Synopsis: Implements what happens when User hits Add in the Config Dialog
  860. //
  861. // Arguments:
  862. //
  863. // Returns:
  864. //
  865. // Modifies:
  866. //
  867. //----------------------------------------------------------------------------
  868. void CSettings::OnConfigDlgAdd(HWND hWnd,CONFIGSETTINGSLPARAM *pConfigSettingslParam)
  869. {
  870. LPSAMPLEITEMSETTINGS pSettings = (LPSAMPLEITEMSETTINGS) CreateNewListItem(sizeof(SAMPLEITEMSETTINGS));
  871. if (pSettings)
  872. {
  873. HRESULT hr;
  874. SYNCMGRITEMID offType;
  875. // generate an ID for the item.
  876. CoCreateGuid(&offType);
  877. pSettings->syncmgrItem.ItemID = offType;
  878. pSettings->syncmgrItem.cbSize = sizeof(SYNCMGRITEM);
  879. pSettings->syncmgrItem.dwItemState = SYNCMGRITEMSTATE_CHECKED;
  880. pSettings->syncmgrItem.hIcon =
  881. LoadIcon(g_hmodThisDll,MAKEINTRESOURCE(IDI_SAMPLEHANDLERICON));
  882. pSettings->syncmgrItem.dwFlags =
  883. SYNCMGRITEM_HASPROPERTIES | SYNCMGRITEM_LASTUPDATETIME;
  884. // if wanted to setup default fields for item dialog on first create
  885. // do it here.
  886. hr = ShowItemProperties(hWnd,TRUE /* fNew */, pSettings,GUID_NULL);
  887. // if user hits okay/apply while in ShowItems
  888. // the item has been added to now add it to the global list
  889. if ( (S_OK == hr) &&
  890. AddItemToList(m_pHandlerItems,(LPGENERICITEM) pSettings))
  891. {
  892. HWND hWndList;
  893. HICON hIcon;
  894. int iIconIndex = -1;
  895. HIMAGELIST himage;
  896. hWndList = GetDlgItem(hWnd,IDC_CONFIGDIALOG_ITEMLIST);
  897. if (hWndList)
  898. {
  899. himage = ListView_GetImageList(hWndList,LVSIL_SMALL);
  900. hIcon = LoadIcon(g_hmodThisDll,MAKEINTRESOURCE(IDI_SAMPLEHANDLERITEMICON));
  901. if (hIcon && himage)
  902. {
  903. iIconIndex = ImageList_AddIcon(himage,hIcon);
  904. }
  905. // add new item to the UI.
  906. ConfigDlgAddListViewItem(hWndList,pSettings->syncmgrItem,0,iIconIndex);
  907. }
  908. // need to reenum when return from showProperties if item was added.
  909. pConfigSettingslParam->hr = S_SYNCMGR_ENUMITEMS;
  910. }
  911. else
  912. {
  913. FREE(pSettings);
  914. }
  915. }
  916. }
  917. //+---------------------------------------------------------------------------
  918. //
  919. // Member: CSettings::OnConfigDlgAdd, private
  920. //
  921. // Synopsis: Implements what happens when User hits Remove in the Config Dialog
  922. //
  923. // Arguments:
  924. //
  925. // Returns:
  926. //
  927. // Modifies:
  928. //
  929. //----------------------------------------------------------------------------
  930. void CSettings::OnConfigDlgRemove(HWND hWnd,CONFIGSETTINGSLPARAM *pConfigSettingslParam,
  931. SYNCMGRITEMID ItemID,int iItem)
  932. {
  933. LPSAMPLEITEMSETTINGS pSettings;
  934. CLock clock(this);
  935. Assert(iItem >= 0);
  936. clock.Enter();
  937. pSettings = FindItemSettings(ItemID);
  938. if (pSettings && iItem >= 0)
  939. {
  940. HWND hwndListView = GetDlgItem(hWnd,IDC_CONFIGDIALOG_ITEMLIST);
  941. DeleteItemSettings(pSettings); // delete item from the registry
  942. DeleteItemFromList(m_pHandlerItems, (LPGENERICITEM) pSettings);// remove from enum list
  943. // now remove from UI
  944. if (hwndListView)
  945. {
  946. ConfigDlgDeleteListViewItem(hwndListView,iItem);
  947. }
  948. // on remove force a re-enum when return from ShowProperties.
  949. pConfigSettingslParam->hr = S_SYNCMGR_ENUMITEMS;
  950. }
  951. clock.Leave();
  952. }
  953. //+---------------------------------------------------------------------------
  954. //
  955. // Member: CSettings::OnConfigDlgEdit, private
  956. //
  957. // Synopsis: Implements what happens when User hits Edit in the Config Dialog
  958. //
  959. // Arguments:
  960. //
  961. // Returns:
  962. //
  963. // Modifies:
  964. //
  965. //----------------------------------------------------------------------------
  966. void CSettings::OnConfigDlgEdit(HWND hWnd,CONFIGSETTINGSLPARAM *pConfigSettingslParam,
  967. SYNCMGRITEMID ItemID,int iSelection)
  968. {
  969. if (S_OK == ShowItemProperties(hWnd,FALSE /* fNew */,NULL,ItemID))
  970. {
  971. HWND hwndListView = GetDlgItem(hWnd,IDC_CONFIGDIALOG_ITEMLIST);
  972. LPSAMPLEITEMSETTINGS pSettings;
  973. CLock clock(this);
  974. clock.Enter();
  975. // update the listview to the new display name.
  976. // get settings again in case list changed.
  977. if (hwndListView &&
  978. (pSettings = FindItemSettings(ItemID)))
  979. {
  980. TCHAR *pDisplayName;
  981. #if _UNICODE
  982. pDisplayName = pSettings->syncmgrItem.wszItemName;
  983. #else
  984. char TextBuf[MAX_PATH];
  985. *TextBuf = NULL;
  986. WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
  987. pSettings->syncmgrItem.wszItemName,
  988. -1, TextBuf,MAX_PATH, NULL, NULL);
  989. pDisplayName = TextBuf;
  990. #endif // _UNICODE
  991. ListView_SetItemText(hwndListView,iSelection,0,pDisplayName);
  992. }
  993. // if user change anything re-enum on return to ShowProperties
  994. // in case the display name was changed.
  995. clock.Leave();
  996. pConfigSettingslParam->hr = S_SYNCMGR_ENUMITEMS;
  997. }
  998. }
  999. //+---------------------------------------------------------------------------
  1000. //
  1001. // Member: CSettings::OnConfigDlgAdd, private
  1002. //
  1003. // Synopsis: Handles WM_COMMAND messages to Config Dialog
  1004. //
  1005. // Arguments:
  1006. //
  1007. // Returns:
  1008. //
  1009. // Modifies:
  1010. //
  1011. //----------------------------------------------------------------------------
  1012. void CSettings::OnConfigDlgCommand(HWND hWnd,CONFIGSETTINGSLPARAM *pConfigSettingslParam,
  1013. UINT uMessage, WPARAM wParam,LPARAM lParam)
  1014. {
  1015. WORD wNotifyCode = HIWORD(wParam);
  1016. WORD wID = LOWORD(wParam);
  1017. HWND hwndCtl = (HWND)lParam;
  1018. HWND hwndListView = GetDlgItem(hWnd,IDC_CONFIGDIALOG_ITEMLIST);
  1019. if (BN_CLICKED == wNotifyCode) // all just respond to clicked
  1020. {
  1021. switch (wID)
  1022. {
  1023. case IDC_CONFIGDIALOG_REMOVE:
  1024. case IDC_CONFIGDIALOG_EDIT:
  1025. {
  1026. int iSelection;
  1027. LV_ITEM lvItem;
  1028. CONFIGITEMLISTVIEWLPARAM *pConfigItemListViewlParam;
  1029. SYNCMGRITEMID ItemID;
  1030. if (!hwndListView || (-1 == (iSelection = ListView_GetSelectionMark(hwndListView))))
  1031. {
  1032. return;
  1033. }
  1034. // grab itemid out of the lParam.
  1035. lvItem.mask = LVIF_PARAM;
  1036. lvItem.iItem = iSelection;
  1037. if (FALSE == ListView_GetItem(hwndListView, &lvItem) )
  1038. {
  1039. return;
  1040. }
  1041. pConfigItemListViewlParam = (CONFIGITEMLISTVIEWLPARAM *) lvItem.lParam;
  1042. if (NULL == pConfigItemListViewlParam)
  1043. {
  1044. return;
  1045. }
  1046. ItemID = pConfigItemListViewlParam->ItemID;
  1047. switch (wID)
  1048. {
  1049. case IDC_CONFIGDIALOG_REMOVE:
  1050. OnConfigDlgRemove(hWnd,pConfigSettingslParam,ItemID,iSelection);
  1051. break;
  1052. case IDC_CONFIGDIALOG_EDIT:
  1053. OnConfigDlgEdit(hWnd,pConfigSettingslParam,ItemID,iSelection);
  1054. break;
  1055. default:
  1056. break;
  1057. }
  1058. break;
  1059. }
  1060. case IDC_CONFIGDIALOG_ADD:
  1061. OnConfigDlgAdd(hWnd,pConfigSettingslParam);
  1062. break;
  1063. default:
  1064. break;
  1065. }
  1066. }
  1067. }
  1068. //+---------------------------------------------------------------------------
  1069. //
  1070. // function: ConfigureDlgProc, private
  1071. //
  1072. // Synopsis: wndProc for Configuration Dialog
  1073. //
  1074. // Arguments:
  1075. //
  1076. // Returns:
  1077. //
  1078. // Modifies:
  1079. //
  1080. //----------------------------------------------------------------------------
  1081. BOOL CALLBACK ConfigureDlgProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
  1082. {
  1083. WORD wNotifyCode = HIWORD(wParam); // notification code
  1084. BOOL bResult = FALSE;
  1085. CONFIGSETTINGSLPARAM *pConfigSettingslParam = (CONFIGSETTINGSLPARAM *) GetWindowLong(hWnd,DWL_USER);
  1086. if (WM_INITDIALOG == uMessage)
  1087. {
  1088. pConfigSettingslParam = (CONFIGSETTINGSLPARAM *) ((PROPSHEETPAGE *) lParam)->lParam;
  1089. SetWindowLong(hWnd, DWL_USER, (LONG) pConfigSettingslParam);
  1090. pConfigSettingslParam->pSettings->OnConfigDlgInit(hWnd,pConfigSettingslParam,uMessage,wParam,lParam);
  1091. }
  1092. else if (pConfigSettingslParam)
  1093. {
  1094. switch (uMessage)
  1095. {
  1096. case WM_DESTROY:
  1097. pConfigSettingslParam->pSettings->OnConfigDlgDestroy(hWnd,pConfigSettingslParam,uMessage,wParam,lParam);
  1098. break;
  1099. case WM_NOTIFY:
  1100. switch (((NMHDR FAR *)lParam)->code)
  1101. {
  1102. case PSN_APPLY:
  1103. // if anything changed mark OK even if later cancel, can't undo
  1104. break;
  1105. default:
  1106. pConfigSettingslParam->pSettings->OnConfigDlgNotify(hWnd,pConfigSettingslParam,uMessage,wParam,lParam);
  1107. break;
  1108. }
  1109. break;
  1110. case WM_COMMAND:
  1111. pConfigSettingslParam->pSettings->OnConfigDlgCommand(hWnd,pConfigSettingslParam,uMessage,wParam,lParam);
  1112. break;
  1113. default:
  1114. break;
  1115. }
  1116. }
  1117. return bResult;
  1118. }
  1119. //+---------------------------------------------------------------------------
  1120. //
  1121. // Member: CSettings::ItemConfigDlgGetItemSettings, private
  1122. //
  1123. // Synopsis: Gets ptr to ItemSettings for specified Item.
  1124. //
  1125. // Arguments:
  1126. //
  1127. // Returns:
  1128. //
  1129. // Modifies:
  1130. //
  1131. //----------------------------------------------------------------------------
  1132. LPSAMPLEITEMSETTINGS CSettings::ItemConfigDlgGetItemSettings(ITEMCONFIGSETTINGSLPARAM *pItemConfigDlglParam)
  1133. {
  1134. LPSAMPLEITEMSETTINGS pSampleItem = NULL;
  1135. ASSERT_LOCKHELD(this);
  1136. if (pItemConfigDlglParam->fNewItem)
  1137. {
  1138. pSampleItem = pItemConfigDlglParam->pItemSettings;
  1139. }
  1140. else
  1141. {
  1142. pSampleItem = FindItemSettings(pItemConfigDlglParam->ItemID);
  1143. }
  1144. return pSampleItem;
  1145. }
  1146. //+---------------------------------------------------------------------------
  1147. //
  1148. // Member: CSettings::OnItemConfigDlgInit, private
  1149. //
  1150. // Synopsis: Handles WM_INITDIALOG message for Item Property Page
  1151. //
  1152. // Arguments:
  1153. //
  1154. // Returns:
  1155. //
  1156. // Modifies:
  1157. //
  1158. //----------------------------------------------------------------------------
  1159. void CSettings::OnItemConfigDlgInit(HWND hWnd,ITEMCONFIGSETTINGSLPARAM *pItemConfigDlglParam,
  1160. UINT uMessage, WPARAM wParam, LPARAM lParam)
  1161. {
  1162. LPSAMPLEITEMSETTINGS pSampleItem;
  1163. CLock clock(this);
  1164. clock.Enter();
  1165. pSampleItem = ItemConfigDlgGetItemSettings(pItemConfigDlglParam);
  1166. pItemConfigDlglParam->hr = S_FALSE; // by default nothing has changed.
  1167. // fill in the dialog values.
  1168. if (pSampleItem)
  1169. {
  1170. HWND hwndCtrl;
  1171. #ifndef _UNICODE
  1172. char TextBuf[MAX_PATH];
  1173. #endif // _UNICODE
  1174. hwndCtrl = GetDlgItem(hWnd,IDC_ITEMCONFIGDIALOG_EDIT_DISPLAYNAME);
  1175. if (hwndCtrl)
  1176. {
  1177. TCHAR *pDisplayName;
  1178. #if _UNICODE
  1179. pDisplayName = pSampleItem->syncmgrItem.wszItemName;
  1180. #else
  1181. *TextBuf = NULL;
  1182. WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
  1183. pSampleItem->syncmgrItem.wszItemName,
  1184. -1, TextBuf,MAX_PATH, NULL, NULL);
  1185. pDisplayName = TextBuf;
  1186. #endif // _UNICODE
  1187. SendMessage(hwndCtrl,EM_SETLIMITTEXT,MAX_SYNCMGRITEMNAME,0);
  1188. SetWindowText(hwndCtrl,pDisplayName);
  1189. }
  1190. hwndCtrl = GetDlgItem(hWnd,IDC_ITEMCONFIGDIALOG_EDIT_DIR1NAME);
  1191. if (hwndCtrl)
  1192. {
  1193. SendMessage(hwndCtrl,EM_SETLIMITTEXT,sizeof(pSampleItem->dir1),0);
  1194. SendMessage(hwndCtrl,WM_SETTEXT,0,(LPARAM) pSampleItem->dir1);
  1195. }
  1196. hwndCtrl = GetDlgItem(hWnd,IDC_ITEMCONFIGDIALOG_EDIT_DIR2NAME);
  1197. if (hwndCtrl)
  1198. {
  1199. SendMessage(hwndCtrl,EM_SETLIMITTEXT,sizeof(pSampleItem->dir2),0);
  1200. SendMessage(hwndCtrl,WM_SETTEXT,0,(LPARAM) pSampleItem->dir2);
  1201. }
  1202. CheckDlgButton(hWnd,IDC_ITEMCONFIGDIALOG_INCLUDESUBDIRS,pSampleItem->fRecursive);
  1203. }
  1204. pItemConfigDlglParam->fDirty = FALSE;
  1205. clock.Leave();
  1206. }
  1207. //+---------------------------------------------------------------------------
  1208. //
  1209. // Member: CSettings::OnItemConfigDlgDetroy, private
  1210. //
  1211. // Synopsis: Handles WM_DESTROY message for Item Property Page
  1212. //
  1213. // Arguments:
  1214. //
  1215. // Returns:
  1216. //
  1217. // Modifies:
  1218. //
  1219. //----------------------------------------------------------------------------
  1220. void CSettings::OnItemConfigDlgDestroy(HWND hWnd,ITEMCONFIGSETTINGSLPARAM *pItemConfigDlglParam,
  1221. UINT uMessage, WPARAM wParam,LPARAM lParam)
  1222. {
  1223. }
  1224. //+---------------------------------------------------------------------------
  1225. //
  1226. // Member: CSettings::OnItemConfigDlgNotify, private
  1227. //
  1228. // Synopsis: Handles WM_NOTIFY message for Item Property Page
  1229. //
  1230. // Arguments:
  1231. //
  1232. // Returns:
  1233. //
  1234. // Modifies:
  1235. //
  1236. //----------------------------------------------------------------------------
  1237. void CSettings::OnItemConfigDlgNotify(HWND hWnd,ITEMCONFIGSETTINGSLPARAM *pItemConfigDlglParam,
  1238. UINT uMessage, WPARAM wParam,LPARAM lParam)
  1239. {
  1240. }
  1241. //+---------------------------------------------------------------------------
  1242. //
  1243. // Member: CSettings::OnItemConfigDlgCommand, private
  1244. //
  1245. // Synopsis: Handles WM_COMMAND message for Item Property Page
  1246. //
  1247. // Arguments:
  1248. //
  1249. // Returns:
  1250. //
  1251. // Modifies:
  1252. //
  1253. //----------------------------------------------------------------------------
  1254. void CSettings::OnItemConfigDlgCommand(HWND hWnd,ITEMCONFIGSETTINGSLPARAM *pItemConfigDlglParam,
  1255. UINT uMessage, WPARAM wParam,LPARAM lParam)
  1256. {
  1257. WORD wNotifyCode = HIWORD(wParam); // notification code
  1258. WORD wID = LOWORD(wParam); // item, control, or accelerator identifier
  1259. HWND hwndCtl = (HWND) lParam; // handle of control
  1260. if ((EN_CHANGE == wNotifyCode) || (BN_CLICKED == wNotifyCode))
  1261. {
  1262. pItemConfigDlglParam->fDirty = TRUE;
  1263. PropSheet_Changed(GetParent(hWnd), hWnd);
  1264. }
  1265. }
  1266. //+---------------------------------------------------------------------------
  1267. //
  1268. // Member: CSettings::OnItemConfigDlgApply, private
  1269. //
  1270. // Synopsis: Called when APPLY or Okay is pressed on item Properties page.
  1271. //
  1272. // Arguments:
  1273. //
  1274. // Returns:
  1275. //
  1276. // Modifies:
  1277. //
  1278. //----------------------------------------------------------------------------
  1279. BOOL CSettings::OnItemConfigDlgApply(HWND hWnd,ITEMCONFIGSETTINGSLPARAM *pItemConfigDlglParam,
  1280. UINT uMessage, WPARAM wParam,LPARAM lParam)
  1281. {
  1282. BOOL fResult = TRUE;
  1283. CLock clock(this);
  1284. if (pItemConfigDlglParam->fDirty)
  1285. {
  1286. LPSAMPLEITEMSETTINGS pSampleItem;
  1287. HWND hwndCtrl;
  1288. TCHAR dir1[MAX_PATH];
  1289. TCHAR dir2[MAX_PATH];
  1290. TCHAR DisplayName[MAX_SYNCMGRITEMNAME];
  1291. WCHAR *pDisplayName;
  1292. BOOL fRecursive = FALSE;
  1293. BOOL fPersist = TRUE;
  1294. // get dialog values, if couldn't find don't return error so user can still cancel
  1295. // dialog
  1296. hwndCtrl = GetDlgItem(hWnd,IDC_ITEMCONFIGDIALOG_EDIT_DISPLAYNAME);
  1297. if (hwndCtrl)
  1298. {
  1299. if (0 >= GetWindowText(hwndCtrl,DisplayName,sizeof(DisplayName)/sizeof(TCHAR)))
  1300. {
  1301. Alert(hWnd,TEXT("Display Name Is Not Valid."));
  1302. SetFocus(hwndCtrl);
  1303. return FALSE;
  1304. }
  1305. #if _UNICODE
  1306. pDisplayName = DisplayName;
  1307. #else
  1308. WCHAR wszTextBuf[MAX_SYNCMGRITEMNAME];
  1309. MultiByteToWideChar(CP_ACP, 0,
  1310. DisplayName,
  1311. -1, wszTextBuf,MAX_SYNCMGRITEMNAME);
  1312. pDisplayName = wszTextBuf;
  1313. #endif // _UNICODE
  1314. }
  1315. else
  1316. {
  1317. fPersist = FALSE;
  1318. }
  1319. // get the new dir names.
  1320. hwndCtrl = GetDlgItem(hWnd,IDC_ITEMCONFIGDIALOG_EDIT_DIR1NAME);
  1321. if (hwndCtrl)
  1322. {
  1323. if (0 >= GetWindowText(hwndCtrl,dir1,sizeof(dir1)/sizeof(TCHAR)))
  1324. {
  1325. Alert(hWnd,TEXT("Dir1 Name Is Not Valid."));
  1326. return FALSE;
  1327. }
  1328. }
  1329. else
  1330. {
  1331. fPersist = FALSE;
  1332. }
  1333. hwndCtrl = GetDlgItem(hWnd,IDC_ITEMCONFIGDIALOG_EDIT_DIR2NAME);
  1334. if (hwndCtrl)
  1335. {
  1336. if (0 >= GetWindowText(hwndCtrl,dir2,sizeof(dir2)/sizeof(TCHAR)))
  1337. {
  1338. Alert(hWnd,TEXT("Dir2 Name Is Not Valid."));
  1339. return FALSE;
  1340. }
  1341. }
  1342. else
  1343. {
  1344. fPersist = FALSE;
  1345. }
  1346. // verify dir paths
  1347. if (!IsValidDir(dir1))
  1348. {
  1349. Alert(hWnd,TEXT("Dir1 Name Is Not a Valid directory"));
  1350. return FALSE;
  1351. }
  1352. if (!IsValidDir(dir2))
  1353. {
  1354. Alert(hWnd,TEXT("Dir2 Name Is Not a Valid directory"));
  1355. return FALSE;
  1356. }
  1357. fRecursive = IsDlgButtonChecked(hWnd,IDC_ITEMCONFIGDIALOG_INCLUDESUBDIRS);
  1358. // if everything validated write it out.
  1359. clock.Enter();
  1360. pSampleItem = ItemConfigDlgGetItemSettings(pItemConfigDlglParam);
  1361. if (fPersist && pSampleItem)
  1362. {
  1363. lstrcpyW(pSampleItem->syncmgrItem.wszItemName,pDisplayName);
  1364. lstrcpy(pSampleItem->dir1,dir1);
  1365. lstrcpy(pSampleItem->dir2,dir2);
  1366. pSampleItem->fRecursive = fRecursive;
  1367. WriteItemSettings(pSampleItem);
  1368. pItemConfigDlglParam->hr = S_OK; // only say items saved okay when dirty and saved properly
  1369. }
  1370. clock.Leave();
  1371. }
  1372. return fResult;
  1373. }
  1374. //+---------------------------------------------------------------------------
  1375. //
  1376. // fucntion: ItemConfigureDlgProc, private
  1377. //
  1378. // Synopsis: wndproc for Items Property page
  1379. //
  1380. // Arguments:
  1381. //
  1382. // Returns:
  1383. //
  1384. // Modifies:
  1385. //
  1386. //----------------------------------------------------------------------------
  1387. BOOL CALLBACK ItemConfigDlgProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
  1388. {
  1389. WORD wNotifyCode = HIWORD(wParam); // notification code
  1390. BOOL bResult = FALSE;
  1391. ITEMCONFIGSETTINGSLPARAM *pItemConfigDlglParam = (ITEMCONFIGSETTINGSLPARAM *) GetWindowLong(hWnd,DWL_USER);
  1392. if (WM_INITDIALOG == uMessage)
  1393. {
  1394. pItemConfigDlglParam = (ITEMCONFIGSETTINGSLPARAM *) ((PROPSHEETPAGE *) lParam)->lParam;
  1395. SetWindowLong(hWnd, DWL_USER, (LONG) pItemConfigDlglParam);
  1396. pItemConfigDlglParam->pSettings->OnItemConfigDlgInit(hWnd,pItemConfigDlglParam,uMessage,wParam,lParam);
  1397. }
  1398. else if (pItemConfigDlglParam)
  1399. {
  1400. switch (uMessage)
  1401. {
  1402. case WM_DESTROY:
  1403. pItemConfigDlglParam->pSettings->OnItemConfigDlgDestroy(hWnd,pItemConfigDlglParam,uMessage,wParam,lParam);
  1404. break;
  1405. case WM_NOTIFY:
  1406. switch (((NMHDR FAR *)lParam)->code)
  1407. {
  1408. case PSN_APPLY:
  1409. // after a successful apply the item has changed.
  1410. // so set return value to S_OK:
  1411. if (pItemConfigDlglParam->pSettings->OnItemConfigDlgApply(hWnd,pItemConfigDlglParam,uMessage,wParam,lParam))
  1412. {
  1413. SetWindowLong(hWnd,DWL_MSGRESULT,PSNRET_NOERROR);
  1414. }
  1415. else
  1416. {
  1417. SetWindowLong(hWnd,DWL_MSGRESULT,PSNRET_INVALID);
  1418. }
  1419. return TRUE; // !!!return true so SetWindowLong DWL_MSGRESULT is applied
  1420. break;
  1421. default:
  1422. pItemConfigDlglParam->pSettings->OnItemConfigDlgNotify(hWnd,pItemConfigDlglParam,uMessage,wParam,lParam);
  1423. break;
  1424. }
  1425. break;
  1426. case WM_COMMAND:
  1427. pItemConfigDlglParam->pSettings->OnItemConfigDlgCommand(hWnd,pItemConfigDlglParam,uMessage,wParam,lParam);
  1428. break;
  1429. default:
  1430. break;
  1431. }
  1432. }
  1433. return bResult;
  1434. }
  1435. // implementation for item enumerator used and managed by settings.
  1436. //+---------------------------------------------------------------------------
  1437. //
  1438. // Member: CEnumSyncMgrItems::CEnumSyncMgrItems, public
  1439. //
  1440. // Synopsis: contructor
  1441. //
  1442. // Returns:
  1443. //
  1444. // Modifies:
  1445. //
  1446. //----------------------------------------------------------------------------
  1447. CEnumSyncMgrItems::CEnumSyncMgrItems(LPGENERICITEMLIST pGenericItemList,DWORD cOffset)
  1448. : CGenericEnum(pGenericItemList,cOffset)
  1449. {
  1450. }
  1451. //+---------------------------------------------------------------------------
  1452. //
  1453. // Member: CEnumSyncMgrItems::DeleteThisObject, public
  1454. //
  1455. // Synopsis: called by generic Enum when refcount hits zero
  1456. //
  1457. // Returns:
  1458. //
  1459. // Modifies:
  1460. //
  1461. //----------------------------------------------------------------------------
  1462. void CEnumSyncMgrItems::DeleteThisObject()
  1463. {
  1464. delete this;
  1465. }
  1466. //+---------------------------------------------------------------------------
  1467. //
  1468. // Member: CEnumSyncMgrItems::QueryInteface, public
  1469. //
  1470. // Synopsis: must override generic implementation.
  1471. //
  1472. // Returns:
  1473. //
  1474. // Modifies:
  1475. //
  1476. //----------------------------------------------------------------------------
  1477. STDMETHODIMP CEnumSyncMgrItems::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  1478. {
  1479. *ppv = NULL;
  1480. if (IsEqualIID(riid, IID_IUnknown))
  1481. {
  1482. *ppv = (LPUNKNOWN) this;
  1483. }
  1484. else if (IsEqualIID(riid, IID_ISyncMgrEnumItems))
  1485. {
  1486. *ppv = (LPSYNCMGRENUMITEMS) this;
  1487. }
  1488. if (*ppv)
  1489. {
  1490. AddRef();
  1491. return NOERROR;
  1492. }
  1493. return E_NOINTERFACE;
  1494. }
  1495. //+---------------------------------------------------------------------------
  1496. //
  1497. // Member: CEnumSyncMgrItems::AddRef, public
  1498. //
  1499. // Synopsis:
  1500. //
  1501. // Returns:
  1502. //
  1503. // Modifies:
  1504. //
  1505. //----------------------------------------------------------------------------
  1506. STDMETHODIMP_(ULONG) CEnumSyncMgrItems::AddRef()
  1507. {
  1508. return CGenericEnum::AddRef();
  1509. }
  1510. //+---------------------------------------------------------------------------
  1511. //
  1512. // Member: CEnumSyncMgrItems::Release, public
  1513. //
  1514. // Synopsis:
  1515. //
  1516. // Returns:
  1517. //
  1518. // Modifies:
  1519. //
  1520. //----------------------------------------------------------------------------
  1521. STDMETHODIMP_(ULONG) CEnumSyncMgrItems::Release()
  1522. {
  1523. return CGenericEnum::Release();
  1524. }
  1525. //+---------------------------------------------------------------------------
  1526. //
  1527. // Member: CEnumSyncMgrItems::Next, public
  1528. //
  1529. // Synopsis: must override generic implementation.
  1530. //
  1531. // Returns:
  1532. //
  1533. // Modifies:
  1534. //
  1535. //----------------------------------------------------------------------------
  1536. STDMETHODIMP CEnumSyncMgrItems::Next(ULONG celt, LPSYNCMGRITEM rgelt,ULONG *pceltFetched)
  1537. {
  1538. HRESULT hr = NOERROR;
  1539. ULONG ulFetchCount = celt;
  1540. ULONG ulTransferCount = 0;
  1541. LPSYNCMGRITEM pGenericItem;
  1542. if ( (m_cOffset + celt) > m_pGenericItemList->dwNumItems)
  1543. {
  1544. ulFetchCount = m_pGenericItemList->dwNumItems - m_cOffset;
  1545. hr = S_FALSE;
  1546. }
  1547. pGenericItem = rgelt;
  1548. while (ulFetchCount--)
  1549. {
  1550. LPSAMPLEITEMSETTINGS pNextSyncMgrItem;
  1551. Assert(m_pNextItem->cbSize == sizeof(SAMPLEITEMSETTINGS));
  1552. pNextSyncMgrItem = (LPSAMPLEITEMSETTINGS) m_pNextItem;
  1553. memcpy(pGenericItem,&(pNextSyncMgrItem->syncmgrItem),sizeof(SYNCMGRITEM));
  1554. m_pNextItem = m_pNextItem->pNextGenericItem; // add error checking
  1555. ++m_cOffset;
  1556. ++ulTransferCount;
  1557. ++pGenericItem;
  1558. }
  1559. if (pceltFetched)
  1560. {
  1561. *pceltFetched = ulTransferCount;
  1562. }
  1563. return hr;
  1564. }
  1565. //+---------------------------------------------------------------------------
  1566. //
  1567. // Member: CEnumSyncMgrItems::Skip, public
  1568. //
  1569. // Synopsis:
  1570. //
  1571. // Returns:
  1572. //
  1573. // Modifies:
  1574. //
  1575. //----------------------------------------------------------------------------
  1576. STDMETHODIMP CEnumSyncMgrItems::Skip(ULONG celt)
  1577. {
  1578. return CGenericEnum::Skip(celt);
  1579. }
  1580. //+---------------------------------------------------------------------------
  1581. //
  1582. // Member: CEnumSyncMgrItems::Reset, public
  1583. //
  1584. // Synopsis:
  1585. //
  1586. // Returns:
  1587. //
  1588. // Modifies:
  1589. //
  1590. //----------------------------------------------------------------------------
  1591. STDMETHODIMP CEnumSyncMgrItems::Reset()
  1592. {
  1593. return CGenericEnum::Reset();
  1594. }
  1595. //+---------------------------------------------------------------------------
  1596. //
  1597. // Member: CEnumSyncMgrItems::Clone, public
  1598. //
  1599. // Synopsis: must override generic implementation.
  1600. //
  1601. // Returns:
  1602. //
  1603. // Modifies:
  1604. //
  1605. //----------------------------------------------------------------------------
  1606. STDMETHODIMP CEnumSyncMgrItems::Clone(ISyncMgrEnumItems **ppenum)
  1607. {
  1608. *ppenum = new CEnumSyncMgrItems(m_pGenericItemList,m_cOffset);
  1609. return *ppenum ? NOERROR : E_OUTOFMEMORY;
  1610. }