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.

4056 lines
110 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // SpamUI.cpp
  4. //
  5. ///////////////////////////////////////////////////////////////////////////////
  6. #include <pch.hxx>
  7. #include "oerules.h"
  8. #include "spamui.h"
  9. #include "junkrule.h"
  10. #include "rule.h"
  11. #include "ruleutil.h"
  12. #include <rulesdlg.h>
  13. #include <imagelst.h>
  14. #include <msoejunk.h>
  15. #include "shlwapip.h"
  16. #include <ipab.h>
  17. #include <demand.h>
  18. // Type definitions
  19. typedef struct tagEDIT_EXCPT
  20. {
  21. DWORD dwFlags;
  22. LPSTR pszExcpt;
  23. } EDIT_EXCPT, * PEDIT_EXCPT;
  24. // Class definitions
  25. class CEditExceptionUI
  26. {
  27. private:
  28. enum
  29. {
  30. STATE_UNINIT = 0x00000000,
  31. STATE_INITIALIZED = 0x00000001,
  32. STATE_DIRTY = 0x00000002
  33. };
  34. private:
  35. HWND m_hwndOwner;
  36. DWORD m_dwFlags;
  37. DWORD m_dwState;
  38. HWND m_hwndDlg;
  39. HWND m_hwndExcpt;
  40. EDIT_EXCPT * m_pEditExcpt;
  41. public:
  42. CEditExceptionUI() : m_hwndOwner(NULL), m_dwFlags(0), m_dwState(STATE_UNINIT),
  43. m_hwndDlg(NULL), m_hwndExcpt(NULL), m_pEditExcpt(NULL) {}
  44. ~CEditExceptionUI();
  45. HRESULT HrInit(HWND hwndOwner, DWORD dwFlags, EDIT_EXCPT * pEditExcpt);
  46. HRESULT HrShow(VOID);
  47. static INT_PTR CALLBACK FEditExcptDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);
  48. // Message handling methods
  49. BOOL FOnInitDialog(HWND hwndDlg);
  50. BOOL FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl);
  51. };
  52. // global data
  53. const static HELPMAP g_rgCtxMapJunkRules[] = {
  54. {idcJunkMail, idhJunkMail},
  55. {idbExceptions, idhExceptions},
  56. {idcJunkSlider, idhJunkSlider},
  57. {idcJunkDelete, idhJunkDelete},
  58. {0, 0}};
  59. const static HELPMAP g_rgCtxMapSenderRules[] = {
  60. {idbAddSender, idhAddSender},
  61. {idbModifySender, idhModifySender},
  62. {idbRemoveSender, idhRemoveSender},
  63. {0, 0}};
  64. CEditSenderUI::~CEditSenderUI()
  65. {
  66. if ((NULL != m_pEditSender) && (NULL != m_pEditSender->pszSender))
  67. {
  68. MemFree(m_pEditSender->pszSender);
  69. }
  70. }
  71. ///////////////////////////////////////////////////////////////////////////////
  72. //
  73. // HrInit
  74. //
  75. // This initializes the edit sender UI dialog
  76. //
  77. // hwndOwner - the handle to the owner window of this dialog
  78. // dwFlags - modifiers on how this dialog should act
  79. // pEditSender - the edit sender parameters
  80. //
  81. // Returns: S_OK, if it was successfully initialized
  82. //
  83. ///////////////////////////////////////////////////////////////////////////////
  84. HRESULT CEditSenderUI::HrInit(HWND hwndOwner, DWORD dwFlags, EDIT_SENDER * pEditSender)
  85. {
  86. HRESULT hr = S_OK;
  87. // Check incoming params
  88. if ((NULL == hwndOwner) || (NULL == pEditSender))
  89. {
  90. hr = E_INVALIDARG;
  91. goto exit;
  92. }
  93. if (0 != (m_dwState & STATE_INITIALIZED))
  94. {
  95. hr = E_UNEXPECTED;
  96. goto exit;
  97. }
  98. m_hwndOwner = hwndOwner;
  99. m_dwFlags = dwFlags;
  100. m_pEditSender = pEditSender;
  101. m_dwState |= STATE_INITIALIZED;
  102. hr = S_OK;
  103. exit:
  104. return hr;
  105. }
  106. ///////////////////////////////////////////////////////////////////////////////
  107. //
  108. // HrShow
  109. //
  110. // This brings up the edit sender UI dialog
  111. //
  112. // Returns: S_OK, if the sender was successfully entered
  113. // S_FALSE, if the dialog was canceled
  114. //
  115. ///////////////////////////////////////////////////////////////////////////////
  116. HRESULT CEditSenderUI::HrShow(VOID)
  117. {
  118. HRESULT hr = S_OK;
  119. int iRet = 0;
  120. if (0 == (m_dwState & STATE_INITIALIZED))
  121. {
  122. hr = E_UNEXPECTED;
  123. goto exit;
  124. }
  125. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddEditSender),
  126. m_hwndOwner, CEditSenderUI::FEditSendersDlgProc,
  127. (LPARAM) this);
  128. if (-1 == iRet)
  129. {
  130. hr = E_FAIL;
  131. goto exit;
  132. }
  133. // Set the proper return code
  134. hr = (IDOK == iRet) ? S_OK : S_FALSE;
  135. exit:
  136. return hr;
  137. }
  138. ///////////////////////////////////////////////////////////////////////////////
  139. //
  140. // FEditSendersDlgProc
  141. //
  142. // This is the main dialog proc for entering a sender
  143. //
  144. // hwndDlg - handle to the filter manager dialog
  145. // uMsg - the message to be acted upon
  146. // wParam - the 'word' parameter for the message
  147. // lParam - the 'long' parameter for the message
  148. //
  149. // Returns: TRUE, if the message was handled
  150. // FALSE, otherwise
  151. //
  152. ///////////////////////////////////////////////////////////////////////////////
  153. INT_PTR CALLBACK CEditSenderUI::FEditSendersDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  154. {
  155. BOOL fRet = FALSE;
  156. CEditSenderUI * pEditSenderUI = NULL;
  157. pEditSenderUI = (CEditSenderUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  158. switch (uiMsg)
  159. {
  160. case WM_INITDIALOG:
  161. pEditSenderUI = (CEditSenderUI *) lParam;
  162. if (NULL == pEditSenderUI)
  163. {
  164. fRet = FALSE;
  165. EndDialog(hwndDlg, -1);
  166. goto exit;
  167. }
  168. // Set it into the dialog so we can get it back
  169. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LPARAM) pEditSenderUI);
  170. if (FALSE == pEditSenderUI->FOnInitDialog(hwndDlg))
  171. {
  172. EndDialog(hwndDlg, -1);
  173. fRet = TRUE;
  174. goto exit;
  175. }
  176. // We didn't set the focus so return TRUE
  177. fRet = TRUE;
  178. break;
  179. case WM_COMMAND:
  180. fRet = pEditSenderUI->FOnCommand((UINT) HIWORD(wParam), (INT) LOWORD(wParam), (HWND) lParam);
  181. break;
  182. }
  183. exit:
  184. return fRet;
  185. }
  186. ///////////////////////////////////////////////////////////////////////////////
  187. //
  188. // FOnInitDialog
  189. //
  190. // This handles the WM_INITDIALOG message for the edit senders dialog
  191. //
  192. // hwndDlg - the handle to the dialog window
  193. //
  194. // Returns: TRUE, if it was successfully initialized
  195. // FALSE, otherwise
  196. //
  197. ///////////////////////////////////////////////////////////////////////////////
  198. BOOL CEditSenderUI::FOnInitDialog(HWND hwndDlg)
  199. {
  200. BOOL fRet = FALSE;
  201. UINT uiCtrl = 0;
  202. HWND hwndCtrl = NULL;
  203. CHAR szRes[CCHMAX_STRINGRES];
  204. UINT uiTitle = 0;
  205. // Check incoming params
  206. if (NULL == hwndDlg)
  207. {
  208. fRet = FALSE;
  209. goto exit;
  210. }
  211. // If we haven't been initialized yet...
  212. if (0 == (m_dwState & STATE_INITIALIZED))
  213. {
  214. fRet = FALSE;
  215. goto exit;
  216. }
  217. // Save off the dialog window handle
  218. m_hwndDlg = hwndDlg;
  219. // Set the default font onto the dialog
  220. SetIntlFont(m_hwndDlg);
  221. // Save off some of the controls
  222. m_hwndSender = GetDlgItem(hwndDlg, idedtSender);
  223. if (NULL == m_hwndSender)
  224. {
  225. fRet = FALSE;
  226. goto exit;
  227. }
  228. // If we have a sender, then set it into the list
  229. if (NULL != m_pEditSender->pszSender)
  230. {
  231. // Misformatted sender?
  232. if (SNDF_NONE == m_pEditSender->dwFlags)
  233. {
  234. fRet = FALSE;
  235. goto exit;
  236. }
  237. // Set the sender into the dialog
  238. Edit_SetText(m_hwndSender, m_pEditSender->pszSender);
  239. // Set the proper
  240. if ((SNDF_MAIL | SNDF_NEWS) == m_pEditSender->dwFlags)
  241. {
  242. uiCtrl = idcBlockBoth;
  243. }
  244. else if (SNDF_NEWS == m_pEditSender->dwFlags)
  245. {
  246. uiCtrl = idcBlockNews;
  247. }
  248. else
  249. {
  250. uiCtrl = idcBlockMail;
  251. }
  252. uiTitle = idsEditBlockSender;
  253. }
  254. else
  255. {
  256. Edit_SetText(m_hwndSender, c_szEmpty);
  257. uiCtrl = idcBlockMail;
  258. uiTitle = idsAddBlockSender;
  259. }
  260. // Get the window title
  261. AthLoadString(uiTitle, szRes, sizeof(szRes));
  262. // Set the window title
  263. SetWindowText(m_hwndDlg, szRes);
  264. hwndCtrl = GetDlgItem(m_hwndDlg, uiCtrl);
  265. if (NULL == hwndCtrl)
  266. {
  267. fRet = FALSE;
  268. goto exit;
  269. }
  270. SendMessage(hwndCtrl, BM_SETCHECK, (WPARAM) BST_CHECKED, (LPARAM) 0);
  271. // Everything's AOK
  272. fRet = TRUE;
  273. exit:
  274. return fRet;
  275. }
  276. ///////////////////////////////////////////////////////////////////////////////
  277. //
  278. // FOnCommand
  279. //
  280. // This handles the WM_COMMAND message for the senders UI dialog
  281. //
  282. // Returns: TRUE, if it was successfully handled
  283. // FALSE, otherwise
  284. //
  285. ///////////////////////////////////////////////////////////////////////////////
  286. BOOL CEditSenderUI::FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl)
  287. {
  288. BOOL fRet = FALSE;
  289. ULONG cchSender = 0;
  290. LPSTR pszSender = NULL;
  291. CHAR szRes[CCHMAX_STRINGRES];
  292. LPSTR pszText = NULL;
  293. // Deal with the edit control notifications
  294. if ((EN_CHANGE == uiNotify) && (idedtSender == iCtl))
  295. {
  296. Assert(NULL != m_hwndSender);
  297. Assert((HWND) hwndCtl == m_hwndSender);
  298. RuleUtil_FEnDisDialogItem(m_hwndDlg, IDOK, 0 != Edit_GetTextLength(m_hwndSender));
  299. goto exit;
  300. }
  301. // We only handle menu and accelerator commands
  302. if ((0 != uiNotify) && (1 != uiNotify))
  303. {
  304. fRet = FALSE;
  305. goto exit;
  306. }
  307. switch (iCtl)
  308. {
  309. case IDCANCEL:
  310. EndDialog(m_hwndDlg, IDCANCEL);
  311. fRet = TRUE;
  312. break;
  313. case IDOK:
  314. // Get the sender from the edit well
  315. cchSender = Edit_GetTextLength(m_hwndSender) + 1;
  316. if (FAILED(HrAlloc((void **) &pszSender, cchSender * sizeof(*pszSender))))
  317. {
  318. fRet = FALSE;
  319. goto exit;
  320. }
  321. pszSender[0] = '\0';
  322. cchSender = Edit_GetText(m_hwndSender, pszSender, cchSender);
  323. // Check to see if the sender is valid
  324. if (0 == UlStripWhitespace(pszSender, TRUE, TRUE, NULL))
  325. {
  326. // Put up a message saying something is busted
  327. AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail),
  328. MAKEINTRESOURCEW(idsSenderBlank), NULL,
  329. MB_OK | MB_ICONINFORMATION);
  330. fRet = FALSE;
  331. goto exit;
  332. }
  333. if (FALSE != SendMessage(m_hwndOwner, WM_OE_FIND_DUP, (WPARAM) (m_pEditSender->lSelected), (LPARAM) pszSender))
  334. {
  335. AthLoadString(idsSenderDupWarn, szRes, sizeof(szRes));
  336. DWORD cchSize = (lstrlen(pszSender) * 2 + lstrlen(szRes) + 1);
  337. if (FAILED(HrAlloc((VOID **) &pszText, cchSize * sizeof(*pszText))))
  338. {
  339. fRet = FALSE;
  340. goto exit;
  341. }
  342. wnsprintf(pszText, cchSize, szRes, pszSender, pszSender);
  343. // Put up a message saying something is busted
  344. if (IDYES != AthMessageBox(m_hwndDlg, MAKEINTRESOURCE(idsAthenaMail),
  345. pszText, NULL, MB_YESNO | MB_ICONINFORMATION))
  346. {
  347. fRet = FALSE;
  348. goto exit;
  349. }
  350. }
  351. // Save off the sender
  352. SafeMemFree(m_pEditSender->pszSender);
  353. m_pEditSender->pszSender = pszSender;
  354. pszSender = NULL;
  355. if (BST_CHECKED == SendMessage(GetDlgItem(m_hwndDlg, idcBlockMail),
  356. BM_GETCHECK, (WPARAM) 0, (LPARAM) 0))
  357. {
  358. m_pEditSender->dwFlags = SNDF_MAIL;
  359. }
  360. else if (BST_CHECKED == SendMessage(GetDlgItem(m_hwndDlg, idcBlockNews),
  361. BM_GETCHECK, (WPARAM) 0, (LPARAM) 0))
  362. {
  363. m_pEditSender->dwFlags = SNDF_NEWS;
  364. }
  365. else if (BST_CHECKED == SendMessage(GetDlgItem(m_hwndDlg, idcBlockBoth),
  366. BM_GETCHECK, (WPARAM) 0, (LPARAM) 0))
  367. {
  368. m_pEditSender->dwFlags = SNDF_MAIL | SNDF_NEWS;
  369. }
  370. EndDialog(m_hwndDlg, IDOK);
  371. fRet = TRUE;
  372. break;
  373. }
  374. exit:
  375. SafeMemFree(pszText);
  376. SafeMemFree(pszSender);
  377. return fRet;
  378. }
  379. // This is for editing the exceptions from the exceptions list UI
  380. ///////////////////////////////////////////////////////////////////////////////
  381. //
  382. // ~CEditExceptionUI
  383. //
  384. // This is the default destructor for the Exception editor
  385. //
  386. // Returns: None
  387. //
  388. ///////////////////////////////////////////////////////////////////////////////
  389. CEditExceptionUI::~CEditExceptionUI()
  390. {
  391. if ((NULL != m_pEditExcpt) && (NULL != m_pEditExcpt->pszExcpt))
  392. {
  393. MemFree(m_pEditExcpt->pszExcpt);
  394. }
  395. }
  396. ///////////////////////////////////////////////////////////////////////////////
  397. //
  398. // HrInit
  399. //
  400. // This initializes the edit exception UI dialog
  401. //
  402. // hwndOwner - the handle to the owner window of this dialog
  403. // dwFlags - modifiers on how this dialog should act
  404. // pEditExcpt - the edit exception parameters
  405. //
  406. // Returns: S_OK, if it was successfully initialized
  407. //
  408. ///////////////////////////////////////////////////////////////////////////////
  409. HRESULT CEditExceptionUI::HrInit(HWND hwndOwner, DWORD dwFlags, EDIT_EXCPT * pEditExcpt)
  410. {
  411. HRESULT hr = S_OK;
  412. // Check incoming params
  413. if ((NULL == hwndOwner) || (NULL == pEditExcpt))
  414. {
  415. hr = E_INVALIDARG;
  416. goto exit;
  417. }
  418. if (0 != (m_dwState & STATE_INITIALIZED))
  419. {
  420. hr = E_UNEXPECTED;
  421. goto exit;
  422. }
  423. m_hwndOwner = hwndOwner;
  424. m_dwFlags = dwFlags;
  425. m_pEditExcpt = pEditExcpt;
  426. m_dwState |= STATE_INITIALIZED;
  427. hr = S_OK;
  428. exit:
  429. return hr;
  430. }
  431. ///////////////////////////////////////////////////////////////////////////////
  432. //
  433. // HrShow
  434. //
  435. // This brings up the edit exception UI dialog
  436. //
  437. // Returns: S_OK, if the sender was successfully entered
  438. // S_FALSE, if the dialog was canceled
  439. //
  440. ///////////////////////////////////////////////////////////////////////////////
  441. HRESULT CEditExceptionUI::HrShow(VOID)
  442. {
  443. HRESULT hr = S_OK;
  444. int iRet = 0;
  445. if (0 == (m_dwState & STATE_INITIALIZED))
  446. {
  447. hr = E_UNEXPECTED;
  448. goto exit;
  449. }
  450. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddEditException),
  451. m_hwndOwner, CEditExceptionUI::FEditExcptDlgProc,
  452. (LPARAM) this);
  453. if (-1 == iRet)
  454. {
  455. hr = E_FAIL;
  456. goto exit;
  457. }
  458. // Set the proper return code
  459. hr = (IDOK == iRet) ? S_OK : S_FALSE;
  460. exit:
  461. return hr;
  462. }
  463. ///////////////////////////////////////////////////////////////////////////////
  464. //
  465. // FEditExcptDlgProc
  466. //
  467. // This is the main dialog proc for entering an exception
  468. //
  469. // hwndDlg - handle to the filter manager dialog
  470. // uMsg - the message to be acted upon
  471. // wParam - the 'word' parameter for the message
  472. // lParam - the 'long' parameter for the message
  473. //
  474. // Returns: TRUE, if the message was handled
  475. // FALSE, otherwise
  476. //
  477. ///////////////////////////////////////////////////////////////////////////////
  478. INT_PTR CALLBACK CEditExceptionUI::FEditExcptDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  479. {
  480. BOOL fRet = FALSE;
  481. CEditExceptionUI * pEditExcptUI = NULL;
  482. pEditExcptUI = (CEditExceptionUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  483. switch (uiMsg)
  484. {
  485. case WM_INITDIALOG:
  486. pEditExcptUI = (CEditExceptionUI *) lParam;
  487. if (NULL == pEditExcptUI)
  488. {
  489. fRet = FALSE;
  490. EndDialog(hwndDlg, -1);
  491. goto exit;
  492. }
  493. // Set it into the dialog so we can get it back
  494. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LPARAM) pEditExcptUI);
  495. if (FALSE == pEditExcptUI->FOnInitDialog(hwndDlg))
  496. {
  497. EndDialog(hwndDlg, -1);
  498. fRet = TRUE;
  499. goto exit;
  500. }
  501. // We didn't set the focus so return TRUE
  502. fRet = TRUE;
  503. break;
  504. case WM_COMMAND:
  505. fRet = pEditExcptUI->FOnCommand((UINT) HIWORD(wParam), (INT) LOWORD(wParam), (HWND) lParam);
  506. break;
  507. }
  508. exit:
  509. return fRet;
  510. }
  511. ///////////////////////////////////////////////////////////////////////////////
  512. //
  513. // FOnInitDialog
  514. //
  515. // This handles the WM_INITDIALOG message for the edit exception dialog
  516. //
  517. // hwndDlg - the handle to the dialog window
  518. //
  519. // Returns: TRUE, if it was successfully initialized
  520. // FALSE, otherwise
  521. //
  522. ///////////////////////////////////////////////////////////////////////////////
  523. BOOL CEditExceptionUI::FOnInitDialog(HWND hwndDlg)
  524. {
  525. BOOL fRet = FALSE;
  526. UINT uiCtrl = 0;
  527. HWND hwndCtrl = NULL;
  528. CHAR szRes[CCHMAX_STRINGRES];
  529. UINT uiTitle = 0;
  530. // Check incoming params
  531. if (NULL == hwndDlg)
  532. {
  533. fRet = FALSE;
  534. goto exit;
  535. }
  536. // If we haven't been initialized yet...
  537. if (0 == (m_dwState & STATE_INITIALIZED))
  538. {
  539. fRet = FALSE;
  540. goto exit;
  541. }
  542. // Save off the dialog window handle
  543. m_hwndDlg = hwndDlg;
  544. // Set the default font onto the dialog
  545. SetIntlFont(m_hwndDlg);
  546. // Save off some of the controls
  547. m_hwndExcpt = GetDlgItem(hwndDlg, idedtException);
  548. if (NULL == m_hwndExcpt)
  549. {
  550. fRet = FALSE;
  551. goto exit;
  552. }
  553. // If we have a sender, then set it into the list
  554. if (NULL != m_pEditExcpt->pszExcpt)
  555. {
  556. // Set the sender into the dialog
  557. Edit_SetText(m_hwndExcpt, m_pEditExcpt->pszExcpt);
  558. uiTitle = idsEditException;
  559. }
  560. else
  561. {
  562. Edit_SetText(m_hwndExcpt, c_szEmpty);
  563. uiTitle = idsAddException;
  564. }
  565. // Get the window title
  566. AthLoadString(uiTitle, szRes, sizeof(szRes));
  567. // Set the window title
  568. SetWindowText(m_hwndDlg, szRes);
  569. // Everything's AOK
  570. fRet = TRUE;
  571. exit:
  572. return fRet;
  573. }
  574. ///////////////////////////////////////////////////////////////////////////////
  575. //
  576. // FOnCommand
  577. //
  578. // This handles the WM_COMMAND message for the exception UI dialog
  579. //
  580. // Returns: TRUE, if it was successfully handled
  581. // FALSE, otherwise
  582. //
  583. ///////////////////////////////////////////////////////////////////////////////
  584. BOOL CEditExceptionUI::FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl)
  585. {
  586. BOOL fRet = FALSE;
  587. ULONG cchExcpt = 0;
  588. LPSTR pszExcpt = NULL;
  589. // Deal with the edit control notifications
  590. if ((EN_CHANGE == uiNotify) && (idedtException == iCtl))
  591. {
  592. Assert(NULL != m_hwndExcpt);
  593. Assert((HWND) hwndCtl == m_hwndExcpt);
  594. RuleUtil_FEnDisDialogItem(m_hwndDlg, IDOK, 0 != Edit_GetTextLength(m_hwndExcpt));
  595. goto exit;
  596. }
  597. // We only handle menu and accelerator commands
  598. if ((0 != uiNotify) && (1 != uiNotify))
  599. {
  600. fRet = FALSE;
  601. goto exit;
  602. }
  603. switch (iCtl)
  604. {
  605. case IDCANCEL:
  606. EndDialog(m_hwndDlg, IDCANCEL);
  607. fRet = TRUE;
  608. break;
  609. case IDOK:
  610. // Get the sender from the edit well
  611. cchExcpt = Edit_GetTextLength(m_hwndExcpt) + 1;
  612. if (FAILED(HrAlloc((void **) &pszExcpt, cchExcpt * sizeof(*pszExcpt))))
  613. {
  614. fRet = FALSE;
  615. goto exit;
  616. }
  617. pszExcpt[0] = '\0';
  618. cchExcpt = Edit_GetText(m_hwndExcpt, pszExcpt, cchExcpt);
  619. // Check to see if the sender is valid
  620. if (0 == UlStripWhitespace(pszExcpt, TRUE, TRUE, NULL))
  621. {
  622. // Put up a message saying something is busted
  623. AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail),
  624. MAKEINTRESOURCEW(idsExceptionBlank), NULL,
  625. MB_OK | MB_ICONINFORMATION);
  626. MemFree(pszExcpt);
  627. fRet = FALSE;
  628. goto exit;
  629. }
  630. // Save off the sender
  631. SafeMemFree(m_pEditExcpt->pszExcpt);
  632. m_pEditExcpt->pszExcpt = pszExcpt;
  633. EndDialog(m_hwndDlg, IDOK);
  634. fRet = TRUE;
  635. break;
  636. }
  637. exit:
  638. return fRet;
  639. }
  640. // Default destructor for the Junk Rules UI
  641. COEJunkRulesPageUI::~COEJunkRulesPageUI()
  642. {
  643. if (NULL != m_himl)
  644. {
  645. ImageList_Destroy(m_himl);
  646. }
  647. if (NULL != m_pExceptionsUI)
  648. {
  649. delete m_pExceptionsUI;
  650. m_pExceptionsUI = NULL;
  651. }
  652. SafeRelease(m_pIRuleJunk);
  653. }
  654. ///////////////////////////////////////////////////////////////////////////////
  655. //
  656. // HrInit
  657. //
  658. // This initializes the junk UI dialog
  659. //
  660. // hwndOwner - the handle to the owner window of this dialog
  661. // dwFlags - modifiers on how this dialog should act
  662. //
  663. // Returns: S_OK, if it was successfully initialized
  664. //
  665. ///////////////////////////////////////////////////////////////////////////////
  666. HRESULT COEJunkRulesPageUI::HrInit(HWND hwndOwner, DWORD dwFlags)
  667. {
  668. HRESULT hr = S_OK;
  669. // Check incoming params
  670. if (NULL == hwndOwner)
  671. {
  672. hr = E_INVALIDARG;
  673. goto exit;
  674. }
  675. if (0 != (m_dwState & STATE_INITIALIZED))
  676. {
  677. hr = E_UNEXPECTED;
  678. goto exit;
  679. }
  680. m_hwndOwner = hwndOwner;
  681. m_dwFlags = dwFlags;
  682. // Let's create the Exception List UI
  683. m_pExceptionsUI = new CExceptionsListUI;
  684. if (NULL == m_pExceptionsUI)
  685. {
  686. hr = E_OUTOFMEMORY;
  687. goto exit;
  688. }
  689. m_dwState |= STATE_INITIALIZED;
  690. hr = S_OK;
  691. exit:
  692. return hr;
  693. }
  694. ///////////////////////////////////////////////////////////////////////////////
  695. //
  696. // HrCommitChanges
  697. //
  698. // This commits the changes to the rules
  699. //
  700. // dwFlags - modifiers on how we should commit the changes
  701. // fClearDirty - should we clear the dirty state
  702. //
  703. // Returns: S_OK, if it was successfully committed
  704. //
  705. ///////////////////////////////////////////////////////////////////////////////
  706. HRESULT COEJunkRulesPageUI::HrCommitChanges(DWORD dwFlags, BOOL fClearDirty)
  707. {
  708. HRESULT hr = S_OK;
  709. BOOL fJunkEnable = FALSE;
  710. DWORD dwVal = 0;
  711. RULEINFO infoRule = {0};
  712. // Check incoming params
  713. if (0 != dwFlags)
  714. {
  715. hr = E_INVALIDARG;
  716. goto exit;
  717. }
  718. // Fail if we weren't initialized
  719. if (0 == (m_dwState & STATE_INITIALIZED))
  720. {
  721. hr = E_UNEXPECTED;
  722. goto exit;
  723. }
  724. // If we aren't dirty, then there's
  725. // nothing to do
  726. if (0 == (m_dwState & STATE_DIRTY))
  727. {
  728. hr = S_FALSE;
  729. goto exit;
  730. }
  731. // Save the junk mail rule settings
  732. if (FALSE == _FSaveJunkSettings())
  733. {
  734. hr = E_FAIL;
  735. goto exit;
  736. }
  737. // Initialize the rule info
  738. infoRule.ridRule = RULEID_JUNK;
  739. infoRule.pIRule = m_pIRuleJunk;
  740. // Set the rules into the rules manager
  741. hr = g_pRulesMan->SetRules(SETF_JUNK, RULE_TYPE_MAIL, &infoRule, 1);
  742. if (FAILED(hr))
  743. {
  744. goto exit;
  745. }
  746. // Should we delete items from the Junk folder
  747. dwVal = (BST_CHECKED == Button_GetCheck(GetDlgItem(m_hwndDlg, idcJunkDelete))) ? 1 : 0;
  748. SetDwOption(OPT_DELETEJUNK, dwVal, NULL, 0);
  749. // How many days should we wait?
  750. dwVal = (DWORD) SendMessage(GetDlgItem(m_hwndDlg, idcJunkDeleteSpin), UDM_GETPOS, (WPARAM) 0, (LPARAM) 0);
  751. if (0 == HIWORD(dwVal))
  752. {
  753. SetDwOption(OPT_DELETEJUNKDAYS, dwVal, NULL, 0);
  754. }
  755. // Should we clear the dirty state
  756. if (FALSE != fClearDirty)
  757. {
  758. m_dwState &= ~STATE_DIRTY;
  759. }
  760. hr = S_OK;
  761. exit:
  762. return hr;
  763. }
  764. INT_PTR CALLBACK COEJunkRulesPageUI::FJunkRulesPageDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  765. {
  766. BOOL fRet = FALSE;
  767. COEJunkRulesPageUI * pJunkUI = NULL;
  768. pJunkUI = (COEJunkRulesPageUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  769. switch (uiMsg)
  770. {
  771. case WM_INITDIALOG:
  772. // Grab the UI object pointer
  773. pJunkUI = (COEJunkRulesPageUI *) lParam;
  774. // Set it into the dialog so we can get it back
  775. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LPARAM) pJunkUI);
  776. if (FALSE == pJunkUI->FOnInitDialog(hwndDlg))
  777. {
  778. EndDialog(hwndDlg, -1);
  779. fRet = TRUE;
  780. goto exit;
  781. }
  782. // We didn't set the focus so return TRUE
  783. fRet = TRUE;
  784. break;
  785. case WM_COMMAND:
  786. if (NULL != pJunkUI)
  787. {
  788. fRet = pJunkUI->FOnCommand((UINT) HIWORD(wParam), (INT) LOWORD(wParam), (HWND) lParam);
  789. }
  790. break;
  791. case WM_NOTIFY:
  792. if (NULL != pJunkUI)
  793. {
  794. fRet = pJunkUI->FOnNotify((INT) LOWORD(wParam), (NMHDR *) lParam);
  795. }
  796. break;
  797. case WM_HSCROLL:
  798. if (NULL != pJunkUI)
  799. {
  800. fRet = pJunkUI->FOnHScroll((INT) LOWORD(wParam), (short int) HIWORD(wParam), (HWND) lParam);
  801. }
  802. break;
  803. case WM_DESTROY:
  804. if (NULL != pJunkUI)
  805. {
  806. fRet = pJunkUI->FOnDestroy();
  807. }
  808. break;
  809. case WM_HELP:
  810. case WM_CONTEXTMENU:
  811. fRet = OnContextHelp(hwndDlg, uiMsg, wParam, lParam, g_rgCtxMapJunkRules);
  812. break;
  813. }
  814. exit:
  815. return fRet;
  816. }
  817. ///////////////////////////////////////////////////////////////////////////////
  818. //
  819. // FGetRules
  820. //
  821. // This brings up the edit UI for the selected rule from the mail rules list
  822. //
  823. // fBegin - is this for the LVN_BEGINLABELEDIT notification
  824. // pdi - the display info for the message
  825. //
  826. // Returns: TRUE, if the message was handled
  827. // FALSE, otherwise
  828. //
  829. ///////////////////////////////////////////////////////////////////////////////
  830. BOOL COEJunkRulesPageUI::FGetRules(RULE_TYPE typeRule, RULENODE ** pprnode)
  831. {
  832. BOOL fRet = FALSE;
  833. IOERule * pIRule = NULL;
  834. RULENODE * prnodeNew = NULL;
  835. HRESULT hr = S_OK;
  836. PROPVARIANT propvar = {0};
  837. if (NULL == pprnode)
  838. {
  839. fRet = FALSE;
  840. goto exit;
  841. }
  842. // Fail if we weren't initialized
  843. if (0 == (m_dwState & STATE_INITIALIZED))
  844. {
  845. fRet = FALSE;
  846. goto exit;
  847. }
  848. // Initialize the outgoing param
  849. *pprnode = NULL;
  850. // Make sure we don't lose any changes
  851. // Get the correct rule
  852. if (RULE_TYPE_MAIL == typeRule)
  853. {
  854. if (FALSE != _FSaveJunkSettings())
  855. {
  856. pIRule = m_pIRuleJunk;
  857. }
  858. }
  859. else
  860. {
  861. fRet = FALSE;
  862. goto exit;
  863. }
  864. // Nothing to do if we don't have a rule
  865. if (NULL == pIRule)
  866. {
  867. fRet = TRUE;
  868. goto exit;
  869. }
  870. // Skip over invalid rules
  871. hr = pIRule->Validate(0);
  872. if (FAILED(hr) || (S_FALSE == hr))
  873. {
  874. fRet = FALSE;
  875. goto exit;
  876. }
  877. // Skip over the junk rule if it is disabled
  878. hr = pIRule->GetProp(RULE_PROP_DISABLED, 0, &propvar);
  879. if ((FAILED(hr)) || (FALSE != propvar.boolVal))
  880. {
  881. fRet = FALSE;
  882. goto exit;
  883. }
  884. // Create a new rule node
  885. prnodeNew = new RULENODE;
  886. if (NULL == prnodeNew)
  887. {
  888. fRet = FALSE;
  889. goto exit;
  890. }
  891. prnodeNew->pNext = NULL;
  892. prnodeNew->pIRule = pIRule;
  893. prnodeNew->pIRule->AddRef();
  894. // Set the outgoing param
  895. *pprnode = prnodeNew;
  896. prnodeNew = NULL;
  897. fRet = TRUE;
  898. exit:
  899. PropVariantClear(&propvar);
  900. if (NULL != prnodeNew)
  901. {
  902. if (NULL != prnodeNew->pIRule)
  903. {
  904. prnodeNew->pIRule->Release();
  905. }
  906. delete prnodeNew; // MemFree(prnodeNew);
  907. }
  908. return fRet;
  909. }
  910. ///////////////////////////////////////////////////////////////////////////////
  911. //
  912. // FOnInitDialog
  913. //
  914. // This handles the WM_INITDIALOG message for the junk UI dialog
  915. //
  916. // hwndDlg - the handle to the dialog window
  917. //
  918. // Returns: TRUE, if it was successfully initialized
  919. // FALSE, otherwise
  920. //
  921. ///////////////////////////////////////////////////////////////////////////////
  922. BOOL COEJunkRulesPageUI::FOnInitDialog(HWND hwndDlg)
  923. {
  924. BOOL fRet = FALSE;
  925. CHAR szRes[CCHMAX_STRINGRES];
  926. // Check incoming params
  927. if (NULL == hwndDlg)
  928. {
  929. fRet = FALSE;
  930. goto exit;
  931. }
  932. // If we haven't been initialized yet...
  933. if (0 == (m_dwState & STATE_INITIALIZED))
  934. {
  935. fRet = FALSE;
  936. goto exit;
  937. }
  938. // Save off the dialog window handle
  939. m_hwndDlg = hwndDlg;
  940. // Set the default font onto the dialog
  941. SetIntlFont(m_hwndDlg);
  942. // Initialize the controls
  943. fRet = _FInitCtrls();
  944. if (FALSE == fRet)
  945. {
  946. goto exit;
  947. }
  948. // Initialize the Exceptions List
  949. if (FAILED(m_pExceptionsUI->HrInit(m_hwndDlg, m_dwFlags)))
  950. {
  951. fRet = FALSE;
  952. goto exit;
  953. }
  954. if (FALSE != FIsIMAPOrHTTPAvailable())
  955. {
  956. AthLoadString(idsJunkMailNoIMAP, szRes, sizeof(szRes));
  957. SetDlgItemText(m_hwndDlg, idcJunkTitle, szRes);
  958. }
  959. // Update the buttons
  960. _EnableButtons();
  961. // Everything's AOK
  962. fRet = TRUE;
  963. exit:
  964. return fRet;
  965. }
  966. ///////////////////////////////////////////////////////////////////////////////
  967. //
  968. // FOnCommand
  969. //
  970. // This handles the WM_COMMAND message for the junk UI dialog
  971. //
  972. // Returns: TRUE, if it was successfully handled
  973. // FALSE, otherwise
  974. //
  975. ///////////////////////////////////////////////////////////////////////////////
  976. BOOL COEJunkRulesPageUI::FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl)
  977. {
  978. BOOL fRet = FALSE;
  979. HRESULT hr = S_OK;
  980. switch (iCtl)
  981. {
  982. case idcJunkMail:
  983. if (BST_CHECKED == Button_GetCheck(GetDlgItem(m_hwndDlg, idcJunkMail)))
  984. {
  985. if (NULL == m_pIRuleJunk)
  986. {
  987. hr = HrCreateJunkRule(&m_pIRuleJunk);
  988. if (FAILED(hr))
  989. {
  990. fRet = FALSE;
  991. SafeRelease(m_pIRuleJunk);
  992. goto exit;
  993. }
  994. }
  995. }
  996. // Fall through
  997. case idcJunkDelete:
  998. // Update the buttons
  999. _EnableButtons();
  1000. // Note that the state has changed
  1001. m_dwState |= STATE_DIRTY;
  1002. fRet = FALSE;
  1003. break;
  1004. case idedtJunkDelete:
  1005. if ((0 != (m_dwState & STATE_CTRL_INIT)) && (EN_CHANGE == uiNotify))
  1006. {
  1007. // Note that the state has changed
  1008. m_dwState |= STATE_DIRTY;
  1009. fRet = FALSE;
  1010. }
  1011. break;
  1012. case idbExceptions:
  1013. if (S_OK == m_pExceptionsUI->HrShow(m_pIRuleJunk))
  1014. {
  1015. // Note that the state has changed
  1016. m_dwState |= STATE_DIRTY;
  1017. fRet = FALSE;
  1018. }
  1019. break;
  1020. }
  1021. exit:
  1022. return fRet;
  1023. }
  1024. ///////////////////////////////////////////////////////////////////////////////
  1025. //
  1026. // FOnNotify
  1027. //
  1028. // This handles the WM_NOTIFY message for the junk UI dialog
  1029. //
  1030. // Returns: TRUE, if it was successfully destroyed
  1031. // FALSE, otherwise
  1032. //
  1033. ///////////////////////////////////////////////////////////////////////////////
  1034. BOOL COEJunkRulesPageUI::FOnNotify(INT iCtl, NMHDR * pnmhdr)
  1035. {
  1036. BOOL fRet = FALSE;
  1037. NMLISTVIEW * pnmlv = NULL;
  1038. NMLVKEYDOWN * pnmlvkd = NULL;
  1039. INT iSelected = 0;
  1040. LVHITTESTINFO lvh;
  1041. // We only handle notifications for the list control
  1042. if (idcJunkDeleteSpin != pnmhdr->idFrom)
  1043. {
  1044. fRet = FALSE;
  1045. goto exit;
  1046. }
  1047. pnmlv = (LPNMLISTVIEW) pnmhdr;
  1048. switch (pnmlv->hdr.code)
  1049. {
  1050. case UDN_DELTAPOS:
  1051. // Note that the state has changed
  1052. m_dwState |= STATE_DIRTY;
  1053. fRet = FALSE;
  1054. break;
  1055. }
  1056. exit:
  1057. return fRet;
  1058. }
  1059. ///////////////////////////////////////////////////////////////////////////////
  1060. //
  1061. // FOnHScroll
  1062. //
  1063. // This handles the WM_NOTIFY message for the junk UI dialog
  1064. //
  1065. // Returns: TRUE, if it was successfully handled
  1066. // FALSE, otherwise
  1067. //
  1068. ///////////////////////////////////////////////////////////////////////////////
  1069. BOOL COEJunkRulesPageUI::FOnHScroll(INT iScrollCode, short int iPos, HWND hwndCtl)
  1070. {
  1071. BOOL fRet = FALSE;
  1072. // We only handle messags for the slider control
  1073. if (GetDlgItem(m_hwndDlg, idcJunkSlider) != hwndCtl)
  1074. {
  1075. fRet = FALSE;
  1076. goto exit;
  1077. }
  1078. // Note that the state has changed
  1079. m_dwState |= STATE_DIRTY;
  1080. fRet = FALSE;
  1081. exit:
  1082. return fRet;
  1083. }
  1084. ///////////////////////////////////////////////////////////////////////////////
  1085. //
  1086. // _FInitCtrls
  1087. //
  1088. // This initializes the controls in the junk UI dialog
  1089. //
  1090. // Returns: TRUE, on successful initialization
  1091. // FALSE, otherwise.
  1092. //
  1093. ///////////////////////////////////////////////////////////////////////////////
  1094. BOOL COEJunkRulesPageUI::_FInitCtrls(VOID)
  1095. {
  1096. BOOL fRet = FALSE;
  1097. DWORD dwJunkPct = 0;
  1098. BOOL fEnableDelete = FALSE;
  1099. HICON hIcon = NULL;
  1100. IOERule * pIRuleOrig = NULL;
  1101. IOERule * pIRule = NULL;
  1102. HRESULT hr = S_OK;
  1103. // Get the icons
  1104. m_himl = ImageList_LoadBitmap(g_hLocRes, MAKEINTRESOURCE(idbRules), 32, 0,
  1105. RGB(255, 0, 255));
  1106. if (NULL == m_himl)
  1107. {
  1108. fRet = FALSE;
  1109. goto exit;
  1110. }
  1111. // Set the icons into the dialog
  1112. hIcon = ImageList_GetIcon(m_himl, ID_JUNK_SCALE, ILD_TRANSPARENT);
  1113. SendDlgItemMessage(m_hwndDlg, idcJunkSliderIcon, STM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon);
  1114. hIcon = ImageList_GetIcon(m_himl, ID_JUNK_DELETE, ILD_TRANSPARENT);
  1115. SendDlgItemMessage(m_hwndDlg, idcJunkDeleteIcon, STM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon);
  1116. // Set the range of the slider
  1117. SendDlgItemMessage(m_hwndDlg, idcJunkSlider, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG(0, 4));
  1118. // Get the junk mail rule
  1119. Assert(NULL != g_pRulesMan);
  1120. hr = g_pRulesMan->GetRule(RULEID_JUNK, RULE_TYPE_MAIL, 0, &pIRuleOrig);
  1121. if (FAILED(hr))
  1122. {
  1123. fRet = FALSE;
  1124. goto exit;
  1125. }
  1126. // Save off the junk mail rule
  1127. Assert (NULL == m_pIRuleJunk);
  1128. hr = pIRuleOrig->Clone(&pIRule);
  1129. if (FAILED(hr))
  1130. {
  1131. fRet = FALSE;
  1132. goto exit;
  1133. }
  1134. m_pIRuleJunk = pIRule;
  1135. pIRule = NULL;
  1136. // Get the setings from the junk rule
  1137. _FLoadJunkSettings();
  1138. // Do we want to delete the junk mail
  1139. fEnableDelete = !!DwGetOption(OPT_DELETEJUNK);
  1140. Button_SetCheck(GetDlgItem(m_hwndDlg, idcJunkDelete), fEnableDelete ? BST_CHECKED : BST_UNCHECKED);
  1141. // Set the range of the spinner
  1142. SendDlgItemMessage(m_hwndDlg, idcJunkDeleteSpin, UDM_SETRANGE, (WPARAM) 0, (LPARAM) MAKELONG(999, 1));
  1143. // How many days should we wait?
  1144. SendDlgItemMessage(m_hwndDlg, idcJunkDeleteSpin, UDM_SETPOS, (WPARAM) 0,
  1145. (LPARAM) MAKELONG(DwGetOption(OPT_DELETEJUNKDAYS), 0));
  1146. if (FALSE == fEnableDelete)
  1147. {
  1148. EnableWindow(GetDlgItem(m_hwndDlg, idcJunkDeleteSpin), FALSE);
  1149. EnableWindow(GetDlgItem(m_hwndDlg, idedtJunkDelete), FALSE);
  1150. }
  1151. m_dwState |= STATE_CTRL_INIT;
  1152. // We worked
  1153. fRet = TRUE;
  1154. exit:
  1155. SafeRelease(pIRule);
  1156. SafeRelease(pIRuleOrig);
  1157. return fRet;
  1158. }
  1159. ///////////////////////////////////////////////////////////////////////////////
  1160. //
  1161. // _FLoadJunkSettings
  1162. //
  1163. // This load the senders from the rule and inserts them into the senders list.
  1164. //
  1165. // Returns: TRUE, if it was successfully loaded
  1166. // FALSE, otherwise
  1167. //
  1168. ///////////////////////////////////////////////////////////////////////////////
  1169. BOOL COEJunkRulesPageUI::_FLoadJunkSettings()
  1170. {
  1171. BOOL fRet = FALSE;
  1172. PROPVARIANT propvar = {0};
  1173. int iEnabled = 0;
  1174. DWORD dwJunkPct = 0;
  1175. Assert(NULL != m_pIRuleJunk);
  1176. // Get the Junk detection enabled state
  1177. iEnabled = BST_UNCHECKED;
  1178. if ((SUCCEEDED(m_pIRuleJunk->GetProp(RULE_PROP_DISABLED, 0, &propvar))))
  1179. {
  1180. Assert(VT_BOOL == propvar.vt);
  1181. iEnabled = (FALSE == propvar.boolVal) ? BST_CHECKED : BST_UNCHECKED;
  1182. }
  1183. // Set the junk mail flag
  1184. Button_SetCheck(GetDlgItem(m_hwndDlg, idcJunkMail), iEnabled);
  1185. // Get the Junk percent
  1186. dwJunkPct = 2;
  1187. if (SUCCEEDED(m_pIRuleJunk->GetProp(RULE_PROP_JUNKPCT, 0, &propvar)))
  1188. {
  1189. Assert(VT_UI4 == propvar.vt);
  1190. dwJunkPct = propvar.ulVal;
  1191. }
  1192. // Set the Junk percent
  1193. SendDlgItemMessage(m_hwndDlg, idcJunkSlider, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) dwJunkPct);
  1194. fRet = TRUE;
  1195. return fRet;
  1196. }
  1197. ///////////////////////////////////////////////////////////////////////////////
  1198. //
  1199. // _FSaveJunkSettings
  1200. //
  1201. // This load the senders from the rule and inserts them into the senders list.
  1202. //
  1203. // Returns: TRUE, if it was successfully loaded
  1204. // FALSE, otherwise
  1205. //
  1206. ///////////////////////////////////////////////////////////////////////////////
  1207. BOOL COEJunkRulesPageUI::_FSaveJunkSettings()
  1208. {
  1209. BOOL fRet = FALSE;
  1210. PROPVARIANT propvar = {0};
  1211. BOOL fDisabled = 0;
  1212. DWORD dwJunkPct = 0;
  1213. HRESULT hr = S_OK;
  1214. Assert(NULL != m_pIRuleJunk);
  1215. // Get the Junk detection enabled state
  1216. fDisabled = !!(BST_UNCHECKED == Button_GetCheck(GetDlgItem(m_hwndDlg, idcJunkMail)));
  1217. // Set the disabled state
  1218. propvar.vt = VT_BOOL;
  1219. propvar.boolVal = (VARIANT_BOOL) !!fDisabled;
  1220. if (FAILED(m_pIRuleJunk->SetProp(RULE_PROP_DISABLED, 0, &propvar)))
  1221. {
  1222. fRet = FALSE;
  1223. goto exit;
  1224. }
  1225. // Get the Junk percent
  1226. dwJunkPct = (DWORD) SendMessage(GetDlgItem(m_hwndDlg, idcJunkSlider), TBM_GETPOS, (WPARAM) 0, (LPARAM) 0);
  1227. // Set the Junk percent
  1228. propvar.vt = VT_UI4;
  1229. propvar.ulVal = dwJunkPct;
  1230. if (FAILED(m_pIRuleJunk->SetProp(RULE_PROP_JUNKPCT, 0, &propvar)))
  1231. {
  1232. fRet = FALSE;
  1233. goto exit;
  1234. }
  1235. // Set the return value
  1236. fRet = TRUE;
  1237. exit:
  1238. return fRet;
  1239. }
  1240. ///////////////////////////////////////////////////////////////////////////////
  1241. //
  1242. // _EnableButtons
  1243. //
  1244. // This enables or disables the buttons in the junk UI dialog
  1245. // depending on what is selected.
  1246. //
  1247. // iSelected - the item that was selected,
  1248. // -1 means that nothing was selected
  1249. //
  1250. // Returns: NONE
  1251. //
  1252. ///////////////////////////////////////////////////////////////////////////////
  1253. VOID COEJunkRulesPageUI::_EnableButtons(VOID)
  1254. {
  1255. int cRules = 0;
  1256. BOOL fEnableJunk = FALSE;
  1257. BOOL fEnableDelete = FALSE;
  1258. // Get the enabled state of Junk
  1259. fEnableJunk = !!(BST_CHECKED == Button_GetCheck(GetDlgItem(m_hwndDlg, idcJunkMail)));
  1260. // Get the enabled state of Delete
  1261. fEnableDelete = !!(BST_CHECKED == Button_GetCheck(GetDlgItem(m_hwndDlg, idcJunkDelete)));
  1262. // Enable the senders action buttons
  1263. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcJunkDays, fEnableJunk);
  1264. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcJunkDeleteSpin, (fEnableDelete && fEnableJunk));
  1265. RuleUtil_FEnDisDialogItem(m_hwndDlg, idedtJunkDelete, (fEnableDelete && fEnableJunk));
  1266. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcJunkDelete, fEnableJunk);
  1267. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcJunkSliderMore, fEnableJunk);
  1268. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcJunkSlider, fEnableJunk);
  1269. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcJunkSliderLess, fEnableJunk);
  1270. RuleUtil_FEnDisDialogItem(m_hwndDlg, idbExceptions, fEnableJunk);
  1271. return;
  1272. }
  1273. const COLUMNITEM COESendersRulesPageUI::m_rgcitem[] =
  1274. {
  1275. {idsCaptionMail, 50},
  1276. {idsCaptionNews, 50},
  1277. {idsSenderDesc, 105}
  1278. };
  1279. const UINT COESendersRulesPageUI::m_crgcitem = ARRAYSIZE(COESendersRulesPageUI::m_rgcitem);
  1280. // Default destructor for the Mail Rules UI
  1281. COESendersRulesPageUI::~COESendersRulesPageUI()
  1282. {
  1283. SafeRelease(m_pIRuleMail);
  1284. SafeRelease(m_pIRuleNews);
  1285. }
  1286. ///////////////////////////////////////////////////////////////////////////////
  1287. //
  1288. // HrInit
  1289. //
  1290. // This initializes the senders UI dialog
  1291. //
  1292. // hwndOwner - the handle to the owner window of this dialog
  1293. // dwFlags - modifiers on how this dialog should act
  1294. //
  1295. // Returns: S_OK, if it was successfully initialized
  1296. //
  1297. ///////////////////////////////////////////////////////////////////////////////
  1298. HRESULT COESendersRulesPageUI::HrInit(HWND hwndOwner, DWORD dwFlags)
  1299. {
  1300. HRESULT hr = S_OK;
  1301. // Check incoming params
  1302. if (NULL == hwndOwner)
  1303. {
  1304. hr = E_INVALIDARG;
  1305. goto exit;
  1306. }
  1307. if (0 != (m_dwState & STATE_INITIALIZED))
  1308. {
  1309. hr = E_UNEXPECTED;
  1310. goto exit;
  1311. }
  1312. m_hwndOwner = hwndOwner;
  1313. m_dwFlags = dwFlags;
  1314. m_dwState |= STATE_INITIALIZED;
  1315. hr = S_OK;
  1316. exit:
  1317. return hr;
  1318. }
  1319. ///////////////////////////////////////////////////////////////////////////////
  1320. //
  1321. // HrCommitChanges
  1322. //
  1323. // This commits the changes to the rules
  1324. //
  1325. // dwFlags - modifiers on how we should commit the changes
  1326. // fClearDirty - should we clear the dirty state
  1327. //
  1328. // Returns: S_OK, if it was successfully committed
  1329. //
  1330. ///////////////////////////////////////////////////////////////////////////////
  1331. HRESULT COESendersRulesPageUI::HrCommitChanges(DWORD dwFlags, BOOL fClearDirty)
  1332. {
  1333. HRESULT hr = S_OK;
  1334. RULEINFO infoRule = {0};
  1335. Assert(NULL != m_hwndList);
  1336. // Check incoming params
  1337. if (0 != dwFlags)
  1338. {
  1339. hr = E_INVALIDARG;
  1340. goto exit;
  1341. }
  1342. // Fail if we weren't initialized
  1343. if (0 == (m_dwState & STATE_INITIALIZED))
  1344. {
  1345. hr = E_UNEXPECTED;
  1346. goto exit;
  1347. }
  1348. // If we aren't dirty, then there's
  1349. // nothing to do
  1350. if (0 == (m_dwState & STATE_DIRTY))
  1351. {
  1352. hr = S_FALSE;
  1353. goto exit;
  1354. }
  1355. // Save the mail senders
  1356. if (FALSE == _FSaveSenders(RULE_TYPE_MAIL))
  1357. {
  1358. hr = E_FAIL;
  1359. goto exit;
  1360. }
  1361. // Initialize the rule info
  1362. infoRule.ridRule = RULEID_SENDERS;
  1363. infoRule.pIRule = m_pIRuleMail;
  1364. // Set the rules into the rules manager
  1365. hr = g_pRulesMan->SetRules(SETF_SENDER, RULE_TYPE_MAIL, &infoRule, 1);
  1366. if (FAILED(hr))
  1367. {
  1368. goto exit;
  1369. }
  1370. // Save the news senders
  1371. if (FALSE == _FSaveSenders(RULE_TYPE_NEWS))
  1372. {
  1373. hr = E_FAIL;
  1374. goto exit;
  1375. }
  1376. // Initialize the rule info
  1377. infoRule.ridRule = RULEID_SENDERS;
  1378. infoRule.pIRule = m_pIRuleNews;
  1379. // Set the rules into the rules manager
  1380. hr = g_pRulesMan->SetRules(SETF_SENDER, RULE_TYPE_NEWS, &infoRule, 1);
  1381. if (FAILED(hr))
  1382. {
  1383. goto exit;
  1384. }
  1385. // Should we clear the dirty state
  1386. if (FALSE != fClearDirty)
  1387. {
  1388. m_dwState &= ~STATE_DIRTY;
  1389. }
  1390. hr = S_OK;
  1391. exit:
  1392. return hr;
  1393. }
  1394. INT_PTR CALLBACK COESendersRulesPageUI::FSendersRulesPageDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  1395. {
  1396. BOOL fRet = FALSE;
  1397. COESendersRulesPageUI * pSendersUI = NULL;
  1398. pSendersUI = (COESendersRulesPageUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  1399. switch (uiMsg)
  1400. {
  1401. case WM_INITDIALOG:
  1402. // Grab the UI object pointer
  1403. pSendersUI = (COESendersRulesPageUI *) lParam;
  1404. // Set it into the dialog so we can get it back
  1405. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LPARAM) pSendersUI);
  1406. if (FALSE == pSendersUI->FOnInitDialog(hwndDlg))
  1407. {
  1408. EndDialog(hwndDlg, -1);
  1409. fRet = TRUE;
  1410. goto exit;
  1411. }
  1412. // We didn't set the focus so return TRUE
  1413. fRet = TRUE;
  1414. break;
  1415. case WM_COMMAND:
  1416. fRet = pSendersUI->FOnCommand((UINT) HIWORD(wParam), (INT) LOWORD(wParam), (HWND) lParam);
  1417. break;
  1418. case WM_NOTIFY:
  1419. fRet = pSendersUI->FOnNotify((INT) LOWORD(wParam), (NMHDR *) lParam);
  1420. break;
  1421. case WM_DESTROY:
  1422. fRet = pSendersUI->FOnDestroy();
  1423. break;
  1424. case WM_HELP:
  1425. case WM_CONTEXTMENU:
  1426. fRet = OnContextHelp(hwndDlg, uiMsg, wParam, lParam, g_rgCtxMapSenderRules);
  1427. break;
  1428. case WM_OE_FIND_DUP:
  1429. fRet = pSendersUI->FFindItem((LPCSTR) lParam, (LONG) wParam);
  1430. break;
  1431. }
  1432. exit:
  1433. return fRet;
  1434. }
  1435. ///////////////////////////////////////////////////////////////////////////////
  1436. //
  1437. // FGetRules
  1438. //
  1439. // This brings up the edit UI for the selected rule from the mail rules list
  1440. //
  1441. // fBegin - is this for the LVN_BEGINLABELEDIT notification
  1442. // pdi - the display info for the message
  1443. //
  1444. // Returns: TRUE, if the message was handled
  1445. // FALSE, otherwise
  1446. //
  1447. ///////////////////////////////////////////////////////////////////////////////
  1448. BOOL COESendersRulesPageUI::FGetRules(RULE_TYPE typeRule, RULENODE ** pprnode)
  1449. {
  1450. BOOL fRet = FALSE;
  1451. IOERule * pIRule = NULL;
  1452. RULENODE * prnodeNew = NULL;
  1453. HRESULT hr = S_OK;
  1454. if (NULL == pprnode)
  1455. {
  1456. fRet = FALSE;
  1457. goto exit;
  1458. }
  1459. // Fail if we weren't initialized
  1460. if ((0 == (m_dwState & STATE_INITIALIZED)) || (NULL == m_hwndList))
  1461. {
  1462. fRet = FALSE;
  1463. goto exit;
  1464. }
  1465. // Initialize the outgoing param
  1466. *pprnode = NULL;
  1467. // Make sure we don't loose any changes
  1468. _FSaveSenders(typeRule);
  1469. if (RULE_TYPE_MAIL == typeRule)
  1470. {
  1471. pIRule = m_pIRuleMail;
  1472. }
  1473. else if (RULE_TYPE_NEWS == typeRule)
  1474. {
  1475. pIRule = m_pIRuleNews;
  1476. }
  1477. else
  1478. {
  1479. fRet = FALSE;
  1480. goto exit;
  1481. }
  1482. // Nothing to do if we don't have a rule
  1483. if (NULL == pIRule)
  1484. {
  1485. fRet = TRUE;
  1486. goto exit;
  1487. }
  1488. // Skip over invalid rules
  1489. hr = pIRule->Validate(0);
  1490. if (FAILED(hr) || (S_FALSE == hr))
  1491. {
  1492. fRet = FALSE;
  1493. goto exit;
  1494. }
  1495. // Create a new rule node
  1496. prnodeNew = new RULENODE;
  1497. if (NULL == prnodeNew)
  1498. {
  1499. fRet = FALSE;
  1500. goto exit;
  1501. }
  1502. prnodeNew->pNext = NULL;
  1503. prnodeNew->pIRule = pIRule;
  1504. prnodeNew->pIRule->AddRef();
  1505. // Set the outgoing param
  1506. *pprnode = prnodeNew;
  1507. prnodeNew = NULL;
  1508. fRet = TRUE;
  1509. exit:
  1510. if (NULL != prnodeNew)
  1511. {
  1512. if (NULL != prnodeNew->pIRule)
  1513. {
  1514. prnodeNew->pIRule->Release();
  1515. }
  1516. delete prnodeNew; // MemFree(prnodeNew);
  1517. }
  1518. return fRet;
  1519. }
  1520. ///////////////////////////////////////////////////////////////////////////////
  1521. //
  1522. // FOnInitDialog
  1523. //
  1524. // This handles the WM_INITDIALOG message for the senders UI dialog
  1525. //
  1526. // hwndDlg - the handle to the dialog window
  1527. //
  1528. // Returns: TRUE, if it was successfully initialized
  1529. // FALSE, otherwise
  1530. //
  1531. ///////////////////////////////////////////////////////////////////////////////
  1532. BOOL COESendersRulesPageUI::FOnInitDialog(HWND hwndDlg)
  1533. {
  1534. BOOL fRet = FALSE;
  1535. CHAR szRes[CCHMAX_STRINGRES];
  1536. // Check incoming params
  1537. if (NULL == hwndDlg)
  1538. {
  1539. fRet = FALSE;
  1540. goto exit;
  1541. }
  1542. // If we haven't been initialized yet...
  1543. if (0 == (m_dwState & STATE_INITIALIZED))
  1544. {
  1545. fRet = FALSE;
  1546. goto exit;
  1547. }
  1548. // Save off the dialog window handle
  1549. m_hwndDlg = hwndDlg;
  1550. // Set the default font onto the dialog
  1551. SetIntlFont(m_hwndDlg);
  1552. // Save off some of the controls
  1553. m_hwndList = GetDlgItem(hwndDlg, idlvSenderList);
  1554. if (NULL == m_hwndList)
  1555. {
  1556. fRet = FALSE;
  1557. goto exit;
  1558. }
  1559. // Initialize the list view
  1560. fRet = _FInitListCtrl();
  1561. if (FALSE == fRet)
  1562. {
  1563. goto exit;
  1564. }
  1565. // Load the list view
  1566. fRet = _FLoadListCtrl();
  1567. if (FALSE == fRet)
  1568. {
  1569. goto exit;
  1570. }
  1571. if (FALSE != FIsIMAPOrHTTPAvailable())
  1572. {
  1573. AthLoadString(idsBlockSenderNoIMAP, szRes, sizeof(szRes));
  1574. SetDlgItemText(m_hwndDlg, idcSenderTitle, szRes);
  1575. }
  1576. // Everything's AOK
  1577. fRet = TRUE;
  1578. exit:
  1579. return fRet;
  1580. }
  1581. ///////////////////////////////////////////////////////////////////////////////
  1582. //
  1583. // FOnCommand
  1584. //
  1585. // This handles the WM_COMMAND message for the senders UI dialog
  1586. //
  1587. // Returns: TRUE, if it was successfully handled
  1588. // FALSE, otherwise
  1589. //
  1590. ///////////////////////////////////////////////////////////////////////////////
  1591. BOOL COESendersRulesPageUI::FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl)
  1592. {
  1593. BOOL fRet = FALSE;
  1594. LVITEM lvitem;
  1595. INT iSelected = 0;
  1596. // We only handle menu and accelerator commands
  1597. if ((0 != uiNotify) && (1 != uiNotify))
  1598. {
  1599. fRet = FALSE;
  1600. goto exit;
  1601. }
  1602. switch (iCtl)
  1603. {
  1604. case idbAddSender:
  1605. _NewSender();
  1606. fRet = TRUE;
  1607. break;
  1608. case idbModifySender:
  1609. // Get the selected item from the rule list
  1610. iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
  1611. if (-1 != iSelected)
  1612. {
  1613. // Bring up the rule editor for that item
  1614. _EditSender(iSelected);
  1615. fRet = TRUE;
  1616. }
  1617. break;
  1618. case idbRemoveSender:
  1619. // Get the selected item from the rule list
  1620. iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
  1621. if (-1 != iSelected)
  1622. {
  1623. // Remove the rule from the list
  1624. _RemoveSender(iSelected);
  1625. fRet = TRUE;
  1626. }
  1627. break;
  1628. }
  1629. exit:
  1630. return fRet;
  1631. }
  1632. ///////////////////////////////////////////////////////////////////////////////
  1633. //
  1634. // FOnNotify
  1635. //
  1636. // This handles the WM_NOTIFY message for the senders UI dialog
  1637. //
  1638. // Returns: TRUE, if it was successfully destroyed
  1639. // FALSE, otherwise
  1640. //
  1641. ///////////////////////////////////////////////////////////////////////////////
  1642. BOOL COESendersRulesPageUI::FOnNotify(INT iCtl, NMHDR * pnmhdr)
  1643. {
  1644. BOOL fRet = FALSE;
  1645. NMLISTVIEW * pnmlv = NULL;
  1646. NMLVKEYDOWN * pnmlvkd = NULL;
  1647. INT iSelected = 0;
  1648. LVHITTESTINFO lvh;
  1649. // We only handle notifications for the list control
  1650. if (idlvSenderList != pnmhdr->idFrom)
  1651. {
  1652. fRet = FALSE;
  1653. goto exit;
  1654. }
  1655. pnmlv = (LPNMLISTVIEW) pnmhdr;
  1656. switch (pnmlv->hdr.code)
  1657. {
  1658. case NM_CLICK:
  1659. // Did we click on an item?
  1660. if (-1 != pnmlv->iItem)
  1661. {
  1662. ZeroMemory(&lvh, sizeof(lvh));
  1663. lvh.pt = pnmlv->ptAction;
  1664. iSelected = ListView_SubItemHitTest(m_hwndList, &lvh);
  1665. if (-1 != iSelected)
  1666. {
  1667. // Did we click on the enable field?
  1668. if ((0 != (lvh.flags & LVHT_ONITEMICON)) &&
  1669. (0 == (lvh.flags & LVHT_ONITEMLABEL)))
  1670. {
  1671. // Make sure this item is selected
  1672. ListView_SetItemState(m_hwndList, iSelected,
  1673. LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  1674. // Set the proper enable state
  1675. if (2 != lvh.iSubItem)
  1676. {
  1677. _EnableSender((0 != lvh.iSubItem) ? RULE_TYPE_NEWS : RULE_TYPE_MAIL, iSelected);
  1678. }
  1679. }
  1680. }
  1681. }
  1682. else
  1683. {
  1684. // Disable the buttons
  1685. _EnableButtons(pnmlv->iItem);
  1686. }
  1687. break;
  1688. case NM_DBLCLK:
  1689. // Did we click on an item?
  1690. if (-1 != pnmlv->iItem)
  1691. {
  1692. ZeroMemory(&lvh, sizeof(lvh));
  1693. lvh.pt = pnmlv->ptAction;
  1694. iSelected = ListView_SubItemHitTest(pnmlv->hdr.hwndFrom, &lvh);
  1695. if (-1 != iSelected)
  1696. {
  1697. // Did we click on the rule name?
  1698. if (((0 == (lvh.flags & LVHT_ONITEMICON)) &&
  1699. (0 != (lvh.flags & LVHT_ONITEMLABEL))) || (2 == lvh.iSubItem))
  1700. {
  1701. // Edit the rule
  1702. _EditSender(iSelected);
  1703. }
  1704. }
  1705. }
  1706. else
  1707. {
  1708. // Disable the buttons
  1709. _EnableButtons(pnmlv->iItem);
  1710. }
  1711. break;
  1712. case LVN_ITEMCHANGED:
  1713. // If an item's state changed to selected..
  1714. if ((-1 != pnmlv->iItem) &&
  1715. (0 != (pnmlv->uChanged & LVIF_STATE)) &&
  1716. (0 == (pnmlv->uOldState & LVIS_SELECTED)) &&
  1717. (0 != (pnmlv->uNewState & LVIS_SELECTED)))
  1718. {
  1719. // Enable the buttons
  1720. _EnableButtons(pnmlv->iItem);
  1721. }
  1722. break;
  1723. case LVN_KEYDOWN:
  1724. pnmlvkd = (NMLVKEYDOWN *) pnmhdr;
  1725. // The delete key removes the rule from the list view
  1726. if (VK_DELETE == pnmlvkd->wVKey)
  1727. {
  1728. // Are we on a rule?
  1729. iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
  1730. if (-1 != iSelected)
  1731. {
  1732. // Remove the rule from the list
  1733. _RemoveSender(iSelected);
  1734. }
  1735. }
  1736. break;
  1737. }
  1738. exit:
  1739. return fRet;
  1740. }
  1741. ///////////////////////////////////////////////////////////////////////////////
  1742. //
  1743. // FFindItem
  1744. //
  1745. //
  1746. ///////////////////////////////////////////////////////////////////////////////
  1747. BOOL COESendersRulesPageUI::FFindItem(LPCSTR pszFind, LONG lSkip)
  1748. {
  1749. BOOL fRet = FALSE;
  1750. fRet = _FFindSender(pszFind, lSkip, NULL);
  1751. // Tell the dialog it's aok to proceed
  1752. SetDlgMsgResult(m_hwndDlg, WM_OE_FIND_DUP, fRet);
  1753. return fRet;
  1754. }
  1755. ///////////////////////////////////////////////////////////////////////////////
  1756. //
  1757. // _FInitListCtrl
  1758. //
  1759. // This initializes the list view control in the senders dialog
  1760. //
  1761. // Returns: TRUE, on successful initialization
  1762. // FALSE, otherwise.
  1763. //
  1764. ///////////////////////////////////////////////////////////////////////////////
  1765. BOOL COESendersRulesPageUI::_FInitListCtrl(VOID)
  1766. {
  1767. BOOL fRet = FALSE;
  1768. LVCOLUMN lvc;
  1769. TCHAR szRes[CCHMAX_STRINGRES];
  1770. RECT rc;
  1771. UINT ulIndex = 0;
  1772. HIMAGELIST himl = NULL;
  1773. Assert(NULL != m_hwndList);
  1774. // Initialize the list view structure
  1775. ZeroMemory(&lvc, sizeof(lvc));
  1776. lvc.mask = LVCF_TEXT | LVCF_WIDTH;
  1777. lvc.fmt = LVCFMT_LEFT;
  1778. lvc.pszText = szRes;
  1779. // Calculate the size of the list view
  1780. GetClientRect(m_hwndList, &rc);
  1781. rc.right = rc.right - GetSystemMetrics(SM_CXVSCROLL);
  1782. // Add the columns to the list view
  1783. for (ulIndex = 0; ulIndex < m_crgcitem; ulIndex++)
  1784. {
  1785. Assert(g_hLocRes);
  1786. LoadString(g_hLocRes, m_rgcitem[ulIndex].uidsName, szRes, ARRAYSIZE(szRes));
  1787. lvc.cchTextMax = lstrlen(szRes);
  1788. if (ulIndex != (m_crgcitem - 1))
  1789. {
  1790. lvc.cx = m_rgcitem[ulIndex].uiWidth;
  1791. rc.right -= lvc.cx;
  1792. }
  1793. else
  1794. {
  1795. lvc.cx = rc.right;
  1796. }
  1797. ListView_InsertColumn(m_hwndList, ulIndex, &lvc);
  1798. }
  1799. // Set the state image list
  1800. himl = ImageList_LoadBitmap(g_hLocRes, MAKEINTRESOURCE(idb16x16st), 16, 0, RGB(255, 0, 255));
  1801. if (NULL != himl)
  1802. {
  1803. ListView_SetImageList(m_hwndList, himl, LVSIL_SMALL);
  1804. }
  1805. // Full row selection and subitem images on listview
  1806. ListView_SetExtendedListViewStyle(m_hwndList, LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES);
  1807. // We worked
  1808. fRet = TRUE;
  1809. return fRet;
  1810. }
  1811. ///////////////////////////////////////////////////////////////////////////////
  1812. //
  1813. // _FLoadListCtrl
  1814. //
  1815. // This loads the list view with the current senders
  1816. //
  1817. // Returns: TRUE, if it was successfully loaded
  1818. // FALSE, otherwise
  1819. //
  1820. ///////////////////////////////////////////////////////////////////////////////
  1821. BOOL COESendersRulesPageUI::_FLoadListCtrl(VOID)
  1822. {
  1823. BOOL fRet = FALSE;
  1824. HRESULT hr = S_OK;
  1825. DWORD dwListIndex = 0;
  1826. IOERule * pIRuleOrig = NULL;
  1827. IOERule * pIRule = NULL;
  1828. Assert(NULL != m_hwndList);
  1829. // Remove all the items from the list control
  1830. ListView_DeleteAllItems(m_hwndList);
  1831. // Get the mail sender rule
  1832. Assert(NULL != g_pRulesMan);
  1833. hr = g_pRulesMan->GetRule(RULEID_SENDERS, RULE_TYPE_MAIL, 0, &pIRuleOrig);
  1834. if (SUCCEEDED(hr))
  1835. {
  1836. // If the block sender rule exist
  1837. if (FALSE != _FLoadSenders(RULE_TYPE_MAIL, pIRuleOrig))
  1838. {
  1839. Assert (NULL == m_pIRuleMail);
  1840. hr = pIRuleOrig->Clone(&pIRule);
  1841. if (FAILED(hr))
  1842. {
  1843. fRet = FALSE;
  1844. goto exit;
  1845. }
  1846. m_pIRuleMail = pIRule;
  1847. pIRule = NULL;
  1848. }
  1849. }
  1850. SafeRelease(pIRuleOrig);
  1851. // Get the news sender rule
  1852. Assert(NULL != g_pRulesMan);
  1853. hr = g_pRulesMan->GetRule(RULEID_SENDERS, RULE_TYPE_NEWS, 0, &pIRuleOrig);
  1854. if (SUCCEEDED(hr))
  1855. {
  1856. // If the block sender rule exist
  1857. if (FALSE != _FLoadSenders(RULE_TYPE_NEWS, pIRuleOrig))
  1858. {
  1859. Assert (NULL == m_pIRuleNews);
  1860. hr = pIRuleOrig->Clone(&pIRule);
  1861. if (FAILED(hr))
  1862. {
  1863. fRet = FALSE;
  1864. goto exit;
  1865. }
  1866. m_pIRuleNews = pIRule;
  1867. pIRule = NULL;
  1868. }
  1869. }
  1870. SafeRelease(pIRuleOrig);
  1871. // Select the first item in the list
  1872. if ((NULL != m_pIRuleMail) || (NULL != m_pIRuleNews))
  1873. {
  1874. ListView_SetItemState(m_hwndList, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  1875. }
  1876. // Enable the dialog buttons.
  1877. _EnableButtons(((NULL != m_pIRuleMail) || (NULL != m_pIRuleNews)) ? 0 : -1);
  1878. fRet = TRUE;
  1879. exit:
  1880. SafeRelease(pIRule);
  1881. SafeRelease(pIRuleOrig);
  1882. return fRet;
  1883. }
  1884. ///////////////////////////////////////////////////////////////////////////////
  1885. //
  1886. // _FAddRuleToList
  1887. //
  1888. // This adds the filter passed in to the list view
  1889. //
  1890. // dwIndex - the index on where to add the filter to into the list
  1891. // pIRule - the actual rule
  1892. //
  1893. // Returns: TRUE, if it was successfully added
  1894. // FALSE, otherwise
  1895. //
  1896. ///////////////////////////////////////////////////////////////////////////////
  1897. BOOL COESendersRulesPageUI::_FAddSenderToList(RULE_TYPE type, LPSTR pszSender)
  1898. {
  1899. BOOL fRet = FALSE;
  1900. LONG lIndex = 0;
  1901. LVITEM lvitem = {0};
  1902. ULONG cchSender = 0;
  1903. Assert(NULL != m_hwndList);
  1904. // If there's nothing to do...
  1905. if (NULL == pszSender)
  1906. {
  1907. fRet = FALSE;
  1908. goto exit;
  1909. }
  1910. lvitem.mask = LVIF_IMAGE;
  1911. // Insert it if we didn't find it
  1912. if (FALSE == _FFindSender(pszSender, -1, &lIndex))
  1913. {
  1914. lvitem.iItem = ListView_GetItemCount(m_hwndList);
  1915. lvitem.iImage = iiconStateUnchecked;
  1916. lIndex = ListView_InsertItem(m_hwndList, &lvitem);
  1917. if (-1 == lIndex)
  1918. {
  1919. fRet = FALSE;
  1920. goto exit;
  1921. }
  1922. lvitem.iItem = lIndex;
  1923. lvitem.iSubItem = 1;
  1924. if (-1 == ListView_SetItem(m_hwndList, &lvitem))
  1925. {
  1926. fRet = FALSE;
  1927. goto exit;
  1928. }
  1929. ListView_SetItemText(m_hwndList, lIndex, 2, pszSender);
  1930. cchSender = lstrlen(pszSender) + 1;
  1931. if (cchSender > m_cchLabelMax)
  1932. {
  1933. m_cchLabelMax = cchSender;
  1934. }
  1935. }
  1936. // Enable the proper type
  1937. lvitem.iItem = lIndex;
  1938. lvitem.iImage = iiconStateChecked;
  1939. lvitem.iSubItem = (RULE_TYPE_MAIL != type) ? 1 : 0;
  1940. ListView_SetItem(m_hwndList, &lvitem);
  1941. fRet = TRUE;
  1942. exit:
  1943. return fRet;
  1944. }
  1945. ///////////////////////////////////////////////////////////////////////////////
  1946. //
  1947. // _EnableButtons
  1948. //
  1949. // This enables or disables the buttons in the senders UI dialog
  1950. // depending on what is selected.
  1951. //
  1952. // iSelected - the item that was selected,
  1953. // -1 means that nothing was selected
  1954. //
  1955. // Returns: NONE
  1956. //
  1957. ///////////////////////////////////////////////////////////////////////////////
  1958. void COESendersRulesPageUI::_EnableButtons(INT iSelected)
  1959. {
  1960. int cRules = 0;
  1961. BOOL fSelected = FALSE;
  1962. Assert(NULL != m_hwndList);
  1963. fSelected = (-1 != iSelected);
  1964. // Enable the senders action buttons
  1965. RuleUtil_FEnDisDialogItem(m_hwndDlg, idbRemoveSender, fSelected);
  1966. RuleUtil_FEnDisDialogItem(m_hwndDlg, idbModifySender, fSelected);
  1967. return;
  1968. }
  1969. ///////////////////////////////////////////////////////////////////////////////
  1970. //
  1971. // _EnableRule
  1972. //
  1973. // This switches the current enabled state of the list view item
  1974. // and updates the UI
  1975. //
  1976. // iSelected - index of the item in the listview to work on
  1977. //
  1978. // Returns: NONE
  1979. //
  1980. ///////////////////////////////////////////////////////////////////////////////
  1981. VOID COESendersRulesPageUI::_EnableSender(RULE_TYPE type, int iSelected)
  1982. {
  1983. HRESULT hr = S_OK;
  1984. LVITEM lvi;
  1985. IOERule * pIRule = NULL;
  1986. BOOL fBlockNews = FALSE;
  1987. BOOL fBlockMail = FALSE;
  1988. PROPVARIANT propvar;
  1989. Assert(NULL != m_hwndList);
  1990. // Are we blocking mail?
  1991. ZeroMemory(&lvi, sizeof(lvi));
  1992. lvi.mask = LVIF_IMAGE;
  1993. lvi.iItem = iSelected;
  1994. if (FALSE == ListView_GetItem(m_hwndList, &lvi))
  1995. {
  1996. goto exit;
  1997. }
  1998. fBlockMail = (iiconStateUnchecked != lvi.iImage);
  1999. // Are we blocking news?
  2000. lvi.iSubItem = 1;
  2001. if (FALSE == ListView_GetItem(m_hwndList, &lvi))
  2002. {
  2003. goto exit;
  2004. }
  2005. fBlockNews = (iiconStateUnchecked != lvi.iImage);
  2006. // Disallow disabling both mail and news
  2007. if (((RULE_TYPE_MAIL == type) && (FALSE != fBlockMail) && (FALSE == fBlockNews)) ||
  2008. ((RULE_TYPE_NEWS == type) && (FALSE != fBlockNews) && (FALSE == fBlockMail)))
  2009. {
  2010. // Put up a message saying something is busted
  2011. AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail),
  2012. MAKEINTRESOURCEW(idsRuleSenderErrorNone), NULL,
  2013. MB_OK | MB_ICONERROR);
  2014. goto exit;
  2015. }
  2016. // Set the UI to the opposite enabled state
  2017. lvi.iSubItem = (RULE_TYPE_MAIL != type) ? 1 : 0;
  2018. lvi.iImage = (RULE_TYPE_MAIL != type) ?
  2019. ((FALSE != fBlockNews) ? iiconStateUnchecked : iiconStateChecked) :
  2020. ((FALSE != fBlockMail) ? iiconStateUnchecked : iiconStateChecked);
  2021. ListView_SetItem(m_hwndList, &lvi);
  2022. // Mark the rule list as dirty
  2023. m_dwState |= STATE_DIRTY;
  2024. exit:
  2025. return;
  2026. }
  2027. ///////////////////////////////////////////////////////////////////////////////
  2028. //
  2029. // _FLoadSenders
  2030. //
  2031. // This load the senders from the rule and inserts them into the senders list.
  2032. //
  2033. // type - the type of senders these are
  2034. // pIRule - the rule to get the senders from
  2035. //
  2036. // Returns: TRUE, if it was successfully loaded
  2037. // FALSE, otherwise
  2038. //
  2039. ///////////////////////////////////////////////////////////////////////////////
  2040. BOOL COESendersRulesPageUI::_FLoadSenders(RULE_TYPE type, IOERule * pIRule)
  2041. {
  2042. BOOL fRet = FALSE;
  2043. PROPVARIANT propvar;
  2044. CRIT_ITEM * pCritItem = NULL;
  2045. ULONG cCritItem = 0;
  2046. ULONG ulIndex = 0;
  2047. if (NULL == pIRule)
  2048. {
  2049. fRet = FALSE;
  2050. goto exit;
  2051. }
  2052. // Get the list of senders from the rule
  2053. if (FAILED(pIRule->GetProp(RULE_PROP_CRITERIA, 0, &propvar)))
  2054. {
  2055. fRet = FALSE;
  2056. goto exit;
  2057. }
  2058. if (0 != propvar.blob.cbSize)
  2059. {
  2060. Assert(VT_BLOB == propvar.vt);
  2061. Assert(NULL != propvar.blob.pBlobData);
  2062. cCritItem = propvar.blob.cbSize / sizeof(CRIT_ITEM);
  2063. pCritItem = (CRIT_ITEM *) (propvar.blob.pBlobData);
  2064. propvar.blob.pBlobData = NULL;
  2065. propvar.blob.cbSize = 0;
  2066. // Add each sender to the list
  2067. for (ulIndex = 0; ulIndex < cCritItem; ulIndex++)
  2068. {
  2069. if ((CRIT_TYPE_SENDER == pCritItem[ulIndex].type) &&
  2070. (VT_LPSTR == pCritItem[ulIndex].propvar.vt) &&
  2071. (NULL != pCritItem[ulIndex].propvar.pszVal))
  2072. {
  2073. _FAddSenderToList(type, pCritItem[ulIndex].propvar.pszVal);
  2074. }
  2075. }
  2076. }
  2077. fRet = TRUE;
  2078. exit:
  2079. RuleUtil_HrFreeCriteriaItem(pCritItem, cCritItem);
  2080. SafeMemFree(pCritItem);
  2081. return fRet;
  2082. }
  2083. ///////////////////////////////////////////////////////////////////////////////
  2084. //
  2085. // _FSaveSenders
  2086. //
  2087. // This save the senders from the list into the rule.
  2088. //
  2089. // type - the type of senders to save
  2090. //
  2091. // Returns: TRUE, if it was successfully saved
  2092. // FALSE, otherwise
  2093. //
  2094. ///////////////////////////////////////////////////////////////////////////////
  2095. BOOL COESendersRulesPageUI::_FSaveSenders(RULE_TYPE type)
  2096. {
  2097. BOOL fRet = FALSE;
  2098. ULONG cSender = 0;
  2099. LPSTR pszSender = NULL;
  2100. CRIT_ITEM * pcitemList = NULL;
  2101. ULONG ccitemList = 0;
  2102. LVITEM lvitem;
  2103. ULONG ulIndex = 0;
  2104. IOERule * pIRule = NULL;
  2105. ACT_ITEM aitem;
  2106. PROPVARIANT propvar;
  2107. TCHAR szRes[CCHMAX_STRINGRES];
  2108. HRESULT hr = S_OK;
  2109. Assert(NULL != m_hwndList);
  2110. ZeroMemory(&propvar, sizeof(propvar));
  2111. // Figure out how many senders we have
  2112. cSender = ListView_GetItemCount(m_hwndList);
  2113. if (0 != cSender)
  2114. {
  2115. // Allocate space to hold the sender
  2116. if (FAILED(HrAlloc((void **) &pszSender, m_cchLabelMax)))
  2117. {
  2118. fRet = FALSE;
  2119. goto exit;
  2120. }
  2121. pszSender[0] = '\0';
  2122. // Allocate space to hold the criteria
  2123. if (FAILED(HrAlloc((void **) &pcitemList, cSender * sizeof(*pcitemList))))
  2124. {
  2125. fRet = FALSE;
  2126. goto exit;
  2127. }
  2128. ZeroMemory(pcitemList, cSender * sizeof(*pcitemList));
  2129. }
  2130. ZeroMemory(&lvitem, sizeof(lvitem));
  2131. lvitem.mask = LVIF_IMAGE;
  2132. ccitemList = 0;
  2133. for (ulIndex = 0; ulIndex < cSender; ulIndex++)
  2134. {
  2135. lvitem.iItem = ulIndex;
  2136. lvitem.iSubItem = (RULE_TYPE_MAIL != type) ? 1 : 0;
  2137. if (FALSE == ListView_GetItem(m_hwndList, &lvitem))
  2138. {
  2139. continue;
  2140. }
  2141. if (FALSE != (iiconStateUnchecked != lvitem.iImage))
  2142. {
  2143. // Grab the sender from the list
  2144. pszSender[0] ='\0';
  2145. ListView_GetItemText(m_hwndList, ulIndex, 2, pszSender, m_cchLabelMax);
  2146. if ('\0' != pszSender[0])
  2147. {
  2148. // Grab a copy of the sender
  2149. pcitemList[ccitemList].propvar.pszVal = PszDupA(pszSender);
  2150. if (NULL == pcitemList[ccitemList].propvar.pszVal)
  2151. {
  2152. fRet = FALSE;
  2153. goto exit;
  2154. }
  2155. // Set the criteria specifics
  2156. pcitemList[ccitemList].type = CRIT_TYPE_SENDER;
  2157. pcitemList[ccitemList].logic = CRIT_LOGIC_OR;
  2158. pcitemList[ccitemList].dwFlags = CRIT_FLAG_DEFAULT;
  2159. pcitemList[ccitemList].propvar.vt = VT_LPSTR;
  2160. ccitemList++;
  2161. }
  2162. }
  2163. }
  2164. if (0 != ccitemList)
  2165. {
  2166. // Which rule are we looking at
  2167. pIRule = (RULE_TYPE_MAIL != type) ? m_pIRuleNews : m_pIRuleMail;
  2168. // Check the state
  2169. if (NULL == pIRule)
  2170. {
  2171. // Create the new rule
  2172. if (FAILED(RuleUtil_HrCreateSendersRule(0, &pIRule)))
  2173. {
  2174. fRet = FALSE;
  2175. goto exit;
  2176. }
  2177. }
  2178. else
  2179. {
  2180. pIRule->AddRef();
  2181. }
  2182. // Set the new criteria in the rule
  2183. ZeroMemory(&propvar, sizeof(propvar));
  2184. propvar.vt = VT_BLOB;
  2185. propvar.blob.cbSize = sizeof(CRIT_ITEM) * ccitemList;
  2186. propvar.blob.pBlobData = (BYTE *) pcitemList;
  2187. // Grab the list of criteria from the rule
  2188. if (FAILED(pIRule->SetProp(RULE_PROP_CRITERIA, 0, &propvar)))
  2189. {
  2190. fRet = FALSE;
  2191. goto exit;
  2192. }
  2193. }
  2194. if (RULE_TYPE_MAIL != type)
  2195. {
  2196. SafeRelease(m_pIRuleNews);
  2197. m_pIRuleNews = pIRule;
  2198. }
  2199. else
  2200. {
  2201. SafeRelease(m_pIRuleMail);
  2202. m_pIRuleMail = pIRule;
  2203. }
  2204. pIRule = NULL;
  2205. // Set the proper return value
  2206. fRet = TRUE;
  2207. exit:
  2208. RuleUtil_HrFreeCriteriaItem(pcitemList, ccitemList);
  2209. SafeMemFree(pcitemList);
  2210. SafeMemFree(pszSender);
  2211. SafeRelease(pIRule);
  2212. return fRet;
  2213. }
  2214. ///////////////////////////////////////////////////////////////////////////////
  2215. //
  2216. // _FFindSender
  2217. //
  2218. // This brings up the edit UI to create a new sender for the senders list
  2219. //
  2220. // Returns: NONE
  2221. //
  2222. ///////////////////////////////////////////////////////////////////////////////
  2223. BOOL COESendersRulesPageUI::_FFindSender(LPCSTR pszSender, LONG iSkip, LONG * plSender)
  2224. {
  2225. BOOL fRet = FALSE;
  2226. LONG cSenders = 0;
  2227. LPSTR pszLabel = NULL;
  2228. LVITEM lvitem = {0};
  2229. LONG lIndex = 0;
  2230. // Check incoming params
  2231. if (NULL == pszSender)
  2232. {
  2233. goto exit;
  2234. }
  2235. // Initialize the outgoing param
  2236. if (NULL != plSender)
  2237. {
  2238. *plSender = -1;
  2239. }
  2240. // Get the number of senders
  2241. cSenders = ListView_GetItemCount(m_hwndList);
  2242. if (0 == cSenders)
  2243. {
  2244. goto exit;
  2245. }
  2246. if (FAILED(HrAlloc((void **) &pszLabel, m_cchLabelMax * sizeof(*pszLabel))))
  2247. {
  2248. goto exit;
  2249. }
  2250. // Set up the
  2251. lvitem.iSubItem = 2;
  2252. lvitem.pszText = pszLabel;
  2253. lvitem.cchTextMax = m_cchLabelMax;
  2254. for (lIndex = 0; lIndex < cSenders; lIndex++)
  2255. {
  2256. // We need to skip over the selected item
  2257. if (lIndex == iSkip)
  2258. {
  2259. continue;
  2260. }
  2261. if (0 != SendMessage(m_hwndList, LVM_GETITEMTEXT, (WPARAM) lIndex, (LPARAM) &lvitem))
  2262. {
  2263. if (0 == lstrcmpi(pszLabel, pszSender))
  2264. {
  2265. fRet = TRUE;
  2266. break;
  2267. }
  2268. }
  2269. }
  2270. if (NULL != plSender)
  2271. {
  2272. if (lIndex < cSenders)
  2273. {
  2274. *plSender = lIndex;
  2275. }
  2276. }
  2277. exit:
  2278. SafeMemFree(pszLabel);
  2279. return fRet;
  2280. }
  2281. ///////////////////////////////////////////////////////////////////////////////
  2282. //
  2283. // _NewSender
  2284. //
  2285. // This brings up the edit UI to create a new sender for the senders list
  2286. //
  2287. // Returns: NONE
  2288. //
  2289. ///////////////////////////////////////////////////////////////////////////////
  2290. VOID COESendersRulesPageUI::_NewSender(VOID)
  2291. {
  2292. HRESULT hr = S_OK;
  2293. EDIT_SENDER editsndr = {0};
  2294. CEditSenderUI * pEditSenderUI = NULL;
  2295. LVITEM lvitem = {0};
  2296. LONG iIndex = 0;
  2297. ULONG cchSender = 0;
  2298. Assert(NULL != m_hwndList);
  2299. editsndr.lSelected = -1;
  2300. // Create the sender editor
  2301. pEditSenderUI = new CEditSenderUI;
  2302. if (NULL == pEditSenderUI)
  2303. {
  2304. goto exit;
  2305. }
  2306. // Initialize the editor object
  2307. if (FAILED(pEditSenderUI->HrInit(m_hwndDlg, 0, &editsndr)))
  2308. {
  2309. goto exit;
  2310. }
  2311. // Bring up the sender editor UI
  2312. hr = pEditSenderUI->HrShow();
  2313. if (FAILED(hr))
  2314. {
  2315. goto exit;
  2316. }
  2317. // If the sender changed, make sure we change the label
  2318. if (S_OK == hr)
  2319. {
  2320. lvitem.mask = LVIF_IMAGE;
  2321. lvitem.iImage = (0 != (editsndr.dwFlags & SNDF_MAIL)) ?
  2322. iiconStateChecked : iiconStateUnchecked;
  2323. // Are we inserting or replacing?
  2324. if (FALSE == _FFindSender(editsndr.pszSender, -1, &iIndex))
  2325. {
  2326. lvitem.iItem = ListView_GetItemCount(m_hwndList);
  2327. iIndex = ListView_InsertItem(m_hwndList, &lvitem);
  2328. if (-1 == iIndex)
  2329. {
  2330. goto exit;
  2331. }
  2332. }
  2333. else
  2334. {
  2335. lvitem.iItem = iIndex;
  2336. if (-1 == ListView_SetItem(m_hwndList, &lvitem))
  2337. {
  2338. goto exit;
  2339. }
  2340. }
  2341. lvitem.iItem = iIndex;
  2342. lvitem.iSubItem = 1;
  2343. lvitem.iImage = (0 != (editsndr.dwFlags & SNDF_NEWS)) ?
  2344. iiconStateChecked : iiconStateUnchecked;
  2345. if (-1 == ListView_SetItem(m_hwndList, &lvitem))
  2346. {
  2347. goto exit;
  2348. }
  2349. ListView_SetItemText(m_hwndList, iIndex, 2, editsndr.pszSender);
  2350. // Make sure the new item is selected
  2351. ListView_SetItemState(m_hwndList, iIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  2352. // Let's make sure we can see this new item
  2353. ListView_EnsureVisible(m_hwndList, iIndex, FALSE);
  2354. // Mark the rule list as dirty
  2355. m_dwState |= STATE_DIRTY;
  2356. cchSender = lstrlen(editsndr.pszSender) + 1;
  2357. if (cchSender > m_cchLabelMax)
  2358. {
  2359. m_cchLabelMax = cchSender;
  2360. }
  2361. }
  2362. exit:
  2363. SafeMemFree(editsndr.pszSender);
  2364. if (NULL != pEditSenderUI)
  2365. {
  2366. delete pEditSenderUI;
  2367. }
  2368. return;
  2369. }
  2370. ///////////////////////////////////////////////////////////////////////////////
  2371. //
  2372. // _EditSender
  2373. //
  2374. // This brings up the edit UI for the selected sender from the senders list
  2375. //
  2376. // iSelected - index of the item in the listview to work on
  2377. //
  2378. // Returns: NONE
  2379. //
  2380. ///////////////////////////////////////////////////////////////////////////////
  2381. VOID COESendersRulesPageUI::_EditSender(int iSelected)
  2382. {
  2383. HRESULT hr = S_OK;
  2384. EDIT_SENDER editsndr = {0};
  2385. LVITEM lvitem = {0};
  2386. CEditSenderUI * pEditSenderUI = NULL;
  2387. ULONG cchSender = 0;
  2388. LONG lItemDelete = 0;
  2389. Assert(NULL != m_hwndList);
  2390. editsndr.lSelected = iSelected;
  2391. // Allocate space to hold the sender
  2392. hr = HrAlloc((void **) &(editsndr.pszSender), m_cchLabelMax);
  2393. if (FAILED(hr))
  2394. {
  2395. goto exit;
  2396. }
  2397. // Grab the sender from the list
  2398. lvitem.iSubItem = 2;
  2399. lvitem.pszText = editsndr.pszSender;
  2400. lvitem.cchTextMax = m_cchLabelMax;
  2401. if (0 == SendMessage(m_hwndList, LVM_GETITEMTEXT, (WPARAM) iSelected, (LPARAM) &lvitem))
  2402. {
  2403. goto exit;
  2404. }
  2405. // Are we blocking mail?
  2406. ZeroMemory(&lvitem, sizeof(lvitem));
  2407. lvitem.mask = LVIF_IMAGE;
  2408. lvitem.iItem = iSelected;
  2409. if (FALSE == ListView_GetItem(m_hwndList, &lvitem))
  2410. {
  2411. goto exit;
  2412. }
  2413. if (FALSE != (iiconStateUnchecked != lvitem.iImage))
  2414. {
  2415. editsndr.dwFlags |= SNDF_MAIL;
  2416. }
  2417. // Are we blocking news?
  2418. lvitem.iSubItem = 1;
  2419. if (FALSE == ListView_GetItem(m_hwndList, &lvitem))
  2420. {
  2421. goto exit;
  2422. }
  2423. if (FALSE != (iiconStateUnchecked != lvitem.iImage))
  2424. {
  2425. editsndr.dwFlags |= SNDF_NEWS;
  2426. }
  2427. // Create the rules editor
  2428. pEditSenderUI = new CEditSenderUI;
  2429. if (NULL == pEditSenderUI)
  2430. {
  2431. goto exit;
  2432. }
  2433. // Initialize the editor object
  2434. if (FAILED(pEditSenderUI->HrInit(m_hwndDlg, 0, &editsndr)))
  2435. {
  2436. goto exit;
  2437. }
  2438. // Bring up the sender editor UI
  2439. hr = pEditSenderUI->HrShow();
  2440. if (FAILED(hr))
  2441. {
  2442. goto exit;
  2443. }
  2444. // If the sender changed, make sure we change the label
  2445. if (S_OK == hr)
  2446. {
  2447. // Do we want to remove a copy of the item
  2448. (VOID) _FFindSender(editsndr.pszSender, iSelected, &lItemDelete);
  2449. ZeroMemory(&lvitem, sizeof(lvitem));
  2450. lvitem.iItem = iSelected;
  2451. lvitem.mask = LVIF_IMAGE;
  2452. lvitem.iImage = (0 != (editsndr.dwFlags & SNDF_MAIL)) ?
  2453. iiconStateChecked : iiconStateUnchecked;
  2454. if (-1 == ListView_SetItem(m_hwndList, &lvitem))
  2455. {
  2456. goto exit;
  2457. }
  2458. lvitem.iSubItem = 1;
  2459. lvitem.iImage = (0 != (editsndr.dwFlags & SNDF_NEWS)) ?
  2460. iiconStateChecked : iiconStateUnchecked;
  2461. if (-1 == ListView_SetItem(m_hwndList, &lvitem))
  2462. {
  2463. goto exit;
  2464. }
  2465. ListView_SetItemText(m_hwndList, iSelected, 2, editsndr.pszSender);
  2466. // Make sure we remove the dup item
  2467. if (-1 != lItemDelete)
  2468. {
  2469. // Remove the item from the list
  2470. ListView_DeleteItem(m_hwndList, lItemDelete);
  2471. }
  2472. // Mark the rule list as dirty
  2473. m_dwState |= STATE_DIRTY;
  2474. cchSender = lstrlen(editsndr.pszSender) + 1;
  2475. if (cchSender > m_cchLabelMax)
  2476. {
  2477. m_cchLabelMax = cchSender;
  2478. }
  2479. }
  2480. exit:
  2481. SafeMemFree(editsndr.pszSender);
  2482. if (NULL != pEditSenderUI)
  2483. {
  2484. delete pEditSenderUI;
  2485. }
  2486. return;
  2487. }
  2488. ///////////////////////////////////////////////////////////////////////////////
  2489. //
  2490. // _RemoveSender
  2491. //
  2492. // This removes the selected sender from the senders list
  2493. //
  2494. // iSelected - index of the item in the listview to work on
  2495. //
  2496. // Returns: NONE
  2497. //
  2498. ///////////////////////////////////////////////////////////////////////////////
  2499. VOID COESendersRulesPageUI::_RemoveSender(int iSelected)
  2500. {
  2501. TCHAR szRes[CCHMAX_STRINGRES];
  2502. ULONG cchRes = 0;
  2503. LPSTR pszSender = NULL;
  2504. LVITEM lvitem;
  2505. LPSTR pszMessage = NULL;
  2506. int cSenders = 0;
  2507. Assert(NULL != m_hwndList);
  2508. // Get the string template to display
  2509. cchRes = LoadString(g_hLocRes, idsRuleSenderWarnDelete, szRes, ARRAYSIZE(szRes));
  2510. if (0 == cchRes)
  2511. {
  2512. goto exit;
  2513. }
  2514. // Allocate space to hold the sender
  2515. if (FAILED(HrAlloc((void **) &pszSender, m_cchLabelMax)))
  2516. {
  2517. goto exit;
  2518. }
  2519. // Grab the sender from the list
  2520. ZeroMemory(&lvitem, sizeof(lvitem));
  2521. lvitem.iSubItem = 2;
  2522. lvitem.pszText = pszSender;
  2523. lvitem.cchTextMax = m_cchLabelMax;
  2524. if (0 == SendMessage(m_hwndList, LVM_GETITEMTEXT, (WPARAM) iSelected, (LPARAM) &lvitem))
  2525. {
  2526. goto exit;
  2527. }
  2528. // Allocate space to hold the final display string
  2529. DWORD cchSize = (cchRes + lstrlen(pszSender) + 1);
  2530. if (FAILED(HrAlloc((void ** ) &pszMessage, cchSize)))
  2531. {
  2532. goto exit;
  2533. }
  2534. // Build up the string and display it
  2535. wnsprintf(pszMessage, cchSize, szRes, pszSender);
  2536. if (IDNO == AthMessageBox(m_hwndDlg, MAKEINTRESOURCE(idsAthenaMail), pszMessage,
  2537. NULL, MB_YESNO | MB_ICONINFORMATION))
  2538. {
  2539. goto exit;
  2540. }
  2541. // Remove the item from the list
  2542. ListView_DeleteItem(m_hwndList, iSelected);
  2543. // Let's make sure we have a selection in the list
  2544. cSenders = ListView_GetItemCount(m_hwndList);
  2545. if (cSenders > 0)
  2546. {
  2547. // Did we delete the last item in the list
  2548. if (iSelected >= cSenders)
  2549. {
  2550. // Move the selection to the new last item in the list
  2551. iSelected = cSenders - 1;
  2552. }
  2553. // Set the new selection
  2554. ListView_SetItemState(m_hwndList, iSelected, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  2555. // Let's make sure we can see this new item
  2556. ListView_EnsureVisible(m_hwndList, iSelected, FALSE);
  2557. }
  2558. else
  2559. {
  2560. // Make sure we clear out all of the buttons
  2561. _EnableButtons(-1);
  2562. }
  2563. // Mark the rule list as dirty
  2564. m_dwState |= STATE_DIRTY;
  2565. exit:
  2566. SafeMemFree(pszSender);
  2567. SafeMemFree(pszMessage);
  2568. return;
  2569. }
  2570. // Default destructor for the Exceptions List UI
  2571. CExceptionsListUI::~CExceptionsListUI()
  2572. {
  2573. }
  2574. ///////////////////////////////////////////////////////////////////////////////
  2575. //
  2576. // HrInit
  2577. //
  2578. // This initializes the Exceptions List UI dialog
  2579. //
  2580. // hwndOwner - the handle to the owner window of this dialog
  2581. // dwFlags - modifiers on how this dialog should act
  2582. //
  2583. // Returns: S_OK, if it was successfully initialized
  2584. //
  2585. ///////////////////////////////////////////////////////////////////////////////
  2586. HRESULT CExceptionsListUI::HrInit(HWND hwndOwner, DWORD dwFlags)
  2587. {
  2588. HRESULT hr = S_OK;
  2589. // Check incoming params
  2590. if (NULL == hwndOwner)
  2591. {
  2592. hr = E_INVALIDARG;
  2593. goto exit;
  2594. }
  2595. if (0 != (m_dwState & STATE_INITIALIZED))
  2596. {
  2597. hr = E_UNEXPECTED;
  2598. goto exit;
  2599. }
  2600. m_hwndOwner = hwndOwner;
  2601. m_dwFlags = dwFlags;
  2602. m_dwState |= STATE_INITIALIZED;
  2603. hr = S_OK;
  2604. exit:
  2605. return hr;
  2606. }
  2607. ///////////////////////////////////////////////////////////////////////////////
  2608. //
  2609. // HrShow
  2610. //
  2611. // This brings up the Exceptions List UI dialog
  2612. //
  2613. // Returns: S_OK, if the sender was successfully entered
  2614. // S_FALSE, if the dialog was canceled
  2615. //
  2616. ///////////////////////////////////////////////////////////////////////////////
  2617. HRESULT CExceptionsListUI::HrShow(IOERule * pIRule)
  2618. {
  2619. HRESULT hr = S_OK;
  2620. int iRet = 0;
  2621. // Check incoming params
  2622. if (NULL == pIRule)
  2623. {
  2624. hr = E_INVALIDARG;
  2625. goto exit;
  2626. }
  2627. if (0 == (m_dwState & STATE_INITIALIZED))
  2628. {
  2629. hr = E_UNEXPECTED;
  2630. goto exit;
  2631. }
  2632. // Save off the item
  2633. m_pIRule = pIRule;
  2634. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddExceptionsList),
  2635. m_hwndOwner, CExceptionsListUI::FExceptionsListDlgProc,
  2636. (LPARAM) this);
  2637. if (-1 == iRet)
  2638. {
  2639. hr = E_FAIL;
  2640. goto exit;
  2641. }
  2642. // Set the proper return code
  2643. hr = (IDOK == iRet) ? S_OK : S_FALSE;
  2644. exit:
  2645. return hr;
  2646. }
  2647. INT_PTR CALLBACK CExceptionsListUI::FExceptionsListDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  2648. {
  2649. BOOL fRet = FALSE;
  2650. CExceptionsListUI * pExceptionsUI = NULL;
  2651. pExceptionsUI = (CExceptionsListUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  2652. switch (uiMsg)
  2653. {
  2654. case WM_INITDIALOG:
  2655. // Grab the UI object pointer
  2656. pExceptionsUI = (CExceptionsListUI *) lParam;
  2657. // Set it into the dialog so we can get it back
  2658. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LPARAM) pExceptionsUI);
  2659. if (FALSE == pExceptionsUI->FOnInitDialog(hwndDlg))
  2660. {
  2661. EndDialog(hwndDlg, -1);
  2662. fRet = TRUE;
  2663. goto exit;
  2664. }
  2665. // We didn't set the focus so return TRUE
  2666. fRet = FALSE;
  2667. break;
  2668. case WM_COMMAND:
  2669. fRet = pExceptionsUI->FOnCommand((UINT) HIWORD(wParam), (INT) LOWORD(wParam), (HWND) lParam);
  2670. break;
  2671. case WM_NOTIFY:
  2672. fRet = pExceptionsUI->FOnNotify((INT) LOWORD(wParam), (NMHDR *) lParam);
  2673. break;
  2674. }
  2675. exit:
  2676. return fRet;
  2677. }
  2678. ///////////////////////////////////////////////////////////////////////////////
  2679. //
  2680. // FOnInitDialog
  2681. //
  2682. // This handles the WM_INITDIALOG message for the Exceptions List UI dialog
  2683. //
  2684. // hwndDlg - the handle to the dialog window
  2685. //
  2686. // Returns: TRUE, if it was successfully initialized
  2687. // FALSE, otherwise
  2688. //
  2689. ///////////////////////////////////////////////////////////////////////////////
  2690. BOOL CExceptionsListUI::FOnInitDialog(HWND hwndDlg)
  2691. {
  2692. BOOL fRet = FALSE;
  2693. // Check incoming params
  2694. if (NULL == hwndDlg)
  2695. {
  2696. fRet = FALSE;
  2697. goto exit;
  2698. }
  2699. // If we haven't been initialized yet...
  2700. if (0 == (m_dwState & STATE_INITIALIZED))
  2701. {
  2702. fRet = FALSE;
  2703. goto exit;
  2704. }
  2705. // Save off the dialog window handle
  2706. m_hwndDlg = hwndDlg;
  2707. // Set the default font onto the dialog
  2708. SetIntlFont(m_hwndDlg);
  2709. // Save off some of the controls
  2710. m_hwndList = GetDlgItem(hwndDlg, idlvExceptions);
  2711. if (NULL == m_hwndList)
  2712. {
  2713. fRet = FALSE;
  2714. goto exit;
  2715. }
  2716. // Initialize the list view
  2717. fRet = _FInitCtrls();
  2718. if (FALSE == fRet)
  2719. {
  2720. goto exit;
  2721. }
  2722. // Load the list view
  2723. fRet = _FLoadListCtrl();
  2724. if (FALSE == fRet)
  2725. {
  2726. goto exit;
  2727. }
  2728. // Set the focus into the list
  2729. SetFocus(m_hwndList);
  2730. // Everything's AOK
  2731. fRet = TRUE;
  2732. exit:
  2733. return fRet;
  2734. }
  2735. ///////////////////////////////////////////////////////////////////////////////
  2736. //
  2737. // FOnCommand
  2738. //
  2739. // This handles the WM_COMMAND message for the Exceptions List UI dialog
  2740. //
  2741. // Returns: TRUE, if it was successfully handled
  2742. // FALSE, otherwise
  2743. //
  2744. ///////////////////////////////////////////////////////////////////////////////
  2745. BOOL CExceptionsListUI::FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl)
  2746. {
  2747. BOOL fRet = FALSE;
  2748. LVITEM lvitem;
  2749. INT iSelected = 0;
  2750. // We only handle menu and accelerator commands
  2751. if ((0 != uiNotify) && (1 != uiNotify))
  2752. {
  2753. fRet = FALSE;
  2754. goto exit;
  2755. }
  2756. switch (iCtl)
  2757. {
  2758. case idcAddException:
  2759. _NewException();
  2760. fRet = TRUE;
  2761. break;
  2762. case idcModifyException:
  2763. // Get the selected item from the rule list
  2764. iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
  2765. if (-1 != iSelected)
  2766. {
  2767. // Bring up the rule editor for that item
  2768. _EditException(iSelected);
  2769. fRet = TRUE;
  2770. }
  2771. break;
  2772. case idcRemoveException:
  2773. // Get the selected item from the rule list
  2774. iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
  2775. if (-1 != iSelected)
  2776. {
  2777. // Remove the rule from the list
  2778. _RemoveException(iSelected);
  2779. fRet = TRUE;
  2780. }
  2781. break;
  2782. case idcExceptionsWAB:
  2783. // Mark the dialog as dirty
  2784. m_dwState |= STATE_DIRTY;
  2785. break;
  2786. case IDOK:
  2787. if (FALSE != _FOnOK())
  2788. {
  2789. EndDialog(m_hwndDlg, IDOK);
  2790. fRet = TRUE;
  2791. }
  2792. break;
  2793. case IDCANCEL:
  2794. EndDialog(m_hwndDlg, IDCANCEL);
  2795. fRet = TRUE;
  2796. break;
  2797. }
  2798. exit:
  2799. return fRet;
  2800. }
  2801. ///////////////////////////////////////////////////////////////////////////////
  2802. //
  2803. // FOnNotify
  2804. //
  2805. // This handles the WM_NOTIFY message for the Exceptions List UI dialog
  2806. //
  2807. // Returns: TRUE, if it was successfully destroyed
  2808. // FALSE, otherwise
  2809. //
  2810. ///////////////////////////////////////////////////////////////////////////////
  2811. BOOL CExceptionsListUI::FOnNotify(INT iCtl, NMHDR * pnmhdr)
  2812. {
  2813. BOOL fRet = FALSE;
  2814. NMLISTVIEW * pnmlv = NULL;
  2815. NMLVKEYDOWN * pnmlvkd = NULL;
  2816. INT iSelected = 0;
  2817. LVHITTESTINFO lvh = {0};
  2818. // We only handle notifications for the list control
  2819. if (idlvExceptions != pnmhdr->idFrom)
  2820. {
  2821. fRet = FALSE;
  2822. goto exit;
  2823. }
  2824. pnmlv = (LPNMLISTVIEW) pnmhdr;
  2825. switch (pnmlv->hdr.code)
  2826. {
  2827. case NM_CLICK:
  2828. // Did we click on an item?
  2829. if (-1 == pnmlv->iItem)
  2830. {
  2831. // Disable the buttons
  2832. _EnableButtons(pnmlv->iItem);
  2833. }
  2834. break;
  2835. case NM_DBLCLK:
  2836. // Did we click on an item?
  2837. if (-1 != pnmlv->iItem)
  2838. {
  2839. ZeroMemory(&lvh, sizeof(lvh));
  2840. lvh.pt = pnmlv->ptAction;
  2841. iSelected = ListView_HitTest(pnmlv->hdr.hwndFrom, &lvh);
  2842. if (-1 != iSelected)
  2843. {
  2844. // Did we click on the exception name?
  2845. if (0 != (lvh.flags & LVHT_ONITEMLABEL))
  2846. {
  2847. // Edit the rule
  2848. _EditException(iSelected);
  2849. }
  2850. }
  2851. }
  2852. else
  2853. {
  2854. // Disable the buttons
  2855. _EnableButtons(pnmlv->iItem);
  2856. }
  2857. break;
  2858. case LVN_ITEMCHANGED:
  2859. // If an item's state changed to selected..
  2860. if ((-1 != pnmlv->iItem) &&
  2861. (0 != (pnmlv->uChanged & LVIF_STATE)) &&
  2862. (0 == (pnmlv->uOldState & LVIS_SELECTED)) &&
  2863. (0 != (pnmlv->uNewState & LVIS_SELECTED)))
  2864. {
  2865. // Enable the buttons
  2866. _EnableButtons(pnmlv->iItem);
  2867. }
  2868. break;
  2869. case LVN_KEYDOWN:
  2870. pnmlvkd = (NMLVKEYDOWN *) pnmhdr;
  2871. // The delete key removes the rule from the list view
  2872. if (VK_DELETE == pnmlvkd->wVKey)
  2873. {
  2874. // Are we on a rule?
  2875. iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
  2876. if (-1 != iSelected)
  2877. {
  2878. // Remove the rule from the list
  2879. _RemoveException(iSelected);
  2880. }
  2881. }
  2882. break;
  2883. }
  2884. exit:
  2885. return fRet;
  2886. }
  2887. ///////////////////////////////////////////////////////////////////////////////
  2888. //
  2889. // _NewException
  2890. //
  2891. // This brings up the edit UI to create a new exception for the Exception List
  2892. //
  2893. // Returns: NONE
  2894. //
  2895. ///////////////////////////////////////////////////////////////////////////////
  2896. VOID CExceptionsListUI::_NewException(VOID)
  2897. {
  2898. HRESULT hr = S_OK;
  2899. CEditExceptionUI * pEditExcptUI = NULL;
  2900. EDIT_EXCPT editexcpt = {0};
  2901. ULONG ulIndex = 0;
  2902. Assert(NULL != m_hwndList);
  2903. // Create the sender editor
  2904. pEditExcptUI = new CEditExceptionUI;
  2905. if (NULL == pEditExcptUI)
  2906. {
  2907. goto exit;
  2908. }
  2909. // Initialize the editor object
  2910. if (FAILED(pEditExcptUI->HrInit(m_hwndDlg, 0, &editexcpt)))
  2911. {
  2912. goto exit;
  2913. }
  2914. // Bring up the sender editor UI
  2915. hr = pEditExcptUI->HrShow();
  2916. if (FAILED(hr))
  2917. {
  2918. goto exit;
  2919. }
  2920. // If the exception changed, make sure we change the label
  2921. if (S_OK == hr)
  2922. {
  2923. if (FALSE == _FAddExceptionToList(editexcpt.pszExcpt, &ulIndex))
  2924. {
  2925. goto exit;
  2926. }
  2927. // Make sure the new item is selected
  2928. ListView_SetItemState(m_hwndList, ulIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  2929. // Let's make sure we can see this new item
  2930. ListView_EnsureVisible(m_hwndList, ulIndex, FALSE);
  2931. // Mark the rule list as dirty
  2932. m_dwState |= STATE_DIRTY;
  2933. }
  2934. exit:
  2935. SafeMemFree(editexcpt.pszExcpt);
  2936. if (NULL != pEditExcptUI)
  2937. {
  2938. delete pEditExcptUI;
  2939. }
  2940. return;
  2941. }
  2942. ///////////////////////////////////////////////////////////////////////////////
  2943. //
  2944. // _EditException
  2945. //
  2946. // This brings up the edit UI for the selected exception from the Execption List
  2947. //
  2948. // iSelected - index of the item in the listview to work on
  2949. //
  2950. // Returns: NONE
  2951. //
  2952. ///////////////////////////////////////////////////////////////////////////////
  2953. VOID CExceptionsListUI::_EditException(int iSelected)
  2954. {
  2955. HRESULT hr = S_OK;
  2956. EDIT_EXCPT editexcpt = {0};
  2957. LVITEM lvitem = {0};
  2958. CEditExceptionUI * pEditExcptUI = NULL;
  2959. ULONG cchExcpt = 0;
  2960. LONG lIndex = 0;
  2961. LVFINDINFO lvfi = {0};
  2962. Assert(NULL != m_hwndList);
  2963. // Allocate space to hold the exception
  2964. hr = HrAlloc((void **) &(editexcpt.pszExcpt), m_cchLabelMax);
  2965. if (FAILED(hr))
  2966. {
  2967. goto exit;
  2968. }
  2969. // Grab the exception from the list
  2970. lvitem.pszText = editexcpt.pszExcpt;
  2971. lvitem.cchTextMax = m_cchLabelMax;
  2972. if (0 == SendMessage(m_hwndList, LVM_GETITEMTEXT, (WPARAM) iSelected, (LPARAM) &lvitem))
  2973. {
  2974. goto exit;
  2975. }
  2976. // Create the exception editor
  2977. pEditExcptUI = new CEditExceptionUI;
  2978. if (NULL == pEditExcptUI)
  2979. {
  2980. goto exit;
  2981. }
  2982. // Initialize the editor object
  2983. if (FAILED(pEditExcptUI->HrInit(m_hwndDlg, 0, &editexcpt)))
  2984. {
  2985. goto exit;
  2986. }
  2987. // Bring up the exception editor UI
  2988. hr = pEditExcptUI->HrShow();
  2989. if (FAILED(hr))
  2990. {
  2991. goto exit;
  2992. }
  2993. // If the exception changed, make sure we change the label
  2994. if (S_OK == hr)
  2995. {
  2996. lvfi.flags = LVFI_STRING;
  2997. lvfi.psz = editexcpt.pszExcpt;
  2998. // Check to see if the item already exists
  2999. lIndex = ListView_FindItem(m_hwndList, -1, &lvfi);
  3000. // If the item already exists
  3001. if ((-1 != lIndex) && (iSelected != lIndex))
  3002. {
  3003. // Make sure the duplicate item is selected
  3004. ListView_SetItemState(m_hwndList, lIndex,
  3005. LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  3006. // Let's make sure we can see this new item
  3007. ListView_EnsureVisible(m_hwndList, lIndex, FALSE);
  3008. // Remove the item from the list
  3009. ListView_DeleteItem(m_hwndList, iSelected);
  3010. }
  3011. else
  3012. {
  3013. ListView_SetItemText(m_hwndList, iSelected, 0, editexcpt.pszExcpt);
  3014. cchExcpt = lstrlen(editexcpt.pszExcpt) + 1;
  3015. if (cchExcpt > m_cchLabelMax)
  3016. {
  3017. m_cchLabelMax = cchExcpt;
  3018. }
  3019. }
  3020. // Mark the rule list as dirty
  3021. m_dwState |= STATE_DIRTY;
  3022. }
  3023. exit:
  3024. SafeMemFree(editexcpt.pszExcpt);
  3025. if (NULL != pEditExcptUI)
  3026. {
  3027. delete pEditExcptUI;
  3028. }
  3029. return;
  3030. }
  3031. ///////////////////////////////////////////////////////////////////////////////
  3032. //
  3033. // _RemoveException
  3034. //
  3035. // This removes the selected exception from the Exception List
  3036. //
  3037. // iSelected - index of the item in the listview to work on
  3038. //
  3039. // Returns: NONE
  3040. //
  3041. ///////////////////////////////////////////////////////////////////////////////
  3042. VOID CExceptionsListUI::_RemoveException(int iSelected)
  3043. {
  3044. TCHAR szRes[CCHMAX_STRINGRES];
  3045. ULONG cchRes = 0;
  3046. LPSTR pszExcpt = NULL;
  3047. LVITEM lvitem = {0};
  3048. LPSTR pszMessage = NULL;
  3049. int cExcpts = 0;
  3050. Assert(NULL != m_hwndList);
  3051. // Get the string template to display
  3052. cchRes = LoadString(g_hLocRes, idsRuleExcptWarnDelete, szRes, ARRAYSIZE(szRes));
  3053. if (0 == cchRes)
  3054. {
  3055. goto exit;
  3056. }
  3057. // Allocate space to hold the execptions
  3058. if (FAILED(HrAlloc((void **) &pszExcpt, m_cchLabelMax)))
  3059. {
  3060. goto exit;
  3061. }
  3062. // Grab the exception from the list
  3063. lvitem.pszText = pszExcpt;
  3064. lvitem.cchTextMax = m_cchLabelMax;
  3065. if (0 == SendMessage(m_hwndList, LVM_GETITEMTEXT, (WPARAM) iSelected, (LPARAM) &lvitem))
  3066. {
  3067. goto exit;
  3068. }
  3069. // Allocate space to hold the final display string
  3070. DWORD cchSize = (cchRes + lstrlen(pszExcpt) + 1);
  3071. if (FAILED(HrAlloc((void ** ) &pszMessage, cchSize)))
  3072. {
  3073. goto exit;
  3074. }
  3075. // Build up the string and display it
  3076. wnsprintf(pszMessage, cchSize, szRes, pszExcpt);
  3077. if (IDNO == AthMessageBox(m_hwndDlg, MAKEINTRESOURCE(idsAthenaMail), pszMessage,
  3078. NULL, MB_YESNO | MB_ICONINFORMATION))
  3079. {
  3080. goto exit;
  3081. }
  3082. // Remove the item from the list
  3083. ListView_DeleteItem(m_hwndList, iSelected);
  3084. // Let's make sure we have a selection in the list
  3085. cExcpts = ListView_GetItemCount(m_hwndList);
  3086. if (cExcpts > 0)
  3087. {
  3088. // Did we delete the last item in the list
  3089. if (iSelected >= cExcpts)
  3090. {
  3091. // Move the selection to the new last item in the list
  3092. iSelected = cExcpts - 1;
  3093. }
  3094. // Set the new selection
  3095. ListView_SetItemState(m_hwndList, iSelected, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  3096. // Let's make sure we can see this new item
  3097. ListView_EnsureVisible(m_hwndList, iSelected, FALSE);
  3098. }
  3099. else
  3100. {
  3101. // Make sure we clear out all of the buttons
  3102. _EnableButtons(-1);
  3103. }
  3104. // Mark the rule list as dirty
  3105. m_dwState |= STATE_DIRTY;
  3106. exit:
  3107. SafeMemFree(pszExcpt);
  3108. SafeMemFree(pszMessage);
  3109. return;
  3110. }
  3111. ///////////////////////////////////////////////////////////////////////////////
  3112. //
  3113. // _FOnOK
  3114. //
  3115. // This initializes the controls in the Exceptions List UI dialog
  3116. //
  3117. // Returns: TRUE, on successful initialization
  3118. // FALSE, otherwise.
  3119. //
  3120. ///////////////////////////////////////////////////////////////////////////////
  3121. BOOL CExceptionsListUI::_FOnOK(VOID)
  3122. {
  3123. BOOL fRet = FALSE;
  3124. BOOL fWABEnable = FALSE;
  3125. PROPVARIANT propvar = {0};
  3126. // Save of the list of addresses
  3127. if (FALSE == _FSaveListCtrl())
  3128. {
  3129. fRet = FALSE;
  3130. goto exit;
  3131. }
  3132. // Are we supposed to check the WAB?
  3133. fWABEnable = !!(BST_CHECKED == Button_GetCheck(GetDlgItem(m_hwndDlg, idcExceptionsWAB)));
  3134. // Save of the state of the Check WAB button
  3135. propvar.vt = VT_BOOL;
  3136. propvar.boolVal = (VARIANT_BOOL) !!fWABEnable;
  3137. if (FAILED(m_pIRule->SetProp(RULE_PROP_EXCPT_WAB, 0, &propvar)))
  3138. {
  3139. fRet = FALSE;
  3140. goto exit;
  3141. }
  3142. // Everything's fine
  3143. fRet = TRUE;
  3144. exit:
  3145. return fRet;
  3146. }
  3147. ///////////////////////////////////////////////////////////////////////////////
  3148. //
  3149. // _FInitCtrls
  3150. //
  3151. // This initializes the controls in the Exceptions List UI dialog
  3152. //
  3153. // Returns: TRUE, on successful initialization
  3154. // FALSE, otherwise.
  3155. //
  3156. ///////////////////////////////////////////////////////////////////////////////
  3157. BOOL CExceptionsListUI::_FInitCtrls(VOID)
  3158. {
  3159. BOOL fRet = FALSE;
  3160. LVCOLUMN lvc = {0};
  3161. RECT rc = {0};
  3162. PROPVARIANT propvar = {0};
  3163. Assert(NULL != m_hwndList);
  3164. if (FAILED(m_pIRule->GetProp(RULE_PROP_EXCPT_WAB, 0, &propvar)))
  3165. {
  3166. fRet = FALSE;
  3167. goto exit;
  3168. }
  3169. // Set the Check WAB button
  3170. Button_SetCheck(GetDlgItem(m_hwndDlg, idcExceptionsWAB),
  3171. (FALSE != propvar.boolVal) ? BST_CHECKED : BST_UNCHECKED);
  3172. // Initialize the list view structure
  3173. lvc.mask = LVCF_WIDTH;
  3174. lvc.fmt = LVCFMT_LEFT;
  3175. // Calculate the size of the list view
  3176. GetClientRect(m_hwndList, &rc);
  3177. lvc.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL);
  3178. // Add the column to the list view
  3179. ListView_InsertColumn(m_hwndList, 0, &lvc);
  3180. // Full row selection and subitem images on listview
  3181. ListView_SetExtendedListViewStyle(m_hwndList, LVS_EX_FULLROWSELECT);
  3182. fRet = TRUE;
  3183. exit:
  3184. return fRet;
  3185. }
  3186. ///////////////////////////////////////////////////////////////////////////////
  3187. //
  3188. // _FLoadListCtrl
  3189. //
  3190. // This loads the list view with the current exceptions
  3191. //
  3192. // Returns: TRUE, if it was successfully loaded
  3193. // FALSE, otherwise
  3194. //
  3195. ///////////////////////////////////////////////////////////////////////////////
  3196. BOOL CExceptionsListUI::_FLoadListCtrl(VOID)
  3197. {
  3198. BOOL fRet = FALSE;
  3199. ULONG ulIndex = 0;
  3200. IOERuleAddrList * pIAddrList = NULL;
  3201. RULEADDRLIST * pralList = NULL;
  3202. ULONG cralList = 0;
  3203. Assert(NULL != m_hwndList);
  3204. // Remove all the items from the list control
  3205. ListView_DeleteAllItems(m_hwndList);
  3206. // Get the exceptions list from the rule
  3207. if (FAILED(m_pIRule->QueryInterface(IID_IOERuleAddrList, (VOID **) &pIAddrList)))
  3208. {
  3209. fRet = FALSE;
  3210. goto exit;
  3211. }
  3212. // Get the list of exceptions from the address list
  3213. if (FAILED(pIAddrList->GetList(0, &pralList, &cralList)))
  3214. {
  3215. fRet = FALSE;
  3216. goto exit;
  3217. }
  3218. // Add each item into the list
  3219. for (ulIndex = 0; ulIndex < cralList; ulIndex++)
  3220. {
  3221. // Verify the item
  3222. if (RALF_MAIL != pralList[ulIndex].dwFlags)
  3223. {
  3224. fRet = FALSE;
  3225. goto exit;
  3226. }
  3227. // Add the item
  3228. if (FALSE == _FAddExceptionToList(pralList[ulIndex].pszAddr, NULL))
  3229. {
  3230. fRet = FALSE;
  3231. goto exit;
  3232. }
  3233. }
  3234. // Select the first item in the list
  3235. if (0 != cralList)
  3236. {
  3237. ListView_SetItemState(m_hwndList, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  3238. }
  3239. // Enable the dialog buttons.
  3240. _EnableButtons((0 != cralList) ? 0 : -1);
  3241. fRet = TRUE;
  3242. exit:
  3243. FreeRuleAddrList(pralList, cralList);
  3244. SafeMemFree(pralList);
  3245. SafeRelease(pIAddrList);
  3246. return fRet;
  3247. }
  3248. ///////////////////////////////////////////////////////////////////////////////
  3249. //
  3250. // _FSaveListCtrl
  3251. //
  3252. // This save the exceptions from the list view
  3253. //
  3254. // Returns: TRUE, if it was successfully saved
  3255. // FALSE, otherwise
  3256. //
  3257. ///////////////////////////////////////////////////////////////////////////////
  3258. BOOL CExceptionsListUI::_FSaveListCtrl(VOID)
  3259. {
  3260. BOOL fRet = FALSE;
  3261. ULONG cExcpts = 0;
  3262. LPSTR pszAddr = NULL;
  3263. RULEADDRLIST * pralList = NULL;
  3264. ULONG ulIndex = 0;
  3265. IOERuleAddrList * pIAddrList = NULL;
  3266. Assert(NULL != m_hwndList);
  3267. // Figure out how many exceptions are in the list
  3268. cExcpts = ListView_GetItemCount(m_hwndList);
  3269. // If there are exceptions
  3270. if (0 != cExcpts)
  3271. {
  3272. // Allocate space to hold the exceptions
  3273. if (FAILED(HrAlloc((VOID **) &pszAddr, (m_cchLabelMax + 1))))
  3274. {
  3275. fRet = FALSE;
  3276. goto exit;
  3277. }
  3278. // Initialize the exception buffer
  3279. pszAddr[0] = '\0';
  3280. // Allocate space to hold the exception list
  3281. if (FAILED(HrAlloc((VOID **) &pralList, cExcpts * sizeof(*pralList))))
  3282. {
  3283. fRet = FALSE;
  3284. goto exit;
  3285. }
  3286. // Initialize the list of exceptions
  3287. ZeroMemory(pralList, cExcpts * sizeof(*pralList));
  3288. // Save each exception from the list
  3289. for (ulIndex = 0; ulIndex < cExcpts; ulIndex++)
  3290. {
  3291. // Get the item from the list
  3292. pszAddr[0] = '\0';
  3293. ListView_GetItemText(m_hwndList, ulIndex, 0, pszAddr, m_cchLabelMax + 1);
  3294. // Verify it isn't empty
  3295. if ('\0' == pszAddr[0])
  3296. {
  3297. fRet = FALSE;
  3298. goto exit;
  3299. }
  3300. // Set the flags
  3301. pralList[ulIndex].dwFlags = RALF_MAIL;
  3302. // Save the item
  3303. pralList[ulIndex].pszAddr = PszDupA(pszAddr);
  3304. if (NULL == pralList[ulIndex].pszAddr)
  3305. {
  3306. fRet = FALSE;
  3307. goto exit;
  3308. }
  3309. }
  3310. }
  3311. // Get the exceptions list from the rule
  3312. if (FAILED(m_pIRule->QueryInterface(IID_IOERuleAddrList, (VOID **) &pIAddrList)))
  3313. {
  3314. fRet = FALSE;
  3315. goto exit;
  3316. }
  3317. // Get the list of exceptions from the address list
  3318. if (FAILED(pIAddrList->SetList(0, pralList, cExcpts)))
  3319. {
  3320. fRet = FALSE;
  3321. goto exit;
  3322. }
  3323. // Set the proper return value
  3324. fRet = TRUE;
  3325. exit:
  3326. SafeRelease(pIAddrList);
  3327. FreeRuleAddrList(pralList, cExcpts);
  3328. SafeMemFree(pralList);
  3329. SafeMemFree(pszAddr);
  3330. return fRet;
  3331. }
  3332. ///////////////////////////////////////////////////////////////////////////////
  3333. //
  3334. // _FAddExceptionToList
  3335. //
  3336. // This adds the exception passed in to the list view
  3337. //
  3338. // pszExcpt - the actual exception
  3339. // pulIndex - the index where the item was added
  3340. //
  3341. // Returns: TRUE, if it was successfully added
  3342. // FALSE, otherwise
  3343. //
  3344. ///////////////////////////////////////////////////////////////////////////////
  3345. BOOL CExceptionsListUI::_FAddExceptionToList(LPSTR pszExcpt, ULONG * pulIndex)
  3346. {
  3347. BOOL fRet = FALSE;
  3348. ULONG cExcpts = 0;
  3349. LPSTR pszLabel = NULL;
  3350. ULONG ulIndex = 0;
  3351. LVITEM lvitem = {0};
  3352. ULONG cchExcpt = 0;
  3353. Assert(NULL != m_hwndList);
  3354. // If there's nothing to do...
  3355. if (NULL == pszExcpt)
  3356. {
  3357. fRet = FALSE;
  3358. goto exit;
  3359. }
  3360. // Initialize the outgoing param
  3361. if (NULL != pulIndex)
  3362. {
  3363. *pulIndex = 0;
  3364. }
  3365. cExcpts = ListView_GetItemCount(m_hwndList);
  3366. // Figure out the maximum size of the buffer needed get the string
  3367. if (0 != cExcpts)
  3368. {
  3369. if (FAILED(HrAlloc((void **) &pszLabel, m_cchLabelMax * sizeof(*pszLabel))))
  3370. {
  3371. fRet = FALSE;
  3372. goto exit;
  3373. }
  3374. // See if the exception is already in the list
  3375. lvitem.pszText = pszLabel;
  3376. lvitem.cchTextMax = m_cchLabelMax;
  3377. for (ulIndex = 0; ulIndex < cExcpts; ulIndex++)
  3378. {
  3379. if (0 != SendMessage(m_hwndList, LVM_GETITEMTEXT, (WPARAM) ulIndex, (LPARAM) &lvitem))
  3380. {
  3381. if (0 == lstrcmpi(pszLabel, pszExcpt))
  3382. {
  3383. break;
  3384. }
  3385. }
  3386. }
  3387. }
  3388. // Insert it if we didn't find it
  3389. if (ulIndex == cExcpts)
  3390. {
  3391. ZeroMemory(&lvitem, sizeof(lvitem));
  3392. lvitem.mask = LVIF_TEXT;
  3393. lvitem.iItem = ulIndex;
  3394. lvitem.pszText = pszExcpt;
  3395. ulIndex = ListView_InsertItem(m_hwndList, &lvitem);
  3396. if (-1 == ulIndex)
  3397. {
  3398. fRet = FALSE;
  3399. goto exit;
  3400. }
  3401. // Figure out the new maximum
  3402. cchExcpt = lstrlen(pszExcpt) + 1;
  3403. if (cchExcpt > m_cchLabelMax)
  3404. {
  3405. m_cchLabelMax = cchExcpt;
  3406. }
  3407. }
  3408. // Set the outgoing param
  3409. if (NULL != pulIndex)
  3410. {
  3411. *pulIndex = ulIndex;
  3412. }
  3413. // Set the proper return value
  3414. fRet = TRUE;
  3415. exit:
  3416. SafeMemFree(pszLabel);
  3417. return fRet;
  3418. }
  3419. ///////////////////////////////////////////////////////////////////////////////
  3420. //
  3421. // _EnableButtons
  3422. //
  3423. // This enables or disables the buttons in the Exceptions List UI dialog
  3424. // depending on what is selected.
  3425. //
  3426. // iSelected - the item that was selected,
  3427. // -1 means that nothing was selected
  3428. //
  3429. // Returns: NONE
  3430. //
  3431. ///////////////////////////////////////////////////////////////////////////////
  3432. void CExceptionsListUI::_EnableButtons(INT iSelected)
  3433. {
  3434. int cExcpts = 0;
  3435. BOOL fSelected = FALSE;
  3436. Assert(NULL != m_hwndList);
  3437. fSelected = (-1 != iSelected);
  3438. // Enable the senders action buttons
  3439. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcRemoveException, fSelected);
  3440. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcModifyException, fSelected);
  3441. return;
  3442. }