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.

6761 lines
200 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // RuleDesc.cpp
  4. //
  5. ///////////////////////////////////////////////////////////////////////////////
  6. #include <pch.hxx>
  7. #include "ruledesc.h"
  8. #include "editrule.h"
  9. #include "ruleutil.h"
  10. #include <rulesdlg.h>
  11. #include <newfldr.h>
  12. #include <richedit.h>
  13. #include <fontnsc.h>
  14. #include <wabdefs.h>
  15. #include <mimeolep.h>
  16. #include <xpcomm.h>
  17. #include "reutil.h"
  18. #include "shlwapip.h"
  19. #include <demand.h>
  20. typedef struct tagSELECTADDR
  21. {
  22. LONG lRecipType;
  23. UINT uidsWell;
  24. LPWSTR pwszAddr;
  25. } SELECTADDR, * PSELECTADDR;
  26. typedef struct tagSELECTACCT
  27. {
  28. RULE_TYPE typeRule;
  29. LPSTR pszAcct;
  30. } SELECTACCT, * PSELECTACCT;
  31. class CEditLogicUI
  32. {
  33. private:
  34. enum
  35. {
  36. STATE_UNINIT = 0x00000000,
  37. STATE_INITIALIZED = 0x00000001,
  38. STATE_DIRTY = 0x00000002
  39. };
  40. private:
  41. HWND m_hwndOwner;
  42. DWORD m_dwFlags;
  43. DWORD m_dwState;
  44. HWND m_hwndDlg;
  45. RULE_TYPE m_typeRule;
  46. HWND m_hwndDescript;
  47. IOERule * m_pIRule;
  48. CRuleDescriptUI * m_pDescriptUI;
  49. public:
  50. CEditLogicUI();
  51. ~CEditLogicUI();
  52. // The main UI methods
  53. HRESULT HrInit(HWND hwndOwner, DWORD dwFlags, RULE_TYPE typeRule, IOERule * pIRule);
  54. HRESULT HrShow(void);
  55. // The Rules Manager dialog function
  56. static INT_PTR CALLBACK FEditLogicDlgProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
  57. // Message handling functions
  58. BOOL FOnInitDialog(HWND hwndDlg);
  59. BOOL FOnOK(void);
  60. BOOL FOnLogicChange(HWND hwndName);
  61. };
  62. // Constants
  63. static const int c_cCritItemGrow = 16;
  64. static const int c_cActItemGrow = 16;
  65. static const int PUI_WORDS = 0x00000001;
  66. HRESULT _HrCriteriaEditPeople(HWND hwnd, CRIT_ITEM * pCritItem);
  67. HRESULT _HrCriteriaEditWords(HWND hwnd, CRIT_ITEM * pCritItem);
  68. CRuleDescriptUI::CRuleDescriptUI() : m_hwndOwner(NULL), m_dwFlags(0), m_dwState(STATE_UNINIT),
  69. m_typeRule(RULE_TYPE_MAIL),
  70. m_pDescriptListCrit(NULL), m_cDescriptListCrit(0),
  71. m_pDescriptListAct(NULL), m_cDescriptListAct(0),
  72. m_hfont(NULL), m_wpcOld(NULL), m_logicCrit(CRIT_LOGIC_AND),
  73. m_fErrorLogic(FALSE)
  74. {
  75. }
  76. CRuleDescriptUI::~CRuleDescriptUI()
  77. {
  78. _FreeDescriptionList(m_pDescriptListCrit);
  79. m_pDescriptListCrit = NULL;
  80. m_cDescriptListCrit = 0;
  81. _FreeDescriptionList(m_pDescriptListAct);
  82. m_pDescriptListAct = NULL;
  83. m_cDescriptListAct = 0;
  84. if ((NULL != m_hwndOwner) && (FALSE != IsWindow(m_hwndOwner)) && (NULL != m_wpcOld))
  85. {
  86. SetWindowLongPtr(m_hwndOwner, GWLP_WNDPROC, (LONG_PTR) m_wpcOld);
  87. m_wpcOld = NULL;
  88. }
  89. }
  90. ///////////////////////////////////////////////////////////////////////////////
  91. //
  92. // HrInit
  93. //
  94. // This initializes us with the owner window and any flags we might have
  95. //
  96. // hwndOwner - handle to the owner window
  97. // dwFlags - flags to use for this instance
  98. // typeRule - the type of rule editor to create
  99. //
  100. // Returns: S_OK
  101. //
  102. ///////////////////////////////////////////////////////////////////////////////
  103. HRESULT CRuleDescriptUI::HrInit(HWND hwndOwner, DWORD dwFlags)
  104. {
  105. HRESULT hr = S_OK;
  106. // If we're already initialized, then fail
  107. if (0 != (m_dwState & STATE_INITIALIZED))
  108. {
  109. hr = E_FAIL;
  110. goto exit;
  111. }
  112. // Save off the owner window
  113. m_hwndOwner = hwndOwner;
  114. // Make sure we set the correct font into the control
  115. m_hfont = HGetSystemFont(FNT_SYS_ICON);
  116. if (NULL != m_hfont)
  117. {
  118. SetFontOnRichEdit(m_hwndOwner, m_hfont);
  119. }
  120. // Save off the flags
  121. m_dwFlags = dwFlags;
  122. if (0 != (m_dwFlags & RDF_READONLY))
  123. {
  124. m_dwState |= STATE_READONLY;
  125. }
  126. // Subclass the original dialog
  127. if ((NULL != m_hwndOwner) && (0 == (m_dwFlags & RDF_READONLY)))
  128. {
  129. // Save off the object pointer
  130. SetWindowLongPtr(m_hwndOwner, GWLP_USERDATA, (LONG_PTR) this);
  131. m_wpcOld = (WNDPROC) SetWindowLongPtr(m_hwndOwner, GWLP_WNDPROC, (LONG_PTR) CRuleDescriptUI::_DescriptWndProc);
  132. }
  133. // We're done
  134. m_dwState |= STATE_INITIALIZED;
  135. hr = S_OK;
  136. exit:
  137. return hr;
  138. }
  139. ///////////////////////////////////////////////////////////////////////////////
  140. //
  141. // HrSetRule
  142. //
  143. // This initializes us with the owner window and any flags we might have
  144. //
  145. // hwndOwner - handle to the owner window
  146. // dwFlags - flags to use for this instance
  147. // typeRule - the type of rule editor to create
  148. //
  149. // Returns: S_OK
  150. //
  151. ///////////////////////////////////////////////////////////////////////////////
  152. HRESULT CRuleDescriptUI::HrSetRule(RULE_TYPE typeRule, IOERule * pIRule)
  153. {
  154. HRESULT hr = S_OK;
  155. RULEDESCRIPT_LIST * pDescriptListCrit = NULL;
  156. ULONG cDescriptListCrit = 0;
  157. CRIT_LOGIC logicCrit = CRIT_LOGIC_AND;
  158. RULEDESCRIPT_LIST * pDescriptListAct = NULL;
  159. ULONG cDescriptListAct = 0;
  160. BOOL fDisabled = FALSE;
  161. PROPVARIANT propvar = {0};
  162. // Are we in a good state?
  163. if (0 == (m_dwState & STATE_INITIALIZED))
  164. {
  165. hr = E_FAIL;
  166. goto exit;
  167. }
  168. if (NULL != pIRule)
  169. {
  170. // Create the criteria list
  171. hr = _HrBuildCriteriaList(pIRule, &pDescriptListCrit, &cDescriptListCrit, &logicCrit);
  172. if (FAILED(hr))
  173. {
  174. goto exit;
  175. }
  176. // Create the actions list
  177. hr = _HrBuildActionList(pIRule, &pDescriptListAct, &cDescriptListAct);
  178. if (FAILED(hr))
  179. {
  180. goto exit;
  181. }
  182. // Get the enabled state
  183. if (SUCCEEDED(pIRule->GetProp(RULE_PROP_DISABLED, 0, &propvar)))
  184. {
  185. Assert(VT_BOOL == propvar.vt);
  186. fDisabled = propvar.boolVal;
  187. }
  188. }
  189. m_typeRule = typeRule;
  190. _FreeDescriptionList(m_pDescriptListCrit);
  191. m_pDescriptListCrit = pDescriptListCrit;
  192. pDescriptListCrit = NULL;
  193. m_cDescriptListCrit = cDescriptListCrit;
  194. m_logicCrit = logicCrit;
  195. m_fErrorLogic = FALSE;
  196. _FreeDescriptionList(m_pDescriptListAct);
  197. m_pDescriptListAct = pDescriptListAct;
  198. pDescriptListAct = NULL;
  199. m_cDescriptListAct = cDescriptListAct;
  200. // Make sure we verify the rule
  201. HrVerifyRule();
  202. // Clear the dirty state
  203. m_dwState &= ~STATE_DIRTY;
  204. // Set the rule state
  205. if (NULL != pIRule)
  206. {
  207. m_dwState |= STATE_HASRULE;
  208. }
  209. else
  210. {
  211. m_dwState &= ~STATE_HASRULE;
  212. }
  213. if (FALSE == fDisabled)
  214. {
  215. m_dwState |= STATE_ENABLED;
  216. }
  217. else
  218. {
  219. m_dwState &= ~STATE_ENABLED;
  220. }
  221. hr = S_OK;
  222. exit:
  223. _FreeDescriptionList(pDescriptListCrit);
  224. _FreeDescriptionList(pDescriptListAct);
  225. return hr;
  226. }
  227. ///////////////////////////////////////////////////////////////////////////////
  228. //
  229. // HrVerifyRule
  230. //
  231. // This verifies the rule string
  232. //
  233. // Returns: S_OK, if the rule state is valid
  234. // S_FALSE, if the rule state is invalid
  235. //
  236. ///////////////////////////////////////////////////////////////////////////////
  237. HRESULT CRuleDescriptUI::HrVerifyRule(void)
  238. {
  239. HRESULT hr = S_OK;
  240. RULEDESCRIPT_LIST * pDescriptListWalk = NULL;
  241. BOOL fBad = FALSE;
  242. // If we have nothing, then the rule is still in error
  243. if ((NULL == m_pDescriptListCrit) && (NULL == m_pDescriptListAct))
  244. {
  245. hr = S_FALSE;
  246. goto exit;
  247. }
  248. // Validate the logic operation
  249. if (1 < m_cDescriptListCrit)
  250. {
  251. m_fErrorLogic = (CRIT_LOGIC_NULL == m_logicCrit);
  252. if (FALSE != m_fErrorLogic)
  253. {
  254. fBad = TRUE;
  255. }
  256. }
  257. // Validate the criteria
  258. for (pDescriptListWalk = m_pDescriptListCrit;
  259. pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext)
  260. {
  261. pDescriptListWalk->fError = !_FVerifyCriteria(pDescriptListWalk);
  262. if (FALSE != pDescriptListWalk->fError)
  263. {
  264. fBad = TRUE;
  265. }
  266. }
  267. // Build up the actions
  268. for (pDescriptListWalk = m_pDescriptListAct;
  269. pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext)
  270. {
  271. pDescriptListWalk->fError = !_FVerifyAction(pDescriptListWalk);
  272. if (FALSE != pDescriptListWalk->fError)
  273. {
  274. fBad = TRUE;
  275. }
  276. }
  277. // Set the correct return value
  278. hr = (FALSE == fBad) ? S_OK : S_FALSE;
  279. exit:
  280. return hr;
  281. }
  282. ///////////////////////////////////////////////////////////////////////////////
  283. //
  284. // HrEnableCriteria
  285. //
  286. // This initializes the actions list view with the list of actions
  287. //
  288. // Returns: TRUE, if it was successfully loaded
  289. // FALSE, otherwise
  290. //
  291. ///////////////////////////////////////////////////////////////////////////////
  292. HRESULT CRuleDescriptUI::HrEnableCriteria(CRIT_TYPE type, BOOL fEnable)
  293. {
  294. HRESULT hr = S_OK;
  295. ULONG ulIndex = 0;
  296. RULEDESCRIPT_LIST * pDescriptListAlloc = NULL;
  297. // Find the index of the criteria
  298. for (ulIndex = 0; ulIndex < ARRAYSIZE(c_rgEditCritList); ulIndex++)
  299. {
  300. if (type == c_rgEditCritList[ulIndex].typeCrit)
  301. {
  302. break;
  303. }
  304. }
  305. // Did we find the criteria item?
  306. if (ulIndex >= ARRAYSIZE(c_rgEditCritList))
  307. {
  308. hr = E_INVALIDARG;
  309. goto exit;
  310. }
  311. // Are we trying to remove the item
  312. if (FALSE == fEnable)
  313. {
  314. if (FALSE == _FRemoveDescription(&m_pDescriptListCrit, ulIndex, &pDescriptListAlloc))
  315. {
  316. hr = E_FAIL;
  317. goto exit;
  318. }
  319. // Free up the description
  320. pDescriptListAlloc->pNext = NULL;
  321. _FreeDescriptionList(pDescriptListAlloc);
  322. m_cDescriptListCrit--;
  323. }
  324. else
  325. {
  326. // Create the description list
  327. hr = HrAlloc((VOID **) &pDescriptListAlloc, sizeof(RULEDESCRIPT_LIST));
  328. if (FAILED(hr))
  329. {
  330. goto exit;
  331. }
  332. // Initialize the description list
  333. ZeroMemory(pDescriptListAlloc, sizeof(RULEDESCRIPT_LIST));
  334. // Save of the criteria type info
  335. pDescriptListAlloc->ulIndex = ulIndex;
  336. _InsertDescription(&m_pDescriptListCrit, pDescriptListAlloc);
  337. m_cDescriptListCrit++;
  338. }
  339. m_dwState |= STATE_DIRTY;
  340. ShowDescriptionString();
  341. hr = S_OK;
  342. exit:
  343. return hr;
  344. }
  345. ///////////////////////////////////////////////////////////////////////////////
  346. //
  347. // HrEnableActions
  348. //
  349. // This initializes the actions list view with the list of actions
  350. //
  351. // Returns: TRUE, if it was successfully loaded
  352. // FALSE, otherwise
  353. //
  354. ///////////////////////////////////////////////////////////////////////////////
  355. HRESULT CRuleDescriptUI::HrEnableActions(ACT_TYPE type, BOOL fEnable)
  356. {
  357. HRESULT hr = S_OK;
  358. ULONG ulIndex = 0;
  359. RULEDESCRIPT_LIST * pDescriptListAlloc = NULL;
  360. // Find the index of the actions
  361. for (ulIndex = 0; ulIndex < ARRAYSIZE(c_rgEditActList); ulIndex++)
  362. {
  363. if (type == c_rgEditActList[ulIndex].typeAct)
  364. {
  365. break;
  366. }
  367. }
  368. // Did we find the action item?
  369. if (ulIndex >= ARRAYSIZE(c_rgEditActList))
  370. {
  371. hr = E_INVALIDARG;
  372. goto exit;
  373. }
  374. // Are we trying to remove the item
  375. if (FALSE == fEnable)
  376. {
  377. if (FALSE == _FRemoveDescription(&m_pDescriptListAct, ulIndex, &pDescriptListAlloc))
  378. {
  379. hr = E_FAIL;
  380. goto exit;
  381. }
  382. // Free up the description
  383. pDescriptListAlloc->pNext = NULL;
  384. _FreeDescriptionList(pDescriptListAlloc);
  385. m_cDescriptListAct--;
  386. }
  387. else
  388. {
  389. // Create the description list
  390. hr = HrAlloc((VOID **) &pDescriptListAlloc, sizeof(RULEDESCRIPT_LIST));
  391. if (FAILED(hr))
  392. {
  393. goto exit;
  394. }
  395. // Initialize the description list
  396. ZeroMemory(pDescriptListAlloc, sizeof(RULEDESCRIPT_LIST));
  397. // Save of the actions type info
  398. pDescriptListAlloc->ulIndex = ulIndex;
  399. _InsertDescription(&m_pDescriptListAct, pDescriptListAlloc);
  400. m_cDescriptListAct++;
  401. }
  402. m_dwState |= STATE_DIRTY;
  403. ShowDescriptionString();
  404. hr = S_OK;
  405. exit:
  406. return hr;
  407. }
  408. ///////////////////////////////////////////////////////////////////////////////
  409. //
  410. // HrGetCriteria
  411. //
  412. // This initializes the actions list view with the list of actions
  413. //
  414. // Returns: TRUE, if it was successfully loaded
  415. // FALSE, otherwise
  416. //
  417. ///////////////////////////////////////////////////////////////////////////////
  418. HRESULT CRuleDescriptUI::HrGetCriteria(CRIT_ITEM ** ppCritList, ULONG * pcCritList)
  419. {
  420. HRESULT hr = S_OK;
  421. RULEDESCRIPT_LIST * pDescriptListWalk = NULL;
  422. CRIT_ITEM * pCritItem = NULL;
  423. ULONG cCritItem = 0;
  424. ULONG cCritItemAlloc = 0;
  425. if (NULL == ppCritList)
  426. {
  427. hr = E_INVALIDARG;
  428. goto exit;
  429. }
  430. *ppCritList = NULL;
  431. if (NULL != pcCritList)
  432. {
  433. *pcCritList = 0;
  434. }
  435. // If we don't have any criteria then return
  436. if (NULL == m_pDescriptListCrit)
  437. {
  438. hr = S_FALSE;
  439. goto exit;
  440. }
  441. for (pDescriptListWalk = m_pDescriptListCrit;
  442. pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext)
  443. {
  444. // Do we need more room?
  445. if (cCritItem == cCritItemAlloc)
  446. {
  447. if (FAILED(HrRealloc((void **) &pCritItem,
  448. sizeof(*pCritItem) * (cCritItemAlloc + c_cCritItemGrow))))
  449. {
  450. hr = E_OUTOFMEMORY;
  451. goto exit;
  452. }
  453. ZeroMemory(pCritItem + cCritItemAlloc, sizeof(*pCritItem) * c_cCritItemGrow);
  454. cCritItemAlloc += c_cCritItemGrow;
  455. }
  456. // Set the criteria type
  457. pCritItem[cCritItem].type = c_rgEditCritList[pDescriptListWalk->ulIndex].typeCrit;
  458. // Set the flags
  459. pCritItem[cCritItem].dwFlags = pDescriptListWalk->dwFlags;
  460. if (VT_EMPTY != pDescriptListWalk->propvar.vt)
  461. {
  462. if (FAILED(PropVariantCopy(&(pCritItem[cCritItem].propvar), &(pDescriptListWalk->propvar))))
  463. {
  464. hr = E_OUTOFMEMORY;
  465. goto exit;
  466. }
  467. }
  468. // Set the logic operator
  469. if (0 != cCritItem)
  470. {
  471. pCritItem[cCritItem - 1].logic = m_logicCrit;
  472. }
  473. // Move to the next item
  474. cCritItem++;
  475. }
  476. *ppCritList = pCritItem;
  477. pCritItem = NULL;
  478. if (NULL != pcCritList)
  479. {
  480. *pcCritList = cCritItem;
  481. }
  482. hr = S_OK;
  483. exit:
  484. RuleUtil_HrFreeCriteriaItem(pCritItem, cCritItem);
  485. SafeMemFree(pCritItem);
  486. return hr;
  487. }
  488. ///////////////////////////////////////////////////////////////////////////////
  489. //
  490. // HrGetActions
  491. //
  492. // This initializes the actions list view with the list of actions
  493. //
  494. // Returns: TRUE, if it was successfully loaded
  495. // FALSE, otherwise
  496. //
  497. ///////////////////////////////////////////////////////////////////////////////
  498. HRESULT CRuleDescriptUI::HrGetActions(ACT_ITEM ** ppActList, ULONG * pcActList)
  499. {
  500. HRESULT hr = S_OK;
  501. RULEDESCRIPT_LIST * pDescriptListWalk = NULL;
  502. ACT_ITEM * pActItem = NULL;
  503. ULONG cActItem = 0;
  504. ULONG cActItemAlloc = 0;
  505. if (NULL == ppActList)
  506. {
  507. hr = E_INVALIDARG;
  508. goto exit;
  509. }
  510. *ppActList = NULL;
  511. if (NULL != pcActList)
  512. {
  513. *pcActList = 0;
  514. }
  515. // If we don't have any criteria then return
  516. if (NULL == m_pDescriptListAct)
  517. {
  518. hr = S_FALSE;
  519. goto exit;
  520. }
  521. for (pDescriptListWalk = m_pDescriptListAct;
  522. pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext)
  523. {
  524. // Do we need more room?
  525. if (cActItem == cActItemAlloc)
  526. {
  527. if (FAILED(HrRealloc((void **) &pActItem,
  528. sizeof(*pActItem) * (cActItemAlloc + c_cActItemGrow))))
  529. {
  530. hr = E_OUTOFMEMORY;
  531. goto exit;
  532. }
  533. ZeroMemory(pActItem + cActItemAlloc, sizeof(*pActItem) * c_cActItemGrow);
  534. cActItemAlloc += c_cActItemGrow;
  535. }
  536. // Set the action type
  537. pActItem[cActItem].type = c_rgEditActList[pDescriptListWalk->ulIndex].typeAct;
  538. // Set the flags
  539. pActItem[cActItem].dwFlags = pDescriptListWalk->dwFlags;
  540. if (VT_EMPTY != pDescriptListWalk->propvar.vt)
  541. {
  542. if (FAILED(PropVariantCopy(&(pActItem[cActItem].propvar), &(pDescriptListWalk->propvar))))
  543. {
  544. hr = E_OUTOFMEMORY;
  545. goto exit;
  546. }
  547. }
  548. // Move to the next item
  549. cActItem++;
  550. }
  551. *ppActList = pActItem;
  552. pActItem = NULL;
  553. if (NULL != pcActList)
  554. {
  555. *pcActList = cActItem;
  556. }
  557. hr = S_OK;
  558. exit:
  559. RuleUtil_HrFreeActionsItem(pActItem, cActItem);
  560. SafeMemFree(pActItem);
  561. return hr;
  562. }
  563. ///////////////////////////////////////////////////////////////////////////////
  564. //
  565. // ShowDescriptionString
  566. //
  567. // This initializes the actions list view with the list of actions
  568. //
  569. // Returns: TRUE, if it was successfully loaded
  570. // FALSE, otherwise
  571. //
  572. ///////////////////////////////////////////////////////////////////////////////
  573. void CRuleDescriptUI::ShowDescriptionString(VOID)
  574. {
  575. WCHAR wszRes[CCHMAX_STRINGRES + 3];
  576. ULONG cchRes = 0;
  577. BOOL fError = FALSE;
  578. CHARFORMAT chFmt = {0};
  579. PARAFORMAT paraFmt = {0};
  580. RULEDESCRIPT_LIST * pDescriptListWalk = NULL;
  581. BOOL fFirst = FALSE;
  582. UINT uiText = 0;
  583. BOOL fErrorFwdSec = FALSE;
  584. CHARRANGE chrg = {0};
  585. Assert(NULL != m_hwndOwner);
  586. // Let's clear the redraw state to reduce flicker.
  587. SendMessage(m_hwndOwner, WM_SETREDRAW, 0, 0);
  588. // Clear text
  589. SetRichEditText(m_hwndOwner, NULL, FALSE, NULL, TRUE);
  590. // Set default CHARFORMAT
  591. chFmt.cbSize = sizeof(chFmt);
  592. chFmt.dwMask = CFM_BOLD | CFM_UNDERLINE | CFM_COLOR;
  593. chFmt.dwEffects = CFE_AUTOCOLOR;
  594. SendMessage(m_hwndOwner, EM_SETCHARFORMAT, (WPARAM)SCF_ALL, (LPARAM)&chFmt);
  595. paraFmt.cbSize = sizeof(paraFmt);
  596. paraFmt.dwMask = PFM_ALIGNMENT;
  597. if (0 == (m_dwState & STATE_HASRULE))
  598. {
  599. // Set up the empty string paragraph style
  600. paraFmt.wAlignment = PFA_CENTER;
  601. uiText = (RULE_TYPE_FILTER != m_typeRule) ?
  602. idsRulesDescriptionEmpty :
  603. idsViewDescriptionEmpty;
  604. }
  605. else
  606. {
  607. paraFmt.wAlignment = PFA_LEFT;
  608. // Determine if the rule is in error
  609. if (m_fErrorLogic)
  610. {
  611. fError = TRUE;
  612. }
  613. if (!fError)
  614. {
  615. // Walk the criteria looking for errors
  616. for (pDescriptListWalk = m_pDescriptListCrit;
  617. pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext)
  618. {
  619. if (pDescriptListWalk->fError)
  620. {
  621. fError = TRUE;
  622. break;
  623. }
  624. }
  625. }
  626. if (!fError)
  627. {
  628. // Walk the actions looking for errors
  629. for (pDescriptListWalk = m_pDescriptListAct;
  630. pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext)
  631. {
  632. if (pDescriptListWalk->fError)
  633. {
  634. // Note that we are in error
  635. fError = TRUE;
  636. // Is we have a FWD action
  637. if (ACT_TYPE_FWD == c_rgEditActList[pDescriptListWalk->ulIndex].typeAct)
  638. {
  639. // If security is turned then note it
  640. if ((0 != DwGetOption(OPT_MAIL_DIGSIGNMESSAGES)) || (0 != DwGetOption(OPT_MAIL_ENCRYPTMESSAGES)))
  641. {
  642. fErrorFwdSec = TRUE;
  643. }
  644. break;
  645. }
  646. }
  647. }
  648. }
  649. if (fError)
  650. {
  651. uiText = fErrorFwdSec ? idsRulesErrorFwdHeader : idsRulesErrorHeader;
  652. }
  653. else if (0 != (m_dwFlags & RDF_APPLYDLG))
  654. {
  655. uiText = idsRulesApplyHeader;
  656. }
  657. else if (RULE_TYPE_FILTER != m_typeRule)
  658. {
  659. uiText = (0 != (m_dwState & STATE_ENABLED)) ? idsRuleHeader : idsRulesOffHeader;
  660. }
  661. }
  662. // Set default PARAFORMAT
  663. SendMessage(m_hwndOwner, EM_SETPARAFORMAT, 0, (LPARAM)&paraFmt);
  664. // Load help text
  665. wszRes[0] = L'\0';
  666. cchRes = LoadStringWrapW(g_hLocRes, uiText, wszRes, ARRAYSIZE(wszRes));
  667. // If error, make sure help text is bolded
  668. if (fError)
  669. {
  670. chFmt.dwMask = CFM_BOLD;
  671. chFmt.dwEffects = CFE_BOLD;
  672. }
  673. // Set help text into the richedit control
  674. RuleUtil_AppendRichEditText(m_hwndOwner, 0, wszRes, &chFmt);
  675. // Build up the criteria
  676. fFirst = TRUE;
  677. for (pDescriptListWalk = m_pDescriptListCrit;
  678. pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext)
  679. {
  680. if (0 != (pDescriptListWalk->dwFlags & CRIT_FLAG_INVERT))
  681. {
  682. uiText = c_rgEditCritList[pDescriptListWalk->ulIndex].uiTextAlt;
  683. }
  684. else
  685. {
  686. uiText = c_rgEditCritList[pDescriptListWalk->ulIndex].uiText;
  687. }
  688. _ShowLinkedString(uiText, pDescriptListWalk, fFirst, TRUE);
  689. fFirst = FALSE;
  690. // Only need to do this once for the block sender rule
  691. if (CRIT_TYPE_SENDER == c_rgEditCritList[pDescriptListWalk->ulIndex].typeCrit)
  692. {
  693. break;
  694. }
  695. }
  696. // Build up the actions
  697. fFirst = TRUE;
  698. for (pDescriptListWalk = m_pDescriptListAct;
  699. pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext)
  700. {
  701. if (0 != (pDescriptListWalk->dwFlags & ACT_FLAG_INVERT))
  702. {
  703. uiText = c_rgEditActList[pDescriptListWalk->ulIndex].uiTextAlt;
  704. }
  705. else
  706. {
  707. uiText = c_rgEditActList[pDescriptListWalk->ulIndex].uiText;
  708. }
  709. _ShowLinkedString(uiText, pDescriptListWalk, fFirst, FALSE);
  710. fFirst = FALSE;
  711. }
  712. // Restore the selection
  713. RichEditExSetSel(m_hwndOwner, &chrg);
  714. // Let's set back the redraw state and invalidate the rect to
  715. // get the string drawn
  716. SendMessage(m_hwndOwner, WM_SETREDRAW, 1, 0);
  717. InvalidateRect(m_hwndOwner, NULL, TRUE);
  718. return;
  719. }
  720. ///////////////////////////////////////////////////////////////////////////////
  721. //
  722. // _ShowLinkedString
  723. //
  724. // This initializes the actions list view with the list of actions
  725. //
  726. // Returns: TRUE, if it was successfully loaded
  727. // FALSE, otherwise
  728. //
  729. ///////////////////////////////////////////////////////////////////////////////
  730. void CRuleDescriptUI::_ShowLinkedString(ULONG ulText, RULEDESCRIPT_LIST * pDescriptListWalk,
  731. BOOL fFirst, BOOL fCrit)
  732. {
  733. HRESULT hr = S_OK;
  734. WCHAR wszRes[CCHMAX_STRINGRES + 2];
  735. ULONG uiStrId = 0;
  736. ULONG cchText = 0;
  737. CHARFORMAT chFmt = {0};
  738. CHARRANGE chrg = {0};
  739. LPWSTR lpwsz = NULL;
  740. if ((0 == ulText) || (NULL == pDescriptListWalk))
  741. {
  742. Assert(FALSE);
  743. goto exit;
  744. }
  745. // Figure out where we're supposed to start
  746. cchText = GetRichEditTextLen(m_hwndOwner);
  747. // So richedit 2 and 3 need to have each beginning line
  748. // have the default charformat reset. It actually only matters
  749. // if you are showing both criteria and actions. In that case, if
  750. // this isn't done, then the default charformat might be incorretly
  751. // set to one of the other charformats that have been used. So, there
  752. // is obviously something amiss here, but I can't figure
  753. // it out, this is what we use to do, and this works.
  754. // See raid 78472 in IE/OE 5.0 database
  755. chrg.cpMin = cchText;
  756. chrg.cpMax = cchText;
  757. RichEditExSetSel(m_hwndOwner, &chrg);
  758. // Set default CHARFORMAT
  759. chFmt.cbSize = sizeof(chFmt);
  760. chFmt.dwMask = CFM_BOLD | CFM_UNDERLINE | CFM_COLOR;
  761. chFmt.dwEffects = CFE_AUTOCOLOR;
  762. SendMessage(m_hwndOwner, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chFmt);
  763. // Should we use a logical op?
  764. if (!fFirst)
  765. {
  766. // Which string should we load?
  767. if (fCrit)
  768. {
  769. if (CRIT_LOGIC_AND == m_logicCrit)
  770. {
  771. uiStrId = idsCriteriaAnd;
  772. }
  773. else if (CRIT_LOGIC_OR == m_logicCrit)
  774. {
  775. uiStrId = idsCriteriaOr;
  776. }
  777. else
  778. {
  779. uiStrId = idsCriteriaAndOr;
  780. }
  781. }
  782. else
  783. {
  784. uiStrId = idsActionsAnd;
  785. }
  786. wszRes[0] = L'\0';
  787. if (0 == LoadStringWrapW(g_hLocRes, uiStrId, wszRes, ARRAYSIZE(wszRes)))
  788. {
  789. goto exit;
  790. }
  791. // Write out the linked logic string
  792. IF_FAILEXIT(hr = RuleUtil_HrShowLinkedString(m_hwndOwner, m_fErrorLogic,
  793. (0 != (m_dwState & STATE_READONLY)), wszRes, NULL, cchText,
  794. &(pDescriptListWalk->ulStartLogic), &(pDescriptListWalk->ulEndLogic), &cchText));
  795. }
  796. // Get the description string
  797. wszRes[0] = L'\0';
  798. if (0 == LoadStringWrapW(g_hLocRes, ulText, wszRes, ARRAYSIZE(wszRes)))
  799. {
  800. goto exit;
  801. }
  802. // Write out the linked string
  803. if(pDescriptListWalk->pszText)
  804. IF_NULLEXIT(lpwsz = PszToUnicode(CP_ACP, pDescriptListWalk->pszText));
  805. IF_FAILEXIT(hr = RuleUtil_HrShowLinkedString(m_hwndOwner, pDescriptListWalk->fError,
  806. (0 != (m_dwState & STATE_READONLY)), wszRes, lpwsz,
  807. cchText, &(pDescriptListWalk->ulStart), &(pDescriptListWalk->ulEnd), &cchText));
  808. // Hack for HyperLinks to work without having to measure text (was broken for BiDi)
  809. RuleUtil_AppendRichEditText(m_hwndOwner, cchText, g_wszSpace, NULL);
  810. // Terminate the string
  811. RuleUtil_AppendRichEditText(m_hwndOwner, cchText + 1, g_wszCRLF, NULL);
  812. exit:
  813. MemFree(lpwsz);
  814. return;
  815. }
  816. ///////////////////////////////////////////////////////////////////////////////
  817. //
  818. // _FChangeLogicValue
  819. //
  820. // This changes the value of the logic op
  821. //
  822. // Returns: TRUE, if the criteria value was changed
  823. // FALSE, otherwise
  824. //
  825. ///////////////////////////////////////////////////////////////////////////////
  826. BOOL CRuleDescriptUI::_FChangeLogicValue(RULEDESCRIPT_LIST * pDescriptList)
  827. {
  828. BOOL fRet = FALSE;
  829. int iRet = 0;
  830. CRIT_LOGIC logicCrit = CRIT_LOGIC_NULL;
  831. // Bring up the choose logic op dialog
  832. if (NULL != m_logicCrit)
  833. {
  834. logicCrit = m_logicCrit;
  835. }
  836. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaLogic),
  837. m_hwndOwner, _FSelectLogicDlgProc,
  838. (LPARAM) &logicCrit);
  839. fRet = (iRet == IDOK);
  840. // Update the description field if neccessary
  841. if (FALSE != fRet)
  842. {
  843. m_logicCrit = logicCrit;
  844. // ZIFF
  845. // Can we be sure we are really OK??
  846. m_fErrorLogic = FALSE;
  847. ShowDescriptionString();
  848. }
  849. return fRet;
  850. }
  851. ///////////////////////////////////////////////////////////////////////////////
  852. //
  853. // _FBuildCriteriaList
  854. //
  855. // This builds the criteria list
  856. //
  857. // Returns: TRUE, if the criteria list was created
  858. // FALSE, otherwise
  859. //
  860. ///////////////////////////////////////////////////////////////////////////////
  861. HRESULT CRuleDescriptUI::_HrBuildCriteriaList(IOERule * pIRule,
  862. RULEDESCRIPT_LIST ** ppDescriptList, ULONG * pcDescriptList,
  863. CRIT_LOGIC * plogicCrit)
  864. {
  865. HRESULT hr = S_OK;
  866. PROPVARIANT propvar = {0};
  867. CRIT_ITEM * pCritItem = NULL;
  868. ULONG cCritItem = 0;
  869. ULONG ulIndex = 0;
  870. RULEDESCRIPT_LIST * pDescriptList = NULL;
  871. ULONG ulList = 0;
  872. ULONG cDescriptList = 0;
  873. RULEDESCRIPT_LIST * pDescriptListAlloc = NULL;
  874. LPSTR pszText = NULL;
  875. CRIT_LOGIC logicCrit = CRIT_LOGIC_NULL;
  876. Assert((NULL != pIRule) && (NULL != ppDescriptList) &&
  877. (NULL != pcDescriptList) && (NULL != plogicCrit));
  878. // Initialize the outgoing param
  879. *ppDescriptList = NULL;
  880. *pcDescriptList = 0;
  881. *plogicCrit = CRIT_LOGIC_AND;
  882. // Get the list of criteria
  883. hr = pIRule->GetProp(RULE_PROP_CRITERIA, 0, &propvar);
  884. if (FAILED(hr))
  885. {
  886. goto exit;
  887. }
  888. // Do we have anything to do?
  889. if (0 == propvar.blob.cbSize)
  890. {
  891. hr = S_FALSE;
  892. goto exit;
  893. }
  894. // Grab the criteria list
  895. Assert(NULL != propvar.blob.pBlobData);
  896. cCritItem = propvar.blob.cbSize / sizeof(CRIT_ITEM);
  897. pCritItem = (CRIT_ITEM *) (propvar.blob.pBlobData);
  898. propvar.blob.pBlobData = NULL;
  899. propvar.blob.cbSize = 0;
  900. // For each criteria, add it to the description list
  901. for (ulIndex = 0; ulIndex < cCritItem; ulIndex++)
  902. {
  903. // Create the description list
  904. hr = HrAlloc((VOID **) &pDescriptListAlloc, sizeof(RULEDESCRIPT_LIST));
  905. if (FAILED(hr))
  906. {
  907. goto exit;
  908. }
  909. // Initialize the description list
  910. ZeroMemory(pDescriptListAlloc, sizeof(RULEDESCRIPT_LIST));
  911. // Search for the criteria type
  912. for (ulList = 0; ulList < ARRAYSIZE(c_rgEditCritList); ulList++)
  913. {
  914. if (pCritItem[ulIndex].type == c_rgEditCritList[ulList].typeCrit)
  915. {
  916. // Save of the criteria type info
  917. pDescriptListAlloc->ulIndex = ulList;
  918. // Save off the flags
  919. pDescriptListAlloc->dwFlags = pCritItem[ulIndex].dwFlags;
  920. // Do we have any data?
  921. if (VT_EMPTY != pCritItem[ulIndex].propvar.vt)
  922. {
  923. // Copy the data
  924. SideAssert(SUCCEEDED(PropVariantCopy(&propvar, &(pCritItem[ulIndex].propvar))));
  925. pDescriptListAlloc->propvar = propvar;
  926. ZeroMemory(&propvar, sizeof(propvar));
  927. // Build up the description text
  928. if (FALSE != _FBuildCriteriaText(pCritItem[ulIndex].type, pDescriptListAlloc->dwFlags,
  929. &(pDescriptListAlloc->propvar), &pszText))
  930. {
  931. // Save off the string
  932. pDescriptListAlloc->pszText = pszText;
  933. pszText = NULL;
  934. }
  935. }
  936. // We're done searching
  937. break;
  938. }
  939. }
  940. // Did we find anything?
  941. if (ulList >= ARRAYSIZE(c_rgEditCritList))
  942. {
  943. // Free up the description
  944. _FreeDescriptionList(pDescriptListAlloc);
  945. }
  946. else
  947. {
  948. // Save the rule description
  949. _InsertDescription(&pDescriptList, pDescriptListAlloc);
  950. pDescriptListAlloc = NULL;
  951. cDescriptList++;
  952. }
  953. SafeMemFree(pszText);
  954. }
  955. // Get the logic op
  956. logicCrit = (cDescriptList > 1) ? pCritItem->logic : CRIT_LOGIC_AND;
  957. // Set the outgoing params
  958. *ppDescriptList = pDescriptList;
  959. pDescriptList = NULL;
  960. *pcDescriptList = cDescriptList;
  961. *plogicCrit = logicCrit;
  962. // Set the return value
  963. hr = S_OK;
  964. exit:
  965. _FreeDescriptionList(pDescriptList);
  966. RuleUtil_HrFreeCriteriaItem(pCritItem, cCritItem);
  967. SafeMemFree(pCritItem);
  968. return hr;
  969. }
  970. ///////////////////////////////////////////////////////////////////////////////
  971. //
  972. // _FChangeCriteriaValue
  973. //
  974. // This changes the value of the criteria value
  975. //
  976. // Returns: TRUE, if the criteria value was changed
  977. // FALSE, otherwise
  978. //
  979. ///////////////////////////////////////////////////////////////////////////////
  980. BOOL CRuleDescriptUI::_FChangeCriteriaValue(RULEDESCRIPT_LIST * pCritList)
  981. {
  982. BOOL fRet = FALSE;
  983. HRESULT hr = S_OK;
  984. LPSTR pszText = NULL;
  985. ULONG cchText = 0;
  986. int iRet = 0;
  987. LONG lDiff = 0;
  988. FOLDERID idFolder = FOLDERID_ROOT;
  989. CHARRANGE chrg;
  990. LPSTR pszVal = NULL;
  991. ULONG ulVal = 0;
  992. SELECTACCT selAcct;
  993. IImnAccount * pAccount = NULL;
  994. CHARFORMAT chfmtLink;
  995. CHARFORMAT chfmtNormal;
  996. CRIT_ITEM critItem;
  997. RULEFOLDERDATA * prfdData = NULL;
  998. ZeroMemory(&critItem, sizeof(critItem));
  999. switch(c_rgEditCritList[pCritList->ulIndex].typeCrit)
  1000. {
  1001. case CRIT_TYPE_NEWSGROUP:
  1002. // Bring up the select newsgroup dialog
  1003. if ((0 != pCritList->propvar.blob.cbSize) && (NULL != pCritList->propvar.blob.pBlobData))
  1004. {
  1005. // Validate the rule folder data
  1006. if (S_OK == RuleUtil_HrValidateRuleFolderData((RULEFOLDERDATA *) (pCritList->propvar.blob.pBlobData)))
  1007. {
  1008. idFolder = ((RULEFOLDERDATA *) (pCritList->propvar.blob.pBlobData))->idFolder;
  1009. }
  1010. }
  1011. hr = SelectFolderDialog(m_hwndOwner, SFD_SELECTFOLDER, idFolder,
  1012. TREEVIEW_NOLOCAL | TREEVIEW_NOIMAP | TREEVIEW_NOHTTP | FD_NONEWFOLDERS | FD_DISABLEROOT | FD_DISABLESERVERS | FD_FORCEINITSELFOLDER,
  1013. MAKEINTRESOURCE(idsSelectNewsgroup), MAKEINTRESOURCE(idsSelectNewsgroupCaption), &idFolder);
  1014. fRet = (S_OK == hr);
  1015. if (FALSE != fRet)
  1016. {
  1017. STOREUSERDATA UserData = {0};
  1018. // Create space for the data structure
  1019. hr = HrAlloc((VOID **) &prfdData, sizeof(*prfdData));
  1020. if (FAILED(hr))
  1021. {
  1022. goto exit;
  1023. }
  1024. // Initialize the data struct
  1025. ZeroMemory(prfdData, sizeof(*prfdData));
  1026. // Get the timestamp for the store
  1027. hr = g_pStore->GetUserData(&UserData, sizeof(STOREUSERDATA));
  1028. if (FAILED(hr))
  1029. {
  1030. goto exit;
  1031. }
  1032. // Set the timestamp
  1033. prfdData->ftStamp = UserData.ftCreated;
  1034. prfdData->idFolder = idFolder;
  1035. // Set the folder id
  1036. PropVariantClear(&(pCritList->propvar));
  1037. pCritList->propvar.vt = VT_BLOB;
  1038. pCritList->propvar.blob.cbSize = sizeof(*prfdData);
  1039. pCritList->propvar.blob.pBlobData = (BYTE *) prfdData;
  1040. prfdData = NULL;
  1041. }
  1042. break;
  1043. case CRIT_TYPE_SUBJECT:
  1044. case CRIT_TYPE_BODY:
  1045. // Duplicate the data
  1046. critItem.type = c_rgEditCritList[pCritList->ulIndex].typeCrit;
  1047. critItem.dwFlags = pCritList->dwFlags;
  1048. critItem.propvar.vt = VT_BLOB;
  1049. // Copy over the blob data if it is there
  1050. if ((0 != pCritList->propvar.blob.cbSize) &&
  1051. (NULL != pCritList->propvar.blob.pBlobData))
  1052. {
  1053. hr = HrAlloc((VOID **) &(critItem.propvar.blob.pBlobData), pCritList->propvar.blob.cbSize);
  1054. if (SUCCEEDED(hr))
  1055. {
  1056. critItem.propvar.blob.cbSize = pCritList->propvar.blob.cbSize;
  1057. CopyMemory(critItem.propvar.blob.pBlobData,
  1058. pCritList->propvar.blob.pBlobData, critItem.propvar.blob.cbSize);
  1059. }
  1060. }
  1061. // Edit the words
  1062. hr = _HrCriteriaEditWords(m_hwndOwner, &critItem);
  1063. if (FAILED(hr))
  1064. {
  1065. fRet = FALSE;
  1066. goto exit;
  1067. }
  1068. fRet = (S_OK == hr);
  1069. if (FALSE != fRet)
  1070. {
  1071. PropVariantClear(&(pCritList->propvar));
  1072. pCritList->dwFlags = critItem.dwFlags;
  1073. pCritList->propvar = critItem.propvar;
  1074. critItem.propvar.blob.pBlobData = NULL;
  1075. critItem.propvar.blob.cbSize = 0;
  1076. }
  1077. break;
  1078. case CRIT_TYPE_TO:
  1079. case CRIT_TYPE_CC:
  1080. case CRIT_TYPE_TOORCC:
  1081. case CRIT_TYPE_FROM:
  1082. // Duplicate the data
  1083. critItem.type = c_rgEditCritList[pCritList->ulIndex].typeCrit;
  1084. critItem.dwFlags = pCritList->dwFlags;
  1085. critItem.propvar.vt = VT_BLOB;
  1086. // Copy over the blob data if it is there
  1087. if ((0 != pCritList->propvar.blob.cbSize) &&
  1088. (NULL != pCritList->propvar.blob.pBlobData))
  1089. {
  1090. hr = HrAlloc((VOID **) &(critItem.propvar.blob.pBlobData), pCritList->propvar.blob.cbSize);
  1091. if (SUCCEEDED(hr))
  1092. {
  1093. critItem.propvar.blob.cbSize = pCritList->propvar.blob.cbSize;
  1094. CopyMemory(critItem.propvar.blob.pBlobData,
  1095. pCritList->propvar.blob.pBlobData, critItem.propvar.blob.cbSize);
  1096. }
  1097. }
  1098. // Edit the people
  1099. hr = _HrCriteriaEditPeople(m_hwndOwner, &critItem);
  1100. if (FAILED(hr))
  1101. {
  1102. fRet = FALSE;
  1103. goto exit;
  1104. }
  1105. fRet = (S_OK == hr);
  1106. if (FALSE != fRet)
  1107. {
  1108. PropVariantClear(&(pCritList->propvar));
  1109. pCritList->dwFlags = critItem.dwFlags;
  1110. pCritList->propvar = critItem.propvar;
  1111. critItem.propvar.blob.pBlobData = NULL;
  1112. critItem.propvar.blob.cbSize = 0;
  1113. }
  1114. break;
  1115. case CRIT_TYPE_ACCOUNT:
  1116. // Bring up the rename rule dialog
  1117. if (NULL != pCritList->propvar.pszVal)
  1118. {
  1119. pszVal = PszDupA(pCritList->propvar.pszVal);
  1120. }
  1121. selAcct.typeRule = m_typeRule;
  1122. selAcct.pszAcct = pszVal;
  1123. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaAcct),
  1124. m_hwndOwner, _FSelectAcctDlgProc,
  1125. (LPARAM) &selAcct);
  1126. pszVal = selAcct.pszAcct;
  1127. fRet = (iRet == IDOK);
  1128. if (FALSE != fRet)
  1129. {
  1130. // Figure out account name
  1131. PropVariantClear(&(pCritList->propvar));
  1132. pCritList->propvar.vt = VT_LPSTR;
  1133. pCritList->propvar.pszVal = pszVal;
  1134. pszVal = NULL;
  1135. }
  1136. break;
  1137. case CRIT_TYPE_SIZE:
  1138. // Bring up the rename rule dialog
  1139. if (NULL != pCritList->propvar.ulVal)
  1140. {
  1141. ulVal = pCritList->propvar.ulVal;
  1142. }
  1143. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaSize),
  1144. m_hwndOwner, _FSelectSizeDlgProc,
  1145. (LPARAM) &ulVal);
  1146. fRet = (iRet == IDOK);
  1147. if (FALSE != fRet)
  1148. {
  1149. PropVariantClear(&(pCritList->propvar));
  1150. pCritList->propvar.vt = VT_UI4;
  1151. pCritList->propvar.ulVal = ulVal;
  1152. }
  1153. break;
  1154. case CRIT_TYPE_LINES:
  1155. // Bring up the line rule dialog
  1156. if (NULL != pCritList->propvar.ulVal)
  1157. {
  1158. ulVal = pCritList->propvar.ulVal;
  1159. }
  1160. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaLines),
  1161. m_hwndOwner, _FSelectLinesDlgProc,
  1162. (LPARAM) &ulVal);
  1163. fRet = (iRet == IDOK);
  1164. if (FALSE != fRet)
  1165. {
  1166. PropVariantClear(&(pCritList->propvar));
  1167. pCritList->propvar.vt = VT_UI4;
  1168. pCritList->propvar.ulVal = ulVal;
  1169. }
  1170. break;
  1171. case CRIT_TYPE_AGE:
  1172. // Bring up the age rule dialog
  1173. if (NULL != pCritList->propvar.ulVal)
  1174. {
  1175. ulVal = pCritList->propvar.ulVal;
  1176. }
  1177. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaAge),
  1178. m_hwndOwner, _FSelectAgeDlgProc,
  1179. (LPARAM) &ulVal);
  1180. fRet = (iRet == IDOK);
  1181. if (FALSE != fRet)
  1182. {
  1183. PropVariantClear(&(pCritList->propvar));
  1184. pCritList->propvar.vt = VT_UI4;
  1185. pCritList->propvar.ulVal = ulVal;
  1186. }
  1187. break;
  1188. case CRIT_TYPE_PRIORITY:
  1189. // Bring up the priority rule dialog
  1190. if (NULL != pCritList->propvar.ulVal)
  1191. {
  1192. ulVal = pCritList->propvar.ulVal;
  1193. }
  1194. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaPriority),
  1195. m_hwndOwner, _FSelectPriorityDlgProc,
  1196. (LPARAM) &ulVal);
  1197. fRet = (iRet == IDOK);
  1198. if (FALSE != fRet)
  1199. {
  1200. PropVariantClear(&(pCritList->propvar));
  1201. pCritList->propvar.vt = VT_UI4;
  1202. pCritList->propvar.ulVal = ulVal;
  1203. }
  1204. break;
  1205. case CRIT_TYPE_SECURE:
  1206. // Bring up the secure rule dialog
  1207. if (NULL != pCritList->propvar.ulVal)
  1208. {
  1209. ulVal = pCritList->propvar.ulVal;
  1210. }
  1211. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaSecure),
  1212. m_hwndOwner, _FSelectSecureDlgProc,
  1213. (LPARAM) &ulVal);
  1214. fRet = (iRet == IDOK);
  1215. if (FALSE != fRet)
  1216. {
  1217. PropVariantClear(&(pCritList->propvar));
  1218. pCritList->propvar.vt = VT_UI4;
  1219. pCritList->propvar.ulVal = ulVal;
  1220. }
  1221. break;
  1222. case CRIT_TYPE_THREADSTATE:
  1223. // Bring up the thread state rule dialog
  1224. if (NULL != pCritList->propvar.ulVal)
  1225. {
  1226. ulVal = pCritList->propvar.ulVal;
  1227. }
  1228. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaThreadState),
  1229. m_hwndOwner, _FSelectThreadStateDlgProc,
  1230. (LPARAM) &ulVal);
  1231. fRet = (iRet == IDOK);
  1232. if (FALSE != fRet)
  1233. {
  1234. PropVariantClear(&(pCritList->propvar));
  1235. pCritList->propvar.vt = VT_UI4;
  1236. pCritList->propvar.ulVal = ulVal;
  1237. }
  1238. break;
  1239. case CRIT_TYPE_FLAGGED:
  1240. // Bring up the flag dialog
  1241. ulVal = (ULONG) (pCritList->dwFlags);
  1242. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaFlag),
  1243. m_hwndOwner, _FSelectFlagDlgProc,
  1244. (LPARAM) &ulVal);
  1245. fRet = (iRet == IDOK);
  1246. if (FALSE != fRet)
  1247. {
  1248. PropVariantClear(&(pCritList->propvar));
  1249. pCritList->dwFlags = (DWORD) ulVal;
  1250. pCritList->propvar.vt = VT_EMPTY;
  1251. }
  1252. break;
  1253. case CRIT_TYPE_DOWNLOADED:
  1254. // Bring up the deletion dialog
  1255. ulVal = (ULONG) (pCritList->dwFlags);
  1256. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaDownloaded),
  1257. m_hwndOwner, _FSelectDownloadedDlgProc,
  1258. (LPARAM) &ulVal);
  1259. fRet = (iRet == IDOK);
  1260. if (FALSE != fRet)
  1261. {
  1262. PropVariantClear(&(pCritList->propvar));
  1263. pCritList->dwFlags = (DWORD) ulVal;
  1264. pCritList->propvar.vt = VT_EMPTY;
  1265. }
  1266. break;
  1267. case CRIT_TYPE_READ:
  1268. // Bring up the deletion dialog
  1269. ulVal = (ULONG) (pCritList->dwFlags);
  1270. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaRead),
  1271. m_hwndOwner, _FSelectReadDlgProc,
  1272. (LPARAM) &ulVal);
  1273. fRet = (iRet == IDOK);
  1274. if (FALSE != fRet)
  1275. {
  1276. PropVariantClear(&(pCritList->propvar));
  1277. pCritList->dwFlags = (DWORD) ulVal;
  1278. pCritList->propvar.vt = VT_EMPTY;
  1279. }
  1280. break;
  1281. default:
  1282. fRet = FALSE;
  1283. break;
  1284. }
  1285. // Update the description field if neccessary
  1286. if (FALSE != fRet)
  1287. {
  1288. // ZIFF
  1289. // Can we be sure we are really OK??
  1290. pCritList->fError = FALSE;
  1291. // If we have something to build up
  1292. if (VT_EMPTY != pCritList->propvar.vt)
  1293. {
  1294. if (FALSE == _FBuildCriteriaText(c_rgEditCritList[pCritList->ulIndex].typeCrit,
  1295. pCritList->dwFlags, &(pCritList->propvar), &pszText))
  1296. {
  1297. goto exit;
  1298. }
  1299. SafeMemFree(pCritList->pszText);
  1300. pCritList->pszText = pszText;
  1301. pszText = NULL;
  1302. }
  1303. ShowDescriptionString();
  1304. }
  1305. exit:
  1306. SafeMemFree(prfdData);
  1307. SafeMemFree(critItem.propvar.blob.pBlobData);
  1308. SafeRelease(pAccount);
  1309. SafeMemFree(pszVal);
  1310. SafeMemFree(pszText);
  1311. return fRet;
  1312. }
  1313. ///////////////////////////////////////////////////////////////////////////////
  1314. //
  1315. // _FBuildCriteriaText
  1316. //
  1317. // This changes the value of the criteria value
  1318. //
  1319. // Returns: TRUE, if the criteria value was changed
  1320. // FALSE, otherwise
  1321. //
  1322. ///////////////////////////////////////////////////////////////////////////////
  1323. BOOL CRuleDescriptUI::_FBuildCriteriaText(CRIT_TYPE type, DWORD dwFlags,
  1324. PROPVARIANT * ppropvar, LPSTR * ppszText)
  1325. {
  1326. BOOL fRet = FALSE;
  1327. LPSTR pszText = NULL;
  1328. ULONG cchText = 0;
  1329. HRESULT hr = S_OK;
  1330. IImnAccount * pAccount = NULL;
  1331. FOLDERINFO Folder = {0};
  1332. UINT uiId = 0;
  1333. TCHAR rgchFirst[CCHMAX_STRINGRES];
  1334. ULONG cchFirst = 0;
  1335. TCHAR rgchSecond[CCHMAX_STRINGRES];
  1336. ULONG cchSecond = 0;
  1337. LPTSTR pszString = NULL;
  1338. LPTSTR pszWalk = NULL;
  1339. UINT uiID = 0;
  1340. RULEFOLDERDATA * prfdData = NULL;
  1341. if ((NULL == ppropvar) || (NULL == ppszText))
  1342. {
  1343. fRet = FALSE;
  1344. goto exit;
  1345. }
  1346. switch(type)
  1347. {
  1348. case CRIT_TYPE_NEWSGROUP:
  1349. if ((0 == ppropvar->blob.cbSize) || (NULL == ppropvar->blob.pBlobData))
  1350. {
  1351. fRet = FALSE;
  1352. goto exit;
  1353. }
  1354. prfdData = (RULEFOLDERDATA *) (ppropvar->blob.pBlobData);
  1355. // Validate the rule folder data
  1356. if (S_OK != RuleUtil_HrValidateRuleFolderData(prfdData))
  1357. {
  1358. fRet = FALSE;
  1359. goto exit;
  1360. }
  1361. hr = g_pStore->GetFolderInfo(prfdData->idFolder, &Folder);
  1362. if (FAILED(hr))
  1363. {
  1364. fRet = FALSE;
  1365. goto exit;
  1366. }
  1367. // Are we subscribed?
  1368. if (0 == (Folder.dwFlags & FOLDER_SUBSCRIBED))
  1369. {
  1370. fRet = FALSE;
  1371. goto exit;
  1372. }
  1373. pszText = PszDupA(Folder.pszName);
  1374. if (NULL == pszText)
  1375. {
  1376. fRet = FALSE;
  1377. goto exit;
  1378. }
  1379. break;
  1380. case CRIT_TYPE_SUBJECT:
  1381. case CRIT_TYPE_BODY:
  1382. case CRIT_TYPE_TO:
  1383. case CRIT_TYPE_CC:
  1384. case CRIT_TYPE_TOORCC:
  1385. case CRIT_TYPE_FROM:
  1386. if ((VT_BLOB != ppropvar->vt) ||
  1387. (0 == ppropvar->blob.cbSize) ||
  1388. (NULL == ppropvar->blob.pBlobData) ||
  1389. ('\0' == ppropvar->blob.pBlobData[0]))
  1390. {
  1391. fRet = FALSE;
  1392. goto exit;
  1393. }
  1394. pszString = (LPTSTR) ppropvar->blob.pBlobData;
  1395. // Load up the first template
  1396. if (0 != (dwFlags & CRIT_FLAG_INVERT))
  1397. {
  1398. uiID = idsCriteriaMultFirstNot;
  1399. }
  1400. else
  1401. {
  1402. uiID = idsCriteriaMultFirst;
  1403. }
  1404. cchFirst = LoadString(g_hLocRes, uiID, rgchFirst, sizeof(rgchFirst));
  1405. if (0 == cchFirst)
  1406. {
  1407. fRet = FALSE;
  1408. goto exit;
  1409. }
  1410. cchText = cchFirst + 1;
  1411. // How many strings do we have?
  1412. if ((lstrlen(pszString) + 3) != (int) ppropvar->blob.cbSize)
  1413. {
  1414. if (0 != (dwFlags & CRIT_FLAG_MULTIPLEAND))
  1415. {
  1416. uiID = idsCriteriaMultAnd;
  1417. }
  1418. else
  1419. {
  1420. uiID = idsCriteriaMultOr;
  1421. }
  1422. // Load up the second template
  1423. cchSecond = LoadString(g_hLocRes, uiID, rgchSecond, sizeof(rgchSecond));
  1424. if (0 == cchSecond)
  1425. {
  1426. fRet = FALSE;
  1427. goto exit;
  1428. }
  1429. // Add in the second string for each other string
  1430. for (pszWalk = pszString; '\0' != pszWalk[0]; pszWalk += lstrlen(pszWalk) + 1)
  1431. {
  1432. cchText += cchSecond;
  1433. }
  1434. }
  1435. else
  1436. {
  1437. rgchSecond[0] = '\0';
  1438. }
  1439. // Total up the space
  1440. cchText += ppropvar->blob.cbSize;
  1441. // Allocate the space
  1442. if (FAILED(HrAlloc((void **) &pszText, cchText)))
  1443. {
  1444. fRet = FALSE;
  1445. goto exit;
  1446. }
  1447. // Copy in the first string
  1448. wnsprintf(pszText, cchText, rgchFirst, pszString);
  1449. pszString += lstrlen(pszString) + 1;
  1450. // For each string
  1451. pszWalk = pszText + lstrlen(pszText);
  1452. cchText -= lstrlen(pszText);
  1453. for (; '\0' != pszString[0]; pszString += lstrlen(pszString) + 1)
  1454. {
  1455. // Build up the string
  1456. wnsprintf(pszWalk, cchText, rgchSecond, pszString);
  1457. cchText -= lstrlen(pszWalk);
  1458. pszWalk += lstrlen(pszWalk);
  1459. }
  1460. break;
  1461. case CRIT_TYPE_ACCOUNT:
  1462. Assert(g_pAcctMan);
  1463. if (!g_pAcctMan || FAILED(g_pAcctMan->FindAccount(AP_ACCOUNT_ID, ppropvar->pszVal, &pAccount)))
  1464. {
  1465. fRet = FALSE;
  1466. goto exit;
  1467. }
  1468. if (FAILED(HrAlloc((void **) &pszText, CCHMAX_ACCOUNT_NAME)))
  1469. {
  1470. fRet = FALSE;
  1471. goto exit;
  1472. }
  1473. if (FAILED(pAccount->GetPropSz(AP_ACCOUNT_NAME, pszText, CCHMAX_ACCOUNT_NAME)))
  1474. {
  1475. fRet = FALSE;
  1476. goto exit;
  1477. }
  1478. break;
  1479. case CRIT_TYPE_SIZE:
  1480. if (FAILED(HrAlloc((void **) &pszText, CCHMAX_STRINGRES)))
  1481. {
  1482. fRet = FALSE;
  1483. goto exit;
  1484. }
  1485. wnsprintf(pszText, CCHMAX_STRINGRES, "%d ", ppropvar->ulVal);
  1486. cchText = lstrlen(pszText);
  1487. LoadString(g_hLocRes, idsKB, pszText + cchText, CCHMAX_STRINGRES - cchText);
  1488. break;
  1489. case CRIT_TYPE_LINES:
  1490. if (FAILED(HrAlloc((void **) &pszText, CCHMAX_STRINGRES)))
  1491. {
  1492. fRet = FALSE;
  1493. goto exit;
  1494. }
  1495. wnsprintf(pszText, CCHMAX_STRINGRES, "%d ", ppropvar->ulVal);
  1496. cchText = lstrlen(pszText);
  1497. LoadString(g_hLocRes, idsLines, pszText + cchText, CCHMAX_STRINGRES - cchText);
  1498. break;
  1499. case CRIT_TYPE_AGE:
  1500. if (FAILED(HrAlloc((void **) &pszText, CCHMAX_STRINGRES)))
  1501. {
  1502. fRet = FALSE;
  1503. goto exit;
  1504. }
  1505. wnsprintf(pszText, CCHMAX_STRINGRES, "%d ", ppropvar->ulVal);
  1506. cchText = lstrlen(pszText);
  1507. LoadString(g_hLocRes, idsDays, pszText + cchText, CCHMAX_STRINGRES - cchText);
  1508. break;
  1509. case CRIT_TYPE_PRIORITY:
  1510. if (FAILED(HrAlloc((void **) &pszText, CCHMAX_STRINGRES)))
  1511. {
  1512. fRet = FALSE;
  1513. goto exit;
  1514. }
  1515. // Figure out which string to use
  1516. if (CRIT_DATA_HIPRI == ppropvar->ulVal)
  1517. {
  1518. uiId = idsHighPri;
  1519. }
  1520. else if (CRIT_DATA_LOPRI == ppropvar->ulVal)
  1521. {
  1522. uiId = idsLowPri;
  1523. }
  1524. else
  1525. {
  1526. uiId = idsNormalPri;
  1527. }
  1528. LoadString(g_hLocRes, uiId, pszText, CCHMAX_STRINGRES);
  1529. break;
  1530. case CRIT_TYPE_SECURE:
  1531. if (FAILED(HrAlloc((void **) &pszText, CCHMAX_STRINGRES)))
  1532. {
  1533. fRet = FALSE;
  1534. goto exit;
  1535. }
  1536. // Figure out which string to use
  1537. if (0 != (ppropvar->ulVal & CRIT_DATA_ENCRYPTSECURE))
  1538. {
  1539. uiId = idsSecureEncrypt;
  1540. }
  1541. else if (0 != (ppropvar->ulVal & CRIT_DATA_SIGNEDSECURE))
  1542. {
  1543. uiId = idsSecureSigned;
  1544. }
  1545. else
  1546. {
  1547. uiId = idsSecureNone;
  1548. }
  1549. LoadString(g_hLocRes, uiId, pszText, CCHMAX_STRINGRES);
  1550. break;
  1551. case CRIT_TYPE_THREADSTATE:
  1552. if (FAILED(HrAlloc((void **) &pszText, CCHMAX_STRINGRES)))
  1553. {
  1554. fRet = FALSE;
  1555. goto exit;
  1556. }
  1557. // Figure out which string to use
  1558. if (0 != (ppropvar->ulVal & CRIT_DATA_WATCHTHREAD))
  1559. {
  1560. uiId = idsThreadWatch;
  1561. }
  1562. else if (0 != (ppropvar->ulVal & CRIT_DATA_IGNORETHREAD))
  1563. {
  1564. uiId = idsThreadIgnore;
  1565. }
  1566. else
  1567. {
  1568. uiId = idsThreadNone;
  1569. }
  1570. LoadString(g_hLocRes, uiId, pszText, CCHMAX_STRINGRES);
  1571. break;
  1572. default:
  1573. fRet = FALSE;
  1574. goto exit;
  1575. break;
  1576. }
  1577. *ppszText = pszText;
  1578. pszText = NULL;
  1579. fRet = TRUE;
  1580. exit:
  1581. g_pStore->FreeRecord(&Folder);
  1582. SafeRelease(pAccount);
  1583. SafeMemFree(pszText);
  1584. return fRet;
  1585. }
  1586. ///////////////////////////////////////////////////////////////////////////////
  1587. //
  1588. // _FVerifyCriteria
  1589. //
  1590. // This verifies the value of the criteria
  1591. //
  1592. // Returns: TRUE, if the criteria value was valid
  1593. // FALSE, otherwise
  1594. //
  1595. ///////////////////////////////////////////////////////////////////////////////
  1596. BOOL CRuleDescriptUI::_FVerifyCriteria(RULEDESCRIPT_LIST * pDescriptList)
  1597. {
  1598. BOOL fRet = FALSE;
  1599. LPSTR pszText = NULL;
  1600. ULONG cchText = 0;
  1601. HRESULT hr = S_OK;
  1602. IImnAccount * pAccount = NULL;
  1603. FOLDERINFO Folder = {0};
  1604. LPSTR pszWalk = NULL;
  1605. RULEFOLDERDATA * prfdData = NULL;
  1606. if (NULL == pDescriptList)
  1607. {
  1608. fRet = FALSE;
  1609. goto exit;
  1610. }
  1611. switch(c_rgEditCritList[pDescriptList->ulIndex].typeCrit)
  1612. {
  1613. case CRIT_TYPE_NEWSGROUP:
  1614. if ((VT_BLOB != pDescriptList->propvar.vt) ||
  1615. (0 == pDescriptList->propvar.blob.cbSize))
  1616. {
  1617. hr = S_FALSE;
  1618. goto exit;
  1619. }
  1620. // Make life simpler
  1621. prfdData = (RULEFOLDERDATA *) (pDescriptList->propvar.blob.pBlobData);
  1622. // Validate the rule folder data
  1623. if (S_OK != RuleUtil_HrValidateRuleFolderData(prfdData))
  1624. {
  1625. hr = S_FALSE;
  1626. goto exit;
  1627. }
  1628. // Does the folder exist
  1629. hr = g_pStore->GetFolderInfo(prfdData->idFolder, &Folder);
  1630. if (FAILED(hr))
  1631. {
  1632. hr = S_FALSE;
  1633. goto exit;
  1634. }
  1635. // Are we subscribed?
  1636. if (0 == (Folder.dwFlags & FOLDER_SUBSCRIBED))
  1637. {
  1638. hr = S_FALSE;
  1639. goto exit;
  1640. }
  1641. break;
  1642. case CRIT_TYPE_ALL:
  1643. case CRIT_TYPE_JUNK:
  1644. case CRIT_TYPE_READ:
  1645. case CRIT_TYPE_REPLIES:
  1646. case CRIT_TYPE_DOWNLOADED:
  1647. case CRIT_TYPE_DELETED:
  1648. case CRIT_TYPE_ATTACH:
  1649. case CRIT_TYPE_FLAGGED:
  1650. if (VT_EMPTY != pDescriptList->propvar.vt)
  1651. {
  1652. fRet = FALSE;
  1653. goto exit;
  1654. }
  1655. break;
  1656. case CRIT_TYPE_SUBJECT:
  1657. case CRIT_TYPE_BODY:
  1658. case CRIT_TYPE_TO:
  1659. case CRIT_TYPE_CC:
  1660. case CRIT_TYPE_TOORCC:
  1661. case CRIT_TYPE_FROM:
  1662. if ((VT_BLOB != pDescriptList->propvar.vt) ||
  1663. (0 == pDescriptList->propvar.blob.cbSize) ||
  1664. (NULL == pDescriptList->propvar.blob.pBlobData) ||
  1665. ('\0' == pDescriptList->propvar.blob.pBlobData[0]))
  1666. {
  1667. fRet = FALSE;
  1668. goto exit;
  1669. }
  1670. // Spin through each item making sure it is perfect
  1671. cchText = 0;
  1672. for (pszWalk = (LPTSTR) pDescriptList->propvar.blob.pBlobData;
  1673. '\0' != pszWalk[0]; pszWalk += lstrlen(pszWalk) + 1)
  1674. {
  1675. cchText += lstrlen(pszWalk) + 1;
  1676. }
  1677. // For the terminator
  1678. if ('\0' == pszWalk[0])
  1679. {
  1680. cchText++;
  1681. }
  1682. if ('\0' == pszWalk[1])
  1683. {
  1684. cchText++;
  1685. }
  1686. if (cchText != pDescriptList->propvar.blob.cbSize)
  1687. {
  1688. fRet = FALSE;
  1689. goto exit;
  1690. }
  1691. break;
  1692. case CRIT_TYPE_SIZE:
  1693. case CRIT_TYPE_THREADSTATE:
  1694. case CRIT_TYPE_LINES:
  1695. case CRIT_TYPE_PRIORITY:
  1696. case CRIT_TYPE_AGE:
  1697. case CRIT_TYPE_SECURE:
  1698. if (VT_UI4 != pDescriptList->propvar.vt)
  1699. {
  1700. fRet = FALSE;
  1701. goto exit;
  1702. }
  1703. break;
  1704. case CRIT_TYPE_ACCOUNT:
  1705. if ((VT_LPSTR != pDescriptList->propvar.vt) ||
  1706. (NULL == pDescriptList->propvar.pszVal))
  1707. {
  1708. fRet = FALSE;
  1709. goto exit;
  1710. }
  1711. Assert(g_pAcctMan);
  1712. if (FAILED(g_pAcctMan->FindAccount(AP_ACCOUNT_ID, pDescriptList->propvar.pszVal, &pAccount)))
  1713. {
  1714. fRet = FALSE;
  1715. goto exit;
  1716. }
  1717. break;
  1718. case CRIT_TYPE_SENDER:
  1719. {
  1720. LPWSTR pwszText = NULL,
  1721. pwszVal = NULL;
  1722. if ((VT_LPSTR != pDescriptList->propvar.vt) ||
  1723. (NULL == pDescriptList->propvar.pszVal))
  1724. {
  1725. AssertSz(VT_LPWSTR != pDescriptList->propvar.vt, "We are getting UNICODE here.");
  1726. fRet = FALSE;
  1727. goto exit;
  1728. }
  1729. // Verify the email string
  1730. pwszVal = PszToUnicode(CP_ACP, pDescriptList->propvar.pszVal);
  1731. if (!pwszVal)
  1732. {
  1733. hr = S_FALSE;
  1734. goto exit;
  1735. }
  1736. hr = RuleUtil_HrParseEmailString(pwszVal, 0, &pwszText, NULL);
  1737. MemFree(pwszVal);
  1738. MemFree(pwszText);
  1739. if (FAILED(hr))
  1740. {
  1741. fRet = FALSE;
  1742. goto exit;
  1743. }
  1744. break;
  1745. }
  1746. default:
  1747. fRet = FALSE;
  1748. goto exit;
  1749. break;
  1750. }
  1751. fRet = TRUE;
  1752. exit:
  1753. g_pStore->FreeRecord(&Folder);
  1754. SafeRelease(pAccount);
  1755. SafeMemFree(pszText);
  1756. return fRet;
  1757. }
  1758. ///////////////////////////////////////////////////////////////////////////////
  1759. //
  1760. // _HrBuildActionList
  1761. //
  1762. // This builds the actions list
  1763. //
  1764. // Returns: TRUE, if the criteria list was created
  1765. // FALSE, otherwise
  1766. //
  1767. ///////////////////////////////////////////////////////////////////////////////
  1768. HRESULT CRuleDescriptUI::_HrBuildActionList(IOERule * pIRule,
  1769. RULEDESCRIPT_LIST ** ppDescriptList, ULONG * pcDescriptList)
  1770. {
  1771. HRESULT hr = S_OK;
  1772. PROPVARIANT propvar = {0};
  1773. ACT_ITEM * pActItem = NULL;
  1774. ULONG cActItem = 0;
  1775. ULONG ulIndex = 0;
  1776. RULEDESCRIPT_LIST * pDescriptList = NULL;
  1777. ULONG ulList = 0;
  1778. ULONG cDescriptList = 0;
  1779. RULEDESCRIPT_LIST * pDescriptListAlloc = NULL;
  1780. LPSTR pszText = NULL;
  1781. Assert((NULL != pIRule) &&
  1782. (NULL != ppDescriptList) && (NULL != pcDescriptList));
  1783. // Initialize the outgoing param
  1784. *ppDescriptList = NULL;
  1785. *pcDescriptList = 0;
  1786. // Get the list of actions
  1787. hr = pIRule->GetProp(RULE_PROP_ACTIONS, 0, &propvar);
  1788. if (FAILED(hr))
  1789. {
  1790. goto exit;
  1791. }
  1792. // Do we have anything to do?
  1793. if (0 == propvar.blob.cbSize)
  1794. {
  1795. hr = S_FALSE;
  1796. goto exit;
  1797. }
  1798. // Grab the actions list
  1799. Assert(NULL != propvar.blob.pBlobData);
  1800. cActItem = propvar.blob.cbSize / sizeof(ACT_ITEM);
  1801. pActItem = (ACT_ITEM *) (propvar.blob.pBlobData);
  1802. propvar.blob.pBlobData = NULL;
  1803. propvar.blob.cbSize = 0;
  1804. // For each action, add it to the description list
  1805. for (ulIndex = 0; ulIndex < cActItem; ulIndex++)
  1806. {
  1807. // Create the description list
  1808. hr = HrAlloc((VOID **) &pDescriptListAlloc, sizeof(RULEDESCRIPT_LIST));
  1809. if (FAILED(hr))
  1810. {
  1811. goto exit;
  1812. }
  1813. // Initialize the description list
  1814. ZeroMemory(pDescriptListAlloc, sizeof(RULEDESCRIPT_LIST));
  1815. // Search for the criteria type
  1816. for (ulList = 0; ulList < ARRAYSIZE(c_rgEditActList); ulList++)
  1817. {
  1818. if (pActItem[ulIndex].type == c_rgEditActList[ulList].typeAct)
  1819. {
  1820. // Save of the criteria type info
  1821. pDescriptListAlloc->ulIndex = ulList;
  1822. // Save off the flags
  1823. pDescriptListAlloc->dwFlags = pActItem[ulIndex].dwFlags;
  1824. // Do we have any data?
  1825. if (VT_EMPTY != pActItem[ulIndex].propvar.vt)
  1826. {
  1827. // Copy the data
  1828. SideAssert(SUCCEEDED(PropVariantCopy(&propvar, &(pActItem[ulIndex].propvar))));
  1829. pDescriptListAlloc->propvar = propvar;
  1830. ZeroMemory(&propvar, sizeof(propvar));
  1831. // Build up the description text
  1832. if (FALSE != _FBuildActionText(pActItem[ulIndex].type,
  1833. &(pDescriptListAlloc->propvar), &pszText))
  1834. {
  1835. pDescriptListAlloc->pszText = pszText;
  1836. pszText = NULL;
  1837. }
  1838. }
  1839. // We're done searching
  1840. break;
  1841. }
  1842. }
  1843. // Did we find anything?
  1844. if (ulList >= ARRAYSIZE(c_rgEditActList))
  1845. {
  1846. // Free up the description
  1847. _FreeDescriptionList(pDescriptListAlloc);
  1848. }
  1849. else
  1850. {
  1851. // Save the rule description
  1852. _InsertDescription(&pDescriptList, pDescriptListAlloc);
  1853. pDescriptListAlloc = NULL;
  1854. cDescriptList++;
  1855. }
  1856. SafeMemFree(pszText);
  1857. }
  1858. // Set the outgoing params
  1859. *ppDescriptList = pDescriptList;
  1860. pDescriptList = NULL;
  1861. *pcDescriptList = cDescriptList;
  1862. // Set the return value
  1863. hr = S_OK;
  1864. exit:
  1865. _FreeDescriptionList(pDescriptList);
  1866. RuleUtil_HrFreeActionsItem(pActItem, cActItem);
  1867. SafeMemFree(pActItem);
  1868. return hr;
  1869. }
  1870. ///////////////////////////////////////////////////////////////////////////////
  1871. //
  1872. // _FChangeActionValue
  1873. //
  1874. // This changes the value of the action value
  1875. //
  1876. // Returns: TRUE, if the criteria value was changed
  1877. // FALSE, otherwise
  1878. //
  1879. ///////////////////////////////////////////////////////////////////////////////
  1880. BOOL CRuleDescriptUI::_FChangeActionValue(RULEDESCRIPT_LIST * pActList)
  1881. {
  1882. BOOL fRet = FALSE;
  1883. LPSTR pszText = NULL;
  1884. int iRet = 0;
  1885. LONG lDiff = 0;
  1886. CHARRANGE chrg;
  1887. FOLDERID idFolder = FOLDERID_ROOT;
  1888. LPSTR pszVal = NULL;
  1889. ULONG ulVal = 0;
  1890. SELECTADDR selAddr;
  1891. HRESULT hr = S_OK;
  1892. OPENFILENAME ofn = {0};
  1893. TCHAR szFilter[MAX_PATH] = _T("");
  1894. TCHAR szDefExt[20] = _T("");
  1895. RULEFOLDERDATA * prfdData = NULL;
  1896. UINT uiID = 0;
  1897. switch(c_rgEditActList[pActList->ulIndex].typeAct)
  1898. {
  1899. case ACT_TYPE_HIGHLIGHT:
  1900. // Bring up the rename rule dialog
  1901. if (NULL != pActList->propvar.ulVal)
  1902. {
  1903. ulVal = pActList->propvar.ulVal;
  1904. }
  1905. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddActionColor),
  1906. m_hwndOwner, _FSelectColorDlgProc,
  1907. (LPARAM) &ulVal);
  1908. fRet = (iRet == IDOK);
  1909. if (FALSE != fRet)
  1910. {
  1911. PropVariantClear(&(pActList->propvar));
  1912. pActList->propvar.vt = VT_UI4;
  1913. pActList->propvar.ulVal = ulVal;
  1914. }
  1915. break;
  1916. case ACT_TYPE_WATCH:
  1917. // Bring up the watch or ignore dialog
  1918. if (NULL != pActList->propvar.ulVal)
  1919. {
  1920. ulVal = pActList->propvar.ulVal;
  1921. }
  1922. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddActionWatch),
  1923. m_hwndOwner, _FSelectWatchDlgProc,
  1924. (LPARAM) &ulVal);
  1925. fRet = (iRet == IDOK);
  1926. if (FALSE != fRet)
  1927. {
  1928. PropVariantClear(&(pActList->propvar));
  1929. pActList->propvar.vt = VT_UI4;
  1930. pActList->propvar.ulVal = ulVal;
  1931. }
  1932. break;
  1933. case ACT_TYPE_COPY:
  1934. case ACT_TYPE_MOVE:
  1935. // Bring up the change folder dialog
  1936. if ((0 != pActList->propvar.blob.cbSize) && (NULL != pActList->propvar.blob.pBlobData))
  1937. {
  1938. // Validate the rule folder data
  1939. if (S_OK == RuleUtil_HrValidateRuleFolderData((RULEFOLDERDATA *) (pActList->propvar.blob.pBlobData)))
  1940. {
  1941. idFolder = ((RULEFOLDERDATA *) (pActList->propvar.blob.pBlobData))->idFolder;
  1942. }
  1943. }
  1944. hr = SelectFolderDialog(m_hwndOwner, SFD_SELECTFOLDER, idFolder,
  1945. TREEVIEW_NONEWS | TREEVIEW_NOIMAP | TREEVIEW_NOHTTP | FD_DISABLEROOT | FD_DISABLEOUTBOX | FD_DISABLEINBOX | FD_DISABLESENTITEMS | FD_DISABLESERVERS | FD_FORCEINITSELFOLDER,
  1946. (c_rgEditActList[pActList->ulIndex].typeAct == ACT_TYPE_COPY) ? MAKEINTRESOURCE(idsCopy) : MAKEINTRESOURCE(idsMove),
  1947. (c_rgEditActList[pActList->ulIndex].typeAct == ACT_TYPE_COPY) ? MAKEINTRESOURCE(idsCopyCaption) : MAKEINTRESOURCE(idsMoveCaption),
  1948. &idFolder);
  1949. fRet = (S_OK == hr);
  1950. if (FALSE != fRet)
  1951. {
  1952. STOREUSERDATA UserData = {0};
  1953. // Create space for the data structure
  1954. hr = HrAlloc((VOID **) &prfdData, sizeof(*prfdData));
  1955. if (FAILED(hr))
  1956. {
  1957. goto exit;
  1958. }
  1959. // Initialize the data struct
  1960. ZeroMemory(prfdData, sizeof(*prfdData));
  1961. // Get the timestamp for the store
  1962. hr = g_pStore->GetUserData(&UserData, sizeof(STOREUSERDATA));
  1963. if (FAILED(hr))
  1964. {
  1965. goto exit;
  1966. }
  1967. // Set the timestamp
  1968. prfdData->ftStamp = UserData.ftCreated;
  1969. prfdData->idFolder = idFolder;
  1970. // Set the folder id
  1971. PropVariantClear(&(pActList->propvar));
  1972. pActList->propvar.vt = VT_BLOB;
  1973. pActList->propvar.blob.cbSize = sizeof(*prfdData);
  1974. pActList->propvar.blob.pBlobData = (BYTE *) prfdData;
  1975. prfdData = NULL;
  1976. }
  1977. break;
  1978. case ACT_TYPE_REPLY:
  1979. case ACT_TYPE_NOTIFYSND:
  1980. // Bring up the select file dialog
  1981. hr = HrAlloc((void **) &pszVal, MAX_PATH * sizeof(*pszVal));
  1982. if (FAILED(hr))
  1983. {
  1984. fRet = FALSE;
  1985. goto exit;
  1986. }
  1987. pszVal[0] = '\0';
  1988. if (NULL != pActList->propvar.pszVal)
  1989. {
  1990. StrCpyN(pszVal, pActList->propvar.pszVal, MAX_PATH * sizeof(*pszVal));
  1991. }
  1992. if (ACT_TYPE_NOTIFYSND == c_rgEditActList[pActList->ulIndex].typeAct)
  1993. {
  1994. uiID = idsRuleNtfySndFilter;
  1995. }
  1996. else
  1997. {
  1998. uiID = idsRuleReplyWithFilter;
  1999. }
  2000. // Load Res Strings
  2001. LoadStringReplaceSpecial(uiID, szFilter, sizeof(szFilter));
  2002. // Setup Save file struct
  2003. ofn.lStructSize = sizeof (ofn);
  2004. ofn.hwndOwner = m_hwndOwner;
  2005. ofn.lpstrFilter = szFilter;
  2006. ofn.nFilterIndex = 2;
  2007. ofn.lpstrFile = pszVal;
  2008. ofn.nMaxFile = MAX_PATH * sizeof(*pszVal);
  2009. ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
  2010. hr = HrAthGetFileName(&ofn, TRUE);
  2011. fRet = (S_OK == hr);
  2012. if (FALSE != fRet)
  2013. {
  2014. PropVariantClear(&(pActList->propvar));
  2015. pActList->propvar.vt = VT_LPSTR;
  2016. pActList->propvar.pszVal = pszVal;
  2017. pszVal = NULL;
  2018. }
  2019. break;
  2020. case ACT_TYPE_FWD:
  2021. {
  2022. LPWSTR pwszVal = NULL;
  2023. if (NULL != pActList->propvar.pszVal)
  2024. {
  2025. pwszVal = PszToUnicode(CP_ACP, pActList->propvar.pszVal);
  2026. if (!pwszVal)
  2027. {
  2028. fRet = FALSE;
  2029. break;
  2030. }
  2031. }
  2032. // Bring up the address picker
  2033. selAddr.lRecipType = MAPI_TO;
  2034. selAddr.uidsWell = idsRulePickForwardTo;
  2035. selAddr.pwszAddr = pwszVal;
  2036. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddActionFwd),
  2037. m_hwndOwner, _FSelectAddrDlgProc,
  2038. (LPARAM) &selAddr);
  2039. pwszVal = selAddr.pwszAddr;
  2040. fRet = (iRet == IDOK);
  2041. if (FALSE != fRet)
  2042. {
  2043. PropVariantClear(&(pActList->propvar));
  2044. pActList->propvar.vt = VT_LPSTR;
  2045. pActList->propvar.pszVal = PszToANSI(CP_ACP, pwszVal);
  2046. pwszVal = NULL;
  2047. }
  2048. MemFree(pwszVal);
  2049. break;
  2050. }
  2051. case ACT_TYPE_SHOW:
  2052. // Bring up the watch or ignore dialog
  2053. if (NULL != pActList->propvar.ulVal)
  2054. {
  2055. ulVal = pActList->propvar.ulVal;
  2056. }
  2057. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddActionsShow),
  2058. m_hwndOwner, _FSelectShowDlgProc,
  2059. (LPARAM) &ulVal);
  2060. fRet = (iRet == IDOK);
  2061. if (FALSE != fRet)
  2062. {
  2063. PropVariantClear(&(pActList->propvar));
  2064. pActList->propvar.vt = VT_UI4;
  2065. pActList->propvar.ulVal = ulVal;
  2066. }
  2067. break;
  2068. default:
  2069. fRet = FALSE;
  2070. break;
  2071. }
  2072. // Update the description field if neccessary
  2073. if (FALSE != fRet)
  2074. {
  2075. // ZIFF
  2076. // Can we be sure we are really OK??
  2077. pActList->fError = FALSE;
  2078. // If we have something to build up
  2079. if (VT_EMPTY != pActList->propvar.vt)
  2080. {
  2081. if (FALSE == _FBuildActionText(c_rgEditActList[pActList->ulIndex].typeAct, &(pActList->propvar), &pszText))
  2082. {
  2083. goto exit;
  2084. }
  2085. SafeMemFree(pActList->pszText);
  2086. pActList->pszText = pszText;
  2087. pszText = NULL;
  2088. }
  2089. ShowDescriptionString();
  2090. }
  2091. exit:
  2092. SafeMemFree(prfdData);
  2093. SafeMemFree(pszVal);
  2094. SafeMemFree(pszText);
  2095. return fRet;
  2096. }
  2097. ///////////////////////////////////////////////////////////////////////////////
  2098. //
  2099. // _FBuildActionText
  2100. //
  2101. // This changes the value of the action value
  2102. //
  2103. // Returns: TRUE, if the criteria value was changed
  2104. // FALSE, otherwise
  2105. //
  2106. ///////////////////////////////////////////////////////////////////////////////
  2107. BOOL CRuleDescriptUI::_FBuildActionText(ACT_TYPE type, PROPVARIANT * ppropvar, LPSTR * ppszText)
  2108. {
  2109. BOOL fRet = FALSE;
  2110. LPSTR pszText = NULL;
  2111. TCHAR szRes[CCHMAX_STRINGRES];
  2112. HRESULT hr = S_OK;
  2113. FOLDERINFO Folder={0};
  2114. UINT uiId = 0;
  2115. RULEFOLDERDATA * prfdData = NULL;
  2116. if ((NULL == ppropvar) || (NULL == ppszText))
  2117. {
  2118. fRet = FALSE;
  2119. goto exit;
  2120. }
  2121. switch(type)
  2122. {
  2123. case ACT_TYPE_HIGHLIGHT:
  2124. LoadString(g_hLocRes, ppropvar->ulVal + idsAutoColor,
  2125. szRes, sizeof(szRes)/sizeof(TCHAR));
  2126. pszText = PszDupA(szRes);
  2127. if (NULL == pszText)
  2128. {
  2129. fRet = FALSE;
  2130. goto exit;
  2131. }
  2132. break;
  2133. case ACT_TYPE_WATCH:
  2134. if (FAILED(HrAlloc((void **) &pszText, CCHMAX_STRINGRES)))
  2135. {
  2136. fRet = FALSE;
  2137. goto exit;
  2138. }
  2139. // Figure out which string to use
  2140. switch (ppropvar->ulVal)
  2141. {
  2142. case ACT_DATA_WATCHTHREAD:
  2143. uiId = idsThreadWatch;
  2144. break;
  2145. case ACT_DATA_IGNORETHREAD:
  2146. uiId = idsThreadIgnore;
  2147. break;
  2148. default:
  2149. uiId = idsThreadNone;
  2150. break;
  2151. }
  2152. LoadString(g_hLocRes, uiId, pszText, CCHMAX_STRINGRES);
  2153. break;
  2154. case ACT_TYPE_COPY:
  2155. case ACT_TYPE_MOVE:
  2156. if ((0 == ppropvar->blob.cbSize) || (NULL == ppropvar->blob.pBlobData))
  2157. {
  2158. fRet = FALSE;
  2159. goto exit;
  2160. }
  2161. prfdData = (RULEFOLDERDATA *) (ppropvar->blob.pBlobData);
  2162. // Validate the rule folder data
  2163. if (S_OK != RuleUtil_HrValidateRuleFolderData(prfdData))
  2164. {
  2165. fRet = FALSE;
  2166. goto exit;
  2167. }
  2168. hr = g_pStore->GetFolderInfo(prfdData->idFolder, &Folder);
  2169. if (FAILED(hr))
  2170. {
  2171. fRet = FALSE;
  2172. goto exit;
  2173. }
  2174. pszText = PszDupA(Folder.pszName);
  2175. if (NULL == pszText)
  2176. {
  2177. fRet = FALSE;
  2178. goto exit;
  2179. }
  2180. break;
  2181. case ACT_TYPE_REPLY:
  2182. case ACT_TYPE_NOTIFYSND:
  2183. pszText = PszDupA(ppropvar->pszVal);
  2184. if (NULL == pszText)
  2185. {
  2186. fRet = FALSE;
  2187. goto exit;
  2188. }
  2189. break;
  2190. case ACT_TYPE_FWD:
  2191. {
  2192. LPWSTR pwszVal = PszToUnicode(CP_ACP, ppropvar->pszVal),
  2193. pwszText = NULL;
  2194. if (ppropvar->pszVal && !pwszVal)
  2195. {
  2196. fRet = FALSE;
  2197. goto exit;
  2198. }
  2199. // Update the display string
  2200. hr = RuleUtil_HrParseEmailString(pwszVal, 0, &pwszText, NULL);
  2201. MemFree(pwszVal);
  2202. pszText = PszToANSI(CP_ACP, pwszText);
  2203. if (pwszText && !pszText)
  2204. {
  2205. fRet = FALSE;
  2206. goto exit;
  2207. }
  2208. MemFree(pwszText);
  2209. if (FAILED(hr))
  2210. {
  2211. fRet = FALSE;
  2212. goto exit;
  2213. }
  2214. break;
  2215. }
  2216. case ACT_TYPE_SHOW:
  2217. if (FAILED(HrAlloc((void **) &pszText, CCHMAX_STRINGRES)))
  2218. {
  2219. fRet = FALSE;
  2220. goto exit;
  2221. }
  2222. // Figure out which string to use
  2223. switch (ppropvar->ulVal)
  2224. {
  2225. case ACT_DATA_SHOW:
  2226. uiId = idsShowMessages;
  2227. break;
  2228. case ACT_DATA_HIDE:
  2229. uiId = idsHideMessages;
  2230. break;
  2231. default:
  2232. uiId = idsShowHideMessages;
  2233. break;
  2234. }
  2235. LoadString(g_hLocRes, uiId, pszText, CCHMAX_STRINGRES);
  2236. break;
  2237. default:
  2238. fRet = FALSE;
  2239. goto exit;
  2240. break;
  2241. }
  2242. *ppszText = pszText;
  2243. pszText = NULL;
  2244. fRet = TRUE;
  2245. exit:
  2246. SafeMemFree(pszText);
  2247. g_pStore->FreeRecord(&Folder);
  2248. return fRet;
  2249. }
  2250. ///////////////////////////////////////////////////////////////////////////////
  2251. //
  2252. // _FVerifyAction
  2253. //
  2254. // This verifies the value of the action value
  2255. //
  2256. // Returns: TRUE, if the criteria value was changed
  2257. // FALSE, otherwise
  2258. //
  2259. ///////////////////////////////////////////////////////////////////////////////
  2260. BOOL CRuleDescriptUI::_FVerifyAction(RULEDESCRIPT_LIST * pDescriptList)
  2261. {
  2262. BOOL fRet = FALSE;
  2263. LPSTR pszText = NULL;
  2264. HRESULT hr = S_OK;
  2265. FOLDERINFO Folder={0};
  2266. RULEFOLDERDATA * prfdData = NULL;
  2267. if (NULL == pDescriptList)
  2268. {
  2269. fRet = FALSE;
  2270. goto exit;
  2271. }
  2272. switch(c_rgEditActList[pDescriptList->ulIndex].typeAct)
  2273. {
  2274. // These ones are always valid
  2275. case ACT_TYPE_DELETESERVER:
  2276. case ACT_TYPE_DONTDOWNLOAD:
  2277. case ACT_TYPE_FLAG:
  2278. case ACT_TYPE_READ:
  2279. case ACT_TYPE_MARKDOWNLOAD:
  2280. case ACT_TYPE_DELETE:
  2281. case ACT_TYPE_JUNKMAIL:
  2282. case ACT_TYPE_STOP:
  2283. if (VT_EMPTY != pDescriptList->propvar.vt)
  2284. {
  2285. fRet = FALSE;
  2286. goto exit;
  2287. }
  2288. break;
  2289. case ACT_TYPE_HIGHLIGHT:
  2290. if (VT_UI4 != pDescriptList->propvar.vt)
  2291. {
  2292. hr = S_FALSE;
  2293. goto exit;
  2294. }
  2295. break;
  2296. case ACT_TYPE_WATCH:
  2297. case ACT_TYPE_SHOW:
  2298. if (VT_UI4 != pDescriptList->propvar.vt)
  2299. {
  2300. hr = S_FALSE;
  2301. goto exit;
  2302. }
  2303. if (ACT_DATA_NULL == pDescriptList->propvar.ulVal)
  2304. {
  2305. hr = S_FALSE;
  2306. goto exit;
  2307. }
  2308. break;
  2309. case ACT_TYPE_COPY:
  2310. case ACT_TYPE_MOVE:
  2311. if ((VT_BLOB != pDescriptList->propvar.vt) ||
  2312. (0 == pDescriptList->propvar.blob.cbSize))
  2313. {
  2314. hr = S_FALSE;
  2315. goto exit;
  2316. }
  2317. // Make life simpler
  2318. prfdData = (RULEFOLDERDATA *) (pDescriptList->propvar.blob.pBlobData);
  2319. // Validate the rule folder data
  2320. if (S_OK != RuleUtil_HrValidateRuleFolderData(prfdData))
  2321. {
  2322. hr = S_FALSE;
  2323. goto exit;
  2324. }
  2325. hr = g_pStore->GetFolderInfo(prfdData->idFolder, &Folder);
  2326. if (FAILED(hr))
  2327. {
  2328. hr = S_FALSE;
  2329. goto exit;
  2330. }
  2331. else
  2332. g_pStore->FreeRecord(&Folder);
  2333. break;
  2334. case ACT_TYPE_REPLY:
  2335. case ACT_TYPE_NOTIFYSND:
  2336. if ((VT_LPSTR != pDescriptList->propvar.vt) ||
  2337. (NULL == pDescriptList->propvar.pszVal))
  2338. {
  2339. fRet = FALSE;
  2340. goto exit;
  2341. }
  2342. Assert(lstrlen(pDescriptList->propvar.pszVal) <= MAX_PATH)
  2343. if (0xFFFFFFFF == GetFileAttributes(pDescriptList->propvar.pszVal))
  2344. {
  2345. hr = S_FALSE;
  2346. goto exit;
  2347. }
  2348. break;
  2349. case ACT_TYPE_FWD:
  2350. {
  2351. LPWSTR pwszVal = NULL,
  2352. pwszText = NULL;
  2353. if ((VT_LPSTR != pDescriptList->propvar.vt) ||
  2354. (NULL == pDescriptList->propvar.pszVal))
  2355. {
  2356. AssertSz(VT_LPWSTR != pDescriptList->propvar.vt, "We have UNICODE coming in.");
  2357. fRet = FALSE;
  2358. goto exit;
  2359. }
  2360. // Update the display string
  2361. pwszVal = PszToUnicode(CP_ACP, pDescriptList->propvar.pszVal);
  2362. if (!pwszVal)
  2363. {
  2364. fRet = FALSE;
  2365. goto exit;
  2366. }
  2367. hr = RuleUtil_HrParseEmailString(pwszVal, 0, &pwszText, NULL);
  2368. MemFree(pwszText);
  2369. MemFree(pwszVal);
  2370. if (FAILED(hr))
  2371. {
  2372. fRet = FALSE;
  2373. goto exit;
  2374. }
  2375. // If either always encrypt or always sign is turned on
  2376. // we can't do anything
  2377. if ((0 != DwGetOption(OPT_MAIL_DIGSIGNMESSAGES)) || (0 != DwGetOption(OPT_MAIL_ENCRYPTMESSAGES)))
  2378. {
  2379. hr = S_FALSE;
  2380. goto exit;
  2381. }
  2382. break;
  2383. }
  2384. default:
  2385. fRet = FALSE;
  2386. goto exit;
  2387. break;
  2388. }
  2389. fRet = TRUE;
  2390. exit:
  2391. SafeMemFree(pszText);
  2392. return fRet;
  2393. }
  2394. ///////////////////////////////////////////////////////////////////////////////
  2395. //
  2396. // _UpdateRanges
  2397. //
  2398. // This initializes the actions list view with the list of actions
  2399. //
  2400. // Returns: TRUE, if it was successfully loaded
  2401. // FALSE, otherwise
  2402. //
  2403. ///////////////////////////////////////////////////////////////////////////////
  2404. void CRuleDescriptUI::_UpdateRanges(LONG lDiff, ULONG ulStart)
  2405. {
  2406. TCHAR szRes[CCHMAX_STRINGRES + 3];
  2407. ULONG cchRes = 0;
  2408. RULEDESCRIPT_LIST * pDescriptListWalk = NULL;
  2409. if (0 == lDiff)
  2410. {
  2411. goto exit;
  2412. }
  2413. // Update the criteria ranges
  2414. for (pDescriptListWalk = m_pDescriptListCrit;
  2415. pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext)
  2416. {
  2417. if (pDescriptListWalk->ulStartLogic > ulStart)
  2418. {
  2419. pDescriptListWalk->ulStartLogic += lDiff;
  2420. pDescriptListWalk->ulEndLogic += lDiff;
  2421. pDescriptListWalk->ulStart += lDiff;
  2422. pDescriptListWalk->ulEnd += lDiff;
  2423. }
  2424. else if (pDescriptListWalk->ulStart > ulStart)
  2425. {
  2426. pDescriptListWalk->ulStart += lDiff;
  2427. pDescriptListWalk->ulEnd += lDiff;
  2428. }
  2429. }
  2430. // Update the action ranges
  2431. for (pDescriptListWalk = m_pDescriptListAct;
  2432. pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext)
  2433. {
  2434. if (pDescriptListWalk->ulStart > ulStart)
  2435. {
  2436. pDescriptListWalk->ulStart += lDiff;
  2437. pDescriptListWalk->ulEnd += lDiff;
  2438. }
  2439. }
  2440. exit:
  2441. return;
  2442. }
  2443. ///////////////////////////////////////////////////////////////////////////////
  2444. //
  2445. // _InsertDescription
  2446. //
  2447. // This adds a description node to the list of descriptions
  2448. //
  2449. // Returns: NONE
  2450. //
  2451. ///////////////////////////////////////////////////////////////////////////////
  2452. void CRuleDescriptUI::_InsertDescription(RULEDESCRIPT_LIST ** ppDescriptList,
  2453. RULEDESCRIPT_LIST * pDescriptListNew)
  2454. {
  2455. RULEDESCRIPT_LIST * pDescriptListWalk = NULL;
  2456. RULEDESCRIPT_LIST * pDescriptListPrev = NULL;
  2457. Assert(NULL != ppDescriptList);
  2458. // Search for the proper place to place the new item
  2459. for (pDescriptListWalk = *ppDescriptList;
  2460. pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext)
  2461. {
  2462. if (pDescriptListWalk->ulIndex > pDescriptListNew->ulIndex)
  2463. {
  2464. break;
  2465. }
  2466. // Save off the old description
  2467. pDescriptListPrev = pDescriptListWalk;
  2468. }
  2469. // If it's supposed to go at the top
  2470. if (NULL == pDescriptListPrev)
  2471. {
  2472. *ppDescriptList = pDescriptListNew;
  2473. pDescriptListNew->pNext = pDescriptListWalk;
  2474. }
  2475. else
  2476. {
  2477. pDescriptListNew->pNext = pDescriptListWalk;
  2478. pDescriptListPrev->pNext = pDescriptListNew;
  2479. }
  2480. return;
  2481. }
  2482. ///////////////////////////////////////////////////////////////////////////////
  2483. //
  2484. // _FRemoveDescription
  2485. //
  2486. // This adds a description node to the list of descriptions
  2487. //
  2488. // Returns: NONE
  2489. //
  2490. ///////////////////////////////////////////////////////////////////////////////
  2491. BOOL CRuleDescriptUI::_FRemoveDescription(RULEDESCRIPT_LIST ** ppDescriptList, ULONG ulIndex,
  2492. RULEDESCRIPT_LIST ** ppDescriptListRemove)
  2493. {
  2494. BOOL fRet = FALSE;
  2495. RULEDESCRIPT_LIST * pDescriptListWalk = NULL;
  2496. RULEDESCRIPT_LIST * pDescriptListPrev = NULL;
  2497. Assert((NULL != ppDescriptList) && (NULL != ppDescriptListRemove));
  2498. *ppDescriptListRemove = NULL;
  2499. // Find the criteria item in the list
  2500. for (pDescriptListWalk = *ppDescriptList;
  2501. pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext)
  2502. {
  2503. if (ulIndex == pDescriptListWalk->ulIndex)
  2504. {
  2505. break;
  2506. }
  2507. // Save off the old description
  2508. pDescriptListPrev = pDescriptListWalk;
  2509. }
  2510. // Did we find the criteria item?
  2511. if (NULL == pDescriptListWalk)
  2512. {
  2513. fRet = FALSE;
  2514. goto exit;
  2515. }
  2516. // Remove the criteria item from the list
  2517. if (NULL == pDescriptListPrev)
  2518. {
  2519. *ppDescriptList = pDescriptListWalk->pNext;
  2520. }
  2521. else
  2522. {
  2523. pDescriptListPrev->pNext = pDescriptListWalk->pNext;
  2524. }
  2525. pDescriptListWalk->pNext = NULL;
  2526. // Set the outgoing params
  2527. *ppDescriptListRemove = pDescriptListWalk;
  2528. // Set the return value
  2529. fRet = TRUE;
  2530. exit:
  2531. return fRet;
  2532. }
  2533. ///////////////////////////////////////////////////////////////////////////////
  2534. //
  2535. // _FreeDescriptionLists
  2536. //
  2537. // This frees the list of descriptions
  2538. //
  2539. // Returns: NONE
  2540. //
  2541. ///////////////////////////////////////////////////////////////////////////////
  2542. void CRuleDescriptUI::_FreeDescriptionList(RULEDESCRIPT_LIST * pDescriptList)
  2543. {
  2544. RULEDESCRIPT_LIST * pDescriptListWalk = NULL;
  2545. while (NULL != pDescriptList)
  2546. {
  2547. pDescriptListWalk = pDescriptList;
  2548. SafeMemFree(pDescriptListWalk->pszText);
  2549. PropVariantClear(&(pDescriptListWalk->propvar));
  2550. pDescriptList = pDescriptListWalk->pNext;
  2551. MemFree(pDescriptListWalk);
  2552. }
  2553. return;
  2554. }
  2555. ///////////////////////////////////////////////////////////////////////////////
  2556. //
  2557. // _FOnDescriptClick
  2558. //
  2559. // This handles clicking on the links in the description field
  2560. //
  2561. // uiMsg - the type of click
  2562. // ulIndex - which criteria/action to change
  2563. // fCrit - did we click on a criteria?
  2564. // fLogic - did we click on a logic op?
  2565. //
  2566. // Returns: TRUE, we changed the criteria/action
  2567. // FALSE, otherwise
  2568. //
  2569. ///////////////////////////////////////////////////////////////////////////////
  2570. BOOL CRuleDescriptUI::_FOnDescriptClick(UINT uiMsg, RULEDESCRIPT_LIST * pDescriptList, BOOL fCrit, BOOL fLogic)
  2571. {
  2572. BOOL fRet = FALSE;
  2573. CHARRANGE chrg;
  2574. NMHDR nmhdr;
  2575. if ((WM_LBUTTONUP == uiMsg) || (WM_KEYDOWN == uiMsg))
  2576. {
  2577. // Release the capture if there is one
  2578. if (NULL != GetCapture())
  2579. {
  2580. ReleaseCapture();
  2581. }
  2582. // Did we click in the logic op?
  2583. if (fLogic)
  2584. {
  2585. fRet = _FChangeLogicValue(pDescriptList);
  2586. }
  2587. // Did we click in the criteria list?
  2588. else if (fCrit)
  2589. {
  2590. fRet = _FChangeCriteriaValue(pDescriptList);
  2591. }
  2592. else
  2593. {
  2594. fRet = _FChangeActionValue(pDescriptList);
  2595. }
  2596. if (fRet)
  2597. {
  2598. m_dwState |= STATE_DIRTY;
  2599. // Tell the parent dialog something has changed
  2600. nmhdr.hwndFrom = m_hwndOwner;
  2601. nmhdr.idFrom = GetDlgCtrlID(m_hwndOwner);
  2602. nmhdr.code = NM_RULE_CHANGED;
  2603. SendMessage(GetParent(m_hwndOwner), WM_NOTIFY, (WPARAM) (nmhdr.idFrom), (LPARAM) &nmhdr);
  2604. }
  2605. fRet = TRUE;
  2606. }
  2607. if (((WM_LBUTTONDOWN == uiMsg) || (WM_LBUTTONDBLCLK == uiMsg)) &&
  2608. (0 == (GetAsyncKeyState(VK_CONTROL) & 0x8000)))
  2609. {
  2610. if (fLogic)
  2611. {
  2612. chrg.cpMin = pDescriptList->ulStartLogic;
  2613. chrg.cpMax = pDescriptList->ulEndLogic;
  2614. }
  2615. else
  2616. {
  2617. chrg.cpMin = pDescriptList->ulStart;
  2618. chrg.cpMax = pDescriptList->ulEnd;
  2619. }
  2620. // Need to make sure we show the selection
  2621. SendMessage(m_hwndOwner, EM_HIDESELECTION, (WPARAM) FALSE, (LPARAM) FALSE);
  2622. RichEditExSetSel(m_hwndOwner, &chrg);
  2623. fRet = TRUE;
  2624. }
  2625. return fRet;
  2626. }
  2627. ///////////////////////////////////////////////////////////////////////////////
  2628. //
  2629. // _FInLink
  2630. //
  2631. // Given a point in the control, this will tell us whether or not the point
  2632. // is in a link
  2633. //
  2634. // ppt - the point to check
  2635. // pulIndex - which criteria/action is the point in
  2636. // pfCrit - is the point over a criteria?
  2637. // pfLogic - is the point over a logic op?
  2638. //
  2639. // Returns: TRUE, if the point is over a criteria/action
  2640. // FALSE, otherwise
  2641. //
  2642. ///////////////////////////////////////////////////////////////////////////////
  2643. BOOL CRuleDescriptUI::_FInLink(int chPos, RULEDESCRIPT_LIST ** ppDescriptList,
  2644. BOOL * pfCrit, BOOL * pfLogic)
  2645. {
  2646. BOOL fFound = FALSE;
  2647. RULEDESCRIPT_LIST * pDescriptListWalk = NULL;
  2648. POINT pt;
  2649. ULONG ulIndex = 0;
  2650. BOOL fCrit = FALSE;
  2651. BOOL fLogic = FALSE;
  2652. LONG idxLine = 0;
  2653. LPSTR pszBuff = NULL;
  2654. ULONG cchBuff = 0;
  2655. HDC hdc = NULL;
  2656. HFONT hfont = NULL;
  2657. HFONT hfontOld = NULL;
  2658. SIZE size;
  2659. LONG idxPosLine = 0;
  2660. // If we're read only then we can't be in a link
  2661. if ((0 != (m_dwState & STATE_READONLY)) || (0 == chPos))
  2662. {
  2663. fFound = FALSE;
  2664. goto exit;
  2665. }
  2666. // Did we click in the criteria list?
  2667. for (pDescriptListWalk = m_pDescriptListCrit;
  2668. NULL != pDescriptListWalk; pDescriptListWalk = pDescriptListWalk->pNext)
  2669. {
  2670. if (((LONG) pDescriptListWalk->ulStart <= chPos) &&
  2671. ((LONG) pDescriptListWalk->ulEnd >= chPos))
  2672. {
  2673. fCrit = TRUE;
  2674. fFound = TRUE;
  2675. break;
  2676. }
  2677. if (((LONG) pDescriptListWalk->ulStartLogic <= chPos) &&
  2678. ((LONG) pDescriptListWalk->ulEndLogic >= chPos))
  2679. {
  2680. fLogic = TRUE;
  2681. fFound = TRUE;
  2682. break;
  2683. }
  2684. }
  2685. if (!fFound)
  2686. {
  2687. // Did we click in the actions list
  2688. for (pDescriptListWalk = m_pDescriptListAct;
  2689. NULL != pDescriptListWalk; pDescriptListWalk = pDescriptListWalk->pNext)
  2690. {
  2691. if (((LONG) pDescriptListWalk->ulStart <= chPos) &&
  2692. ((LONG) pDescriptListWalk->ulEnd >= chPos))
  2693. {
  2694. fFound = TRUE;
  2695. break;
  2696. }
  2697. }
  2698. }
  2699. if (ppDescriptList)
  2700. {
  2701. *ppDescriptList = pDescriptListWalk;
  2702. }
  2703. if (pfCrit)
  2704. {
  2705. *pfCrit = fCrit;
  2706. }
  2707. if (pfLogic)
  2708. {
  2709. *pfLogic = fLogic;
  2710. }
  2711. goto exit;
  2712. exit:
  2713. if (NULL != hdc)
  2714. {
  2715. ReleaseDC(m_hwndOwner, hdc);
  2716. }
  2717. MemFree(pszBuff);
  2718. return fFound;
  2719. }
  2720. VOID _SearchForLink(RULEDESCRIPT_LIST * pDescriptList, BOOL fUp, LONG lPos, CHARRANGE * pcrPos)
  2721. {
  2722. RULEDESCRIPT_LIST * pDescriptListWalk = NULL;
  2723. Assert(NULL != pcrPos);
  2724. // Find the closest link...
  2725. for (pDescriptListWalk = pDescriptList;
  2726. NULL != pDescriptListWalk; pDescriptListWalk = pDescriptListWalk->pNext)
  2727. {
  2728. // Do we have a criteria link?
  2729. if (0 != pDescriptListWalk->ulStart)
  2730. {
  2731. // Are we going down?
  2732. if (FALSE == fUp)
  2733. {
  2734. // Is the link past the current position?
  2735. if ((LONG) pDescriptListWalk->ulEnd > lPos)
  2736. {
  2737. // Save off the closest link to the current position
  2738. if ((0 == pcrPos->cpMin) || ((LONG) pDescriptListWalk->ulStart < pcrPos->cpMin))
  2739. {
  2740. pcrPos->cpMin = (LONG) pDescriptListWalk->ulStart;
  2741. pcrPos->cpMax = (LONG) pDescriptListWalk->ulEnd;
  2742. }
  2743. }
  2744. }
  2745. else
  2746. {
  2747. // Is the link before the current position?
  2748. if ((LONG) pDescriptListWalk->ulEnd < lPos)
  2749. {
  2750. // Save off the closest link to the current position
  2751. if ((0 == pcrPos->cpMin) || ((LONG) pDescriptListWalk->ulStart > pcrPos->cpMin))
  2752. {
  2753. pcrPos->cpMin = (LONG) pDescriptListWalk->ulStart;
  2754. pcrPos->cpMax = (LONG) pDescriptListWalk->ulEnd;
  2755. }
  2756. }
  2757. }
  2758. }
  2759. // Do we have a logic link?
  2760. if (0 != pDescriptListWalk->ulStartLogic)
  2761. {
  2762. // Are we going down?
  2763. if (FALSE == fUp)
  2764. {
  2765. // Is the link past the current position?
  2766. if ((LONG) pDescriptListWalk->ulEndLogic > lPos)
  2767. {
  2768. // Save off the closest link to the current position
  2769. if ((0 == pcrPos->cpMin) || ((LONG) pDescriptListWalk->ulStartLogic < pcrPos->cpMin))
  2770. {
  2771. pcrPos->cpMin = (LONG) pDescriptListWalk->ulStartLogic;
  2772. pcrPos->cpMax = (LONG) pDescriptListWalk->ulEndLogic;
  2773. }
  2774. }
  2775. }
  2776. else
  2777. {
  2778. // Is the link before the current position?
  2779. if ((LONG) pDescriptListWalk->ulEndLogic < lPos)
  2780. {
  2781. // Save off the closest link to the current position
  2782. if ((0 == pcrPos->cpMin) || ((LONG) pDescriptListWalk->ulStartLogic > pcrPos->cpMin))
  2783. {
  2784. pcrPos->cpMin = (LONG) pDescriptListWalk->ulStartLogic;
  2785. pcrPos->cpMax = (LONG) pDescriptListWalk->ulEndLogic;
  2786. }
  2787. }
  2788. }
  2789. }
  2790. }
  2791. return;
  2792. }
  2793. ///////////////////////////////////////////////////////////////////////////////
  2794. //
  2795. // _FMoveToLink
  2796. //
  2797. // Given a point in the control, this will tell us whether or not the point
  2798. // is in a link
  2799. //
  2800. // ppt - the point to check
  2801. // pulIndex - which criteria/action is the point in
  2802. // pfCrit - is the point over a criteria?
  2803. // pfLogic - is the point over a logic op?
  2804. //
  2805. // Returns: TRUE, if the point is over a criteria/action
  2806. // FALSE, otherwise
  2807. //
  2808. ///////////////////////////////////////////////////////////////////////////////
  2809. BOOL CRuleDescriptUI::_FMoveToLink(UINT uiKeyCode)
  2810. {
  2811. BOOL fRet = FALSE;
  2812. BOOL fUp = FALSE;
  2813. CHARRANGE crPos = {0};
  2814. CHARRANGE crLink = {0};
  2815. // Figure out which way we are going
  2816. fUp = ((VK_LEFT == uiKeyCode) || (VK_UP == uiKeyCode));
  2817. // Get the current character position
  2818. RichEditExGetSel(m_hwndOwner, &crPos);
  2819. // Find the closest link in the criteria
  2820. _SearchForLink(m_pDescriptListCrit, fUp, crPos.cpMax, &crLink);
  2821. // Find the closest link in the actions
  2822. _SearchForLink(m_pDescriptListAct, fUp, crPos.cpMax, &crLink);
  2823. // Do we have anything to do?
  2824. if (0 != crLink.cpMin)
  2825. {
  2826. // Set the new selection
  2827. RichEditExSetSel(m_hwndOwner, &crLink);
  2828. SendMessage(m_hwndOwner, EM_SCROLLCARET, (WPARAM) 0, (LPARAM) 0);
  2829. fRet = TRUE;
  2830. }
  2831. return fRet;
  2832. }
  2833. LRESULT CALLBACK CRuleDescriptUI::_DescriptWndProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  2834. {
  2835. LRESULT lRes = 0;
  2836. POINT ptCur;
  2837. CRuleDescriptUI * pDescriptUI = NULL;
  2838. HCURSOR hcursor = NULL;
  2839. RULEDESCRIPT_LIST * pDescriptList = NULL;
  2840. BOOL fCrit = FALSE;
  2841. BOOL fLogic = FALSE;
  2842. CHARRANGE crPos = {0};
  2843. int chPos = 0;
  2844. pDescriptUI = (CRuleDescriptUI *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
  2845. switch (uiMsg)
  2846. {
  2847. case WM_SETCURSOR:
  2848. if((FALSE != IsWindowVisible(hwnd)) && ((HWND) wParam == hwnd))
  2849. {
  2850. lRes = DefWindowProc(hwnd, uiMsg, wParam, lParam);
  2851. if(0 == lRes)
  2852. {
  2853. GetCursorPos(&ptCur);
  2854. ScreenToClient(hwnd, &ptCur);
  2855. chPos = (int) SendMessage(hwnd, EM_CHARFROMPOS, (WPARAM)0, (LPARAM)&ptCur);
  2856. chPos = RichEditNormalizeCharPos(hwnd, chPos, NULL);
  2857. if (FALSE != pDescriptUI->_FInLink(chPos, NULL, NULL, NULL))
  2858. {
  2859. hcursor = LoadCursor(g_hLocRes, MAKEINTRESOURCE(idcurBrHand));
  2860. SetCursor(hcursor);
  2861. lRes = TRUE;
  2862. }
  2863. }
  2864. }
  2865. break;
  2866. case WM_LBUTTONDOWN:
  2867. case WM_LBUTTONDBLCLK:
  2868. case WM_LBUTTONUP:
  2869. GetCursorPos(&ptCur);
  2870. ScreenToClient(hwnd, &ptCur);
  2871. chPos = (int) SendMessage(hwnd, EM_CHARFROMPOS, (WPARAM)0, (LPARAM)&ptCur);
  2872. chPos = RichEditNormalizeCharPos(hwnd, chPos, NULL);
  2873. if (FALSE != pDescriptUI->_FInLink(chPos, &pDescriptList, &fCrit, &fLogic))
  2874. {
  2875. // Change the proper value
  2876. lRes = pDescriptUI->_FOnDescriptClick(uiMsg, pDescriptList, fCrit, fLogic);
  2877. }
  2878. break;
  2879. case WM_KEYDOWN:
  2880. switch (wParam)
  2881. {
  2882. case VK_RETURN:
  2883. RichEditExGetSel(hwnd, &crPos);
  2884. if (FALSE != pDescriptUI->_FInLink(crPos.cpMin, &pDescriptList, &fCrit, &fLogic))
  2885. {
  2886. // Change the proper value
  2887. lRes = pDescriptUI->_FOnDescriptClick(uiMsg, pDescriptList, fCrit, fLogic);
  2888. }
  2889. break;
  2890. case VK_LEFT:
  2891. case VK_UP:
  2892. case VK_RIGHT:
  2893. case VK_DOWN:
  2894. lRes = pDescriptUI->_FMoveToLink((UINT) wParam);
  2895. break;
  2896. }
  2897. break;
  2898. }
  2899. if (0 == lRes)
  2900. {
  2901. lRes = CallWindowProc(pDescriptUI->m_wpcOld, hwnd, uiMsg, wParam, lParam);
  2902. }
  2903. return lRes;
  2904. }
  2905. ///////////////////////////////////////////////////////////////////////////////
  2906. //
  2907. // _FSelectAddrDlgProc
  2908. //
  2909. // This is the main dialog proc for changing addresses
  2910. //
  2911. // hwndDlg - handle to the filter manager dialog
  2912. // uMsg - the message to be acted upon
  2913. // wParam - the 'word' parameter for the message
  2914. // lParam - the 'long' parameter for the message
  2915. //
  2916. // Returns: TRUE, if the message was handled
  2917. // FALSE, otherwise
  2918. //
  2919. ///////////////////////////////////////////////////////////////////////////////
  2920. INT_PTR CALLBACK CRuleDescriptUI::_FSelectAddrDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2921. {
  2922. BOOL fRet = FALSE;
  2923. SELECTADDR * pseladdr = NULL;
  2924. HWND hwndAddr = NULL;
  2925. LPWSTR pwszText = NULL,
  2926. pwszAddr = NULL;
  2927. ULONG cchText = 0,
  2928. cchAddr = 0;
  2929. HRESULT hr = S_OK;
  2930. pseladdr = (SELECTADDR *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  2931. switch (uMsg)
  2932. {
  2933. case WM_INITDIALOG:
  2934. // Grab the propvariant pointer
  2935. pseladdr = (SELECTADDR *) lParam;
  2936. if (NULL == pseladdr)
  2937. {
  2938. fRet = FALSE;
  2939. EndDialog(hwndDlg, -1);
  2940. goto exit;
  2941. }
  2942. // Set it into the dialog so we can get it back
  2943. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pseladdr);
  2944. hwndAddr = GetDlgItem(hwndDlg, idedtCriteriaAddr);
  2945. SetIntlFont(hwndAddr);
  2946. // Set the name of the rule into the edit well
  2947. if (NULL == pseladdr->pwszAddr)
  2948. {
  2949. Edit_SetText(hwndAddr, c_szEmpty);
  2950. }
  2951. else
  2952. {
  2953. if (FAILED(RuleUtil_HrParseEmailString(pseladdr->pwszAddr, 0, &pwszText, NULL)))
  2954. {
  2955. fRet = FALSE;
  2956. EndDialog(hwndDlg, -1);
  2957. goto exit;
  2958. }
  2959. SetWindowTextWrapW(hwndAddr, pwszText);
  2960. SafeMemFree(pwszText);
  2961. }
  2962. // We didn't set the focus so return TRUE
  2963. fRet = TRUE;
  2964. break;
  2965. case WM_COMMAND:
  2966. switch (LOWORD(wParam))
  2967. {
  2968. case idedtCriteriaAddr:
  2969. if (EN_CHANGE == HIWORD(wParam))
  2970. {
  2971. hwndAddr = (HWND) lParam;
  2972. Assert(NULL != hwndAddr);
  2973. RuleUtil_FEnDisDialogItem(hwndDlg, IDOK, 0 != Edit_GetTextLength(hwndAddr));
  2974. }
  2975. break;
  2976. case idbCriteriaAddr:
  2977. hwndAddr = GetDlgItem(hwndDlg, idedtCriteriaAddr);
  2978. // Get the name of the rule from the edit well
  2979. cchText = Edit_GetTextLength(hwndAddr) + 1;
  2980. if (FAILED(HrAlloc((void **) &pwszText, cchText * sizeof(*pwszText))))
  2981. {
  2982. fRet = FALSE;
  2983. goto exit;
  2984. }
  2985. pwszText[0] = L'\0';
  2986. cchText = GetWindowTextWrapW(hwndAddr, pwszText, cchText);
  2987. hr = RuleUtil_HrBuildEmailString(pwszText, cchText, &pwszAddr, &cchAddr);
  2988. SafeMemFree(pwszText);
  2989. if (FAILED(hr))
  2990. {
  2991. fRet = FALSE;
  2992. goto exit;
  2993. }
  2994. hr = RuleUtil_HrPickEMailNames(hwndDlg, pseladdr->lRecipType, pseladdr->uidsWell, &pwszAddr);
  2995. if (S_OK != hr)
  2996. {
  2997. fRet = FALSE;
  2998. SafeMemFree(pwszAddr);
  2999. goto exit;
  3000. }
  3001. if (S_OK != RuleUtil_HrParseEmailString(pwszAddr, 0, &pwszText, NULL))
  3002. {
  3003. fRet = FALSE;
  3004. SafeMemFree(pwszAddr);
  3005. goto exit;
  3006. }
  3007. SetWindowTextWrapW(hwndAddr, pwszText);
  3008. SafeMemFree(pwszText);
  3009. SafeMemFree(pwszAddr);
  3010. break;
  3011. case IDCANCEL:
  3012. EndDialog(hwndDlg, IDCANCEL);
  3013. fRet = TRUE;
  3014. break;
  3015. case IDOK:
  3016. hwndAddr = GetDlgItem(hwndDlg, idedtCriteriaAddr);
  3017. // Get the name of the rule from the edit well
  3018. cchText = Edit_GetTextLength(hwndAddr) + 1;
  3019. if (FAILED(HrAlloc((void **) &pwszText, cchText * sizeof(*pwszText))))
  3020. {
  3021. fRet = FALSE;
  3022. goto exit;
  3023. }
  3024. pwszText[0] = L'\0';
  3025. cchText = GetWindowTextWrapW(hwndAddr, pwszText, cchText);
  3026. // Check to see if the rule name is valid
  3027. if ((FAILED(RuleUtil_HrBuildEmailString(pwszText, cchText, &pwszAddr, &cchAddr))) ||
  3028. (0 == cchAddr))
  3029. {
  3030. // Put up a message saying something is busted
  3031. AthMessageBoxW(hwndDlg, MAKEINTRESOURCEW(idsAthenaMail),
  3032. MAKEINTRESOURCEW(idsRulesErrorNoAddr), NULL,
  3033. MB_OK | MB_ICONINFORMATION);
  3034. SafeMemFree(pwszText);
  3035. SafeMemFree(pwszAddr);
  3036. fRet = FALSE;
  3037. goto exit;
  3038. }
  3039. SafeMemFree(pseladdr->pwszAddr);
  3040. pseladdr->pwszAddr = pwszAddr;
  3041. SafeMemFree(pwszText);
  3042. EndDialog(hwndDlg, IDOK);
  3043. fRet = TRUE;
  3044. break;
  3045. }
  3046. break;
  3047. }
  3048. exit:
  3049. return fRet;
  3050. }
  3051. ///////////////////////////////////////////////////////////////////////////////
  3052. //
  3053. // _FSelectAcctDlgProc
  3054. //
  3055. // This is the main dialog proc for selecting an account dialog
  3056. //
  3057. // hwndDlg - handle to the filter manager dialog
  3058. // uMsg - the message to be acted upon
  3059. // wParam - the 'word' parameter for the message
  3060. // lParam - the 'long' parameter for the message
  3061. //
  3062. // Returns: TRUE, if the message was handled
  3063. // FALSE, otherwise
  3064. //
  3065. ///////////////////////////////////////////////////////////////////////////////
  3066. INT_PTR CALLBACK CRuleDescriptUI::_FSelectAcctDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3067. {
  3068. BOOL fRet = FALSE;
  3069. SELECTACCT * pselacct = NULL;
  3070. LPSTR pszAcct = NULL;
  3071. ULONG cchAcct = 0;
  3072. HWND hwndAcct = NULL;
  3073. CHAR szAccount[CCHMAX_ACCOUNT_NAME];
  3074. IImnAccount * pAccount = NULL;
  3075. IImnEnumAccounts * pEnumAcct = NULL;
  3076. DWORD dwSrvTypes = 0;
  3077. ULONG ulIndex = 0;
  3078. BOOL fSelected = FALSE;
  3079. pselacct = (SELECTACCT *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  3080. switch (uMsg)
  3081. {
  3082. case WM_INITDIALOG:
  3083. // Grab the propvariant pointer
  3084. pselacct = (SELECTACCT *) lParam;
  3085. if (NULL == pselacct)
  3086. {
  3087. fRet = FALSE;
  3088. EndDialog(hwndDlg, -1);
  3089. goto exit;
  3090. }
  3091. // Set it into the dialog so we can get it back
  3092. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pselacct);
  3093. hwndAcct = GetDlgItem(hwndDlg, idcCriteriaAcct);
  3094. SetIntlFont(hwndAcct);
  3095. // Set the name of the rule into the edit well
  3096. Assert(g_pAcctMan);
  3097. switch (pselacct->typeRule)
  3098. {
  3099. case RULE_TYPE_MAIL:
  3100. dwSrvTypes = SRV_POP3;
  3101. break;
  3102. case RULE_TYPE_NEWS:
  3103. dwSrvTypes = SRV_NNTP;
  3104. break;
  3105. case RULE_TYPE_FILTER:
  3106. dwSrvTypes = SRV_MAIL | SRV_NNTP;
  3107. break;
  3108. }
  3109. // Grab the enumerator from the account manager
  3110. if (FAILED(g_pAcctMan->Enumerate(dwSrvTypes, &pEnumAcct)))
  3111. {
  3112. fRet = FALSE;
  3113. goto exit;
  3114. }
  3115. // Insert each account into the combobox
  3116. while(SUCCEEDED(pEnumAcct->GetNext(&pAccount)))
  3117. {
  3118. // We can get back NULL accounts
  3119. if (NULL == pAccount)
  3120. {
  3121. break;
  3122. }
  3123. // Add the account string to the combobox
  3124. if (FAILED(pAccount->GetPropSz(AP_ACCOUNT_NAME, szAccount, sizeof(szAccount))))
  3125. {
  3126. SafeRelease(pAccount);
  3127. continue;
  3128. }
  3129. ulIndex = ComboBox_AddString(hwndAcct, szAccount);
  3130. if (CB_ERR == ulIndex)
  3131. {
  3132. fRet = FALSE;
  3133. SafeRelease(pEnumAcct);
  3134. SafeRelease(pAccount);
  3135. EndDialog(hwndDlg, -1);
  3136. goto exit;
  3137. }
  3138. if (FAILED(pAccount->GetPropSz(AP_ACCOUNT_ID, szAccount, sizeof(szAccount))))
  3139. {
  3140. SafeRelease(pAccount);
  3141. continue;
  3142. }
  3143. // Set the default selection if we have one
  3144. if ((NULL != pselacct->pszAcct) && (0 == lstrcmp(pselacct->pszAcct, szAccount)))
  3145. {
  3146. Assert(FALSE == fSelected);
  3147. ComboBox_SetCurSel(hwndAcct, ulIndex);
  3148. fSelected = TRUE;
  3149. }
  3150. // Release it
  3151. SafeRelease(pAccount);
  3152. }
  3153. SafeRelease(pEnumAcct);
  3154. if (FALSE == fSelected)
  3155. {
  3156. ComboBox_SetCurSel(hwndAcct, 0);
  3157. }
  3158. // We didn't set the focus so return TRUE
  3159. fRet = TRUE;
  3160. break;
  3161. case WM_COMMAND:
  3162. switch (LOWORD(wParam))
  3163. {
  3164. case IDCANCEL:
  3165. EndDialog(hwndDlg, IDCANCEL);
  3166. fRet = TRUE;
  3167. break;
  3168. case IDOK:
  3169. hwndAcct = GetDlgItem(hwndDlg, idcCriteriaAcct);
  3170. // Get the account name that was selected
  3171. ulIndex = ComboBox_GetCurSel(hwndAcct);
  3172. if (CB_ERR == ulIndex)
  3173. {
  3174. fRet = FALSE;
  3175. goto exit;
  3176. }
  3177. cchAcct = ComboBox_GetLBText(hwndAcct, ulIndex, szAccount);
  3178. if (0 == cchAcct)
  3179. {
  3180. fRet = FALSE;
  3181. goto exit;
  3182. }
  3183. Assert(g_pAcctMan);
  3184. if (FAILED(g_pAcctMan->FindAccount(AP_ACCOUNT_NAME, szAccount, &pAccount)))
  3185. {
  3186. fRet = FALSE;
  3187. goto exit;
  3188. }
  3189. if (FAILED(pAccount->GetPropSz(AP_ACCOUNT_ID, szAccount, sizeof(szAccount))))
  3190. {
  3191. fRet = FALSE;
  3192. SafeRelease(pAccount);
  3193. goto exit;
  3194. }
  3195. // Release it
  3196. SafeRelease(pAccount);
  3197. pszAcct = PszDupA(szAccount);
  3198. if (NULL == pszAcct)
  3199. {
  3200. fRet = FALSE;
  3201. goto exit;
  3202. }
  3203. SafeMemFree(pselacct->pszAcct);
  3204. pselacct->pszAcct = pszAcct;
  3205. EndDialog(hwndDlg, IDOK);
  3206. fRet = TRUE;
  3207. break;
  3208. }
  3209. break;
  3210. }
  3211. exit:
  3212. return fRet;
  3213. }
  3214. ///////////////////////////////////////////////////////////////////////////////
  3215. //
  3216. // _FSelectColorDlgProc
  3217. //
  3218. // This is the main dialog proc for selecting a color dialog
  3219. //
  3220. // hwndDlg - handle to the filter manager dialog
  3221. // uMsg - the message to be acted upon
  3222. // wParam - the 'word' parameter for the message
  3223. // lParam - the 'long' parameter for the message
  3224. //
  3225. // Returns: TRUE, if the message was handled
  3226. // FALSE, otherwise
  3227. //
  3228. ///////////////////////////////////////////////////////////////////////////////
  3229. INT_PTR CALLBACK CRuleDescriptUI::_FSelectColorDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3230. {
  3231. BOOL fRet = FALSE;
  3232. ULONG * pulColor = NULL;
  3233. ULONG ulColor = NULL;
  3234. HWND hwndColor = NULL;
  3235. HDC hdc = NULL;
  3236. LPMEASUREITEMSTRUCT pmis = NULL;
  3237. LPDRAWITEMSTRUCT pdis = NULL;
  3238. pulColor = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  3239. switch (uMsg)
  3240. {
  3241. case WM_INITDIALOG:
  3242. // Grab the propvariant pointer
  3243. pulColor = (ULONG *) lParam;
  3244. if (NULL == pulColor)
  3245. {
  3246. fRet = FALSE;
  3247. EndDialog(hwndDlg, -1);
  3248. goto exit;
  3249. }
  3250. // Set it into the dialog so we can get it back
  3251. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulColor);
  3252. hwndColor = GetDlgItem(hwndDlg, idcCriteriaColor);
  3253. SetIntlFont(hwndColor);
  3254. // Let's create the color control
  3255. if (FAILED(HrCreateComboColor(hwndColor)))
  3256. {
  3257. fRet = FALSE;
  3258. goto exit;
  3259. }
  3260. if (0 != *pulColor)
  3261. {
  3262. ulColor = *pulColor;
  3263. }
  3264. ComboBox_SetCurSel(hwndColor, ulColor);
  3265. // We didn't set the focus so return TRUE
  3266. fRet = TRUE;
  3267. break;
  3268. case WM_COMMAND:
  3269. switch (LOWORD(wParam))
  3270. {
  3271. case IDCANCEL:
  3272. EndDialog(hwndDlg, IDCANCEL);
  3273. fRet = TRUE;
  3274. break;
  3275. case IDOK:
  3276. hwndColor = GetDlgItem(hwndDlg, idcCriteriaColor);
  3277. // Get the account name that was selected
  3278. ulColor = ComboBox_GetCurSel(hwndColor);
  3279. if (CB_ERR == ulColor)
  3280. {
  3281. fRet = FALSE;
  3282. goto exit;
  3283. }
  3284. *pulColor = ulColor;
  3285. EndDialog(hwndDlg, IDOK);
  3286. fRet = TRUE;
  3287. break;
  3288. }
  3289. break;
  3290. case WM_DRAWITEM:
  3291. pdis = (LPDRAWITEMSTRUCT)lParam;
  3292. Assert(pdis);
  3293. Color_WMDrawItem(pdis, iColorCombo);
  3294. fRet = FALSE;
  3295. break;
  3296. case WM_MEASUREITEM:
  3297. pmis = (LPMEASUREITEMSTRUCT)lParam;
  3298. hwndColor = GetDlgItem(hwndDlg, idcCriteriaColor);
  3299. hdc = GetDC(hwndColor);
  3300. if(hdc)
  3301. {
  3302. Color_WMMeasureItem(hdc, pmis, iColorCombo);
  3303. ReleaseDC(hwndColor, hdc);
  3304. }
  3305. fRet = TRUE;
  3306. break;
  3307. }
  3308. exit:
  3309. return fRet;
  3310. }
  3311. ///////////////////////////////////////////////////////////////////////////////
  3312. //
  3313. // _FSelectSizeDlgProc
  3314. //
  3315. // This is the main dialog proc for selecting the size dialog
  3316. //
  3317. // hwndDlg - handle to the filter manager dialog
  3318. // uMsg - the message to be acted upon
  3319. // wParam - the 'word' parameter for the message
  3320. // lParam - the 'long' parameter for the message
  3321. //
  3322. // Returns: TRUE, if the message was handled
  3323. // FALSE, otherwise
  3324. //
  3325. ///////////////////////////////////////////////////////////////////////////////
  3326. INT_PTR CALLBACK CRuleDescriptUI::_FSelectSizeDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3327. {
  3328. BOOL fRet = FALSE;
  3329. ULONG * pulSize = NULL;
  3330. HWND hwndSize = NULL;
  3331. HWND hwndText = NULL;
  3332. ULONG ulSize = 0;
  3333. pulSize = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  3334. switch (uMsg)
  3335. {
  3336. case WM_INITDIALOG:
  3337. // Grab the propvariant pointer
  3338. pulSize = (ULONG *) lParam;
  3339. if (NULL == pulSize)
  3340. {
  3341. fRet = FALSE;
  3342. EndDialog(hwndDlg, -1);
  3343. }
  3344. // Set it into the dialog so we can get it back
  3345. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulSize);
  3346. hwndSize = GetDlgItem(hwndDlg, idspnCriteriaSize);
  3347. hwndText = GetDlgItem(hwndDlg, idcCriteriaSize);
  3348. SetIntlFont(hwndText);
  3349. SendMessage(hwndSize, UDM_SETRANGE, 0, MAKELONG( (short) UD_MAXVAL, 0));
  3350. // Set the name of the rule into the edit well
  3351. if (NULL != *pulSize)
  3352. {
  3353. SendMessage(hwndSize, UDM_SETPOS, 0, MAKELONG( (short) *pulSize, 0));
  3354. }
  3355. // We didn't set the focus so return TRUE
  3356. fRet = TRUE;
  3357. break;
  3358. case WM_COMMAND:
  3359. switch (LOWORD(wParam))
  3360. {
  3361. case idcCriteriaSize:
  3362. if (EN_CHANGE == HIWORD(wParam))
  3363. {
  3364. hwndText = (HWND) lParam;
  3365. Assert(NULL != hwndText);
  3366. RuleUtil_FEnDisDialogItem(hwndDlg, IDOK, 0 != Edit_GetTextLength(hwndText));
  3367. }
  3368. break;
  3369. case IDCANCEL:
  3370. EndDialog(hwndDlg, IDCANCEL);
  3371. fRet = TRUE;
  3372. break;
  3373. case IDOK:
  3374. hwndSize = GetDlgItem(hwndDlg, idspnCriteriaSize);
  3375. // Get the name of the rule from the edit well
  3376. ulSize = (INT) SendMessage(hwndSize, UDM_GETPOS, 0, 0);
  3377. if (0 != HIWORD(ulSize))
  3378. {
  3379. fRet = FALSE;
  3380. goto exit;
  3381. }
  3382. *pulSize = LOWORD(ulSize);
  3383. EndDialog(hwndDlg, IDOK);
  3384. fRet = TRUE;
  3385. break;
  3386. }
  3387. break;
  3388. }
  3389. exit:
  3390. return fRet;
  3391. }
  3392. ///////////////////////////////////////////////////////////////////////////////
  3393. //
  3394. // _FSelectLinesDlgProc
  3395. //
  3396. // This is the main dialog proc for selecting the count of lines dialog
  3397. //
  3398. // hwndDlg - handle to the filter manager dialog
  3399. // uMsg - the message to be acted upon
  3400. // wParam - the 'word' parameter for the message
  3401. // lParam - the 'long' parameter for the message
  3402. //
  3403. // Returns: TRUE, if the message was handled
  3404. // FALSE, otherwise
  3405. //
  3406. ///////////////////////////////////////////////////////////////////////////////
  3407. INT_PTR CALLBACK CRuleDescriptUI::_FSelectLinesDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3408. {
  3409. BOOL fRet = FALSE;
  3410. ULONG * pulLines = NULL;
  3411. HWND hwndLines = NULL;
  3412. HWND hwndText = NULL;
  3413. ULONG ulLines = 0;
  3414. pulLines = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  3415. switch (uMsg)
  3416. {
  3417. case WM_INITDIALOG:
  3418. // Grab the propvariant pointer
  3419. pulLines = (ULONG *) lParam;
  3420. if (NULL == pulLines)
  3421. {
  3422. fRet = FALSE;
  3423. EndDialog(hwndDlg, -1);
  3424. }
  3425. // Set it into the dialog so we can get it back
  3426. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulLines);
  3427. hwndLines = GetDlgItem(hwndDlg, idspnCriteriaLines);
  3428. hwndText = GetDlgItem(hwndDlg, idcCriteriaLines);
  3429. SetIntlFont(hwndText);
  3430. SendMessage(hwndLines, UDM_SETRANGE, 0, MAKELONG( (short) UD_MAXVAL, 0));
  3431. // Set the name of the rule into the edit well
  3432. if (NULL != *pulLines)
  3433. {
  3434. SendMessage(hwndLines, UDM_SETPOS, 0, MAKELONG( (short) *pulLines, 0));
  3435. }
  3436. // We didn't set the focus so return TRUE
  3437. fRet = TRUE;
  3438. break;
  3439. case WM_COMMAND:
  3440. switch (LOWORD(wParam))
  3441. {
  3442. case idcCriteriaLines:
  3443. if (EN_CHANGE == HIWORD(wParam))
  3444. {
  3445. hwndText = (HWND) lParam;
  3446. Assert(NULL != hwndText);
  3447. RuleUtil_FEnDisDialogItem(hwndDlg, IDOK, 0 != Edit_GetTextLength(hwndText));
  3448. }
  3449. break;
  3450. case IDCANCEL:
  3451. EndDialog(hwndDlg, IDCANCEL);
  3452. fRet = TRUE;
  3453. break;
  3454. case IDOK:
  3455. hwndLines = GetDlgItem(hwndDlg, idspnCriteriaLines);
  3456. // Get the name of the rule from the edit well
  3457. ulLines = (INT) SendMessage(hwndLines, UDM_GETPOS, 0, 0);
  3458. if (0 != HIWORD(ulLines))
  3459. {
  3460. fRet = FALSE;
  3461. goto exit;
  3462. }
  3463. *pulLines = LOWORD(ulLines);
  3464. EndDialog(hwndDlg, IDOK);
  3465. fRet = TRUE;
  3466. break;
  3467. }
  3468. break;
  3469. }
  3470. exit:
  3471. return fRet;
  3472. }
  3473. ///////////////////////////////////////////////////////////////////////////////
  3474. //
  3475. // _FSelectAgeDlgProc
  3476. //
  3477. // This is the main dialog proc for selecting the count of lines dialog
  3478. //
  3479. // hwndDlg - handle to the filter manager dialog
  3480. // uMsg - the message to be acted upon
  3481. // wParam - the 'word' parameter for the message
  3482. // lParam - the 'long' parameter for the message
  3483. //
  3484. // Returns: TRUE, if the message was handled
  3485. // FALSE, otherwise
  3486. //
  3487. ///////////////////////////////////////////////////////////////////////////////
  3488. INT_PTR CALLBACK CRuleDescriptUI::_FSelectAgeDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3489. {
  3490. BOOL fRet = FALSE;
  3491. ULONG * pulDays = NULL;
  3492. HWND hwndDays = NULL;
  3493. HWND hwndText = NULL;
  3494. ULONG ulDays = 0;
  3495. pulDays = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  3496. switch (uMsg)
  3497. {
  3498. case WM_INITDIALOG:
  3499. // Grab the propvariant pointer
  3500. pulDays = (ULONG *) lParam;
  3501. if (NULL == pulDays)
  3502. {
  3503. fRet = FALSE;
  3504. EndDialog(hwndDlg, -1);
  3505. }
  3506. // Set it into the dialog so we can get it back
  3507. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulDays);
  3508. hwndDays = GetDlgItem(hwndDlg, idspnCriteriaAge);
  3509. hwndText = GetDlgItem(hwndDlg, idcCriteriaAge);
  3510. SetIntlFont(hwndText);
  3511. SendMessage(hwndDays, UDM_SETRANGE, 0, MAKELONG( (short) UD_MAXVAL, 0));
  3512. // Set the name of the rule into the edit well
  3513. if (NULL != *pulDays)
  3514. {
  3515. SendMessage(hwndDays, UDM_SETPOS, 0, MAKELONG( (short) *pulDays, 0));
  3516. }
  3517. // We didn't set the focus so return TRUE
  3518. fRet = TRUE;
  3519. break;
  3520. case WM_COMMAND:
  3521. switch (LOWORD(wParam))
  3522. {
  3523. case idcCriteriaLines:
  3524. if (EN_CHANGE == HIWORD(wParam))
  3525. {
  3526. hwndText = (HWND) lParam;
  3527. Assert(NULL != hwndText);
  3528. RuleUtil_FEnDisDialogItem(hwndDlg, IDOK, 0 != Edit_GetTextLength(hwndText));
  3529. }
  3530. break;
  3531. case IDCANCEL:
  3532. EndDialog(hwndDlg, IDCANCEL);
  3533. fRet = TRUE;
  3534. break;
  3535. case IDOK:
  3536. hwndDays = GetDlgItem(hwndDlg, idspnCriteriaAge);
  3537. // Get the name of the rule from the edit well
  3538. ulDays = (INT) SendMessage(hwndDays, UDM_GETPOS, 0, 0);
  3539. if (0 != HIWORD(ulDays))
  3540. {
  3541. fRet = FALSE;
  3542. goto exit;
  3543. }
  3544. *pulDays = LOWORD(ulDays);
  3545. EndDialog(hwndDlg, IDOK);
  3546. fRet = TRUE;
  3547. break;
  3548. }
  3549. break;
  3550. }
  3551. exit:
  3552. return fRet;
  3553. }
  3554. ///////////////////////////////////////////////////////////////////////////////
  3555. //
  3556. // _FSelectPriorityDlgProc
  3557. //
  3558. // This is the main dialog proc for selecting the priority dialog
  3559. //
  3560. // hwndDlg - handle to the filter manager dialog
  3561. // uMsg - the message to be acted upon
  3562. // wParam - the 'word' parameter for the message
  3563. // lParam - the 'long' parameter for the message
  3564. //
  3565. // Returns: TRUE, if the message was handled
  3566. // FALSE, otherwise
  3567. //
  3568. ///////////////////////////////////////////////////////////////////////////////
  3569. INT_PTR CALLBACK CRuleDescriptUI::_FSelectPriorityDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3570. {
  3571. BOOL fRet = FALSE;
  3572. ULONG * pulPri = NULL;
  3573. ULONG ulPri = 0;
  3574. pulPri = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  3575. switch (uMsg)
  3576. {
  3577. case WM_INITDIALOG:
  3578. // Grab the propvariant pointer
  3579. pulPri = (ULONG *) lParam;
  3580. if (NULL == pulPri)
  3581. {
  3582. fRet = FALSE;
  3583. EndDialog(hwndDlg, -1);
  3584. }
  3585. // Set it into the dialog so we can get it back
  3586. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulPri);
  3587. // Set the default item
  3588. CheckDlgButton(hwndDlg, (CRIT_DATA_LOPRI == *pulPri) ? idcCriteriaLowPri : idcCriteriaHighPri, BST_CHECKED);
  3589. // We didn't set the focus so return TRUE
  3590. fRet = TRUE;
  3591. break;
  3592. case WM_COMMAND:
  3593. switch (LOWORD(wParam))
  3594. {
  3595. case IDCANCEL:
  3596. EndDialog(hwndDlg, IDCANCEL);
  3597. fRet = TRUE;
  3598. break;
  3599. case IDOK:
  3600. if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcCriteriaLowPri))
  3601. {
  3602. ulPri = CRIT_DATA_LOPRI;
  3603. }
  3604. else
  3605. {
  3606. ulPri = CRIT_DATA_HIPRI;
  3607. }
  3608. *pulPri = ulPri;
  3609. EndDialog(hwndDlg, IDOK);
  3610. fRet = TRUE;
  3611. break;
  3612. }
  3613. break;
  3614. }
  3615. return fRet;
  3616. }
  3617. ///////////////////////////////////////////////////////////////////////////////
  3618. //
  3619. // _FSelectSecureDlgProc
  3620. //
  3621. // This is the main dialog proc for selecting the security dialog
  3622. //
  3623. // hwndDlg - handle to the filter manager dialog
  3624. // uMsg - the message to be acted upon
  3625. // wParam - the 'word' parameter for the message
  3626. // lParam - the 'long' parameter for the message
  3627. //
  3628. // Returns: TRUE, if the message was handled
  3629. // FALSE, otherwise
  3630. //
  3631. ///////////////////////////////////////////////////////////////////////////////
  3632. INT_PTR CALLBACK CRuleDescriptUI::_FSelectSecureDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3633. {
  3634. BOOL fRet = FALSE;
  3635. ULONG * pulSec = NULL;
  3636. ULONG ulSec = 0;
  3637. UINT uiId = 0;
  3638. pulSec = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  3639. switch (uMsg)
  3640. {
  3641. case WM_INITDIALOG:
  3642. // Grab the propvariant pointer
  3643. pulSec = (ULONG *) lParam;
  3644. if (NULL == pulSec)
  3645. {
  3646. fRet = FALSE;
  3647. EndDialog(hwndDlg, -1);
  3648. }
  3649. // Set it into the dialog so we can get it back
  3650. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulSec);
  3651. // Set the default item
  3652. if (0 != ((*pulSec) & CRIT_DATA_ENCRYPTSECURE))
  3653. {
  3654. uiId = idcCriteriaEncrypt;
  3655. }
  3656. else
  3657. {
  3658. uiId = idcCriteriaSigned;
  3659. }
  3660. CheckDlgButton(hwndDlg, uiId, BST_CHECKED);
  3661. // We didn't set the focus so return TRUE
  3662. fRet = TRUE;
  3663. break;
  3664. case WM_COMMAND:
  3665. switch (LOWORD(wParam))
  3666. {
  3667. case IDCANCEL:
  3668. EndDialog(hwndDlg, IDCANCEL);
  3669. fRet = TRUE;
  3670. break;
  3671. case IDOK:
  3672. if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcCriteriaSigned))
  3673. {
  3674. ulSec = CRIT_DATA_SIGNEDSECURE;
  3675. }
  3676. else
  3677. {
  3678. ulSec = CRIT_DATA_ENCRYPTSECURE;
  3679. }
  3680. *pulSec = ulSec;
  3681. EndDialog(hwndDlg, IDOK);
  3682. fRet = TRUE;
  3683. break;
  3684. }
  3685. break;
  3686. }
  3687. return fRet;
  3688. }
  3689. ///////////////////////////////////////////////////////////////////////////////
  3690. //
  3691. // _FSelectThreadStateDlgProc
  3692. //
  3693. // This is the main dialog proc for selecting the thread state dialog
  3694. //
  3695. // hwndDlg - handle to the filter manager dialog
  3696. // uMsg - the message to be acted upon
  3697. // wParam - the 'word' parameter for the message
  3698. // lParam - the 'long' parameter for the message
  3699. //
  3700. // Returns: TRUE, if the message was handled
  3701. // FALSE, otherwise
  3702. //
  3703. ///////////////////////////////////////////////////////////////////////////////
  3704. INT_PTR CALLBACK CRuleDescriptUI::_FSelectThreadStateDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3705. {
  3706. BOOL fRet = FALSE;
  3707. ULONG * pulThread = NULL;
  3708. ULONG ulThread = 0;
  3709. UINT uiId = 0;
  3710. pulThread = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  3711. switch (uMsg)
  3712. {
  3713. case WM_INITDIALOG:
  3714. // Grab the propvariant pointer
  3715. pulThread = (ULONG *) lParam;
  3716. if (NULL == pulThread)
  3717. {
  3718. fRet = FALSE;
  3719. EndDialog(hwndDlg, -1);
  3720. }
  3721. // Set it into the dialog so we can get it back
  3722. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulThread);
  3723. // Set the default item
  3724. if (0 != ((*pulThread) & CRIT_DATA_IGNORETHREAD))
  3725. {
  3726. uiId = idcCriteriaIgnoreThread;
  3727. }
  3728. else
  3729. {
  3730. uiId = idcCriteriaWatchThread;
  3731. }
  3732. CheckDlgButton(hwndDlg, uiId, BST_CHECKED);
  3733. // We didn't set the focus so return TRUE
  3734. fRet = TRUE;
  3735. break;
  3736. case WM_COMMAND:
  3737. switch (LOWORD(wParam))
  3738. {
  3739. case IDCANCEL:
  3740. EndDialog(hwndDlg, IDCANCEL);
  3741. fRet = TRUE;
  3742. break;
  3743. case IDOK:
  3744. if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcCriteriaWatchThread))
  3745. {
  3746. ulThread = CRIT_DATA_WATCHTHREAD;
  3747. }
  3748. else
  3749. {
  3750. ulThread = CRIT_DATA_IGNORETHREAD;
  3751. }
  3752. *pulThread = ulThread;
  3753. EndDialog(hwndDlg, IDOK);
  3754. fRet = TRUE;
  3755. break;
  3756. }
  3757. break;
  3758. }
  3759. return fRet;
  3760. }
  3761. ///////////////////////////////////////////////////////////////////////////////
  3762. //
  3763. // _FSelectShowDlgProc
  3764. //
  3765. // This is the main dialog proc for selecting the security dialog
  3766. //
  3767. // hwndDlg - handle to the filter manager dialog
  3768. // uMsg - the message to be acted upon
  3769. // wParam - the 'word' parameter for the message
  3770. // lParam - the 'long' parameter for the message
  3771. //
  3772. // Returns: TRUE, if the message was handled
  3773. // FALSE, otherwise
  3774. //
  3775. ///////////////////////////////////////////////////////////////////////////////
  3776. INT_PTR CALLBACK CRuleDescriptUI::_FSelectShowDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3777. {
  3778. BOOL fRet = FALSE;
  3779. ULONG * pulVal = NULL;
  3780. UINT uiId = 0;
  3781. pulVal = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  3782. switch (uMsg)
  3783. {
  3784. case WM_INITDIALOG:
  3785. // Grab the propvariant pointer
  3786. pulVal = (ULONG *) lParam;
  3787. if (NULL == pulVal)
  3788. {
  3789. fRet = FALSE;
  3790. EndDialog(hwndDlg, -1);
  3791. }
  3792. // Set it into the dialog so we can get it back
  3793. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulVal);
  3794. // Set the default item
  3795. if (ACT_DATA_HIDE == *pulVal)
  3796. {
  3797. uiId = idcCriteriaHide;
  3798. }
  3799. else
  3800. {
  3801. uiId = idcCriteriaShow;
  3802. }
  3803. CheckDlgButton(hwndDlg, uiId, BST_CHECKED);
  3804. // We didn't set the focus so return TRUE
  3805. fRet = TRUE;
  3806. break;
  3807. case WM_COMMAND:
  3808. switch (LOWORD(wParam))
  3809. {
  3810. case IDCANCEL:
  3811. EndDialog(hwndDlg, IDCANCEL);
  3812. fRet = TRUE;
  3813. break;
  3814. case IDOK:
  3815. if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcCriteriaHide))
  3816. {
  3817. *pulVal = ACT_DATA_HIDE;
  3818. }
  3819. else
  3820. {
  3821. *pulVal = ACT_DATA_SHOW;
  3822. }
  3823. EndDialog(hwndDlg, IDOK);
  3824. fRet = TRUE;
  3825. break;
  3826. }
  3827. break;
  3828. }
  3829. return fRet;
  3830. }
  3831. ///////////////////////////////////////////////////////////////////////////////
  3832. //
  3833. // _FSelectShowDlgProc
  3834. //
  3835. // This is the main dialog proc for selecting the security dialog
  3836. //
  3837. // hwndDlg - handle to the filter manager dialog
  3838. // uMsg - the message to be acted upon
  3839. // wParam - the 'word' parameter for the message
  3840. // lParam - the 'long' parameter for the message
  3841. //
  3842. // Returns: TRUE, if the message was handled
  3843. // FALSE, otherwise
  3844. //
  3845. ///////////////////////////////////////////////////////////////////////////////
  3846. INT_PTR CALLBACK CRuleDescriptUI::_FSelectLogicDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3847. {
  3848. BOOL fRet = FALSE;
  3849. CRIT_LOGIC * plogicCrit = NULL;
  3850. UINT uiId = 0;
  3851. plogicCrit = (CRIT_LOGIC *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  3852. switch (uMsg)
  3853. {
  3854. case WM_INITDIALOG:
  3855. // Grab the propvariant pointer
  3856. plogicCrit = (CRIT_LOGIC *) lParam;
  3857. if (NULL == plogicCrit)
  3858. {
  3859. fRet = FALSE;
  3860. EndDialog(hwndDlg, -1);
  3861. }
  3862. // Set it into the dialog so we can get it back
  3863. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) plogicCrit);
  3864. // Set the default item
  3865. if (CRIT_LOGIC_OR == (*plogicCrit))
  3866. {
  3867. uiId = idcCriteriaOr;
  3868. }
  3869. else
  3870. {
  3871. uiId = idcCriteriaAnd;
  3872. }
  3873. CheckDlgButton(hwndDlg, uiId, BST_CHECKED);
  3874. // We didn't set the focus so return TRUE
  3875. fRet = TRUE;
  3876. break;
  3877. case WM_COMMAND:
  3878. switch (LOWORD(wParam))
  3879. {
  3880. case IDCANCEL:
  3881. EndDialog(hwndDlg, IDCANCEL);
  3882. fRet = TRUE;
  3883. break;
  3884. case IDOK:
  3885. if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcCriteriaAnd))
  3886. {
  3887. *plogicCrit = CRIT_LOGIC_AND;
  3888. }
  3889. else
  3890. {
  3891. *plogicCrit = CRIT_LOGIC_OR;
  3892. }
  3893. EndDialog(hwndDlg, IDOK);
  3894. fRet = TRUE;
  3895. break;
  3896. }
  3897. break;
  3898. }
  3899. return fRet;
  3900. }
  3901. ///////////////////////////////////////////////////////////////////////////////
  3902. //
  3903. // _FSelectFlagDlgProc
  3904. //
  3905. // This is the main dialog proc for selecting the security dialog
  3906. //
  3907. // hwndDlg - handle to the filter manager dialog
  3908. // uMsg - the message to be acted upon
  3909. // wParam - the 'word' parameter for the message
  3910. // lParam - the 'long' parameter for the message
  3911. //
  3912. // Returns: TRUE, if the message was handled
  3913. // FALSE, otherwise
  3914. //
  3915. ///////////////////////////////////////////////////////////////////////////////
  3916. INT_PTR CALLBACK CRuleDescriptUI::_FSelectFlagDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3917. {
  3918. BOOL fRet = FALSE;
  3919. ULONG * pulVal = NULL;
  3920. UINT uiId = 0;
  3921. pulVal = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  3922. switch (uMsg)
  3923. {
  3924. case WM_INITDIALOG:
  3925. // Grab the propvariant pointer
  3926. pulVal = (ULONG *) lParam;
  3927. if (NULL == pulVal)
  3928. {
  3929. fRet = FALSE;
  3930. EndDialog(hwndDlg, -1);
  3931. }
  3932. // Set it into the dialog so we can get it back
  3933. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulVal);
  3934. // Set the default item
  3935. if (0 != ((*pulVal) & CRIT_FLAG_INVERT))
  3936. {
  3937. uiId = idcCriteriaNoFlag;
  3938. }
  3939. else
  3940. {
  3941. uiId = idcCriteriaFlag;
  3942. }
  3943. CheckDlgButton(hwndDlg, uiId, BST_CHECKED);
  3944. // We didn't set the focus so return TRUE
  3945. fRet = TRUE;
  3946. break;
  3947. case WM_COMMAND:
  3948. switch (LOWORD(wParam))
  3949. {
  3950. case IDCANCEL:
  3951. EndDialog(hwndDlg, IDCANCEL);
  3952. fRet = TRUE;
  3953. break;
  3954. case IDOK:
  3955. if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcCriteriaNoFlag))
  3956. {
  3957. *pulVal |= CRIT_FLAG_INVERT;
  3958. }
  3959. else
  3960. {
  3961. *pulVal &= ~CRIT_FLAG_INVERT;
  3962. }
  3963. EndDialog(hwndDlg, IDOK);
  3964. fRet = TRUE;
  3965. break;
  3966. }
  3967. break;
  3968. }
  3969. return fRet;
  3970. }
  3971. ///////////////////////////////////////////////////////////////////////////////
  3972. //
  3973. // _FSelectDownloadedDlgProc
  3974. //
  3975. // This is the main dialog proc for selecting the downloaded dialog
  3976. //
  3977. // hwndDlg - handle to the filter manager dialog
  3978. // uMsg - the message to be acted upon
  3979. // wParam - the 'word' parameter for the message
  3980. // lParam - the 'long' parameter for the message
  3981. //
  3982. // Returns: TRUE, if the message was handled
  3983. // FALSE, otherwise
  3984. //
  3985. ///////////////////////////////////////////////////////////////////////////////
  3986. INT_PTR CALLBACK CRuleDescriptUI::_FSelectDownloadedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3987. {
  3988. BOOL fRet = FALSE;
  3989. ULONG * pulVal = NULL;
  3990. UINT uiId = 0;
  3991. pulVal = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  3992. switch (uMsg)
  3993. {
  3994. case WM_INITDIALOG:
  3995. // Grab the propvariant pointer
  3996. pulVal = (ULONG *) lParam;
  3997. if (NULL == pulVal)
  3998. {
  3999. fRet = FALSE;
  4000. EndDialog(hwndDlg, -1);
  4001. }
  4002. // Set it into the dialog so we can get it back
  4003. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulVal);
  4004. // Set the default item
  4005. if (0 != ((*pulVal) & CRIT_FLAG_INVERT))
  4006. {
  4007. uiId = idcCriteriaNotDownloaded;
  4008. }
  4009. else
  4010. {
  4011. uiId = idcCriteriaDownloaded;
  4012. }
  4013. CheckDlgButton(hwndDlg, uiId, BST_CHECKED);
  4014. // We didn't set the focus so return TRUE
  4015. fRet = TRUE;
  4016. break;
  4017. case WM_COMMAND:
  4018. switch (LOWORD(wParam))
  4019. {
  4020. case IDCANCEL:
  4021. EndDialog(hwndDlg, IDCANCEL);
  4022. fRet = TRUE;
  4023. break;
  4024. case IDOK:
  4025. if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcCriteriaNotDownloaded))
  4026. {
  4027. *pulVal |= CRIT_FLAG_INVERT;
  4028. }
  4029. else
  4030. {
  4031. *pulVal &= ~CRIT_FLAG_INVERT;
  4032. }
  4033. EndDialog(hwndDlg, IDOK);
  4034. fRet = TRUE;
  4035. break;
  4036. }
  4037. break;
  4038. }
  4039. return fRet;
  4040. }
  4041. ///////////////////////////////////////////////////////////////////////////////
  4042. //
  4043. // _FSelectReadDlgProc
  4044. //
  4045. // This is the main dialog proc for selecting the read state dialog
  4046. //
  4047. // hwndDlg - handle to the filter manager dialog
  4048. // uMsg - the message to be acted upon
  4049. // wParam - the 'word' parameter for the message
  4050. // lParam - the 'long' parameter for the message
  4051. //
  4052. // Returns: TRUE, if the message was handled
  4053. // FALSE, otherwise
  4054. //
  4055. ///////////////////////////////////////////////////////////////////////////////
  4056. INT_PTR CALLBACK CRuleDescriptUI::_FSelectReadDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  4057. {
  4058. BOOL fRet = FALSE;
  4059. ULONG * pulVal = NULL;
  4060. UINT uiId = 0;
  4061. pulVal = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  4062. switch (uMsg)
  4063. {
  4064. case WM_INITDIALOG:
  4065. // Grab the propvariant pointer
  4066. pulVal = (ULONG *) lParam;
  4067. if (NULL == pulVal)
  4068. {
  4069. fRet = FALSE;
  4070. EndDialog(hwndDlg, -1);
  4071. }
  4072. // Set it into the dialog so we can get it back
  4073. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulVal);
  4074. // Set the default item
  4075. if (0 != ((*pulVal) & CRIT_FLAG_INVERT))
  4076. {
  4077. uiId = idcCriteriaNotRead;
  4078. }
  4079. else
  4080. {
  4081. uiId = idcCriteriaRead;
  4082. }
  4083. CheckDlgButton(hwndDlg, uiId, BST_CHECKED);
  4084. // We didn't set the focus so return TRUE
  4085. fRet = TRUE;
  4086. break;
  4087. case WM_COMMAND:
  4088. switch (LOWORD(wParam))
  4089. {
  4090. case IDCANCEL:
  4091. EndDialog(hwndDlg, IDCANCEL);
  4092. fRet = TRUE;
  4093. break;
  4094. case IDOK:
  4095. if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcCriteriaNotRead))
  4096. {
  4097. *pulVal |= CRIT_FLAG_INVERT;
  4098. }
  4099. else
  4100. {
  4101. *pulVal &= ~CRIT_FLAG_INVERT;
  4102. }
  4103. EndDialog(hwndDlg, IDOK);
  4104. fRet = TRUE;
  4105. break;
  4106. }
  4107. break;
  4108. }
  4109. return fRet;
  4110. }
  4111. ///////////////////////////////////////////////////////////////////////////////
  4112. //
  4113. // _FSelectWatchDlgProc
  4114. //
  4115. // This is the main dialog proc for selecting the thread state dialog
  4116. //
  4117. // hwndDlg - handle to the filter manager dialog
  4118. // uMsg - the message to be acted upon
  4119. // wParam - the 'word' parameter for the message
  4120. // lParam - the 'long' parameter for the message
  4121. //
  4122. // Returns: TRUE, if the message was handled
  4123. // FALSE, otherwise
  4124. //
  4125. ///////////////////////////////////////////////////////////////////////////////
  4126. INT_PTR CALLBACK CRuleDescriptUI::_FSelectWatchDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  4127. {
  4128. BOOL fRet = FALSE;
  4129. ULONG * pulThread = NULL;
  4130. ULONG ulThread = 0;
  4131. UINT uiId = 0;
  4132. pulThread = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  4133. switch (uMsg)
  4134. {
  4135. case WM_INITDIALOG:
  4136. // Grab the propvariant pointer
  4137. pulThread = (ULONG *) lParam;
  4138. if (NULL == pulThread)
  4139. {
  4140. fRet = FALSE;
  4141. EndDialog(hwndDlg, -1);
  4142. }
  4143. // Set it into the dialog so we can get it back
  4144. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulThread);
  4145. // Set the default item
  4146. if (ACT_DATA_IGNORETHREAD == *pulThread)
  4147. {
  4148. uiId = idcActionsIgnoreThread;
  4149. }
  4150. else
  4151. {
  4152. uiId = idcActionsWatchThread;
  4153. }
  4154. CheckDlgButton(hwndDlg, uiId, BST_CHECKED);
  4155. // We didn't set the focus so return TRUE
  4156. fRet = TRUE;
  4157. break;
  4158. case WM_COMMAND:
  4159. switch (LOWORD(wParam))
  4160. {
  4161. case IDCANCEL:
  4162. EndDialog(hwndDlg, IDCANCEL);
  4163. fRet = TRUE;
  4164. break;
  4165. case IDOK:
  4166. if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcActionsWatchThread))
  4167. {
  4168. ulThread = ACT_DATA_WATCHTHREAD;
  4169. }
  4170. else
  4171. {
  4172. ulThread = ACT_DATA_IGNORETHREAD;
  4173. }
  4174. *pulThread = ulThread;
  4175. EndDialog(hwndDlg, IDOK);
  4176. fRet = TRUE;
  4177. break;
  4178. }
  4179. break;
  4180. }
  4181. return fRet;
  4182. }
  4183. // Class definitions
  4184. class CEditPeopleOptionsUI
  4185. {
  4186. private:
  4187. enum
  4188. {
  4189. STATE_UNINIT = 0x00000000,
  4190. STATE_INITIALIZED = 0x00000001,
  4191. STATE_DIRTY = 0x00000002
  4192. };
  4193. private:
  4194. HWND m_hwndOwner;
  4195. DWORD m_dwFlags;
  4196. DWORD m_dwState;
  4197. HWND m_hwndDlg;
  4198. HWND m_hwndList;
  4199. CRIT_ITEM * m_pCritItem;
  4200. public:
  4201. CEditPeopleOptionsUI() : m_hwndOwner(NULL), m_dwFlags(0), m_dwState(STATE_UNINIT),
  4202. m_hwndDlg(NULL), m_hwndList(NULL), m_pCritItem(NULL) {}
  4203. ~CEditPeopleOptionsUI();
  4204. // The main UI methods
  4205. HRESULT HrInit(HWND hwndOwner, DWORD dwFlags);
  4206. HRESULT HrShow(CRIT_ITEM * pCritItem);
  4207. // The Rules Manager dialog function
  4208. static INT_PTR CALLBACK FEditPeopleOptionsDlgProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
  4209. // Message handling functions
  4210. BOOL FOnInitDialog(HWND hwndDlg);
  4211. BOOL FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl);
  4212. BOOL FOnMeasureItem(HWND hwndDlg, UINT uiCtlId, MEASUREITEMSTRUCT * pmis);
  4213. BOOL FOnDrawItem(UINT uiCtlId, DRAWITEMSTRUCT * pdis);
  4214. private:
  4215. BOOL _FLoadCtrls(VOID);
  4216. BOOL _FOnOK(DWORD * pdwFlags);
  4217. BOOL _AddTagLineToList(VOID);
  4218. BOOL _FAddWordToList(DWORD dwFlags, LPCTSTR pszItem);
  4219. };
  4220. typedef struct tagPEOPLEEDITTAG
  4221. {
  4222. CRIT_TYPE type;
  4223. UINT uiNormal;
  4224. UINT uiInverted;
  4225. } PEOPLEEDITTAG, * PPEOPLEEDITTAG;
  4226. static const PEOPLEEDITTAG g_rgpetTagLines[] =
  4227. {
  4228. {CRIT_TYPE_TO, idsCriteriaToEdit, idsCriteriaToNotEdit},
  4229. {CRIT_TYPE_CC, idsCriteriaCCEdit, idsCriteriaCCNotEdit},
  4230. {CRIT_TYPE_FROM, idsCriteriaFromEdit, idsCriteriaFromNotEdit},
  4231. {CRIT_TYPE_TOORCC, idsCriteriaToOrCCEdit, idsCriteriaToOrCCNotEdit},
  4232. {CRIT_TYPE_SUBJECT, idsCriteriaSubjectEdit, idsCriteriaSubjectNotEdit},
  4233. {CRIT_TYPE_BODY, idsCriteriaBodyEdit, idsCriteriaBodyNotEdit}
  4234. };
  4235. static const int g_cpetTagLines = sizeof(g_rgpetTagLines) / sizeof(g_rgpetTagLines[0]);
  4236. class CEditPeopleUI
  4237. {
  4238. private:
  4239. enum
  4240. {
  4241. STATE_UNINIT = 0x00000000,
  4242. STATE_INITIALIZED = 0x00000001,
  4243. STATE_DIRTY = 0x00000002
  4244. };
  4245. private:
  4246. HWND m_hwndOwner;
  4247. DWORD m_dwFlags;
  4248. DWORD m_dwState;
  4249. HWND m_hwndDlg;
  4250. HWND m_hwndPeople;
  4251. HWND m_hwndList;
  4252. ULONG m_cxMaxPixels;
  4253. CRIT_ITEM * m_pCritItem;
  4254. public:
  4255. CEditPeopleUI() : m_hwndOwner(NULL), m_dwFlags(0), m_dwState(STATE_UNINIT),
  4256. m_hwndDlg(NULL), m_hwndPeople(NULL), m_hwndList(NULL),
  4257. m_cxMaxPixels(0), m_pCritItem(NULL) {}
  4258. ~CEditPeopleUI();
  4259. HRESULT HrInit(HWND hwndOwner, DWORD dwFlags);
  4260. HRESULT HrShow(CRIT_ITEM * pCritItem);
  4261. static INT_PTR CALLBACK FEditPeopleDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);
  4262. // Message handling methods
  4263. BOOL FOnInitDialog(HWND hwndDlg);
  4264. BOOL FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl);
  4265. BOOL FOnMeasureItem(HWND hwndDlg, UINT uiCtlId, MEASUREITEMSTRUCT * pmis);
  4266. BOOL FOnDrawItem(UINT uiCtlId, DRAWITEMSTRUCT * pdis);
  4267. private:
  4268. BOOL _FLoadListCtrl(VOID);
  4269. VOID _AddItemToList(VOID);
  4270. VOID _AddItemsFromWAB(VOID);
  4271. VOID _RemoveItemFromList(VOID);
  4272. VOID _ChangeOptions(VOID);
  4273. BOOL _FOnNameChange(VOID);
  4274. BOOL _FOnOK(CRIT_ITEM * pCritItem);
  4275. VOID _UpdateButtons(VOID);
  4276. BOOL _AddTagLineToList(VOID);
  4277. BOOL _FAddWordToList(DWORD dwFlags, LPCTSTR pszItem);
  4278. };
  4279. CEditPeopleOptionsUI::~CEditPeopleOptionsUI()
  4280. {
  4281. }
  4282. ///////////////////////////////////////////////////////////////////////////////
  4283. //
  4284. // HrInit
  4285. //
  4286. // This initializes us with the owner window and any flags we might have
  4287. //
  4288. // hwndOwner - handle to the owner window
  4289. // dwFlags - flags to use for this instance
  4290. // pBlob - the data to edit
  4291. //
  4292. // Returns: S_OK
  4293. //
  4294. ///////////////////////////////////////////////////////////////////////////////
  4295. HRESULT CEditPeopleOptionsUI::HrInit(HWND hwndOwner, DWORD dwFlags)
  4296. {
  4297. HRESULT hr = S_OK;
  4298. CHARFORMAT cf;
  4299. // If we're already initialized, then fail
  4300. if (0 != (m_dwState & STATE_INITIALIZED))
  4301. {
  4302. hr = E_FAIL;
  4303. goto exit;
  4304. }
  4305. // Save off the owner window
  4306. m_hwndOwner = hwndOwner;
  4307. // Save off the flags
  4308. m_dwFlags = dwFlags;
  4309. // We're done
  4310. m_dwState |= STATE_INITIALIZED;
  4311. // Set the return value
  4312. hr = S_OK;
  4313. exit:
  4314. return hr;
  4315. }
  4316. ///////////////////////////////////////////////////////////////////////////////
  4317. //
  4318. // HrShow
  4319. //
  4320. // This initializes us with the owner window and any flags we might have
  4321. //
  4322. // hwndOwner - handle to the owner window
  4323. // dwFlags - flags to use for this instance
  4324. // pBlob - the data to edit
  4325. //
  4326. // Returns: S_OK
  4327. //
  4328. ///////////////////////////////////////////////////////////////////////////////
  4329. HRESULT CEditPeopleOptionsUI::HrShow(CRIT_ITEM * pCritItem)
  4330. {
  4331. HRESULT hr = S_OK;
  4332. int iRet = 0;
  4333. UINT uiID = 0;
  4334. // Check incoming params
  4335. if (NULL == pCritItem)
  4336. {
  4337. hr = E_INVALIDARG;
  4338. goto exit;
  4339. }
  4340. if (0 == (m_dwState & STATE_INITIALIZED))
  4341. {
  4342. hr = E_UNEXPECTED;
  4343. goto exit;
  4344. }
  4345. // Save off the data
  4346. m_pCritItem = pCritItem;
  4347. // Figure out which dialog template to use
  4348. if (0 != (m_dwFlags & PUI_WORDS))
  4349. {
  4350. uiID = iddCriteriaWordsOptions;
  4351. }
  4352. else
  4353. {
  4354. uiID = iddCriteriaPeopleOptions;
  4355. }
  4356. // Bring up the editor dialog
  4357. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(uiID),
  4358. m_hwndOwner, CEditPeopleOptionsUI::FEditPeopleOptionsDlgProc,
  4359. (LPARAM) this);
  4360. if (-1 == iRet)
  4361. {
  4362. hr = E_FAIL;
  4363. goto exit;
  4364. }
  4365. // Set the proper return code
  4366. hr = (IDOK == iRet) ? S_OK : S_FALSE;
  4367. exit:
  4368. return hr;
  4369. }
  4370. INT_PTR CALLBACK CEditPeopleOptionsUI::FEditPeopleOptionsDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  4371. {
  4372. BOOL fRet = FALSE;
  4373. CEditPeopleOptionsUI * pOptionsUI = NULL;
  4374. pOptionsUI = (CEditPeopleOptionsUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  4375. switch (uiMsg)
  4376. {
  4377. case WM_INITDIALOG:
  4378. // Grab the UI object pointer
  4379. pOptionsUI = (CEditPeopleOptionsUI *) lParam;
  4380. // Set it into the dialog so we can get it back
  4381. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pOptionsUI);
  4382. if (FALSE == pOptionsUI->FOnInitDialog(hwndDlg))
  4383. {
  4384. EndDialog(hwndDlg, -1);
  4385. fRet = TRUE;
  4386. goto exit;
  4387. }
  4388. // We set the focus
  4389. fRet = TRUE;
  4390. break;
  4391. case WM_COMMAND:
  4392. fRet = pOptionsUI->FOnCommand((UINT) HIWORD(wParam), (INT) LOWORD(wParam), (HWND) lParam);
  4393. break;
  4394. case WM_MEASUREITEM:
  4395. fRet = pOptionsUI->FOnMeasureItem(hwndDlg, (UINT) wParam, (MEASUREITEMSTRUCT *) lParam);
  4396. break;
  4397. case WM_DRAWITEM:
  4398. fRet = pOptionsUI->FOnDrawItem((UINT) wParam, (DRAWITEMSTRUCT *) lParam);
  4399. break;
  4400. }
  4401. exit:
  4402. return fRet;
  4403. }
  4404. ///////////////////////////////////////////////////////////////////////////////
  4405. //
  4406. // FOnInitDialog
  4407. //
  4408. // This handles the WM_INITDIALOG message for the edit people UI dialog
  4409. //
  4410. // hwndDlg - the handle to the dialog window
  4411. //
  4412. // Returns: TRUE, if it was successfully initialized
  4413. // FALSE, otherwise
  4414. //
  4415. ///////////////////////////////////////////////////////////////////////////////
  4416. BOOL CEditPeopleOptionsUI::FOnInitDialog(HWND hwndDlg)
  4417. {
  4418. BOOL fRet = FALSE;
  4419. HRESULT hr = S_OK;
  4420. // Check incoming params
  4421. if (NULL == hwndDlg)
  4422. {
  4423. fRet = FALSE;
  4424. goto exit;
  4425. }
  4426. // Save off the dialog window handle
  4427. m_hwndDlg = hwndDlg;
  4428. // Set the default font onto the dialog
  4429. SetIntlFont(m_hwndDlg);
  4430. // Save off some of the controls
  4431. m_hwndList = GetDlgItem(hwndDlg, idcCriteriaList);
  4432. if (NULL == m_hwndList)
  4433. {
  4434. fRet = FALSE;
  4435. goto exit;
  4436. }
  4437. // Load the list view
  4438. fRet = _FLoadCtrls();
  4439. if (FALSE == fRet)
  4440. {
  4441. goto exit;
  4442. }
  4443. // Everything's AOK
  4444. fRet = TRUE;
  4445. exit:
  4446. return fRet;
  4447. }
  4448. ///////////////////////////////////////////////////////////////////////////////
  4449. //
  4450. // FOnCommand
  4451. //
  4452. // This handles the WM_COMMAND message for the view manager UI dialog
  4453. //
  4454. // Returns: TRUE, if it was successfully handled
  4455. // FALSE, otherwise
  4456. //
  4457. ///////////////////////////////////////////////////////////////////////////////
  4458. BOOL CEditPeopleOptionsUI::FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl)
  4459. {
  4460. BOOL fRet = FALSE;
  4461. INT iSelected = 0;
  4462. switch (iCtl)
  4463. {
  4464. case IDOK:
  4465. if (FALSE != _FOnOK(&(m_pCritItem->dwFlags)))
  4466. {
  4467. EndDialog(m_hwndDlg, IDOK);
  4468. fRet = TRUE;
  4469. }
  4470. break;
  4471. case IDCANCEL:
  4472. EndDialog(m_hwndDlg, IDCANCEL);
  4473. fRet = TRUE;
  4474. break;
  4475. case idcCriteriaNotCont:
  4476. case idcCriteriaContains:
  4477. case idcCriteriaAnd:
  4478. case idcCriteriaOr:
  4479. if (BN_CLICKED == uiNotify)
  4480. {
  4481. // Make sure the list is redrawn
  4482. InvalidateRect(m_hwndList, NULL, TRUE);
  4483. }
  4484. break;
  4485. }
  4486. return fRet;
  4487. }
  4488. ///////////////////////////////////////////////////////////////////////////////
  4489. //
  4490. // FOnMeasureItem
  4491. //
  4492. // This handles the WM_MEASUREITEM message for the view manager UI dialog
  4493. //
  4494. // Returns: TRUE, if it was successfully handled
  4495. // FALSE, otherwise
  4496. //
  4497. ///////////////////////////////////////////////////////////////////////////////
  4498. BOOL CEditPeopleOptionsUI::FOnMeasureItem(HWND hwndDlg, UINT uiCtlId, MEASUREITEMSTRUCT * pmis)
  4499. {
  4500. BOOL fRet = FALSE;
  4501. HWND hwndList = NULL;
  4502. HDC hdcList = NULL;
  4503. TEXTMETRIC tm = {0};
  4504. // Get the window handle
  4505. hwndList = GetDlgItem(hwndDlg, uiCtlId);
  4506. if (NULL == hwndList)
  4507. {
  4508. fRet = FALSE;
  4509. goto exit;
  4510. }
  4511. // Get the device context
  4512. hdcList = GetDC(hwndList);
  4513. if (NULL == hdcList)
  4514. {
  4515. fRet = FALSE;
  4516. goto exit;
  4517. }
  4518. // Get the text metrics for the device context
  4519. GetTextMetrics(hdcList, &tm);
  4520. // Set the item height
  4521. pmis->itemHeight = tm.tmHeight;
  4522. fRet = TRUE;
  4523. exit:
  4524. if (NULL != hdcList)
  4525. {
  4526. ReleaseDC(hwndList, hdcList);
  4527. }
  4528. return fRet;
  4529. }
  4530. ///////////////////////////////////////////////////////////////////////////////
  4531. //
  4532. // FOnDrawItem
  4533. //
  4534. // This handles the WM_DRAWITEM message for the people editor UI dialog
  4535. //
  4536. // Returns: TRUE, if it was successfully handled
  4537. // FALSE, otherwise
  4538. //
  4539. ///////////////////////////////////////////////////////////////////////////////
  4540. BOOL CEditPeopleOptionsUI::FOnDrawItem(UINT uiCtlId, DRAWITEMSTRUCT * pdis)
  4541. {
  4542. BOOL fRet = FALSE;
  4543. DWORD dwFlags = 0;
  4544. INT cchText = 0;
  4545. LPTSTR pszText = NULL;
  4546. LPTSTR pszString = NULL;
  4547. UINT uiID = 0;
  4548. TCHAR rgchRes[CCHMAX_STRINGRES];
  4549. COLORREF crfBack = NULL;
  4550. COLORREF crfText = NULL;
  4551. ULONG ulIndex = 0;
  4552. LPTSTR pszPrint = NULL;
  4553. // Make sure this is the correct control
  4554. if (ODT_LISTBOX != pdis->CtlType)
  4555. {
  4556. fRet = FALSE;
  4557. goto exit;
  4558. }
  4559. // Get the flags from the dialog
  4560. if (FALSE == _FOnOK(&dwFlags))
  4561. {
  4562. fRet = FALSE;
  4563. goto exit;
  4564. }
  4565. // Nothing else to do if it's the first item
  4566. if (0 == pdis->itemID)
  4567. {
  4568. for (ulIndex = 0; ulIndex < g_cpetTagLines; ulIndex++)
  4569. {
  4570. if (g_rgpetTagLines[ulIndex].type == m_pCritItem->type)
  4571. {
  4572. if (0 != (dwFlags & CRIT_FLAG_INVERT))
  4573. {
  4574. uiID = g_rgpetTagLines[ulIndex].uiInverted;
  4575. }
  4576. else
  4577. {
  4578. uiID = g_rgpetTagLines[ulIndex].uiNormal;
  4579. }
  4580. break;
  4581. }
  4582. }
  4583. // Did we find anything?
  4584. if (ulIndex >= g_cpetTagLines)
  4585. {
  4586. fRet = FALSE;
  4587. goto exit;
  4588. }
  4589. // Load the item template
  4590. if (NULL == AthLoadString(uiID, rgchRes, sizeof(rgchRes)))
  4591. {
  4592. fRet = FALSE;
  4593. goto exit;
  4594. }
  4595. pszPrint = rgchRes;
  4596. }
  4597. else
  4598. {
  4599. // Get the size of the string for the item
  4600. cchText = (INT) SendMessage(m_hwndList, LB_GETTEXTLEN, (WPARAM) (pdis->itemID), (LPARAM) 0);
  4601. if (LB_ERR == cchText)
  4602. {
  4603. fRet = FALSE;
  4604. goto exit;
  4605. }
  4606. // Allocate enough space to hold the the string for the item
  4607. if (FAILED(HrAlloc((VOID **) &pszText, sizeof(*pszText) * (cchText + 1))))
  4608. {
  4609. fRet = FALSE;
  4610. goto exit;
  4611. }
  4612. // Get the string for the item
  4613. cchText = (INT) SendMessage(m_hwndList, LB_GETTEXT, (WPARAM) (pdis->itemID), (LPARAM) pszText);
  4614. if (LB_ERR == cchText)
  4615. {
  4616. fRet = FALSE;
  4617. goto exit;
  4618. }
  4619. // Figure out which string template to use
  4620. if (1 == pdis->itemID)
  4621. {
  4622. uiID = idsCriteriaEditFirst;
  4623. }
  4624. else
  4625. {
  4626. if (0 != (dwFlags & CRIT_FLAG_MULTIPLEAND))
  4627. {
  4628. uiID = idsCriteriaEditAnd;
  4629. }
  4630. else
  4631. {
  4632. uiID = idsCriteriaEditOr;
  4633. }
  4634. }
  4635. // Load the proper string template for the item
  4636. if (NULL == AthLoadString(uiID, rgchRes, sizeof(rgchRes)))
  4637. {
  4638. fRet = FALSE;
  4639. goto exit;
  4640. }
  4641. // Allocate enough space to hold the final string
  4642. DWORD cchSize = (cchText + CCHMAX_STRINGRES + 1);
  4643. if (FAILED(HrAlloc((VOID **) &pszString, sizeof(*pszString) * cchSize)))
  4644. {
  4645. fRet = FALSE;
  4646. goto exit;
  4647. }
  4648. // Create the final string
  4649. wnsprintf(pszString, cchSize, rgchRes, pszText);
  4650. pszPrint = pszString;
  4651. }
  4652. // Determine Colors
  4653. crfBack = SetBkColor(pdis->hDC, GetSysColor(COLOR_WINDOW));
  4654. crfText = SetTextColor(pdis->hDC, GetSysColor(COLOR_WINDOWTEXT));
  4655. // Clear the item
  4656. ExtTextOut(pdis->hDC, pdis->rcItem.left, pdis->rcItem.top, ETO_OPAQUE, &(pdis->rcItem), NULL, 0, NULL);
  4657. // Draw the new item
  4658. DrawTextEx(pdis->hDC, pszPrint, lstrlen(pszPrint), &(pdis->rcItem), DT_BOTTOM | DT_NOPREFIX | DT_SINGLELINE, NULL);
  4659. if (pdis->itemState & ODS_FOCUS)
  4660. {
  4661. DrawFocusRect(pdis->hDC, &(pdis->rcItem));
  4662. }
  4663. // Reset Text Colors
  4664. SetTextColor (pdis->hDC, crfText);
  4665. SetBkColor (pdis->hDC, crfBack);
  4666. // Set return value
  4667. fRet = TRUE;
  4668. exit:
  4669. SafeMemFree(pszString);
  4670. SafeMemFree(pszText);
  4671. return fRet;
  4672. }
  4673. ///////////////////////////////////////////////////////////////////////////////
  4674. //
  4675. // _FLoadListCtrl
  4676. //
  4677. // This loads the list view with the current Mail rules
  4678. //
  4679. // Returns: TRUE, if it was successfully loaded
  4680. // FALSE, otherwise
  4681. //
  4682. ///////////////////////////////////////////////////////////////////////////////
  4683. BOOL CEditPeopleOptionsUI::_FLoadCtrls(VOID)
  4684. {
  4685. BOOL fRet = FALSE;
  4686. UINT uiID = 0;
  4687. LPTSTR pszWalk = NULL;
  4688. Assert(NULL != m_hwndList);
  4689. // Set the contains option
  4690. if (0 != (m_pCritItem->dwFlags & CRIT_FLAG_INVERT))
  4691. {
  4692. uiID = idcCriteriaNotCont;
  4693. }
  4694. else
  4695. {
  4696. uiID = idcCriteriaContains;
  4697. }
  4698. CheckRadioButton(m_hwndDlg, idcCriteriaContains, idcCriteriaNotCont, uiID);
  4699. // Set the logic option
  4700. if (0 != (m_pCritItem->dwFlags & CRIT_FLAG_MULTIPLEAND))
  4701. {
  4702. uiID = idcCriteriaAnd;
  4703. }
  4704. else
  4705. {
  4706. uiID = idcCriteriaOr;
  4707. }
  4708. CheckRadioButton(m_hwndDlg, idcCriteriaAnd, idcCriteriaOr, uiID);
  4709. // Remove all the items from the list control
  4710. SendMessage(m_hwndList, LB_RESETCONTENT, (WPARAM) 0, (LPARAM) 0);
  4711. // Add the tag line to the top of the list
  4712. _AddTagLineToList();
  4713. // If we have some items, let's add them to the list
  4714. if (0 != m_pCritItem->propvar.blob.cbSize)
  4715. {
  4716. // Add each item into the list
  4717. for (pszWalk = (LPSTR) (m_pCritItem->propvar.blob.pBlobData);
  4718. '\0' != pszWalk[0]; pszWalk += lstrlen(pszWalk) + 1)
  4719. {
  4720. if (FALSE == _FAddWordToList(0, pszWalk))
  4721. {
  4722. fRet = FALSE;
  4723. goto exit;
  4724. }
  4725. }
  4726. }
  4727. // If we don't have at least two names in the list
  4728. if (3 > SendMessage(m_hwndList, LB_GETCOUNT, (WPARAM) 0, (LPARAM) 0))
  4729. {
  4730. // Disable the And/Or buttons
  4731. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcCriteriaAnd, FALSE);
  4732. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcCriteriaOr, FALSE);
  4733. }
  4734. fRet = TRUE;
  4735. exit:
  4736. return fRet;
  4737. }
  4738. ///////////////////////////////////////////////////////////////////////////////
  4739. //
  4740. // _FOnOK
  4741. //
  4742. // This handles the user typing into the name field
  4743. //
  4744. // Returns: TRUE, we handled the edit message
  4745. // FALSE, otherwise
  4746. //
  4747. ///////////////////////////////////////////////////////////////////////////////
  4748. BOOL CEditPeopleOptionsUI::_FOnOK(DWORD * pdwFlags)
  4749. {
  4750. BOOL fRet = FALSE;
  4751. Assert(NULL != m_hwndList);
  4752. // Get the contains option
  4753. if (BST_CHECKED == IsDlgButtonChecked(m_hwndDlg, idcCriteriaContains))
  4754. {
  4755. *pdwFlags &= ~CRIT_FLAG_INVERT;
  4756. }
  4757. else
  4758. {
  4759. *pdwFlags |= CRIT_FLAG_INVERT;
  4760. }
  4761. // Get the logic option
  4762. if (BST_CHECKED == IsDlgButtonChecked(m_hwndDlg, idcCriteriaAnd))
  4763. {
  4764. *pdwFlags |= CRIT_FLAG_MULTIPLEAND;
  4765. }
  4766. else
  4767. {
  4768. *pdwFlags &= ~CRIT_FLAG_MULTIPLEAND;
  4769. }
  4770. // Set the return value
  4771. fRet = TRUE;
  4772. return fRet;
  4773. }
  4774. ///////////////////////////////////////////////////////////////////////////////
  4775. //
  4776. // _AddTagLineToList
  4777. //
  4778. // This enables or disables the buttons in the people editor UI dialog
  4779. // depending on what is selected.
  4780. //
  4781. // iSelected - the item that was selected,
  4782. // -1 means that nothing was selected
  4783. //
  4784. // Returns: NONE
  4785. //
  4786. ///////////////////////////////////////////////////////////////////////////////
  4787. BOOL CEditPeopleOptionsUI::_AddTagLineToList(VOID)
  4788. {
  4789. BOOL fRet = FALSE;
  4790. Assert(NULL != m_hwndList);
  4791. fRet = _FAddWordToList(0, " ");
  4792. if (FALSE == fRet)
  4793. {
  4794. goto exit;
  4795. }
  4796. // Set the proper return value
  4797. fRet = TRUE;
  4798. exit:
  4799. return fRet;
  4800. }
  4801. ///////////////////////////////////////////////////////////////////////////////
  4802. //
  4803. // _FAddWordToList
  4804. //
  4805. // This enables or disables the buttons in the people editor UI dialog
  4806. // depending on what is selected.
  4807. //
  4808. // iSelected - the item that was selected,
  4809. // -1 means that nothing was selected
  4810. //
  4811. // Returns: NONE
  4812. //
  4813. ///////////////////////////////////////////////////////////////////////////////
  4814. BOOL CEditPeopleOptionsUI::_FAddWordToList(DWORD dwFlags, LPCTSTR pszItem)
  4815. {
  4816. BOOL fRet = FALSE;
  4817. int cItems = 0;
  4818. INT iRet = 0;
  4819. Assert(NULL != m_hwndList);
  4820. // Is there anything to do?
  4821. if ((NULL == pszItem) || ('\0' == pszItem[0]))
  4822. {
  4823. fRet = FALSE;
  4824. goto exit;
  4825. }
  4826. // Get the number of items in the list
  4827. cItems = (INT) SendMessage(m_hwndList, LB_GETCOUNT, (WPARAM) 0, (LPARAM) 0);
  4828. if (LB_ERR == cItems)
  4829. {
  4830. fRet = FALSE;
  4831. goto exit;
  4832. }
  4833. // Set the data into the list
  4834. iRet = (INT) SendMessage(m_hwndList, LB_ADDSTRING, (WPARAM) cItems, (LPARAM) pszItem);
  4835. if ((LB_ERR == iRet) || (LB_ERRSPACE == iRet))
  4836. {
  4837. fRet = FALSE;
  4838. goto exit;
  4839. }
  4840. // Set the proper return value
  4841. fRet = TRUE;
  4842. exit:
  4843. return fRet;
  4844. }
  4845. CEditPeopleUI::~CEditPeopleUI()
  4846. {
  4847. }
  4848. ///////////////////////////////////////////////////////////////////////////////
  4849. //
  4850. // HrInit
  4851. //
  4852. // This initializes us with the owner window and any flags we might have
  4853. //
  4854. // hwndOwner - handle to the owner window
  4855. // dwFlags - flags to use for this instance
  4856. // pBlob - the data to edit
  4857. //
  4858. // Returns: S_OK
  4859. //
  4860. ///////////////////////////////////////////////////////////////////////////////
  4861. HRESULT CEditPeopleUI::HrInit(HWND hwndOwner, DWORD dwFlags)
  4862. {
  4863. HRESULT hr = S_OK;
  4864. CHARFORMAT cf;
  4865. // If we're already initialized, then fail
  4866. if (0 != (m_dwState & STATE_INITIALIZED))
  4867. {
  4868. hr = E_FAIL;
  4869. goto exit;
  4870. }
  4871. // Save off the owner window
  4872. m_hwndOwner = hwndOwner;
  4873. // Save off the flags
  4874. m_dwFlags = dwFlags;
  4875. // We're done
  4876. m_dwState |= STATE_INITIALIZED;
  4877. // Set the return value
  4878. hr = S_OK;
  4879. exit:
  4880. return hr;
  4881. }
  4882. ///////////////////////////////////////////////////////////////////////////////
  4883. //
  4884. // HrInit
  4885. //
  4886. // This initializes us with the owner window and any flags we might have
  4887. //
  4888. // hwndOwner - handle to the owner window
  4889. // dwFlags - flags to use for this instance
  4890. // pBlob - the data to edit
  4891. //
  4892. // Returns: S_OK
  4893. //
  4894. ///////////////////////////////////////////////////////////////////////////////
  4895. HRESULT CEditPeopleUI::HrShow(CRIT_ITEM * pCritItem)
  4896. {
  4897. HRESULT hr = S_OK;
  4898. int iRet = 0;
  4899. UINT uiID = 0;
  4900. // Check incoming params
  4901. if (NULL == pCritItem)
  4902. {
  4903. hr = E_INVALIDARG;
  4904. goto exit;
  4905. }
  4906. if (0 == (m_dwState & STATE_INITIALIZED))
  4907. {
  4908. hr = E_UNEXPECTED;
  4909. goto exit;
  4910. }
  4911. // Save off the data
  4912. m_pCritItem = pCritItem;
  4913. // Figure out which dialog template to use
  4914. if (0 != (m_dwFlags & PUI_WORDS))
  4915. {
  4916. uiID = iddCriteriaWords;
  4917. }
  4918. else
  4919. {
  4920. uiID = iddCriteriaPeople;
  4921. }
  4922. // Bring up the editor dialog
  4923. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(uiID),
  4924. m_hwndOwner, CEditPeopleUI::FEditPeopleDlgProc,
  4925. (LPARAM) this);
  4926. if (-1 == iRet)
  4927. {
  4928. hr = E_FAIL;
  4929. goto exit;
  4930. }
  4931. // Set the proper return code
  4932. hr = (IDOK == iRet) ? S_OK : S_FALSE;
  4933. exit:
  4934. return hr;
  4935. }
  4936. INT_PTR CALLBACK CEditPeopleUI::FEditPeopleDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  4937. {
  4938. BOOL fRet = FALSE;
  4939. CEditPeopleUI * pPeopleUI = NULL;
  4940. pPeopleUI = (CEditPeopleUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  4941. switch (uiMsg)
  4942. {
  4943. case WM_INITDIALOG:
  4944. // Grab the UI object pointer
  4945. pPeopleUI = (CEditPeopleUI *) lParam;
  4946. // Set it into the dialog so we can get it back
  4947. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pPeopleUI);
  4948. if (FALSE == pPeopleUI->FOnInitDialog(hwndDlg))
  4949. {
  4950. EndDialog(hwndDlg, -1);
  4951. fRet = TRUE;
  4952. goto exit;
  4953. }
  4954. // We set the focus
  4955. fRet = TRUE;
  4956. break;
  4957. case WM_COMMAND:
  4958. fRet = pPeopleUI->FOnCommand((UINT) HIWORD(wParam), (INT) LOWORD(wParam), (HWND) lParam);
  4959. break;
  4960. case WM_MEASUREITEM:
  4961. fRet = pPeopleUI->FOnMeasureItem(hwndDlg, (UINT) wParam, (MEASUREITEMSTRUCT *) lParam);
  4962. break;
  4963. case WM_DRAWITEM:
  4964. fRet = pPeopleUI->FOnDrawItem((UINT) wParam, (DRAWITEMSTRUCT *) lParam);
  4965. break;
  4966. }
  4967. exit:
  4968. return fRet;
  4969. }
  4970. ///////////////////////////////////////////////////////////////////////////////
  4971. //
  4972. // FOnInitDialog
  4973. //
  4974. // This handles the WM_INITDIALOG message for the edit people UI dialog
  4975. //
  4976. // hwndDlg - the handle to the dialog window
  4977. //
  4978. // Returns: TRUE, if it was successfully initialized
  4979. // FALSE, otherwise
  4980. //
  4981. ///////////////////////////////////////////////////////////////////////////////
  4982. BOOL CEditPeopleUI::FOnInitDialog(HWND hwndDlg)
  4983. {
  4984. BOOL fRet = FALSE;
  4985. HRESULT hr = S_OK;
  4986. // Check incoming params
  4987. if (NULL == hwndDlg)
  4988. {
  4989. fRet = FALSE;
  4990. goto exit;
  4991. }
  4992. // Save off the dialog window handle
  4993. m_hwndDlg = hwndDlg;
  4994. // Set the default font onto the dialog
  4995. SetIntlFont(m_hwndDlg);
  4996. // Save off some of the controls
  4997. m_hwndList = GetDlgItem(hwndDlg, idcCriteriaList);
  4998. m_hwndPeople = GetDlgItem(hwndDlg, idcCriteriaEdit);
  4999. if ((NULL == m_hwndList) || (NULL == m_hwndPeople))
  5000. {
  5001. fRet = FALSE;
  5002. goto exit;
  5003. }
  5004. // Load the list view
  5005. fRet = _FLoadListCtrl();
  5006. if (FALSE == fRet)
  5007. {
  5008. goto exit;
  5009. }
  5010. // Everything's AOK
  5011. fRet = TRUE;
  5012. exit:
  5013. return fRet;
  5014. }
  5015. ///////////////////////////////////////////////////////////////////////////////
  5016. //
  5017. // FOnCommand
  5018. //
  5019. // This handles the WM_COMMAND message for the view manager UI dialog
  5020. //
  5021. // Returns: TRUE, if it was successfully handled
  5022. // FALSE, otherwise
  5023. //
  5024. ///////////////////////////////////////////////////////////////////////////////
  5025. BOOL CEditPeopleUI::FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl)
  5026. {
  5027. BOOL fRet = FALSE;
  5028. INT iSelected = 0;
  5029. switch (iCtl)
  5030. {
  5031. case IDOK:
  5032. if (FALSE != _FOnOK(m_pCritItem))
  5033. {
  5034. EndDialog(m_hwndDlg, IDOK);
  5035. fRet = TRUE;
  5036. }
  5037. break;
  5038. case IDCANCEL:
  5039. EndDialog(m_hwndDlg, IDCANCEL);
  5040. fRet = TRUE;
  5041. break;
  5042. case idcCriteriaEdit:
  5043. if (EN_CHANGE == uiNotify)
  5044. {
  5045. _FOnNameChange();
  5046. }
  5047. fRet = FALSE;
  5048. break;
  5049. case idcCriteriaAdd:
  5050. _AddItemToList();
  5051. break;
  5052. case idcCriteriaAddrBook:
  5053. _AddItemsFromWAB();
  5054. break;
  5055. case idcCriteriaRemove:
  5056. _RemoveItemFromList();
  5057. break;
  5058. case idcCriteriaOptions:
  5059. _ChangeOptions();
  5060. break;
  5061. case idcCriteriaList:
  5062. if (LBN_SELCHANGE == uiNotify)
  5063. {
  5064. // Update the buttons
  5065. _UpdateButtons();
  5066. }
  5067. break;
  5068. }
  5069. return fRet;
  5070. }
  5071. ///////////////////////////////////////////////////////////////////////////////
  5072. //
  5073. // FOnMeasureItem
  5074. //
  5075. // This handles the WM_MEASUREITEM message for the view manager UI dialog
  5076. //
  5077. // Returns: TRUE, if it was successfully handled
  5078. // FALSE, otherwise
  5079. //
  5080. ///////////////////////////////////////////////////////////////////////////////
  5081. BOOL CEditPeopleUI::FOnMeasureItem(HWND hwndDlg, UINT uiCtlId, MEASUREITEMSTRUCT * pmis)
  5082. {
  5083. BOOL fRet = FALSE;
  5084. HWND hwndList = NULL;
  5085. HDC hdcList = NULL;
  5086. TEXTMETRIC tm = {0};
  5087. // Get the window handle
  5088. hwndList = GetDlgItem(hwndDlg, uiCtlId);
  5089. if (NULL == hwndList)
  5090. {
  5091. fRet = FALSE;
  5092. goto exit;
  5093. }
  5094. // Get the device context
  5095. hdcList = GetDC(hwndList);
  5096. if (NULL == hdcList)
  5097. {
  5098. fRet = FALSE;
  5099. goto exit;
  5100. }
  5101. // Get the text metrics for the device context
  5102. GetTextMetrics(hdcList, &tm);
  5103. // Set the item height
  5104. pmis->itemHeight = tm.tmHeight;
  5105. fRet = TRUE;
  5106. exit:
  5107. if (NULL != hdcList)
  5108. {
  5109. ReleaseDC(hwndList, hdcList);
  5110. }
  5111. return fRet;
  5112. }
  5113. ///////////////////////////////////////////////////////////////////////////////
  5114. //
  5115. // FOnDrawItem
  5116. //
  5117. // This handles the WM_DRAWITEM message for the people editor UI dialog
  5118. //
  5119. // Returns: TRUE, if it was successfully handled
  5120. // FALSE, otherwise
  5121. //
  5122. ///////////////////////////////////////////////////////////////////////////////
  5123. BOOL CEditPeopleUI::FOnDrawItem(UINT uiCtlId, DRAWITEMSTRUCT * pdis)
  5124. {
  5125. BOOL fRet = FALSE;
  5126. INT cchText = 0;
  5127. LPTSTR pszText = NULL;
  5128. LPTSTR pszString = NULL;
  5129. UINT uiID = 0;
  5130. TCHAR rgchRes[CCHMAX_STRINGRES];
  5131. COLORREF crfBack = NULL;
  5132. COLORREF crfText = NULL;
  5133. ULONG ulIndex = 0;
  5134. LPTSTR pszPrint = NULL;
  5135. // Make sure this is the correct control
  5136. if (ODT_LISTBOX != pdis->CtlType)
  5137. {
  5138. fRet = FALSE;
  5139. goto exit;
  5140. }
  5141. // Nothing else to do if it's the first item
  5142. if (0 == pdis->itemID)
  5143. {
  5144. for (ulIndex = 0; ulIndex < g_cpetTagLines; ulIndex++)
  5145. {
  5146. if (g_rgpetTagLines[ulIndex].type == m_pCritItem->type)
  5147. {
  5148. if (0 != (m_pCritItem->dwFlags & CRIT_FLAG_INVERT))
  5149. {
  5150. uiID = g_rgpetTagLines[ulIndex].uiInverted;
  5151. }
  5152. else
  5153. {
  5154. uiID = g_rgpetTagLines[ulIndex].uiNormal;
  5155. }
  5156. break;
  5157. }
  5158. }
  5159. // Did we find anything?
  5160. if (ulIndex >= g_cpetTagLines)
  5161. {
  5162. fRet = FALSE;
  5163. goto exit;
  5164. }
  5165. // Load the item template
  5166. if (NULL == AthLoadString(uiID, rgchRes, sizeof(rgchRes)))
  5167. {
  5168. fRet = FALSE;
  5169. goto exit;
  5170. }
  5171. pszPrint = rgchRes;
  5172. }
  5173. else
  5174. {
  5175. // Get the size of the string for the item
  5176. cchText = (INT) SendMessage(m_hwndList, LB_GETTEXTLEN, (WPARAM) (pdis->itemID), (LPARAM) 0);
  5177. if (LB_ERR == cchText)
  5178. {
  5179. fRet = FALSE;
  5180. goto exit;
  5181. }
  5182. // Allocate enough space to hold the the string for the item
  5183. if (FAILED(HrAlloc((VOID **) &pszText, sizeof(*pszText) * (cchText + 1))))
  5184. {
  5185. fRet = FALSE;
  5186. goto exit;
  5187. }
  5188. // Get the string for the item
  5189. cchText = (INT) SendMessage(m_hwndList, LB_GETTEXT, (WPARAM) (pdis->itemID), (LPARAM) pszText);
  5190. if (LB_ERR == cchText)
  5191. {
  5192. fRet = FALSE;
  5193. goto exit;
  5194. }
  5195. // Figure out which string template to use
  5196. if (1 == pdis->itemID)
  5197. {
  5198. uiID = idsCriteriaEditFirst;
  5199. }
  5200. else
  5201. {
  5202. if (0 != (m_pCritItem->dwFlags & CRIT_FLAG_MULTIPLEAND))
  5203. {
  5204. uiID = idsCriteriaEditAnd;
  5205. }
  5206. else
  5207. {
  5208. uiID = idsCriteriaEditOr;
  5209. }
  5210. }
  5211. // Load the proper string template for the item
  5212. if (NULL == AthLoadString(uiID, rgchRes, sizeof(rgchRes)))
  5213. {
  5214. fRet = FALSE;
  5215. goto exit;
  5216. }
  5217. // Allocate enough space to hold the final string
  5218. DWORD cchSize = (cchText + CCHMAX_STRINGRES + 1);
  5219. if (FAILED(HrAlloc((VOID **) &pszString, sizeof(*pszString) * cchSize)))
  5220. {
  5221. fRet = FALSE;
  5222. goto exit;
  5223. }
  5224. // Create the final string
  5225. wnsprintf(pszString, cchSize, rgchRes, pszText);
  5226. pszPrint = pszString;
  5227. }
  5228. // Determine Colors
  5229. if (pdis->itemState & ODS_SELECTED)
  5230. {
  5231. crfBack = SetBkColor(pdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
  5232. crfText = SetTextColor(pdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
  5233. }
  5234. else
  5235. {
  5236. crfBack = SetBkColor(pdis->hDC, GetSysColor(COLOR_WINDOW));
  5237. crfText = SetTextColor(pdis->hDC, GetSysColor(COLOR_WINDOWTEXT));
  5238. }
  5239. // Clear the item
  5240. ExtTextOut(pdis->hDC, pdis->rcItem.left, pdis->rcItem.top, ETO_OPAQUE, &(pdis->rcItem), NULL, 0, NULL);
  5241. // Draw the new item
  5242. DrawTextEx(pdis->hDC, pszPrint, lstrlen(pszPrint), &(pdis->rcItem), DT_BOTTOM | DT_NOPREFIX | DT_SINGLELINE, NULL);
  5243. if (pdis->itemState & ODS_FOCUS)
  5244. {
  5245. DrawFocusRect(pdis->hDC, &(pdis->rcItem));
  5246. }
  5247. // Reset Text Colors
  5248. SetTextColor (pdis->hDC, crfText);
  5249. SetBkColor (pdis->hDC, crfBack);
  5250. // Set return value
  5251. fRet = TRUE;
  5252. exit:
  5253. SafeMemFree(pszString);
  5254. SafeMemFree(pszText);
  5255. return fRet;
  5256. }
  5257. ///////////////////////////////////////////////////////////////////////////////
  5258. //
  5259. // _FLoadListCtrl
  5260. //
  5261. // This loads the list view with the current Mail rules
  5262. //
  5263. // Returns: TRUE, if it was successfully loaded
  5264. // FALSE, otherwise
  5265. //
  5266. ///////////////////////////////////////////////////////////////////////////////
  5267. BOOL CEditPeopleUI::_FLoadListCtrl(VOID)
  5268. {
  5269. BOOL fRet = FALSE;
  5270. LPSTR pszWalk = NULL;
  5271. Assert(NULL != m_hwndList);
  5272. // Remove all the items from the list control
  5273. SendMessage(m_hwndList, LB_RESETCONTENT, (WPARAM) 0, (LPARAM) 0);
  5274. // Add the tag line to the top of the list
  5275. _AddTagLineToList();
  5276. // If we have some items, let's add them to the list
  5277. if (0 != m_pCritItem->propvar.blob.cbSize)
  5278. {
  5279. // Add each item into the list
  5280. for (pszWalk = (LPSTR) (m_pCritItem->propvar.blob.pBlobData);
  5281. '\0' != pszWalk[0]; pszWalk += lstrlen(pszWalk) + 1)
  5282. {
  5283. fRet = _FAddWordToList(0, pszWalk);
  5284. if (FALSE == fRet)
  5285. goto exit;
  5286. }
  5287. }
  5288. SendMessage(m_hwndDlg, DM_SETDEFID, IDOK, 0);
  5289. // Enable the dialog buttons.
  5290. _UpdateButtons();
  5291. fRet = TRUE;
  5292. exit:
  5293. return fRet;
  5294. }
  5295. ///////////////////////////////////////////////////////////////////////////////
  5296. //
  5297. // _AddItemToList
  5298. //
  5299. // This handles the user typing into the name field
  5300. //
  5301. // Returns: TRUE, we handled the edit message
  5302. // FALSE, otherwise
  5303. //
  5304. ///////////////////////////////////////////////////////////////////////////////
  5305. VOID CEditPeopleUI::_AddItemToList(VOID)
  5306. {
  5307. ULONG cchName = 0;
  5308. LPTSTR pszItem = NULL;
  5309. // Get the item from the edit well
  5310. cchName = Edit_GetTextLength(m_hwndPeople) + 1;
  5311. if (FAILED(HrAlloc((void **) &pszItem, cchName * sizeof(*pszItem))))
  5312. {
  5313. goto exit;
  5314. }
  5315. pszItem[0] = '\0';
  5316. cchName = Edit_GetText(m_hwndPeople, pszItem, cchName);
  5317. // Check to see if the name is valid
  5318. if (0 == UlStripWhitespace(pszItem, TRUE, TRUE, NULL))
  5319. {
  5320. // Put up a message saying something is busted
  5321. AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail),
  5322. MAKEINTRESOURCEW(idsEditPeopleErrorNoName),
  5323. NULL, MB_OK | MB_ICONINFORMATION);
  5324. goto exit;
  5325. }
  5326. _FAddWordToList(0, pszItem);
  5327. // Clear out the edit well
  5328. Edit_SetText(m_hwndPeople, "");
  5329. _UpdateButtons();
  5330. exit:
  5331. SafeMemFree(pszItem);
  5332. return;
  5333. }
  5334. ///////////////////////////////////////////////////////////////////////////////
  5335. //
  5336. // _AddItemsFromWAB
  5337. //
  5338. // This handles the user typing into the name field
  5339. //
  5340. // Returns: TRUE, we handled the edit message
  5341. // FALSE, otherwise
  5342. //
  5343. ///////////////////////////////////////////////////////////////////////////////
  5344. VOID CEditPeopleUI::_AddItemsFromWAB(VOID)
  5345. {
  5346. ULONG cchName = 0;
  5347. LPWSTR pwszAddrs = NULL;
  5348. LPWSTR pwszWalk = NULL;
  5349. LONG lRecipType = 0;
  5350. UINT uidsWell = 0;
  5351. // Set the proper tags
  5352. switch(m_pCritItem->type)
  5353. {
  5354. case CRIT_TYPE_TO:
  5355. lRecipType = MAPI_TO;
  5356. uidsWell = idsRulePickTo;
  5357. break;
  5358. case CRIT_TYPE_CC:
  5359. lRecipType = MAPI_CC;
  5360. uidsWell = idsRulePickCC;
  5361. break;
  5362. case CRIT_TYPE_FROM:
  5363. lRecipType = MAPI_ORIG;
  5364. uidsWell = idsRulePickFrom;
  5365. break;
  5366. case CRIT_TYPE_TOORCC:
  5367. lRecipType = MAPI_TO;
  5368. uidsWell = idsRulePickToOrCC;
  5369. break;
  5370. default:
  5371. goto exit;
  5372. break;
  5373. }
  5374. if (FAILED(RuleUtil_HrGetAddressesFromWAB(m_hwndDlg, lRecipType, uidsWell, &pwszAddrs)))
  5375. {
  5376. goto exit;
  5377. }
  5378. // Loop through each of the addresses
  5379. for (pwszWalk = pwszAddrs; '\0' != pwszWalk[0]; pwszWalk += lstrlenW(pwszWalk) + 1)
  5380. {
  5381. LPSTR pszWalk = NULL;
  5382. // Addresses only have to be US ASCII so won't loose anything in this conversion.
  5383. pszWalk = PszToANSI(CP_ACP, pwszWalk);
  5384. if (!pszWalk)
  5385. {
  5386. TraceResult(E_OUTOFMEMORY);
  5387. goto exit;
  5388. }
  5389. _FAddWordToList(0, pszWalk);
  5390. MemFree(pszWalk);
  5391. }
  5392. _UpdateButtons();
  5393. exit:
  5394. MemFree(pwszAddrs);
  5395. return;
  5396. }
  5397. ///////////////////////////////////////////////////////////////////////////////
  5398. //
  5399. // _RemoveItemFromList
  5400. //
  5401. // This handles the user typing into the name field
  5402. //
  5403. // Returns: TRUE, we handled the edit message
  5404. // FALSE, otherwise
  5405. //
  5406. ///////////////////////////////////////////////////////////////////////////////
  5407. VOID CEditPeopleUI::_RemoveItemFromList(VOID)
  5408. {
  5409. INT iSelected = 0;
  5410. INT cItems = 0;
  5411. Assert(NULL != m_hwndList);
  5412. // Figure out which item is selected in the list
  5413. iSelected = (INT) SendMessage(m_hwndList, LB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
  5414. if (LB_ERR == iSelected)
  5415. {
  5416. goto exit;
  5417. }
  5418. // If it's the tag line, then fail
  5419. if (0 == iSelected)
  5420. {
  5421. goto exit;
  5422. }
  5423. // Get the current number of items
  5424. cItems = (INT) SendMessage(m_hwndList, LB_GETCOUNT, (WPARAM) 0, (LPARAM) 0);
  5425. if (LB_ERR == cItems)
  5426. {
  5427. goto exit;
  5428. }
  5429. // Remove the item
  5430. if (LB_ERR == (INT) SendMessage(m_hwndList, LB_DELETESTRING, (WPARAM) iSelected, (LPARAM) 0))
  5431. {
  5432. goto exit;
  5433. }
  5434. // If we deleted the last item, select the new last item
  5435. if (iSelected == (cItems - 1))
  5436. {
  5437. iSelected--;
  5438. }
  5439. // Set the new selection
  5440. if (0 != iSelected)
  5441. {
  5442. SideAssert(LB_ERR != (INT) SendMessage(m_hwndList, LB_SETCURSEL, (WPARAM) iSelected, (LPARAM) 0));
  5443. }
  5444. _UpdateButtons();
  5445. exit:
  5446. return;
  5447. }
  5448. ///////////////////////////////////////////////////////////////////////////////
  5449. //
  5450. // _ChangeOptions
  5451. //
  5452. // This handles the user typing into the name field
  5453. //
  5454. // Returns: TRUE, we handled the edit message
  5455. // FALSE, otherwise
  5456. //
  5457. ///////////////////////////////////////////////////////////////////////////////
  5458. VOID CEditPeopleUI::_ChangeOptions(VOID)
  5459. {
  5460. HRESULT hr = S_OK;
  5461. CEditPeopleOptionsUI * pOptionUI = NULL;
  5462. CRIT_ITEM critItem;
  5463. Assert(NULL != m_pCritItem);
  5464. // Initialize local variables
  5465. ZeroMemory(&critItem, sizeof(critItem));
  5466. // Create the options UI object
  5467. pOptionUI = new CEditPeopleOptionsUI;
  5468. if (NULL == pOptionUI)
  5469. {
  5470. goto exit;
  5471. }
  5472. // Initialize the options UI object
  5473. hr = pOptionUI->HrInit(m_hwndDlg, m_dwFlags);
  5474. if (FAILED(hr))
  5475. {
  5476. goto exit;
  5477. }
  5478. // Create the parameters to pass to the options dialog
  5479. critItem.type = m_pCritItem->type;
  5480. critItem.dwFlags = m_pCritItem->dwFlags;
  5481. critItem.propvar.vt = VT_BLOB;
  5482. // Get the parameter from the dialog
  5483. if (FALSE == _FOnOK(&critItem))
  5484. {
  5485. goto exit;
  5486. }
  5487. // Show the options UI
  5488. hr = pOptionUI->HrShow(&critItem);
  5489. if (FAILED(hr))
  5490. {
  5491. goto exit;
  5492. }
  5493. // If anything changed
  5494. if (S_OK == hr)
  5495. {
  5496. // Set the new value
  5497. m_pCritItem->dwFlags = critItem.dwFlags;
  5498. // Make sure the list is redrawn
  5499. InvalidateRect(m_hwndList, NULL, TRUE);
  5500. // Mark us as dirty
  5501. m_dwState |= STATE_DIRTY;
  5502. }
  5503. exit:
  5504. PropVariantClear(&(critItem.propvar));
  5505. if (NULL != pOptionUI)
  5506. {
  5507. delete pOptionUI;
  5508. }
  5509. return;
  5510. }
  5511. ///////////////////////////////////////////////////////////////////////////////
  5512. //
  5513. // _FOnNameChange
  5514. //
  5515. // This handles the user typing into the name field
  5516. //
  5517. // Returns: TRUE, we handled the edit message
  5518. // FALSE, otherwise
  5519. //
  5520. ///////////////////////////////////////////////////////////////////////////////
  5521. BOOL CEditPeopleUI::_FOnNameChange(VOID)
  5522. {
  5523. BOOL fRet = FALSE;
  5524. BOOL fIsText = FALSE;
  5525. Assert(NULL != m_hwndPeople);
  5526. // Note that we're dirty
  5527. m_dwState |= STATE_DIRTY;
  5528. fIsText = (0 != Edit_GetTextLength(m_hwndPeople));
  5529. // Disable the Add button if the name is empty
  5530. fRet = RuleUtil_FEnDisDialogItem(m_hwndDlg, idcCriteriaAdd, fIsText);
  5531. SendMessage(m_hwndDlg, DM_SETDEFID, (FALSE != fIsText) ? idcCriteriaAdd : IDOK, 0);
  5532. return fRet;
  5533. }
  5534. ///////////////////////////////////////////////////////////////////////////////
  5535. //
  5536. // _FOnOK
  5537. //
  5538. // This handles the user typing into the name field
  5539. //
  5540. // Returns: TRUE, we handled the edit message
  5541. // FALSE, otherwise
  5542. //
  5543. ///////////////////////////////////////////////////////////////////////////////
  5544. BOOL CEditPeopleUI::_FOnOK(CRIT_ITEM * pCritItem)
  5545. {
  5546. BOOL fRet = FALSE;
  5547. INT cItems = 0;
  5548. INT iIndex = 0;
  5549. INT iRet = 0;
  5550. ULONG cchText = 0;
  5551. LPTSTR pszText = NULL;
  5552. LPTSTR pszWalk = NULL;
  5553. Assert(NULL != m_hwndList);
  5554. // Get the total number of items in the list
  5555. cItems = (INT) SendMessage(m_hwndList, LB_GETCOUNT, (WPARAM) 0, (LPARAM) 0);
  5556. if ((LB_ERR == cItems) || (2 > cItems))
  5557. {
  5558. fRet = FALSE;
  5559. goto exit;
  5560. }
  5561. // Loop through each item, calculating the space each would take
  5562. for (iIndex = 1; iIndex < cItems; iIndex++)
  5563. {
  5564. // Get the space for the item
  5565. iRet = (INT) SendMessage(m_hwndList, LB_GETTEXTLEN, (WPARAM) iIndex, (LPARAM) 0);
  5566. if ((LB_ERR == iRet) || (0 == iRet))
  5567. {
  5568. continue;
  5569. }
  5570. // Count the space needed
  5571. cchText += iRet + 1;
  5572. }
  5573. // Add in space for the terminator
  5574. cchText += 2;
  5575. // Allocate space to hold the item
  5576. if (FAILED(HrAlloc((VOID **) &pszText, sizeof(*pszText) * cchText)))
  5577. {
  5578. fRet = FALSE;
  5579. goto exit;
  5580. }
  5581. // Loop through each item, calculating the space each would take
  5582. pszWalk = pszText;
  5583. for (iIndex = 1; iIndex < cItems; iIndex++)
  5584. {
  5585. // Get the space for the item
  5586. iRet = (INT) SendMessage(m_hwndList, LB_GETTEXT, (WPARAM) iIndex, (LPARAM) pszWalk);
  5587. if ((LB_ERR == iRet) || (0 == iRet))
  5588. {
  5589. continue;
  5590. }
  5591. // Count the space needed
  5592. pszWalk += iRet + 1;
  5593. }
  5594. // Add in space for the terminator
  5595. pszWalk[0] = '\0';
  5596. pszWalk[1] = '\0';
  5597. // Set the new string in the blob
  5598. SafeMemFree(pCritItem->propvar.blob.pBlobData);
  5599. pCritItem->propvar.blob.pBlobData = (BYTE *) pszText;
  5600. pszText = NULL;
  5601. pCritItem->propvar.blob.cbSize = sizeof(*pszText) * cchText;
  5602. // Set the return value
  5603. fRet = TRUE;
  5604. exit:
  5605. SafeMemFree(pszText);
  5606. return fRet;
  5607. }
  5608. ///////////////////////////////////////////////////////////////////////////////
  5609. //
  5610. // _UpdateButtons
  5611. //
  5612. // This enables or disables the buttons in the people editor UI dialog
  5613. // depending on what is selected.
  5614. //
  5615. // iSelected - the item that was selected,
  5616. // -1 means that nothing was selected
  5617. //
  5618. // Returns: NONE
  5619. //
  5620. ///////////////////////////////////////////////////////////////////////////////
  5621. void CEditPeopleUI::_UpdateButtons(VOID)
  5622. {
  5623. INT iSelected = 0;
  5624. BOOL fSelected = FALSE;
  5625. BOOL fEditable = FALSE;
  5626. INT cItems = 0;
  5627. Assert(NULL != m_hwndList);
  5628. // Get the currently selected item
  5629. iSelected = (INT) SendMessage(m_hwndList, LB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
  5630. if (LB_ERR == iSelected)
  5631. {
  5632. iSelected = -1;
  5633. }
  5634. fSelected = (-1 != iSelected);
  5635. fEditable = ((FALSE != fSelected) && (0 != iSelected));
  5636. cItems = (INT) SendMessage(m_hwndList, LB_GETCOUNT, (WPARAM) 0, (LPARAM) 0);
  5637. // Enable the rule action buttons
  5638. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcCriteriaRemove, fSelected && fEditable);
  5639. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcCriteriaOptions, cItems > 1);
  5640. RuleUtil_FEnDisDialogItem(m_hwndDlg, IDOK, cItems > 1);
  5641. return;
  5642. }
  5643. ///////////////////////////////////////////////////////////////////////////////
  5644. //
  5645. // _AddTagLineToList
  5646. //
  5647. // This enables or disables the buttons in the people editor UI dialog
  5648. // depending on what is selected.
  5649. //
  5650. // iSelected - the item that was selected,
  5651. // -1 means that nothing was selected
  5652. //
  5653. // Returns: NONE
  5654. //
  5655. ///////////////////////////////////////////////////////////////////////////////
  5656. BOOL CEditPeopleUI::_AddTagLineToList(VOID)
  5657. {
  5658. BOOL fRet = FALSE;
  5659. Assert(NULL != m_hwndList);
  5660. fRet = _FAddWordToList(0, " ");
  5661. if (FALSE == fRet)
  5662. {
  5663. goto exit;
  5664. }
  5665. // Set the proper return value
  5666. fRet = TRUE;
  5667. exit:
  5668. return fRet;
  5669. }
  5670. ///////////////////////////////////////////////////////////////////////////////
  5671. //
  5672. // _FAddWordToList
  5673. //
  5674. // This enables or disables the buttons in the people editor UI dialog
  5675. // depending on what is selected.
  5676. //
  5677. // iSelected - the item that was selected,
  5678. // -1 means that nothing was selected
  5679. //
  5680. // Returns: NONE
  5681. //
  5682. ///////////////////////////////////////////////////////////////////////////////
  5683. BOOL CEditPeopleUI::_FAddWordToList(DWORD dwFlags, LPCTSTR pszItem)
  5684. {
  5685. BOOL fRet = FALSE;
  5686. int cItems = 0;
  5687. INT iRet = 0;
  5688. Assert(NULL != m_hwndList);
  5689. // Is there anything to do?
  5690. if ((NULL == pszItem) || (L'\0' == pszItem[0]))
  5691. {
  5692. fRet = FALSE;
  5693. goto exit;
  5694. }
  5695. // Get the number of items in the list
  5696. cItems = (INT) SendMessage(m_hwndList, LB_GETCOUNT, (WPARAM) 0, (LPARAM) 0);
  5697. if (LB_ERR == cItems)
  5698. {
  5699. fRet = FALSE;
  5700. goto exit;
  5701. }
  5702. // Set the data into the list
  5703. iRet = (INT) SendMessage(m_hwndList, LB_ADDSTRING, (WPARAM) cItems, (LPARAM) pszItem);
  5704. if ((LB_ERR == iRet) || (LB_ERRSPACE == iRet))
  5705. {
  5706. fRet = FALSE;
  5707. goto exit;
  5708. }
  5709. // Set the proper return value
  5710. fRet = TRUE;
  5711. exit:
  5712. return fRet;
  5713. }
  5714. ///////////////////////////////////////////////////////////////////////////////
  5715. //
  5716. // _HrCriteriaEditPeople
  5717. //
  5718. // This creates a people editor.
  5719. //
  5720. // ppViewMenu - pointer to return the view menu
  5721. //
  5722. // Returns: S_OK, on success
  5723. // E_OUTOFMEMORY, if can't create the View Menu object
  5724. //
  5725. ///////////////////////////////////////////////////////////////////////////////
  5726. HRESULT _HrCriteriaEditPeople(HWND hwnd, CRIT_ITEM * pCritItem)
  5727. {
  5728. HRESULT hr = S_OK;
  5729. CEditPeopleUI * pPeopleUI = NULL;
  5730. // Check the incoming params
  5731. if (NULL == pCritItem)
  5732. {
  5733. hr = E_INVALIDARG;
  5734. goto exit;
  5735. }
  5736. // Create the view menu object
  5737. pPeopleUI = new CEditPeopleUI;
  5738. if (NULL == pPeopleUI)
  5739. {
  5740. hr = E_OUTOFMEMORY;
  5741. goto exit;
  5742. }
  5743. // Initialize the view menu
  5744. hr = pPeopleUI->HrInit(hwnd, 0);
  5745. if (FAILED(hr))
  5746. {
  5747. goto exit;
  5748. }
  5749. // Show the UI
  5750. hr = pPeopleUI->HrShow(pCritItem);
  5751. if (FAILED(hr))
  5752. {
  5753. goto exit;
  5754. }
  5755. exit:
  5756. if (NULL != pPeopleUI)
  5757. {
  5758. delete pPeopleUI;
  5759. }
  5760. return hr;
  5761. }
  5762. ///////////////////////////////////////////////////////////////////////////////
  5763. //
  5764. // _HrCriteriaEditWords
  5765. //
  5766. // This creates a words editor.
  5767. //
  5768. // ppViewMenu - pointer to return the view menu
  5769. //
  5770. // Returns: S_OK, on success
  5771. // E_OUTOFMEMORY, if can't create the View Menu object
  5772. //
  5773. ///////////////////////////////////////////////////////////////////////////////
  5774. HRESULT _HrCriteriaEditWords(HWND hwnd, CRIT_ITEM * pCritItem)
  5775. {
  5776. HRESULT hr = S_OK;
  5777. CEditPeopleUI * pPeopleUI = NULL;
  5778. // Check the incoming params
  5779. if (NULL == pCritItem)
  5780. {
  5781. hr = E_INVALIDARG;
  5782. goto exit;
  5783. }
  5784. // Create the view menu object
  5785. pPeopleUI = new CEditPeopleUI;
  5786. if (NULL == pPeopleUI)
  5787. {
  5788. hr = E_OUTOFMEMORY;
  5789. goto exit;
  5790. }
  5791. // Initialize the view menu
  5792. hr = pPeopleUI->HrInit(hwnd, PUI_WORDS);
  5793. if (FAILED(hr))
  5794. {
  5795. goto exit;
  5796. }
  5797. // Show the UI
  5798. hr = pPeopleUI->HrShow(pCritItem);
  5799. if (FAILED(hr))
  5800. {
  5801. goto exit;
  5802. }
  5803. exit:
  5804. if (NULL != pPeopleUI)
  5805. {
  5806. delete pPeopleUI;
  5807. }
  5808. return hr;
  5809. }