/////////////////////////////////////////////////////////////////////////////// // // RuleDesc.cpp // /////////////////////////////////////////////////////////////////////////////// #include #include "ruledesc.h" #include "editrule.h" #include "ruleutil.h" #include #include #include #include #include #include #include #include "reutil.h" #include "shlwapip.h" #include typedef struct tagSELECTADDR { LONG lRecipType; UINT uidsWell; LPWSTR pwszAddr; } SELECTADDR, * PSELECTADDR; typedef struct tagSELECTACCT { RULE_TYPE typeRule; LPSTR pszAcct; } SELECTACCT, * PSELECTACCT; class CEditLogicUI { private: enum { STATE_UNINIT = 0x00000000, STATE_INITIALIZED = 0x00000001, STATE_DIRTY = 0x00000002 }; private: HWND m_hwndOwner; DWORD m_dwFlags; DWORD m_dwState; HWND m_hwndDlg; RULE_TYPE m_typeRule; HWND m_hwndDescript; IOERule * m_pIRule; CRuleDescriptUI * m_pDescriptUI; public: CEditLogicUI(); ~CEditLogicUI(); // The main UI methods HRESULT HrInit(HWND hwndOwner, DWORD dwFlags, RULE_TYPE typeRule, IOERule * pIRule); HRESULT HrShow(void); // The Rules Manager dialog function static INT_PTR CALLBACK FEditLogicDlgProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam); // Message handling functions BOOL FOnInitDialog(HWND hwndDlg); BOOL FOnOK(void); BOOL FOnLogicChange(HWND hwndName); }; // Constants static const int c_cCritItemGrow = 16; static const int c_cActItemGrow = 16; static const int PUI_WORDS = 0x00000001; HRESULT _HrCriteriaEditPeople(HWND hwnd, CRIT_ITEM * pCritItem); HRESULT _HrCriteriaEditWords(HWND hwnd, CRIT_ITEM * pCritItem); CRuleDescriptUI::CRuleDescriptUI() : m_hwndOwner(NULL), m_dwFlags(0), m_dwState(STATE_UNINIT), m_typeRule(RULE_TYPE_MAIL), m_pDescriptListCrit(NULL), m_cDescriptListCrit(0), m_pDescriptListAct(NULL), m_cDescriptListAct(0), m_hfont(NULL), m_wpcOld(NULL), m_logicCrit(CRIT_LOGIC_AND), m_fErrorLogic(FALSE) { } CRuleDescriptUI::~CRuleDescriptUI() { _FreeDescriptionList(m_pDescriptListCrit); m_pDescriptListCrit = NULL; m_cDescriptListCrit = 0; _FreeDescriptionList(m_pDescriptListAct); m_pDescriptListAct = NULL; m_cDescriptListAct = 0; if ((NULL != m_hwndOwner) && (FALSE != IsWindow(m_hwndOwner)) && (NULL != m_wpcOld)) { SetWindowLongPtr(m_hwndOwner, GWLP_WNDPROC, (LONG_PTR) m_wpcOld); m_wpcOld = NULL; } } /////////////////////////////////////////////////////////////////////////////// // // HrInit // // This initializes us with the owner window and any flags we might have // // hwndOwner - handle to the owner window // dwFlags - flags to use for this instance // typeRule - the type of rule editor to create // // Returns: S_OK // /////////////////////////////////////////////////////////////////////////////// HRESULT CRuleDescriptUI::HrInit(HWND hwndOwner, DWORD dwFlags) { HRESULT hr = S_OK; // If we're already initialized, then fail if (0 != (m_dwState & STATE_INITIALIZED)) { hr = E_FAIL; goto exit; } // Save off the owner window m_hwndOwner = hwndOwner; // Make sure we set the correct font into the control m_hfont = HGetSystemFont(FNT_SYS_ICON); if (NULL != m_hfont) { SetFontOnRichEdit(m_hwndOwner, m_hfont); } // Save off the flags m_dwFlags = dwFlags; if (0 != (m_dwFlags & RDF_READONLY)) { m_dwState |= STATE_READONLY; } // Subclass the original dialog if ((NULL != m_hwndOwner) && (0 == (m_dwFlags & RDF_READONLY))) { // Save off the object pointer SetWindowLongPtr(m_hwndOwner, GWLP_USERDATA, (LONG_PTR) this); m_wpcOld = (WNDPROC) SetWindowLongPtr(m_hwndOwner, GWLP_WNDPROC, (LONG_PTR) CRuleDescriptUI::_DescriptWndProc); } // We're done m_dwState |= STATE_INITIALIZED; hr = S_OK; exit: return hr; } /////////////////////////////////////////////////////////////////////////////// // // HrSetRule // // This initializes us with the owner window and any flags we might have // // hwndOwner - handle to the owner window // dwFlags - flags to use for this instance // typeRule - the type of rule editor to create // // Returns: S_OK // /////////////////////////////////////////////////////////////////////////////// HRESULT CRuleDescriptUI::HrSetRule(RULE_TYPE typeRule, IOERule * pIRule) { HRESULT hr = S_OK; RULEDESCRIPT_LIST * pDescriptListCrit = NULL; ULONG cDescriptListCrit = 0; CRIT_LOGIC logicCrit = CRIT_LOGIC_AND; RULEDESCRIPT_LIST * pDescriptListAct = NULL; ULONG cDescriptListAct = 0; BOOL fDisabled = FALSE; PROPVARIANT propvar = {0}; // Are we in a good state? if (0 == (m_dwState & STATE_INITIALIZED)) { hr = E_FAIL; goto exit; } if (NULL != pIRule) { // Create the criteria list hr = _HrBuildCriteriaList(pIRule, &pDescriptListCrit, &cDescriptListCrit, &logicCrit); if (FAILED(hr)) { goto exit; } // Create the actions list hr = _HrBuildActionList(pIRule, &pDescriptListAct, &cDescriptListAct); if (FAILED(hr)) { goto exit; } // Get the enabled state if (SUCCEEDED(pIRule->GetProp(RULE_PROP_DISABLED, 0, &propvar))) { Assert(VT_BOOL == propvar.vt); fDisabled = propvar.boolVal; } } m_typeRule = typeRule; _FreeDescriptionList(m_pDescriptListCrit); m_pDescriptListCrit = pDescriptListCrit; pDescriptListCrit = NULL; m_cDescriptListCrit = cDescriptListCrit; m_logicCrit = logicCrit; m_fErrorLogic = FALSE; _FreeDescriptionList(m_pDescriptListAct); m_pDescriptListAct = pDescriptListAct; pDescriptListAct = NULL; m_cDescriptListAct = cDescriptListAct; // Make sure we verify the rule HrVerifyRule(); // Clear the dirty state m_dwState &= ~STATE_DIRTY; // Set the rule state if (NULL != pIRule) { m_dwState |= STATE_HASRULE; } else { m_dwState &= ~STATE_HASRULE; } if (FALSE == fDisabled) { m_dwState |= STATE_ENABLED; } else { m_dwState &= ~STATE_ENABLED; } hr = S_OK; exit: _FreeDescriptionList(pDescriptListCrit); _FreeDescriptionList(pDescriptListAct); return hr; } /////////////////////////////////////////////////////////////////////////////// // // HrVerifyRule // // This verifies the rule string // // Returns: S_OK, if the rule state is valid // S_FALSE, if the rule state is invalid // /////////////////////////////////////////////////////////////////////////////// HRESULT CRuleDescriptUI::HrVerifyRule(void) { HRESULT hr = S_OK; RULEDESCRIPT_LIST * pDescriptListWalk = NULL; BOOL fBad = FALSE; // If we have nothing, then the rule is still in error if ((NULL == m_pDescriptListCrit) && (NULL == m_pDescriptListAct)) { hr = S_FALSE; goto exit; } // Validate the logic operation if (1 < m_cDescriptListCrit) { m_fErrorLogic = (CRIT_LOGIC_NULL == m_logicCrit); if (FALSE != m_fErrorLogic) { fBad = TRUE; } } // Validate the criteria for (pDescriptListWalk = m_pDescriptListCrit; pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext) { pDescriptListWalk->fError = !_FVerifyCriteria(pDescriptListWalk); if (FALSE != pDescriptListWalk->fError) { fBad = TRUE; } } // Build up the actions for (pDescriptListWalk = m_pDescriptListAct; pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext) { pDescriptListWalk->fError = !_FVerifyAction(pDescriptListWalk); if (FALSE != pDescriptListWalk->fError) { fBad = TRUE; } } // Set the correct return value hr = (FALSE == fBad) ? S_OK : S_FALSE; exit: return hr; } /////////////////////////////////////////////////////////////////////////////// // // HrEnableCriteria // // This initializes the actions list view with the list of actions // // Returns: TRUE, if it was successfully loaded // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// HRESULT CRuleDescriptUI::HrEnableCriteria(CRIT_TYPE type, BOOL fEnable) { HRESULT hr = S_OK; ULONG ulIndex = 0; RULEDESCRIPT_LIST * pDescriptListAlloc = NULL; // Find the index of the criteria for (ulIndex = 0; ulIndex < ARRAYSIZE(c_rgEditCritList); ulIndex++) { if (type == c_rgEditCritList[ulIndex].typeCrit) { break; } } // Did we find the criteria item? if (ulIndex >= ARRAYSIZE(c_rgEditCritList)) { hr = E_INVALIDARG; goto exit; } // Are we trying to remove the item if (FALSE == fEnable) { if (FALSE == _FRemoveDescription(&m_pDescriptListCrit, ulIndex, &pDescriptListAlloc)) { hr = E_FAIL; goto exit; } // Free up the description pDescriptListAlloc->pNext = NULL; _FreeDescriptionList(pDescriptListAlloc); m_cDescriptListCrit--; } else { // Create the description list hr = HrAlloc((VOID **) &pDescriptListAlloc, sizeof(RULEDESCRIPT_LIST)); if (FAILED(hr)) { goto exit; } // Initialize the description list ZeroMemory(pDescriptListAlloc, sizeof(RULEDESCRIPT_LIST)); // Save of the criteria type info pDescriptListAlloc->ulIndex = ulIndex; _InsertDescription(&m_pDescriptListCrit, pDescriptListAlloc); m_cDescriptListCrit++; } m_dwState |= STATE_DIRTY; ShowDescriptionString(); hr = S_OK; exit: return hr; } /////////////////////////////////////////////////////////////////////////////// // // HrEnableActions // // This initializes the actions list view with the list of actions // // Returns: TRUE, if it was successfully loaded // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// HRESULT CRuleDescriptUI::HrEnableActions(ACT_TYPE type, BOOL fEnable) { HRESULT hr = S_OK; ULONG ulIndex = 0; RULEDESCRIPT_LIST * pDescriptListAlloc = NULL; // Find the index of the actions for (ulIndex = 0; ulIndex < ARRAYSIZE(c_rgEditActList); ulIndex++) { if (type == c_rgEditActList[ulIndex].typeAct) { break; } } // Did we find the action item? if (ulIndex >= ARRAYSIZE(c_rgEditActList)) { hr = E_INVALIDARG; goto exit; } // Are we trying to remove the item if (FALSE == fEnable) { if (FALSE == _FRemoveDescription(&m_pDescriptListAct, ulIndex, &pDescriptListAlloc)) { hr = E_FAIL; goto exit; } // Free up the description pDescriptListAlloc->pNext = NULL; _FreeDescriptionList(pDescriptListAlloc); m_cDescriptListAct--; } else { // Create the description list hr = HrAlloc((VOID **) &pDescriptListAlloc, sizeof(RULEDESCRIPT_LIST)); if (FAILED(hr)) { goto exit; } // Initialize the description list ZeroMemory(pDescriptListAlloc, sizeof(RULEDESCRIPT_LIST)); // Save of the actions type info pDescriptListAlloc->ulIndex = ulIndex; _InsertDescription(&m_pDescriptListAct, pDescriptListAlloc); m_cDescriptListAct++; } m_dwState |= STATE_DIRTY; ShowDescriptionString(); hr = S_OK; exit: return hr; } /////////////////////////////////////////////////////////////////////////////// // // HrGetCriteria // // This initializes the actions list view with the list of actions // // Returns: TRUE, if it was successfully loaded // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// HRESULT CRuleDescriptUI::HrGetCriteria(CRIT_ITEM ** ppCritList, ULONG * pcCritList) { HRESULT hr = S_OK; RULEDESCRIPT_LIST * pDescriptListWalk = NULL; CRIT_ITEM * pCritItem = NULL; ULONG cCritItem = 0; ULONG cCritItemAlloc = 0; if (NULL == ppCritList) { hr = E_INVALIDARG; goto exit; } *ppCritList = NULL; if (NULL != pcCritList) { *pcCritList = 0; } // If we don't have any criteria then return if (NULL == m_pDescriptListCrit) { hr = S_FALSE; goto exit; } for (pDescriptListWalk = m_pDescriptListCrit; pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext) { // Do we need more room? if (cCritItem == cCritItemAlloc) { if (FAILED(HrRealloc((void **) &pCritItem, sizeof(*pCritItem) * (cCritItemAlloc + c_cCritItemGrow)))) { hr = E_OUTOFMEMORY; goto exit; } ZeroMemory(pCritItem + cCritItemAlloc, sizeof(*pCritItem) * c_cCritItemGrow); cCritItemAlloc += c_cCritItemGrow; } // Set the criteria type pCritItem[cCritItem].type = c_rgEditCritList[pDescriptListWalk->ulIndex].typeCrit; // Set the flags pCritItem[cCritItem].dwFlags = pDescriptListWalk->dwFlags; if (VT_EMPTY != pDescriptListWalk->propvar.vt) { if (FAILED(PropVariantCopy(&(pCritItem[cCritItem].propvar), &(pDescriptListWalk->propvar)))) { hr = E_OUTOFMEMORY; goto exit; } } // Set the logic operator if (0 != cCritItem) { pCritItem[cCritItem - 1].logic = m_logicCrit; } // Move to the next item cCritItem++; } *ppCritList = pCritItem; pCritItem = NULL; if (NULL != pcCritList) { *pcCritList = cCritItem; } hr = S_OK; exit: RuleUtil_HrFreeCriteriaItem(pCritItem, cCritItem); SafeMemFree(pCritItem); return hr; } /////////////////////////////////////////////////////////////////////////////// // // HrGetActions // // This initializes the actions list view with the list of actions // // Returns: TRUE, if it was successfully loaded // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// HRESULT CRuleDescriptUI::HrGetActions(ACT_ITEM ** ppActList, ULONG * pcActList) { HRESULT hr = S_OK; RULEDESCRIPT_LIST * pDescriptListWalk = NULL; ACT_ITEM * pActItem = NULL; ULONG cActItem = 0; ULONG cActItemAlloc = 0; if (NULL == ppActList) { hr = E_INVALIDARG; goto exit; } *ppActList = NULL; if (NULL != pcActList) { *pcActList = 0; } // If we don't have any criteria then return if (NULL == m_pDescriptListAct) { hr = S_FALSE; goto exit; } for (pDescriptListWalk = m_pDescriptListAct; pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext) { // Do we need more room? if (cActItem == cActItemAlloc) { if (FAILED(HrRealloc((void **) &pActItem, sizeof(*pActItem) * (cActItemAlloc + c_cActItemGrow)))) { hr = E_OUTOFMEMORY; goto exit; } ZeroMemory(pActItem + cActItemAlloc, sizeof(*pActItem) * c_cActItemGrow); cActItemAlloc += c_cActItemGrow; } // Set the action type pActItem[cActItem].type = c_rgEditActList[pDescriptListWalk->ulIndex].typeAct; // Set the flags pActItem[cActItem].dwFlags = pDescriptListWalk->dwFlags; if (VT_EMPTY != pDescriptListWalk->propvar.vt) { if (FAILED(PropVariantCopy(&(pActItem[cActItem].propvar), &(pDescriptListWalk->propvar)))) { hr = E_OUTOFMEMORY; goto exit; } } // Move to the next item cActItem++; } *ppActList = pActItem; pActItem = NULL; if (NULL != pcActList) { *pcActList = cActItem; } hr = S_OK; exit: RuleUtil_HrFreeActionsItem(pActItem, cActItem); SafeMemFree(pActItem); return hr; } /////////////////////////////////////////////////////////////////////////////// // // ShowDescriptionString // // This initializes the actions list view with the list of actions // // Returns: TRUE, if it was successfully loaded // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// void CRuleDescriptUI::ShowDescriptionString(VOID) { WCHAR wszRes[CCHMAX_STRINGRES + 3]; ULONG cchRes = 0; BOOL fError = FALSE; CHARFORMAT chFmt = {0}; PARAFORMAT paraFmt = {0}; RULEDESCRIPT_LIST * pDescriptListWalk = NULL; BOOL fFirst = FALSE; UINT uiText = 0; BOOL fErrorFwdSec = FALSE; CHARRANGE chrg = {0}; Assert(NULL != m_hwndOwner); // Let's clear the redraw state to reduce flicker. SendMessage(m_hwndOwner, WM_SETREDRAW, 0, 0); // Clear text SetRichEditText(m_hwndOwner, NULL, FALSE, NULL, TRUE); // Set default CHARFORMAT chFmt.cbSize = sizeof(chFmt); chFmt.dwMask = CFM_BOLD | CFM_UNDERLINE | CFM_COLOR; chFmt.dwEffects = CFE_AUTOCOLOR; SendMessage(m_hwndOwner, EM_SETCHARFORMAT, (WPARAM)SCF_ALL, (LPARAM)&chFmt); paraFmt.cbSize = sizeof(paraFmt); paraFmt.dwMask = PFM_ALIGNMENT; if (0 == (m_dwState & STATE_HASRULE)) { // Set up the empty string paragraph style paraFmt.wAlignment = PFA_CENTER; uiText = (RULE_TYPE_FILTER != m_typeRule) ? idsRulesDescriptionEmpty : idsViewDescriptionEmpty; } else { paraFmt.wAlignment = PFA_LEFT; // Determine if the rule is in error if (m_fErrorLogic) { fError = TRUE; } if (!fError) { // Walk the criteria looking for errors for (pDescriptListWalk = m_pDescriptListCrit; pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext) { if (pDescriptListWalk->fError) { fError = TRUE; break; } } } if (!fError) { // Walk the actions looking for errors for (pDescriptListWalk = m_pDescriptListAct; pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext) { if (pDescriptListWalk->fError) { // Note that we are in error fError = TRUE; // Is we have a FWD action if (ACT_TYPE_FWD == c_rgEditActList[pDescriptListWalk->ulIndex].typeAct) { // If security is turned then note it if ((0 != DwGetOption(OPT_MAIL_DIGSIGNMESSAGES)) || (0 != DwGetOption(OPT_MAIL_ENCRYPTMESSAGES))) { fErrorFwdSec = TRUE; } break; } } } } if (fError) { uiText = fErrorFwdSec ? idsRulesErrorFwdHeader : idsRulesErrorHeader; } else if (0 != (m_dwFlags & RDF_APPLYDLG)) { uiText = idsRulesApplyHeader; } else if (RULE_TYPE_FILTER != m_typeRule) { uiText = (0 != (m_dwState & STATE_ENABLED)) ? idsRuleHeader : idsRulesOffHeader; } } // Set default PARAFORMAT SendMessage(m_hwndOwner, EM_SETPARAFORMAT, 0, (LPARAM)¶Fmt); // Load help text wszRes[0] = L'\0'; cchRes = LoadStringWrapW(g_hLocRes, uiText, wszRes, ARRAYSIZE(wszRes)); // If error, make sure help text is bolded if (fError) { chFmt.dwMask = CFM_BOLD; chFmt.dwEffects = CFE_BOLD; } // Set help text into the richedit control RuleUtil_AppendRichEditText(m_hwndOwner, 0, wszRes, &chFmt); // Build up the criteria fFirst = TRUE; for (pDescriptListWalk = m_pDescriptListCrit; pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext) { if (0 != (pDescriptListWalk->dwFlags & CRIT_FLAG_INVERT)) { uiText = c_rgEditCritList[pDescriptListWalk->ulIndex].uiTextAlt; } else { uiText = c_rgEditCritList[pDescriptListWalk->ulIndex].uiText; } _ShowLinkedString(uiText, pDescriptListWalk, fFirst, TRUE); fFirst = FALSE; // Only need to do this once for the block sender rule if (CRIT_TYPE_SENDER == c_rgEditCritList[pDescriptListWalk->ulIndex].typeCrit) { break; } } // Build up the actions fFirst = TRUE; for (pDescriptListWalk = m_pDescriptListAct; pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext) { if (0 != (pDescriptListWalk->dwFlags & ACT_FLAG_INVERT)) { uiText = c_rgEditActList[pDescriptListWalk->ulIndex].uiTextAlt; } else { uiText = c_rgEditActList[pDescriptListWalk->ulIndex].uiText; } _ShowLinkedString(uiText, pDescriptListWalk, fFirst, FALSE); fFirst = FALSE; } // Restore the selection RichEditExSetSel(m_hwndOwner, &chrg); // Let's set back the redraw state and invalidate the rect to // get the string drawn SendMessage(m_hwndOwner, WM_SETREDRAW, 1, 0); InvalidateRect(m_hwndOwner, NULL, TRUE); return; } /////////////////////////////////////////////////////////////////////////////// // // _ShowLinkedString // // This initializes the actions list view with the list of actions // // Returns: TRUE, if it was successfully loaded // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// void CRuleDescriptUI::_ShowLinkedString(ULONG ulText, RULEDESCRIPT_LIST * pDescriptListWalk, BOOL fFirst, BOOL fCrit) { HRESULT hr = S_OK; WCHAR wszRes[CCHMAX_STRINGRES + 2]; ULONG uiStrId = 0; ULONG cchText = 0; CHARFORMAT chFmt = {0}; CHARRANGE chrg = {0}; LPWSTR lpwsz = NULL; if ((0 == ulText) || (NULL == pDescriptListWalk)) { Assert(FALSE); goto exit; } // Figure out where we're supposed to start cchText = GetRichEditTextLen(m_hwndOwner); // So richedit 2 and 3 need to have each beginning line // have the default charformat reset. It actually only matters // if you are showing both criteria and actions. In that case, if // this isn't done, then the default charformat might be incorretly // set to one of the other charformats that have been used. So, there // is obviously something amiss here, but I can't figure // it out, this is what we use to do, and this works. // See raid 78472 in IE/OE 5.0 database chrg.cpMin = cchText; chrg.cpMax = cchText; RichEditExSetSel(m_hwndOwner, &chrg); // Set default CHARFORMAT chFmt.cbSize = sizeof(chFmt); chFmt.dwMask = CFM_BOLD | CFM_UNDERLINE | CFM_COLOR; chFmt.dwEffects = CFE_AUTOCOLOR; SendMessage(m_hwndOwner, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chFmt); // Should we use a logical op? if (!fFirst) { // Which string should we load? if (fCrit) { if (CRIT_LOGIC_AND == m_logicCrit) { uiStrId = idsCriteriaAnd; } else if (CRIT_LOGIC_OR == m_logicCrit) { uiStrId = idsCriteriaOr; } else { uiStrId = idsCriteriaAndOr; } } else { uiStrId = idsActionsAnd; } wszRes[0] = L'\0'; if (0 == LoadStringWrapW(g_hLocRes, uiStrId, wszRes, ARRAYSIZE(wszRes))) { goto exit; } // Write out the linked logic string IF_FAILEXIT(hr = RuleUtil_HrShowLinkedString(m_hwndOwner, m_fErrorLogic, (0 != (m_dwState & STATE_READONLY)), wszRes, NULL, cchText, &(pDescriptListWalk->ulStartLogic), &(pDescriptListWalk->ulEndLogic), &cchText)); } // Get the description string wszRes[0] = L'\0'; if (0 == LoadStringWrapW(g_hLocRes, ulText, wszRes, ARRAYSIZE(wszRes))) { goto exit; } // Write out the linked string if(pDescriptListWalk->pszText) IF_NULLEXIT(lpwsz = PszToUnicode(CP_ACP, pDescriptListWalk->pszText)); IF_FAILEXIT(hr = RuleUtil_HrShowLinkedString(m_hwndOwner, pDescriptListWalk->fError, (0 != (m_dwState & STATE_READONLY)), wszRes, lpwsz, cchText, &(pDescriptListWalk->ulStart), &(pDescriptListWalk->ulEnd), &cchText)); // Hack for HyperLinks to work without having to measure text (was broken for BiDi) RuleUtil_AppendRichEditText(m_hwndOwner, cchText, g_wszSpace, NULL); // Terminate the string RuleUtil_AppendRichEditText(m_hwndOwner, cchText + 1, g_wszCRLF, NULL); exit: MemFree(lpwsz); return; } /////////////////////////////////////////////////////////////////////////////// // // _FChangeLogicValue // // This changes the value of the logic op // // Returns: TRUE, if the criteria value was changed // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CRuleDescriptUI::_FChangeLogicValue(RULEDESCRIPT_LIST * pDescriptList) { BOOL fRet = FALSE; int iRet = 0; CRIT_LOGIC logicCrit = CRIT_LOGIC_NULL; // Bring up the choose logic op dialog if (NULL != m_logicCrit) { logicCrit = m_logicCrit; } iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaLogic), m_hwndOwner, _FSelectLogicDlgProc, (LPARAM) &logicCrit); fRet = (iRet == IDOK); // Update the description field if neccessary if (FALSE != fRet) { m_logicCrit = logicCrit; // ZIFF // Can we be sure we are really OK?? m_fErrorLogic = FALSE; ShowDescriptionString(); } return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FBuildCriteriaList // // This builds the criteria list // // Returns: TRUE, if the criteria list was created // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// HRESULT CRuleDescriptUI::_HrBuildCriteriaList(IOERule * pIRule, RULEDESCRIPT_LIST ** ppDescriptList, ULONG * pcDescriptList, CRIT_LOGIC * plogicCrit) { HRESULT hr = S_OK; PROPVARIANT propvar = {0}; CRIT_ITEM * pCritItem = NULL; ULONG cCritItem = 0; ULONG ulIndex = 0; RULEDESCRIPT_LIST * pDescriptList = NULL; ULONG ulList = 0; ULONG cDescriptList = 0; RULEDESCRIPT_LIST * pDescriptListAlloc = NULL; LPSTR pszText = NULL; CRIT_LOGIC logicCrit = CRIT_LOGIC_NULL; Assert((NULL != pIRule) && (NULL != ppDescriptList) && (NULL != pcDescriptList) && (NULL != plogicCrit)); // Initialize the outgoing param *ppDescriptList = NULL; *pcDescriptList = 0; *plogicCrit = CRIT_LOGIC_AND; // Get the list of criteria hr = pIRule->GetProp(RULE_PROP_CRITERIA, 0, &propvar); if (FAILED(hr)) { goto exit; } // Do we have anything to do? if (0 == propvar.blob.cbSize) { hr = S_FALSE; goto exit; } // Grab the criteria list Assert(NULL != propvar.blob.pBlobData); cCritItem = propvar.blob.cbSize / sizeof(CRIT_ITEM); pCritItem = (CRIT_ITEM *) (propvar.blob.pBlobData); propvar.blob.pBlobData = NULL; propvar.blob.cbSize = 0; // For each criteria, add it to the description list for (ulIndex = 0; ulIndex < cCritItem; ulIndex++) { // Create the description list hr = HrAlloc((VOID **) &pDescriptListAlloc, sizeof(RULEDESCRIPT_LIST)); if (FAILED(hr)) { goto exit; } // Initialize the description list ZeroMemory(pDescriptListAlloc, sizeof(RULEDESCRIPT_LIST)); // Search for the criteria type for (ulList = 0; ulList < ARRAYSIZE(c_rgEditCritList); ulList++) { if (pCritItem[ulIndex].type == c_rgEditCritList[ulList].typeCrit) { // Save of the criteria type info pDescriptListAlloc->ulIndex = ulList; // Save off the flags pDescriptListAlloc->dwFlags = pCritItem[ulIndex].dwFlags; // Do we have any data? if (VT_EMPTY != pCritItem[ulIndex].propvar.vt) { // Copy the data SideAssert(SUCCEEDED(PropVariantCopy(&propvar, &(pCritItem[ulIndex].propvar)))); pDescriptListAlloc->propvar = propvar; ZeroMemory(&propvar, sizeof(propvar)); // Build up the description text if (FALSE != _FBuildCriteriaText(pCritItem[ulIndex].type, pDescriptListAlloc->dwFlags, &(pDescriptListAlloc->propvar), &pszText)) { // Save off the string pDescriptListAlloc->pszText = pszText; pszText = NULL; } } // We're done searching break; } } // Did we find anything? if (ulList >= ARRAYSIZE(c_rgEditCritList)) { // Free up the description _FreeDescriptionList(pDescriptListAlloc); } else { // Save the rule description _InsertDescription(&pDescriptList, pDescriptListAlloc); pDescriptListAlloc = NULL; cDescriptList++; } SafeMemFree(pszText); } // Get the logic op logicCrit = (cDescriptList > 1) ? pCritItem->logic : CRIT_LOGIC_AND; // Set the outgoing params *ppDescriptList = pDescriptList; pDescriptList = NULL; *pcDescriptList = cDescriptList; *plogicCrit = logicCrit; // Set the return value hr = S_OK; exit: _FreeDescriptionList(pDescriptList); RuleUtil_HrFreeCriteriaItem(pCritItem, cCritItem); SafeMemFree(pCritItem); return hr; } /////////////////////////////////////////////////////////////////////////////// // // _FChangeCriteriaValue // // This changes the value of the criteria value // // Returns: TRUE, if the criteria value was changed // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CRuleDescriptUI::_FChangeCriteriaValue(RULEDESCRIPT_LIST * pCritList) { BOOL fRet = FALSE; HRESULT hr = S_OK; LPSTR pszText = NULL; ULONG cchText = 0; int iRet = 0; LONG lDiff = 0; FOLDERID idFolder = FOLDERID_ROOT; CHARRANGE chrg; LPSTR pszVal = NULL; ULONG ulVal = 0; SELECTACCT selAcct; IImnAccount * pAccount = NULL; CHARFORMAT chfmtLink; CHARFORMAT chfmtNormal; CRIT_ITEM critItem; RULEFOLDERDATA * prfdData = NULL; ZeroMemory(&critItem, sizeof(critItem)); switch(c_rgEditCritList[pCritList->ulIndex].typeCrit) { case CRIT_TYPE_NEWSGROUP: // Bring up the select newsgroup dialog if ((0 != pCritList->propvar.blob.cbSize) && (NULL != pCritList->propvar.blob.pBlobData)) { // Validate the rule folder data if (S_OK == RuleUtil_HrValidateRuleFolderData((RULEFOLDERDATA *) (pCritList->propvar.blob.pBlobData))) { idFolder = ((RULEFOLDERDATA *) (pCritList->propvar.blob.pBlobData))->idFolder; } } hr = SelectFolderDialog(m_hwndOwner, SFD_SELECTFOLDER, idFolder, TREEVIEW_NOLOCAL | TREEVIEW_NOIMAP | TREEVIEW_NOHTTP | FD_NONEWFOLDERS | FD_DISABLEROOT | FD_DISABLESERVERS | FD_FORCEINITSELFOLDER, MAKEINTRESOURCE(idsSelectNewsgroup), MAKEINTRESOURCE(idsSelectNewsgroupCaption), &idFolder); fRet = (S_OK == hr); if (FALSE != fRet) { STOREUSERDATA UserData = {0}; // Create space for the data structure hr = HrAlloc((VOID **) &prfdData, sizeof(*prfdData)); if (FAILED(hr)) { goto exit; } // Initialize the data struct ZeroMemory(prfdData, sizeof(*prfdData)); // Get the timestamp for the store hr = g_pStore->GetUserData(&UserData, sizeof(STOREUSERDATA)); if (FAILED(hr)) { goto exit; } // Set the timestamp prfdData->ftStamp = UserData.ftCreated; prfdData->idFolder = idFolder; // Set the folder id PropVariantClear(&(pCritList->propvar)); pCritList->propvar.vt = VT_BLOB; pCritList->propvar.blob.cbSize = sizeof(*prfdData); pCritList->propvar.blob.pBlobData = (BYTE *) prfdData; prfdData = NULL; } break; case CRIT_TYPE_SUBJECT: case CRIT_TYPE_BODY: // Duplicate the data critItem.type = c_rgEditCritList[pCritList->ulIndex].typeCrit; critItem.dwFlags = pCritList->dwFlags; critItem.propvar.vt = VT_BLOB; // Copy over the blob data if it is there if ((0 != pCritList->propvar.blob.cbSize) && (NULL != pCritList->propvar.blob.pBlobData)) { hr = HrAlloc((VOID **) &(critItem.propvar.blob.pBlobData), pCritList->propvar.blob.cbSize); if (SUCCEEDED(hr)) { critItem.propvar.blob.cbSize = pCritList->propvar.blob.cbSize; CopyMemory(critItem.propvar.blob.pBlobData, pCritList->propvar.blob.pBlobData, critItem.propvar.blob.cbSize); } } // Edit the words hr = _HrCriteriaEditWords(m_hwndOwner, &critItem); if (FAILED(hr)) { fRet = FALSE; goto exit; } fRet = (S_OK == hr); if (FALSE != fRet) { PropVariantClear(&(pCritList->propvar)); pCritList->dwFlags = critItem.dwFlags; pCritList->propvar = critItem.propvar; critItem.propvar.blob.pBlobData = NULL; critItem.propvar.blob.cbSize = 0; } break; case CRIT_TYPE_TO: case CRIT_TYPE_CC: case CRIT_TYPE_TOORCC: case CRIT_TYPE_FROM: // Duplicate the data critItem.type = c_rgEditCritList[pCritList->ulIndex].typeCrit; critItem.dwFlags = pCritList->dwFlags; critItem.propvar.vt = VT_BLOB; // Copy over the blob data if it is there if ((0 != pCritList->propvar.blob.cbSize) && (NULL != pCritList->propvar.blob.pBlobData)) { hr = HrAlloc((VOID **) &(critItem.propvar.blob.pBlobData), pCritList->propvar.blob.cbSize); if (SUCCEEDED(hr)) { critItem.propvar.blob.cbSize = pCritList->propvar.blob.cbSize; CopyMemory(critItem.propvar.blob.pBlobData, pCritList->propvar.blob.pBlobData, critItem.propvar.blob.cbSize); } } // Edit the people hr = _HrCriteriaEditPeople(m_hwndOwner, &critItem); if (FAILED(hr)) { fRet = FALSE; goto exit; } fRet = (S_OK == hr); if (FALSE != fRet) { PropVariantClear(&(pCritList->propvar)); pCritList->dwFlags = critItem.dwFlags; pCritList->propvar = critItem.propvar; critItem.propvar.blob.pBlobData = NULL; critItem.propvar.blob.cbSize = 0; } break; case CRIT_TYPE_ACCOUNT: // Bring up the rename rule dialog if (NULL != pCritList->propvar.pszVal) { pszVal = PszDupA(pCritList->propvar.pszVal); } selAcct.typeRule = m_typeRule; selAcct.pszAcct = pszVal; iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaAcct), m_hwndOwner, _FSelectAcctDlgProc, (LPARAM) &selAcct); pszVal = selAcct.pszAcct; fRet = (iRet == IDOK); if (FALSE != fRet) { // Figure out account name PropVariantClear(&(pCritList->propvar)); pCritList->propvar.vt = VT_LPSTR; pCritList->propvar.pszVal = pszVal; pszVal = NULL; } break; case CRIT_TYPE_SIZE: // Bring up the rename rule dialog if (NULL != pCritList->propvar.ulVal) { ulVal = pCritList->propvar.ulVal; } iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaSize), m_hwndOwner, _FSelectSizeDlgProc, (LPARAM) &ulVal); fRet = (iRet == IDOK); if (FALSE != fRet) { PropVariantClear(&(pCritList->propvar)); pCritList->propvar.vt = VT_UI4; pCritList->propvar.ulVal = ulVal; } break; case CRIT_TYPE_LINES: // Bring up the line rule dialog if (NULL != pCritList->propvar.ulVal) { ulVal = pCritList->propvar.ulVal; } iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaLines), m_hwndOwner, _FSelectLinesDlgProc, (LPARAM) &ulVal); fRet = (iRet == IDOK); if (FALSE != fRet) { PropVariantClear(&(pCritList->propvar)); pCritList->propvar.vt = VT_UI4; pCritList->propvar.ulVal = ulVal; } break; case CRIT_TYPE_AGE: // Bring up the age rule dialog if (NULL != pCritList->propvar.ulVal) { ulVal = pCritList->propvar.ulVal; } iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaAge), m_hwndOwner, _FSelectAgeDlgProc, (LPARAM) &ulVal); fRet = (iRet == IDOK); if (FALSE != fRet) { PropVariantClear(&(pCritList->propvar)); pCritList->propvar.vt = VT_UI4; pCritList->propvar.ulVal = ulVal; } break; case CRIT_TYPE_PRIORITY: // Bring up the priority rule dialog if (NULL != pCritList->propvar.ulVal) { ulVal = pCritList->propvar.ulVal; } iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaPriority), m_hwndOwner, _FSelectPriorityDlgProc, (LPARAM) &ulVal); fRet = (iRet == IDOK); if (FALSE != fRet) { PropVariantClear(&(pCritList->propvar)); pCritList->propvar.vt = VT_UI4; pCritList->propvar.ulVal = ulVal; } break; case CRIT_TYPE_SECURE: // Bring up the secure rule dialog if (NULL != pCritList->propvar.ulVal) { ulVal = pCritList->propvar.ulVal; } iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaSecure), m_hwndOwner, _FSelectSecureDlgProc, (LPARAM) &ulVal); fRet = (iRet == IDOK); if (FALSE != fRet) { PropVariantClear(&(pCritList->propvar)); pCritList->propvar.vt = VT_UI4; pCritList->propvar.ulVal = ulVal; } break; case CRIT_TYPE_THREADSTATE: // Bring up the thread state rule dialog if (NULL != pCritList->propvar.ulVal) { ulVal = pCritList->propvar.ulVal; } iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaThreadState), m_hwndOwner, _FSelectThreadStateDlgProc, (LPARAM) &ulVal); fRet = (iRet == IDOK); if (FALSE != fRet) { PropVariantClear(&(pCritList->propvar)); pCritList->propvar.vt = VT_UI4; pCritList->propvar.ulVal = ulVal; } break; case CRIT_TYPE_FLAGGED: // Bring up the flag dialog ulVal = (ULONG) (pCritList->dwFlags); iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaFlag), m_hwndOwner, _FSelectFlagDlgProc, (LPARAM) &ulVal); fRet = (iRet == IDOK); if (FALSE != fRet) { PropVariantClear(&(pCritList->propvar)); pCritList->dwFlags = (DWORD) ulVal; pCritList->propvar.vt = VT_EMPTY; } break; case CRIT_TYPE_DOWNLOADED: // Bring up the deletion dialog ulVal = (ULONG) (pCritList->dwFlags); iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaDownloaded), m_hwndOwner, _FSelectDownloadedDlgProc, (LPARAM) &ulVal); fRet = (iRet == IDOK); if (FALSE != fRet) { PropVariantClear(&(pCritList->propvar)); pCritList->dwFlags = (DWORD) ulVal; pCritList->propvar.vt = VT_EMPTY; } break; case CRIT_TYPE_READ: // Bring up the deletion dialog ulVal = (ULONG) (pCritList->dwFlags); iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCriteriaRead), m_hwndOwner, _FSelectReadDlgProc, (LPARAM) &ulVal); fRet = (iRet == IDOK); if (FALSE != fRet) { PropVariantClear(&(pCritList->propvar)); pCritList->dwFlags = (DWORD) ulVal; pCritList->propvar.vt = VT_EMPTY; } break; default: fRet = FALSE; break; } // Update the description field if neccessary if (FALSE != fRet) { // ZIFF // Can we be sure we are really OK?? pCritList->fError = FALSE; // If we have something to build up if (VT_EMPTY != pCritList->propvar.vt) { if (FALSE == _FBuildCriteriaText(c_rgEditCritList[pCritList->ulIndex].typeCrit, pCritList->dwFlags, &(pCritList->propvar), &pszText)) { goto exit; } SafeMemFree(pCritList->pszText); pCritList->pszText = pszText; pszText = NULL; } ShowDescriptionString(); } exit: SafeMemFree(prfdData); SafeMemFree(critItem.propvar.blob.pBlobData); SafeRelease(pAccount); SafeMemFree(pszVal); SafeMemFree(pszText); return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FBuildCriteriaText // // This changes the value of the criteria value // // Returns: TRUE, if the criteria value was changed // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CRuleDescriptUI::_FBuildCriteriaText(CRIT_TYPE type, DWORD dwFlags, PROPVARIANT * ppropvar, LPSTR * ppszText) { BOOL fRet = FALSE; LPSTR pszText = NULL; ULONG cchText = 0; HRESULT hr = S_OK; IImnAccount * pAccount = NULL; FOLDERINFO Folder = {0}; UINT uiId = 0; TCHAR rgchFirst[CCHMAX_STRINGRES]; ULONG cchFirst = 0; TCHAR rgchSecond[CCHMAX_STRINGRES]; ULONG cchSecond = 0; LPTSTR pszString = NULL; LPTSTR pszWalk = NULL; UINT uiID = 0; RULEFOLDERDATA * prfdData = NULL; if ((NULL == ppropvar) || (NULL == ppszText)) { fRet = FALSE; goto exit; } switch(type) { case CRIT_TYPE_NEWSGROUP: if ((0 == ppropvar->blob.cbSize) || (NULL == ppropvar->blob.pBlobData)) { fRet = FALSE; goto exit; } prfdData = (RULEFOLDERDATA *) (ppropvar->blob.pBlobData); // Validate the rule folder data if (S_OK != RuleUtil_HrValidateRuleFolderData(prfdData)) { fRet = FALSE; goto exit; } hr = g_pStore->GetFolderInfo(prfdData->idFolder, &Folder); if (FAILED(hr)) { fRet = FALSE; goto exit; } // Are we subscribed? if (0 == (Folder.dwFlags & FOLDER_SUBSCRIBED)) { fRet = FALSE; goto exit; } pszText = PszDupA(Folder.pszName); if (NULL == pszText) { fRet = FALSE; goto exit; } break; case CRIT_TYPE_SUBJECT: case CRIT_TYPE_BODY: case CRIT_TYPE_TO: case CRIT_TYPE_CC: case CRIT_TYPE_TOORCC: case CRIT_TYPE_FROM: if ((VT_BLOB != ppropvar->vt) || (0 == ppropvar->blob.cbSize) || (NULL == ppropvar->blob.pBlobData) || ('\0' == ppropvar->blob.pBlobData[0])) { fRet = FALSE; goto exit; } pszString = (LPTSTR) ppropvar->blob.pBlobData; // Load up the first template if (0 != (dwFlags & CRIT_FLAG_INVERT)) { uiID = idsCriteriaMultFirstNot; } else { uiID = idsCriteriaMultFirst; } cchFirst = LoadString(g_hLocRes, uiID, rgchFirst, sizeof(rgchFirst)); if (0 == cchFirst) { fRet = FALSE; goto exit; } cchText = cchFirst + 1; // How many strings do we have? if ((lstrlen(pszString) + 3) != (int) ppropvar->blob.cbSize) { if (0 != (dwFlags & CRIT_FLAG_MULTIPLEAND)) { uiID = idsCriteriaMultAnd; } else { uiID = idsCriteriaMultOr; } // Load up the second template cchSecond = LoadString(g_hLocRes, uiID, rgchSecond, sizeof(rgchSecond)); if (0 == cchSecond) { fRet = FALSE; goto exit; } // Add in the second string for each other string for (pszWalk = pszString; '\0' != pszWalk[0]; pszWalk += lstrlen(pszWalk) + 1) { cchText += cchSecond; } } else { rgchSecond[0] = '\0'; } // Total up the space cchText += ppropvar->blob.cbSize; // Allocate the space if (FAILED(HrAlloc((void **) &pszText, cchText))) { fRet = FALSE; goto exit; } // Copy in the first string wnsprintf(pszText, cchText, rgchFirst, pszString); pszString += lstrlen(pszString) + 1; // For each string pszWalk = pszText + lstrlen(pszText); cchText -= lstrlen(pszText); for (; '\0' != pszString[0]; pszString += lstrlen(pszString) + 1) { // Build up the string wnsprintf(pszWalk, cchText, rgchSecond, pszString); cchText -= lstrlen(pszWalk); pszWalk += lstrlen(pszWalk); } break; case CRIT_TYPE_ACCOUNT: Assert(g_pAcctMan); if (!g_pAcctMan || FAILED(g_pAcctMan->FindAccount(AP_ACCOUNT_ID, ppropvar->pszVal, &pAccount))) { fRet = FALSE; goto exit; } if (FAILED(HrAlloc((void **) &pszText, CCHMAX_ACCOUNT_NAME))) { fRet = FALSE; goto exit; } if (FAILED(pAccount->GetPropSz(AP_ACCOUNT_NAME, pszText, CCHMAX_ACCOUNT_NAME))) { fRet = FALSE; goto exit; } break; case CRIT_TYPE_SIZE: if (FAILED(HrAlloc((void **) &pszText, CCHMAX_STRINGRES))) { fRet = FALSE; goto exit; } wnsprintf(pszText, CCHMAX_STRINGRES, "%d ", ppropvar->ulVal); cchText = lstrlen(pszText); LoadString(g_hLocRes, idsKB, pszText + cchText, CCHMAX_STRINGRES - cchText); break; case CRIT_TYPE_LINES: if (FAILED(HrAlloc((void **) &pszText, CCHMAX_STRINGRES))) { fRet = FALSE; goto exit; } wnsprintf(pszText, CCHMAX_STRINGRES, "%d ", ppropvar->ulVal); cchText = lstrlen(pszText); LoadString(g_hLocRes, idsLines, pszText + cchText, CCHMAX_STRINGRES - cchText); break; case CRIT_TYPE_AGE: if (FAILED(HrAlloc((void **) &pszText, CCHMAX_STRINGRES))) { fRet = FALSE; goto exit; } wnsprintf(pszText, CCHMAX_STRINGRES, "%d ", ppropvar->ulVal); cchText = lstrlen(pszText); LoadString(g_hLocRes, idsDays, pszText + cchText, CCHMAX_STRINGRES - cchText); break; case CRIT_TYPE_PRIORITY: if (FAILED(HrAlloc((void **) &pszText, CCHMAX_STRINGRES))) { fRet = FALSE; goto exit; } // Figure out which string to use if (CRIT_DATA_HIPRI == ppropvar->ulVal) { uiId = idsHighPri; } else if (CRIT_DATA_LOPRI == ppropvar->ulVal) { uiId = idsLowPri; } else { uiId = idsNormalPri; } LoadString(g_hLocRes, uiId, pszText, CCHMAX_STRINGRES); break; case CRIT_TYPE_SECURE: if (FAILED(HrAlloc((void **) &pszText, CCHMAX_STRINGRES))) { fRet = FALSE; goto exit; } // Figure out which string to use if (0 != (ppropvar->ulVal & CRIT_DATA_ENCRYPTSECURE)) { uiId = idsSecureEncrypt; } else if (0 != (ppropvar->ulVal & CRIT_DATA_SIGNEDSECURE)) { uiId = idsSecureSigned; } else { uiId = idsSecureNone; } LoadString(g_hLocRes, uiId, pszText, CCHMAX_STRINGRES); break; case CRIT_TYPE_THREADSTATE: if (FAILED(HrAlloc((void **) &pszText, CCHMAX_STRINGRES))) { fRet = FALSE; goto exit; } // Figure out which string to use if (0 != (ppropvar->ulVal & CRIT_DATA_WATCHTHREAD)) { uiId = idsThreadWatch; } else if (0 != (ppropvar->ulVal & CRIT_DATA_IGNORETHREAD)) { uiId = idsThreadIgnore; } else { uiId = idsThreadNone; } LoadString(g_hLocRes, uiId, pszText, CCHMAX_STRINGRES); break; default: fRet = FALSE; goto exit; break; } *ppszText = pszText; pszText = NULL; fRet = TRUE; exit: g_pStore->FreeRecord(&Folder); SafeRelease(pAccount); SafeMemFree(pszText); return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FVerifyCriteria // // This verifies the value of the criteria // // Returns: TRUE, if the criteria value was valid // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CRuleDescriptUI::_FVerifyCriteria(RULEDESCRIPT_LIST * pDescriptList) { BOOL fRet = FALSE; LPSTR pszText = NULL; ULONG cchText = 0; HRESULT hr = S_OK; IImnAccount * pAccount = NULL; FOLDERINFO Folder = {0}; LPSTR pszWalk = NULL; RULEFOLDERDATA * prfdData = NULL; if (NULL == pDescriptList) { fRet = FALSE; goto exit; } switch(c_rgEditCritList[pDescriptList->ulIndex].typeCrit) { case CRIT_TYPE_NEWSGROUP: if ((VT_BLOB != pDescriptList->propvar.vt) || (0 == pDescriptList->propvar.blob.cbSize)) { hr = S_FALSE; goto exit; } // Make life simpler prfdData = (RULEFOLDERDATA *) (pDescriptList->propvar.blob.pBlobData); // Validate the rule folder data if (S_OK != RuleUtil_HrValidateRuleFolderData(prfdData)) { hr = S_FALSE; goto exit; } // Does the folder exist hr = g_pStore->GetFolderInfo(prfdData->idFolder, &Folder); if (FAILED(hr)) { hr = S_FALSE; goto exit; } // Are we subscribed? if (0 == (Folder.dwFlags & FOLDER_SUBSCRIBED)) { hr = S_FALSE; goto exit; } break; case CRIT_TYPE_ALL: case CRIT_TYPE_JUNK: case CRIT_TYPE_READ: case CRIT_TYPE_REPLIES: case CRIT_TYPE_DOWNLOADED: case CRIT_TYPE_DELETED: case CRIT_TYPE_ATTACH: case CRIT_TYPE_FLAGGED: if (VT_EMPTY != pDescriptList->propvar.vt) { fRet = FALSE; goto exit; } break; case CRIT_TYPE_SUBJECT: case CRIT_TYPE_BODY: case CRIT_TYPE_TO: case CRIT_TYPE_CC: case CRIT_TYPE_TOORCC: case CRIT_TYPE_FROM: if ((VT_BLOB != pDescriptList->propvar.vt) || (0 == pDescriptList->propvar.blob.cbSize) || (NULL == pDescriptList->propvar.blob.pBlobData) || ('\0' == pDescriptList->propvar.blob.pBlobData[0])) { fRet = FALSE; goto exit; } // Spin through each item making sure it is perfect cchText = 0; for (pszWalk = (LPTSTR) pDescriptList->propvar.blob.pBlobData; '\0' != pszWalk[0]; pszWalk += lstrlen(pszWalk) + 1) { cchText += lstrlen(pszWalk) + 1; } // For the terminator if ('\0' == pszWalk[0]) { cchText++; } if ('\0' == pszWalk[1]) { cchText++; } if (cchText != pDescriptList->propvar.blob.cbSize) { fRet = FALSE; goto exit; } break; case CRIT_TYPE_SIZE: case CRIT_TYPE_THREADSTATE: case CRIT_TYPE_LINES: case CRIT_TYPE_PRIORITY: case CRIT_TYPE_AGE: case CRIT_TYPE_SECURE: if (VT_UI4 != pDescriptList->propvar.vt) { fRet = FALSE; goto exit; } break; case CRIT_TYPE_ACCOUNT: if ((VT_LPSTR != pDescriptList->propvar.vt) || (NULL == pDescriptList->propvar.pszVal)) { fRet = FALSE; goto exit; } Assert(g_pAcctMan); if (FAILED(g_pAcctMan->FindAccount(AP_ACCOUNT_ID, pDescriptList->propvar.pszVal, &pAccount))) { fRet = FALSE; goto exit; } break; case CRIT_TYPE_SENDER: { LPWSTR pwszText = NULL, pwszVal = NULL; if ((VT_LPSTR != pDescriptList->propvar.vt) || (NULL == pDescriptList->propvar.pszVal)) { AssertSz(VT_LPWSTR != pDescriptList->propvar.vt, "We are getting UNICODE here."); fRet = FALSE; goto exit; } // Verify the email string pwszVal = PszToUnicode(CP_ACP, pDescriptList->propvar.pszVal); if (!pwszVal) { hr = S_FALSE; goto exit; } hr = RuleUtil_HrParseEmailString(pwszVal, 0, &pwszText, NULL); MemFree(pwszVal); MemFree(pwszText); if (FAILED(hr)) { fRet = FALSE; goto exit; } break; } default: fRet = FALSE; goto exit; break; } fRet = TRUE; exit: g_pStore->FreeRecord(&Folder); SafeRelease(pAccount); SafeMemFree(pszText); return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _HrBuildActionList // // This builds the actions list // // Returns: TRUE, if the criteria list was created // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// HRESULT CRuleDescriptUI::_HrBuildActionList(IOERule * pIRule, RULEDESCRIPT_LIST ** ppDescriptList, ULONG * pcDescriptList) { HRESULT hr = S_OK; PROPVARIANT propvar = {0}; ACT_ITEM * pActItem = NULL; ULONG cActItem = 0; ULONG ulIndex = 0; RULEDESCRIPT_LIST * pDescriptList = NULL; ULONG ulList = 0; ULONG cDescriptList = 0; RULEDESCRIPT_LIST * pDescriptListAlloc = NULL; LPSTR pszText = NULL; Assert((NULL != pIRule) && (NULL != ppDescriptList) && (NULL != pcDescriptList)); // Initialize the outgoing param *ppDescriptList = NULL; *pcDescriptList = 0; // Get the list of actions hr = pIRule->GetProp(RULE_PROP_ACTIONS, 0, &propvar); if (FAILED(hr)) { goto exit; } // Do we have anything to do? if (0 == propvar.blob.cbSize) { hr = S_FALSE; goto exit; } // Grab the actions list Assert(NULL != propvar.blob.pBlobData); cActItem = propvar.blob.cbSize / sizeof(ACT_ITEM); pActItem = (ACT_ITEM *) (propvar.blob.pBlobData); propvar.blob.pBlobData = NULL; propvar.blob.cbSize = 0; // For each action, add it to the description list for (ulIndex = 0; ulIndex < cActItem; ulIndex++) { // Create the description list hr = HrAlloc((VOID **) &pDescriptListAlloc, sizeof(RULEDESCRIPT_LIST)); if (FAILED(hr)) { goto exit; } // Initialize the description list ZeroMemory(pDescriptListAlloc, sizeof(RULEDESCRIPT_LIST)); // Search for the criteria type for (ulList = 0; ulList < ARRAYSIZE(c_rgEditActList); ulList++) { if (pActItem[ulIndex].type == c_rgEditActList[ulList].typeAct) { // Save of the criteria type info pDescriptListAlloc->ulIndex = ulList; // Save off the flags pDescriptListAlloc->dwFlags = pActItem[ulIndex].dwFlags; // Do we have any data? if (VT_EMPTY != pActItem[ulIndex].propvar.vt) { // Copy the data SideAssert(SUCCEEDED(PropVariantCopy(&propvar, &(pActItem[ulIndex].propvar)))); pDescriptListAlloc->propvar = propvar; ZeroMemory(&propvar, sizeof(propvar)); // Build up the description text if (FALSE != _FBuildActionText(pActItem[ulIndex].type, &(pDescriptListAlloc->propvar), &pszText)) { pDescriptListAlloc->pszText = pszText; pszText = NULL; } } // We're done searching break; } } // Did we find anything? if (ulList >= ARRAYSIZE(c_rgEditActList)) { // Free up the description _FreeDescriptionList(pDescriptListAlloc); } else { // Save the rule description _InsertDescription(&pDescriptList, pDescriptListAlloc); pDescriptListAlloc = NULL; cDescriptList++; } SafeMemFree(pszText); } // Set the outgoing params *ppDescriptList = pDescriptList; pDescriptList = NULL; *pcDescriptList = cDescriptList; // Set the return value hr = S_OK; exit: _FreeDescriptionList(pDescriptList); RuleUtil_HrFreeActionsItem(pActItem, cActItem); SafeMemFree(pActItem); return hr; } /////////////////////////////////////////////////////////////////////////////// // // _FChangeActionValue // // This changes the value of the action value // // Returns: TRUE, if the criteria value was changed // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CRuleDescriptUI::_FChangeActionValue(RULEDESCRIPT_LIST * pActList) { BOOL fRet = FALSE; LPSTR pszText = NULL; int iRet = 0; LONG lDiff = 0; CHARRANGE chrg; FOLDERID idFolder = FOLDERID_ROOT; LPSTR pszVal = NULL; ULONG ulVal = 0; SELECTADDR selAddr; HRESULT hr = S_OK; OPENFILENAME ofn = {0}; TCHAR szFilter[MAX_PATH] = _T(""); TCHAR szDefExt[20] = _T(""); RULEFOLDERDATA * prfdData = NULL; UINT uiID = 0; switch(c_rgEditActList[pActList->ulIndex].typeAct) { case ACT_TYPE_HIGHLIGHT: // Bring up the rename rule dialog if (NULL != pActList->propvar.ulVal) { ulVal = pActList->propvar.ulVal; } iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddActionColor), m_hwndOwner, _FSelectColorDlgProc, (LPARAM) &ulVal); fRet = (iRet == IDOK); if (FALSE != fRet) { PropVariantClear(&(pActList->propvar)); pActList->propvar.vt = VT_UI4; pActList->propvar.ulVal = ulVal; } break; case ACT_TYPE_WATCH: // Bring up the watch or ignore dialog if (NULL != pActList->propvar.ulVal) { ulVal = pActList->propvar.ulVal; } iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddActionWatch), m_hwndOwner, _FSelectWatchDlgProc, (LPARAM) &ulVal); fRet = (iRet == IDOK); if (FALSE != fRet) { PropVariantClear(&(pActList->propvar)); pActList->propvar.vt = VT_UI4; pActList->propvar.ulVal = ulVal; } break; case ACT_TYPE_COPY: case ACT_TYPE_MOVE: // Bring up the change folder dialog if ((0 != pActList->propvar.blob.cbSize) && (NULL != pActList->propvar.blob.pBlobData)) { // Validate the rule folder data if (S_OK == RuleUtil_HrValidateRuleFolderData((RULEFOLDERDATA *) (pActList->propvar.blob.pBlobData))) { idFolder = ((RULEFOLDERDATA *) (pActList->propvar.blob.pBlobData))->idFolder; } } hr = SelectFolderDialog(m_hwndOwner, SFD_SELECTFOLDER, idFolder, TREEVIEW_NONEWS | TREEVIEW_NOIMAP | TREEVIEW_NOHTTP | FD_DISABLEROOT | FD_DISABLEOUTBOX | FD_DISABLEINBOX | FD_DISABLESENTITEMS | FD_DISABLESERVERS | FD_FORCEINITSELFOLDER, (c_rgEditActList[pActList->ulIndex].typeAct == ACT_TYPE_COPY) ? MAKEINTRESOURCE(idsCopy) : MAKEINTRESOURCE(idsMove), (c_rgEditActList[pActList->ulIndex].typeAct == ACT_TYPE_COPY) ? MAKEINTRESOURCE(idsCopyCaption) : MAKEINTRESOURCE(idsMoveCaption), &idFolder); fRet = (S_OK == hr); if (FALSE != fRet) { STOREUSERDATA UserData = {0}; // Create space for the data structure hr = HrAlloc((VOID **) &prfdData, sizeof(*prfdData)); if (FAILED(hr)) { goto exit; } // Initialize the data struct ZeroMemory(prfdData, sizeof(*prfdData)); // Get the timestamp for the store hr = g_pStore->GetUserData(&UserData, sizeof(STOREUSERDATA)); if (FAILED(hr)) { goto exit; } // Set the timestamp prfdData->ftStamp = UserData.ftCreated; prfdData->idFolder = idFolder; // Set the folder id PropVariantClear(&(pActList->propvar)); pActList->propvar.vt = VT_BLOB; pActList->propvar.blob.cbSize = sizeof(*prfdData); pActList->propvar.blob.pBlobData = (BYTE *) prfdData; prfdData = NULL; } break; case ACT_TYPE_REPLY: case ACT_TYPE_NOTIFYSND: // Bring up the select file dialog hr = HrAlloc((void **) &pszVal, MAX_PATH * sizeof(*pszVal)); if (FAILED(hr)) { fRet = FALSE; goto exit; } pszVal[0] = '\0'; if (NULL != pActList->propvar.pszVal) { StrCpyN(pszVal, pActList->propvar.pszVal, MAX_PATH * sizeof(*pszVal)); } if (ACT_TYPE_NOTIFYSND == c_rgEditActList[pActList->ulIndex].typeAct) { uiID = idsRuleNtfySndFilter; } else { uiID = idsRuleReplyWithFilter; } // Load Res Strings LoadStringReplaceSpecial(uiID, szFilter, sizeof(szFilter)); // Setup Save file struct ofn.lStructSize = sizeof (ofn); ofn.hwndOwner = m_hwndOwner; ofn.lpstrFilter = szFilter; ofn.nFilterIndex = 2; ofn.lpstrFile = pszVal; ofn.nMaxFile = MAX_PATH * sizeof(*pszVal); ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR; hr = HrAthGetFileName(&ofn, TRUE); fRet = (S_OK == hr); if (FALSE != fRet) { PropVariantClear(&(pActList->propvar)); pActList->propvar.vt = VT_LPSTR; pActList->propvar.pszVal = pszVal; pszVal = NULL; } break; case ACT_TYPE_FWD: { LPWSTR pwszVal = NULL; if (NULL != pActList->propvar.pszVal) { pwszVal = PszToUnicode(CP_ACP, pActList->propvar.pszVal); if (!pwszVal) { fRet = FALSE; break; } } // Bring up the address picker selAddr.lRecipType = MAPI_TO; selAddr.uidsWell = idsRulePickForwardTo; selAddr.pwszAddr = pwszVal; iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddActionFwd), m_hwndOwner, _FSelectAddrDlgProc, (LPARAM) &selAddr); pwszVal = selAddr.pwszAddr; fRet = (iRet == IDOK); if (FALSE != fRet) { PropVariantClear(&(pActList->propvar)); pActList->propvar.vt = VT_LPSTR; pActList->propvar.pszVal = PszToANSI(CP_ACP, pwszVal); pwszVal = NULL; } MemFree(pwszVal); break; } case ACT_TYPE_SHOW: // Bring up the watch or ignore dialog if (NULL != pActList->propvar.ulVal) { ulVal = pActList->propvar.ulVal; } iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddActionsShow), m_hwndOwner, _FSelectShowDlgProc, (LPARAM) &ulVal); fRet = (iRet == IDOK); if (FALSE != fRet) { PropVariantClear(&(pActList->propvar)); pActList->propvar.vt = VT_UI4; pActList->propvar.ulVal = ulVal; } break; default: fRet = FALSE; break; } // Update the description field if neccessary if (FALSE != fRet) { // ZIFF // Can we be sure we are really OK?? pActList->fError = FALSE; // If we have something to build up if (VT_EMPTY != pActList->propvar.vt) { if (FALSE == _FBuildActionText(c_rgEditActList[pActList->ulIndex].typeAct, &(pActList->propvar), &pszText)) { goto exit; } SafeMemFree(pActList->pszText); pActList->pszText = pszText; pszText = NULL; } ShowDescriptionString(); } exit: SafeMemFree(prfdData); SafeMemFree(pszVal); SafeMemFree(pszText); return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FBuildActionText // // This changes the value of the action value // // Returns: TRUE, if the criteria value was changed // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CRuleDescriptUI::_FBuildActionText(ACT_TYPE type, PROPVARIANT * ppropvar, LPSTR * ppszText) { BOOL fRet = FALSE; LPSTR pszText = NULL; TCHAR szRes[CCHMAX_STRINGRES]; HRESULT hr = S_OK; FOLDERINFO Folder={0}; UINT uiId = 0; RULEFOLDERDATA * prfdData = NULL; if ((NULL == ppropvar) || (NULL == ppszText)) { fRet = FALSE; goto exit; } switch(type) { case ACT_TYPE_HIGHLIGHT: LoadString(g_hLocRes, ppropvar->ulVal + idsAutoColor, szRes, sizeof(szRes)/sizeof(TCHAR)); pszText = PszDupA(szRes); if (NULL == pszText) { fRet = FALSE; goto exit; } break; case ACT_TYPE_WATCH: if (FAILED(HrAlloc((void **) &pszText, CCHMAX_STRINGRES))) { fRet = FALSE; goto exit; } // Figure out which string to use switch (ppropvar->ulVal) { case ACT_DATA_WATCHTHREAD: uiId = idsThreadWatch; break; case ACT_DATA_IGNORETHREAD: uiId = idsThreadIgnore; break; default: uiId = idsThreadNone; break; } LoadString(g_hLocRes, uiId, pszText, CCHMAX_STRINGRES); break; case ACT_TYPE_COPY: case ACT_TYPE_MOVE: if ((0 == ppropvar->blob.cbSize) || (NULL == ppropvar->blob.pBlobData)) { fRet = FALSE; goto exit; } prfdData = (RULEFOLDERDATA *) (ppropvar->blob.pBlobData); // Validate the rule folder data if (S_OK != RuleUtil_HrValidateRuleFolderData(prfdData)) { fRet = FALSE; goto exit; } hr = g_pStore->GetFolderInfo(prfdData->idFolder, &Folder); if (FAILED(hr)) { fRet = FALSE; goto exit; } pszText = PszDupA(Folder.pszName); if (NULL == pszText) { fRet = FALSE; goto exit; } break; case ACT_TYPE_REPLY: case ACT_TYPE_NOTIFYSND: pszText = PszDupA(ppropvar->pszVal); if (NULL == pszText) { fRet = FALSE; goto exit; } break; case ACT_TYPE_FWD: { LPWSTR pwszVal = PszToUnicode(CP_ACP, ppropvar->pszVal), pwszText = NULL; if (ppropvar->pszVal && !pwszVal) { fRet = FALSE; goto exit; } // Update the display string hr = RuleUtil_HrParseEmailString(pwszVal, 0, &pwszText, NULL); MemFree(pwszVal); pszText = PszToANSI(CP_ACP, pwszText); if (pwszText && !pszText) { fRet = FALSE; goto exit; } MemFree(pwszText); if (FAILED(hr)) { fRet = FALSE; goto exit; } break; } case ACT_TYPE_SHOW: if (FAILED(HrAlloc((void **) &pszText, CCHMAX_STRINGRES))) { fRet = FALSE; goto exit; } // Figure out which string to use switch (ppropvar->ulVal) { case ACT_DATA_SHOW: uiId = idsShowMessages; break; case ACT_DATA_HIDE: uiId = idsHideMessages; break; default: uiId = idsShowHideMessages; break; } LoadString(g_hLocRes, uiId, pszText, CCHMAX_STRINGRES); break; default: fRet = FALSE; goto exit; break; } *ppszText = pszText; pszText = NULL; fRet = TRUE; exit: SafeMemFree(pszText); g_pStore->FreeRecord(&Folder); return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FVerifyAction // // This verifies the value of the action value // // Returns: TRUE, if the criteria value was changed // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CRuleDescriptUI::_FVerifyAction(RULEDESCRIPT_LIST * pDescriptList) { BOOL fRet = FALSE; LPSTR pszText = NULL; HRESULT hr = S_OK; FOLDERINFO Folder={0}; RULEFOLDERDATA * prfdData = NULL; if (NULL == pDescriptList) { fRet = FALSE; goto exit; } switch(c_rgEditActList[pDescriptList->ulIndex].typeAct) { // These ones are always valid case ACT_TYPE_DELETESERVER: case ACT_TYPE_DONTDOWNLOAD: case ACT_TYPE_FLAG: case ACT_TYPE_READ: case ACT_TYPE_MARKDOWNLOAD: case ACT_TYPE_DELETE: case ACT_TYPE_JUNKMAIL: case ACT_TYPE_STOP: if (VT_EMPTY != pDescriptList->propvar.vt) { fRet = FALSE; goto exit; } break; case ACT_TYPE_HIGHLIGHT: if (VT_UI4 != pDescriptList->propvar.vt) { hr = S_FALSE; goto exit; } break; case ACT_TYPE_WATCH: case ACT_TYPE_SHOW: if (VT_UI4 != pDescriptList->propvar.vt) { hr = S_FALSE; goto exit; } if (ACT_DATA_NULL == pDescriptList->propvar.ulVal) { hr = S_FALSE; goto exit; } break; case ACT_TYPE_COPY: case ACT_TYPE_MOVE: if ((VT_BLOB != pDescriptList->propvar.vt) || (0 == pDescriptList->propvar.blob.cbSize)) { hr = S_FALSE; goto exit; } // Make life simpler prfdData = (RULEFOLDERDATA *) (pDescriptList->propvar.blob.pBlobData); // Validate the rule folder data if (S_OK != RuleUtil_HrValidateRuleFolderData(prfdData)) { hr = S_FALSE; goto exit; } hr = g_pStore->GetFolderInfo(prfdData->idFolder, &Folder); if (FAILED(hr)) { hr = S_FALSE; goto exit; } else g_pStore->FreeRecord(&Folder); break; case ACT_TYPE_REPLY: case ACT_TYPE_NOTIFYSND: if ((VT_LPSTR != pDescriptList->propvar.vt) || (NULL == pDescriptList->propvar.pszVal)) { fRet = FALSE; goto exit; } Assert(lstrlen(pDescriptList->propvar.pszVal) <= MAX_PATH) if (0xFFFFFFFF == GetFileAttributes(pDescriptList->propvar.pszVal)) { hr = S_FALSE; goto exit; } break; case ACT_TYPE_FWD: { LPWSTR pwszVal = NULL, pwszText = NULL; if ((VT_LPSTR != pDescriptList->propvar.vt) || (NULL == pDescriptList->propvar.pszVal)) { AssertSz(VT_LPWSTR != pDescriptList->propvar.vt, "We have UNICODE coming in."); fRet = FALSE; goto exit; } // Update the display string pwszVal = PszToUnicode(CP_ACP, pDescriptList->propvar.pszVal); if (!pwszVal) { fRet = FALSE; goto exit; } hr = RuleUtil_HrParseEmailString(pwszVal, 0, &pwszText, NULL); MemFree(pwszText); MemFree(pwszVal); if (FAILED(hr)) { fRet = FALSE; goto exit; } // If either always encrypt or always sign is turned on // we can't do anything if ((0 != DwGetOption(OPT_MAIL_DIGSIGNMESSAGES)) || (0 != DwGetOption(OPT_MAIL_ENCRYPTMESSAGES))) { hr = S_FALSE; goto exit; } break; } default: fRet = FALSE; goto exit; break; } fRet = TRUE; exit: SafeMemFree(pszText); return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _UpdateRanges // // This initializes the actions list view with the list of actions // // Returns: TRUE, if it was successfully loaded // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// void CRuleDescriptUI::_UpdateRanges(LONG lDiff, ULONG ulStart) { TCHAR szRes[CCHMAX_STRINGRES + 3]; ULONG cchRes = 0; RULEDESCRIPT_LIST * pDescriptListWalk = NULL; if (0 == lDiff) { goto exit; } // Update the criteria ranges for (pDescriptListWalk = m_pDescriptListCrit; pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext) { if (pDescriptListWalk->ulStartLogic > ulStart) { pDescriptListWalk->ulStartLogic += lDiff; pDescriptListWalk->ulEndLogic += lDiff; pDescriptListWalk->ulStart += lDiff; pDescriptListWalk->ulEnd += lDiff; } else if (pDescriptListWalk->ulStart > ulStart) { pDescriptListWalk->ulStart += lDiff; pDescriptListWalk->ulEnd += lDiff; } } // Update the action ranges for (pDescriptListWalk = m_pDescriptListAct; pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext) { if (pDescriptListWalk->ulStart > ulStart) { pDescriptListWalk->ulStart += lDiff; pDescriptListWalk->ulEnd += lDiff; } } exit: return; } /////////////////////////////////////////////////////////////////////////////// // // _InsertDescription // // This adds a description node to the list of descriptions // // Returns: NONE // /////////////////////////////////////////////////////////////////////////////// void CRuleDescriptUI::_InsertDescription(RULEDESCRIPT_LIST ** ppDescriptList, RULEDESCRIPT_LIST * pDescriptListNew) { RULEDESCRIPT_LIST * pDescriptListWalk = NULL; RULEDESCRIPT_LIST * pDescriptListPrev = NULL; Assert(NULL != ppDescriptList); // Search for the proper place to place the new item for (pDescriptListWalk = *ppDescriptList; pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext) { if (pDescriptListWalk->ulIndex > pDescriptListNew->ulIndex) { break; } // Save off the old description pDescriptListPrev = pDescriptListWalk; } // If it's supposed to go at the top if (NULL == pDescriptListPrev) { *ppDescriptList = pDescriptListNew; pDescriptListNew->pNext = pDescriptListWalk; } else { pDescriptListNew->pNext = pDescriptListWalk; pDescriptListPrev->pNext = pDescriptListNew; } return; } /////////////////////////////////////////////////////////////////////////////// // // _FRemoveDescription // // This adds a description node to the list of descriptions // // Returns: NONE // /////////////////////////////////////////////////////////////////////////////// BOOL CRuleDescriptUI::_FRemoveDescription(RULEDESCRIPT_LIST ** ppDescriptList, ULONG ulIndex, RULEDESCRIPT_LIST ** ppDescriptListRemove) { BOOL fRet = FALSE; RULEDESCRIPT_LIST * pDescriptListWalk = NULL; RULEDESCRIPT_LIST * pDescriptListPrev = NULL; Assert((NULL != ppDescriptList) && (NULL != ppDescriptListRemove)); *ppDescriptListRemove = NULL; // Find the criteria item in the list for (pDescriptListWalk = *ppDescriptList; pDescriptListWalk != NULL; pDescriptListWalk = pDescriptListWalk->pNext) { if (ulIndex == pDescriptListWalk->ulIndex) { break; } // Save off the old description pDescriptListPrev = pDescriptListWalk; } // Did we find the criteria item? if (NULL == pDescriptListWalk) { fRet = FALSE; goto exit; } // Remove the criteria item from the list if (NULL == pDescriptListPrev) { *ppDescriptList = pDescriptListWalk->pNext; } else { pDescriptListPrev->pNext = pDescriptListWalk->pNext; } pDescriptListWalk->pNext = NULL; // Set the outgoing params *ppDescriptListRemove = pDescriptListWalk; // Set the return value fRet = TRUE; exit: return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FreeDescriptionLists // // This frees the list of descriptions // // Returns: NONE // /////////////////////////////////////////////////////////////////////////////// void CRuleDescriptUI::_FreeDescriptionList(RULEDESCRIPT_LIST * pDescriptList) { RULEDESCRIPT_LIST * pDescriptListWalk = NULL; while (NULL != pDescriptList) { pDescriptListWalk = pDescriptList; SafeMemFree(pDescriptListWalk->pszText); PropVariantClear(&(pDescriptListWalk->propvar)); pDescriptList = pDescriptListWalk->pNext; MemFree(pDescriptListWalk); } return; } /////////////////////////////////////////////////////////////////////////////// // // _FOnDescriptClick // // This handles clicking on the links in the description field // // uiMsg - the type of click // ulIndex - which criteria/action to change // fCrit - did we click on a criteria? // fLogic - did we click on a logic op? // // Returns: TRUE, we changed the criteria/action // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CRuleDescriptUI::_FOnDescriptClick(UINT uiMsg, RULEDESCRIPT_LIST * pDescriptList, BOOL fCrit, BOOL fLogic) { BOOL fRet = FALSE; CHARRANGE chrg; NMHDR nmhdr; if ((WM_LBUTTONUP == uiMsg) || (WM_KEYDOWN == uiMsg)) { // Release the capture if there is one if (NULL != GetCapture()) { ReleaseCapture(); } // Did we click in the logic op? if (fLogic) { fRet = _FChangeLogicValue(pDescriptList); } // Did we click in the criteria list? else if (fCrit) { fRet = _FChangeCriteriaValue(pDescriptList); } else { fRet = _FChangeActionValue(pDescriptList); } if (fRet) { m_dwState |= STATE_DIRTY; // Tell the parent dialog something has changed nmhdr.hwndFrom = m_hwndOwner; nmhdr.idFrom = GetDlgCtrlID(m_hwndOwner); nmhdr.code = NM_RULE_CHANGED; SendMessage(GetParent(m_hwndOwner), WM_NOTIFY, (WPARAM) (nmhdr.idFrom), (LPARAM) &nmhdr); } fRet = TRUE; } if (((WM_LBUTTONDOWN == uiMsg) || (WM_LBUTTONDBLCLK == uiMsg)) && (0 == (GetAsyncKeyState(VK_CONTROL) & 0x8000))) { if (fLogic) { chrg.cpMin = pDescriptList->ulStartLogic; chrg.cpMax = pDescriptList->ulEndLogic; } else { chrg.cpMin = pDescriptList->ulStart; chrg.cpMax = pDescriptList->ulEnd; } // Need to make sure we show the selection SendMessage(m_hwndOwner, EM_HIDESELECTION, (WPARAM) FALSE, (LPARAM) FALSE); RichEditExSetSel(m_hwndOwner, &chrg); fRet = TRUE; } return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FInLink // // Given a point in the control, this will tell us whether or not the point // is in a link // // ppt - the point to check // pulIndex - which criteria/action is the point in // pfCrit - is the point over a criteria? // pfLogic - is the point over a logic op? // // Returns: TRUE, if the point is over a criteria/action // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CRuleDescriptUI::_FInLink(int chPos, RULEDESCRIPT_LIST ** ppDescriptList, BOOL * pfCrit, BOOL * pfLogic) { BOOL fFound = FALSE; RULEDESCRIPT_LIST * pDescriptListWalk = NULL; POINT pt; ULONG ulIndex = 0; BOOL fCrit = FALSE; BOOL fLogic = FALSE; LONG idxLine = 0; LPSTR pszBuff = NULL; ULONG cchBuff = 0; HDC hdc = NULL; HFONT hfont = NULL; HFONT hfontOld = NULL; SIZE size; LONG idxPosLine = 0; // If we're read only then we can't be in a link if ((0 != (m_dwState & STATE_READONLY)) || (0 == chPos)) { fFound = FALSE; goto exit; } // Did we click in the criteria list? for (pDescriptListWalk = m_pDescriptListCrit; NULL != pDescriptListWalk; pDescriptListWalk = pDescriptListWalk->pNext) { if (((LONG) pDescriptListWalk->ulStart <= chPos) && ((LONG) pDescriptListWalk->ulEnd >= chPos)) { fCrit = TRUE; fFound = TRUE; break; } if (((LONG) pDescriptListWalk->ulStartLogic <= chPos) && ((LONG) pDescriptListWalk->ulEndLogic >= chPos)) { fLogic = TRUE; fFound = TRUE; break; } } if (!fFound) { // Did we click in the actions list for (pDescriptListWalk = m_pDescriptListAct; NULL != pDescriptListWalk; pDescriptListWalk = pDescriptListWalk->pNext) { if (((LONG) pDescriptListWalk->ulStart <= chPos) && ((LONG) pDescriptListWalk->ulEnd >= chPos)) { fFound = TRUE; break; } } } if (ppDescriptList) { *ppDescriptList = pDescriptListWalk; } if (pfCrit) { *pfCrit = fCrit; } if (pfLogic) { *pfLogic = fLogic; } goto exit; exit: if (NULL != hdc) { ReleaseDC(m_hwndOwner, hdc); } MemFree(pszBuff); return fFound; } VOID _SearchForLink(RULEDESCRIPT_LIST * pDescriptList, BOOL fUp, LONG lPos, CHARRANGE * pcrPos) { RULEDESCRIPT_LIST * pDescriptListWalk = NULL; Assert(NULL != pcrPos); // Find the closest link... for (pDescriptListWalk = pDescriptList; NULL != pDescriptListWalk; pDescriptListWalk = pDescriptListWalk->pNext) { // Do we have a criteria link? if (0 != pDescriptListWalk->ulStart) { // Are we going down? if (FALSE == fUp) { // Is the link past the current position? if ((LONG) pDescriptListWalk->ulEnd > lPos) { // Save off the closest link to the current position if ((0 == pcrPos->cpMin) || ((LONG) pDescriptListWalk->ulStart < pcrPos->cpMin)) { pcrPos->cpMin = (LONG) pDescriptListWalk->ulStart; pcrPos->cpMax = (LONG) pDescriptListWalk->ulEnd; } } } else { // Is the link before the current position? if ((LONG) pDescriptListWalk->ulEnd < lPos) { // Save off the closest link to the current position if ((0 == pcrPos->cpMin) || ((LONG) pDescriptListWalk->ulStart > pcrPos->cpMin)) { pcrPos->cpMin = (LONG) pDescriptListWalk->ulStart; pcrPos->cpMax = (LONG) pDescriptListWalk->ulEnd; } } } } // Do we have a logic link? if (0 != pDescriptListWalk->ulStartLogic) { // Are we going down? if (FALSE == fUp) { // Is the link past the current position? if ((LONG) pDescriptListWalk->ulEndLogic > lPos) { // Save off the closest link to the current position if ((0 == pcrPos->cpMin) || ((LONG) pDescriptListWalk->ulStartLogic < pcrPos->cpMin)) { pcrPos->cpMin = (LONG) pDescriptListWalk->ulStartLogic; pcrPos->cpMax = (LONG) pDescriptListWalk->ulEndLogic; } } } else { // Is the link before the current position? if ((LONG) pDescriptListWalk->ulEndLogic < lPos) { // Save off the closest link to the current position if ((0 == pcrPos->cpMin) || ((LONG) pDescriptListWalk->ulStartLogic > pcrPos->cpMin)) { pcrPos->cpMin = (LONG) pDescriptListWalk->ulStartLogic; pcrPos->cpMax = (LONG) pDescriptListWalk->ulEndLogic; } } } } } return; } /////////////////////////////////////////////////////////////////////////////// // // _FMoveToLink // // Given a point in the control, this will tell us whether or not the point // is in a link // // ppt - the point to check // pulIndex - which criteria/action is the point in // pfCrit - is the point over a criteria? // pfLogic - is the point over a logic op? // // Returns: TRUE, if the point is over a criteria/action // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CRuleDescriptUI::_FMoveToLink(UINT uiKeyCode) { BOOL fRet = FALSE; BOOL fUp = FALSE; CHARRANGE crPos = {0}; CHARRANGE crLink = {0}; // Figure out which way we are going fUp = ((VK_LEFT == uiKeyCode) || (VK_UP == uiKeyCode)); // Get the current character position RichEditExGetSel(m_hwndOwner, &crPos); // Find the closest link in the criteria _SearchForLink(m_pDescriptListCrit, fUp, crPos.cpMax, &crLink); // Find the closest link in the actions _SearchForLink(m_pDescriptListAct, fUp, crPos.cpMax, &crLink); // Do we have anything to do? if (0 != crLink.cpMin) { // Set the new selection RichEditExSetSel(m_hwndOwner, &crLink); SendMessage(m_hwndOwner, EM_SCROLLCARET, (WPARAM) 0, (LPARAM) 0); fRet = TRUE; } return fRet; } LRESULT CALLBACK CRuleDescriptUI::_DescriptWndProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) { LRESULT lRes = 0; POINT ptCur; CRuleDescriptUI * pDescriptUI = NULL; HCURSOR hcursor = NULL; RULEDESCRIPT_LIST * pDescriptList = NULL; BOOL fCrit = FALSE; BOOL fLogic = FALSE; CHARRANGE crPos = {0}; int chPos = 0; pDescriptUI = (CRuleDescriptUI *) GetWindowLongPtr(hwnd, GWLP_USERDATA); switch (uiMsg) { case WM_SETCURSOR: if((FALSE != IsWindowVisible(hwnd)) && ((HWND) wParam == hwnd)) { lRes = DefWindowProc(hwnd, uiMsg, wParam, lParam); if(0 == lRes) { GetCursorPos(&ptCur); ScreenToClient(hwnd, &ptCur); chPos = (int) SendMessage(hwnd, EM_CHARFROMPOS, (WPARAM)0, (LPARAM)&ptCur); chPos = RichEditNormalizeCharPos(hwnd, chPos, NULL); if (FALSE != pDescriptUI->_FInLink(chPos, NULL, NULL, NULL)) { hcursor = LoadCursor(g_hLocRes, MAKEINTRESOURCE(idcurBrHand)); SetCursor(hcursor); lRes = TRUE; } } } break; case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONUP: GetCursorPos(&ptCur); ScreenToClient(hwnd, &ptCur); chPos = (int) SendMessage(hwnd, EM_CHARFROMPOS, (WPARAM)0, (LPARAM)&ptCur); chPos = RichEditNormalizeCharPos(hwnd, chPos, NULL); if (FALSE != pDescriptUI->_FInLink(chPos, &pDescriptList, &fCrit, &fLogic)) { // Change the proper value lRes = pDescriptUI->_FOnDescriptClick(uiMsg, pDescriptList, fCrit, fLogic); } break; case WM_KEYDOWN: switch (wParam) { case VK_RETURN: RichEditExGetSel(hwnd, &crPos); if (FALSE != pDescriptUI->_FInLink(crPos.cpMin, &pDescriptList, &fCrit, &fLogic)) { // Change the proper value lRes = pDescriptUI->_FOnDescriptClick(uiMsg, pDescriptList, fCrit, fLogic); } break; case VK_LEFT: case VK_UP: case VK_RIGHT: case VK_DOWN: lRes = pDescriptUI->_FMoveToLink((UINT) wParam); break; } break; } if (0 == lRes) { lRes = CallWindowProc(pDescriptUI->m_wpcOld, hwnd, uiMsg, wParam, lParam); } return lRes; } /////////////////////////////////////////////////////////////////////////////// // // _FSelectAddrDlgProc // // This is the main dialog proc for changing addresses // // hwndDlg - handle to the filter manager dialog // uMsg - the message to be acted upon // wParam - the 'word' parameter for the message // lParam - the 'long' parameter for the message // // Returns: TRUE, if the message was handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// INT_PTR CALLBACK CRuleDescriptUI::_FSelectAddrDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; SELECTADDR * pseladdr = NULL; HWND hwndAddr = NULL; LPWSTR pwszText = NULL, pwszAddr = NULL; ULONG cchText = 0, cchAddr = 0; HRESULT hr = S_OK; pseladdr = (SELECTADDR *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: // Grab the propvariant pointer pseladdr = (SELECTADDR *) lParam; if (NULL == pseladdr) { fRet = FALSE; EndDialog(hwndDlg, -1); goto exit; } // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pseladdr); hwndAddr = GetDlgItem(hwndDlg, idedtCriteriaAddr); SetIntlFont(hwndAddr); // Set the name of the rule into the edit well if (NULL == pseladdr->pwszAddr) { Edit_SetText(hwndAddr, c_szEmpty); } else { if (FAILED(RuleUtil_HrParseEmailString(pseladdr->pwszAddr, 0, &pwszText, NULL))) { fRet = FALSE; EndDialog(hwndDlg, -1); goto exit; } SetWindowTextWrapW(hwndAddr, pwszText); SafeMemFree(pwszText); } // We didn't set the focus so return TRUE fRet = TRUE; break; case WM_COMMAND: switch (LOWORD(wParam)) { case idedtCriteriaAddr: if (EN_CHANGE == HIWORD(wParam)) { hwndAddr = (HWND) lParam; Assert(NULL != hwndAddr); RuleUtil_FEnDisDialogItem(hwndDlg, IDOK, 0 != Edit_GetTextLength(hwndAddr)); } break; case idbCriteriaAddr: hwndAddr = GetDlgItem(hwndDlg, idedtCriteriaAddr); // Get the name of the rule from the edit well cchText = Edit_GetTextLength(hwndAddr) + 1; if (FAILED(HrAlloc((void **) &pwszText, cchText * sizeof(*pwszText)))) { fRet = FALSE; goto exit; } pwszText[0] = L'\0'; cchText = GetWindowTextWrapW(hwndAddr, pwszText, cchText); hr = RuleUtil_HrBuildEmailString(pwszText, cchText, &pwszAddr, &cchAddr); SafeMemFree(pwszText); if (FAILED(hr)) { fRet = FALSE; goto exit; } hr = RuleUtil_HrPickEMailNames(hwndDlg, pseladdr->lRecipType, pseladdr->uidsWell, &pwszAddr); if (S_OK != hr) { fRet = FALSE; SafeMemFree(pwszAddr); goto exit; } if (S_OK != RuleUtil_HrParseEmailString(pwszAddr, 0, &pwszText, NULL)) { fRet = FALSE; SafeMemFree(pwszAddr); goto exit; } SetWindowTextWrapW(hwndAddr, pwszText); SafeMemFree(pwszText); SafeMemFree(pwszAddr); break; case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); fRet = TRUE; break; case IDOK: hwndAddr = GetDlgItem(hwndDlg, idedtCriteriaAddr); // Get the name of the rule from the edit well cchText = Edit_GetTextLength(hwndAddr) + 1; if (FAILED(HrAlloc((void **) &pwszText, cchText * sizeof(*pwszText)))) { fRet = FALSE; goto exit; } pwszText[0] = L'\0'; cchText = GetWindowTextWrapW(hwndAddr, pwszText, cchText); // Check to see if the rule name is valid if ((FAILED(RuleUtil_HrBuildEmailString(pwszText, cchText, &pwszAddr, &cchAddr))) || (0 == cchAddr)) { // Put up a message saying something is busted AthMessageBoxW(hwndDlg, MAKEINTRESOURCEW(idsAthenaMail), MAKEINTRESOURCEW(idsRulesErrorNoAddr), NULL, MB_OK | MB_ICONINFORMATION); SafeMemFree(pwszText); SafeMemFree(pwszAddr); fRet = FALSE; goto exit; } SafeMemFree(pseladdr->pwszAddr); pseladdr->pwszAddr = pwszAddr; SafeMemFree(pwszText); EndDialog(hwndDlg, IDOK); fRet = TRUE; break; } break; } exit: return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FSelectAcctDlgProc // // This is the main dialog proc for selecting an account dialog // // hwndDlg - handle to the filter manager dialog // uMsg - the message to be acted upon // wParam - the 'word' parameter for the message // lParam - the 'long' parameter for the message // // Returns: TRUE, if the message was handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// INT_PTR CALLBACK CRuleDescriptUI::_FSelectAcctDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; SELECTACCT * pselacct = NULL; LPSTR pszAcct = NULL; ULONG cchAcct = 0; HWND hwndAcct = NULL; CHAR szAccount[CCHMAX_ACCOUNT_NAME]; IImnAccount * pAccount = NULL; IImnEnumAccounts * pEnumAcct = NULL; DWORD dwSrvTypes = 0; ULONG ulIndex = 0; BOOL fSelected = FALSE; pselacct = (SELECTACCT *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: // Grab the propvariant pointer pselacct = (SELECTACCT *) lParam; if (NULL == pselacct) { fRet = FALSE; EndDialog(hwndDlg, -1); goto exit; } // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pselacct); hwndAcct = GetDlgItem(hwndDlg, idcCriteriaAcct); SetIntlFont(hwndAcct); // Set the name of the rule into the edit well Assert(g_pAcctMan); switch (pselacct->typeRule) { case RULE_TYPE_MAIL: dwSrvTypes = SRV_POP3; break; case RULE_TYPE_NEWS: dwSrvTypes = SRV_NNTP; break; case RULE_TYPE_FILTER: dwSrvTypes = SRV_MAIL | SRV_NNTP; break; } // Grab the enumerator from the account manager if (FAILED(g_pAcctMan->Enumerate(dwSrvTypes, &pEnumAcct))) { fRet = FALSE; goto exit; } // Insert each account into the combobox while(SUCCEEDED(pEnumAcct->GetNext(&pAccount))) { // We can get back NULL accounts if (NULL == pAccount) { break; } // Add the account string to the combobox if (FAILED(pAccount->GetPropSz(AP_ACCOUNT_NAME, szAccount, sizeof(szAccount)))) { SafeRelease(pAccount); continue; } ulIndex = ComboBox_AddString(hwndAcct, szAccount); if (CB_ERR == ulIndex) { fRet = FALSE; SafeRelease(pEnumAcct); SafeRelease(pAccount); EndDialog(hwndDlg, -1); goto exit; } if (FAILED(pAccount->GetPropSz(AP_ACCOUNT_ID, szAccount, sizeof(szAccount)))) { SafeRelease(pAccount); continue; } // Set the default selection if we have one if ((NULL != pselacct->pszAcct) && (0 == lstrcmp(pselacct->pszAcct, szAccount))) { Assert(FALSE == fSelected); ComboBox_SetCurSel(hwndAcct, ulIndex); fSelected = TRUE; } // Release it SafeRelease(pAccount); } SafeRelease(pEnumAcct); if (FALSE == fSelected) { ComboBox_SetCurSel(hwndAcct, 0); } // We didn't set the focus so return TRUE fRet = TRUE; break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); fRet = TRUE; break; case IDOK: hwndAcct = GetDlgItem(hwndDlg, idcCriteriaAcct); // Get the account name that was selected ulIndex = ComboBox_GetCurSel(hwndAcct); if (CB_ERR == ulIndex) { fRet = FALSE; goto exit; } cchAcct = ComboBox_GetLBText(hwndAcct, ulIndex, szAccount); if (0 == cchAcct) { fRet = FALSE; goto exit; } Assert(g_pAcctMan); if (FAILED(g_pAcctMan->FindAccount(AP_ACCOUNT_NAME, szAccount, &pAccount))) { fRet = FALSE; goto exit; } if (FAILED(pAccount->GetPropSz(AP_ACCOUNT_ID, szAccount, sizeof(szAccount)))) { fRet = FALSE; SafeRelease(pAccount); goto exit; } // Release it SafeRelease(pAccount); pszAcct = PszDupA(szAccount); if (NULL == pszAcct) { fRet = FALSE; goto exit; } SafeMemFree(pselacct->pszAcct); pselacct->pszAcct = pszAcct; EndDialog(hwndDlg, IDOK); fRet = TRUE; break; } break; } exit: return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FSelectColorDlgProc // // This is the main dialog proc for selecting a color dialog // // hwndDlg - handle to the filter manager dialog // uMsg - the message to be acted upon // wParam - the 'word' parameter for the message // lParam - the 'long' parameter for the message // // Returns: TRUE, if the message was handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// INT_PTR CALLBACK CRuleDescriptUI::_FSelectColorDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; ULONG * pulColor = NULL; ULONG ulColor = NULL; HWND hwndColor = NULL; HDC hdc = NULL; LPMEASUREITEMSTRUCT pmis = NULL; LPDRAWITEMSTRUCT pdis = NULL; pulColor = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: // Grab the propvariant pointer pulColor = (ULONG *) lParam; if (NULL == pulColor) { fRet = FALSE; EndDialog(hwndDlg, -1); goto exit; } // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulColor); hwndColor = GetDlgItem(hwndDlg, idcCriteriaColor); SetIntlFont(hwndColor); // Let's create the color control if (FAILED(HrCreateComboColor(hwndColor))) { fRet = FALSE; goto exit; } if (0 != *pulColor) { ulColor = *pulColor; } ComboBox_SetCurSel(hwndColor, ulColor); // We didn't set the focus so return TRUE fRet = TRUE; break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); fRet = TRUE; break; case IDOK: hwndColor = GetDlgItem(hwndDlg, idcCriteriaColor); // Get the account name that was selected ulColor = ComboBox_GetCurSel(hwndColor); if (CB_ERR == ulColor) { fRet = FALSE; goto exit; } *pulColor = ulColor; EndDialog(hwndDlg, IDOK); fRet = TRUE; break; } break; case WM_DRAWITEM: pdis = (LPDRAWITEMSTRUCT)lParam; Assert(pdis); Color_WMDrawItem(pdis, iColorCombo); fRet = FALSE; break; case WM_MEASUREITEM: pmis = (LPMEASUREITEMSTRUCT)lParam; hwndColor = GetDlgItem(hwndDlg, idcCriteriaColor); hdc = GetDC(hwndColor); if(hdc) { Color_WMMeasureItem(hdc, pmis, iColorCombo); ReleaseDC(hwndColor, hdc); } fRet = TRUE; break; } exit: return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FSelectSizeDlgProc // // This is the main dialog proc for selecting the size dialog // // hwndDlg - handle to the filter manager dialog // uMsg - the message to be acted upon // wParam - the 'word' parameter for the message // lParam - the 'long' parameter for the message // // Returns: TRUE, if the message was handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// INT_PTR CALLBACK CRuleDescriptUI::_FSelectSizeDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; ULONG * pulSize = NULL; HWND hwndSize = NULL; HWND hwndText = NULL; ULONG ulSize = 0; pulSize = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: // Grab the propvariant pointer pulSize = (ULONG *) lParam; if (NULL == pulSize) { fRet = FALSE; EndDialog(hwndDlg, -1); } // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulSize); hwndSize = GetDlgItem(hwndDlg, idspnCriteriaSize); hwndText = GetDlgItem(hwndDlg, idcCriteriaSize); SetIntlFont(hwndText); SendMessage(hwndSize, UDM_SETRANGE, 0, MAKELONG( (short) UD_MAXVAL, 0)); // Set the name of the rule into the edit well if (NULL != *pulSize) { SendMessage(hwndSize, UDM_SETPOS, 0, MAKELONG( (short) *pulSize, 0)); } // We didn't set the focus so return TRUE fRet = TRUE; break; case WM_COMMAND: switch (LOWORD(wParam)) { case idcCriteriaSize: if (EN_CHANGE == HIWORD(wParam)) { hwndText = (HWND) lParam; Assert(NULL != hwndText); RuleUtil_FEnDisDialogItem(hwndDlg, IDOK, 0 != Edit_GetTextLength(hwndText)); } break; case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); fRet = TRUE; break; case IDOK: hwndSize = GetDlgItem(hwndDlg, idspnCriteriaSize); // Get the name of the rule from the edit well ulSize = (INT) SendMessage(hwndSize, UDM_GETPOS, 0, 0); if (0 != HIWORD(ulSize)) { fRet = FALSE; goto exit; } *pulSize = LOWORD(ulSize); EndDialog(hwndDlg, IDOK); fRet = TRUE; break; } break; } exit: return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FSelectLinesDlgProc // // This is the main dialog proc for selecting the count of lines dialog // // hwndDlg - handle to the filter manager dialog // uMsg - the message to be acted upon // wParam - the 'word' parameter for the message // lParam - the 'long' parameter for the message // // Returns: TRUE, if the message was handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// INT_PTR CALLBACK CRuleDescriptUI::_FSelectLinesDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; ULONG * pulLines = NULL; HWND hwndLines = NULL; HWND hwndText = NULL; ULONG ulLines = 0; pulLines = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: // Grab the propvariant pointer pulLines = (ULONG *) lParam; if (NULL == pulLines) { fRet = FALSE; EndDialog(hwndDlg, -1); } // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulLines); hwndLines = GetDlgItem(hwndDlg, idspnCriteriaLines); hwndText = GetDlgItem(hwndDlg, idcCriteriaLines); SetIntlFont(hwndText); SendMessage(hwndLines, UDM_SETRANGE, 0, MAKELONG( (short) UD_MAXVAL, 0)); // Set the name of the rule into the edit well if (NULL != *pulLines) { SendMessage(hwndLines, UDM_SETPOS, 0, MAKELONG( (short) *pulLines, 0)); } // We didn't set the focus so return TRUE fRet = TRUE; break; case WM_COMMAND: switch (LOWORD(wParam)) { case idcCriteriaLines: if (EN_CHANGE == HIWORD(wParam)) { hwndText = (HWND) lParam; Assert(NULL != hwndText); RuleUtil_FEnDisDialogItem(hwndDlg, IDOK, 0 != Edit_GetTextLength(hwndText)); } break; case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); fRet = TRUE; break; case IDOK: hwndLines = GetDlgItem(hwndDlg, idspnCriteriaLines); // Get the name of the rule from the edit well ulLines = (INT) SendMessage(hwndLines, UDM_GETPOS, 0, 0); if (0 != HIWORD(ulLines)) { fRet = FALSE; goto exit; } *pulLines = LOWORD(ulLines); EndDialog(hwndDlg, IDOK); fRet = TRUE; break; } break; } exit: return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FSelectAgeDlgProc // // This is the main dialog proc for selecting the count of lines dialog // // hwndDlg - handle to the filter manager dialog // uMsg - the message to be acted upon // wParam - the 'word' parameter for the message // lParam - the 'long' parameter for the message // // Returns: TRUE, if the message was handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// INT_PTR CALLBACK CRuleDescriptUI::_FSelectAgeDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; ULONG * pulDays = NULL; HWND hwndDays = NULL; HWND hwndText = NULL; ULONG ulDays = 0; pulDays = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: // Grab the propvariant pointer pulDays = (ULONG *) lParam; if (NULL == pulDays) { fRet = FALSE; EndDialog(hwndDlg, -1); } // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulDays); hwndDays = GetDlgItem(hwndDlg, idspnCriteriaAge); hwndText = GetDlgItem(hwndDlg, idcCriteriaAge); SetIntlFont(hwndText); SendMessage(hwndDays, UDM_SETRANGE, 0, MAKELONG( (short) UD_MAXVAL, 0)); // Set the name of the rule into the edit well if (NULL != *pulDays) { SendMessage(hwndDays, UDM_SETPOS, 0, MAKELONG( (short) *pulDays, 0)); } // We didn't set the focus so return TRUE fRet = TRUE; break; case WM_COMMAND: switch (LOWORD(wParam)) { case idcCriteriaLines: if (EN_CHANGE == HIWORD(wParam)) { hwndText = (HWND) lParam; Assert(NULL != hwndText); RuleUtil_FEnDisDialogItem(hwndDlg, IDOK, 0 != Edit_GetTextLength(hwndText)); } break; case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); fRet = TRUE; break; case IDOK: hwndDays = GetDlgItem(hwndDlg, idspnCriteriaAge); // Get the name of the rule from the edit well ulDays = (INT) SendMessage(hwndDays, UDM_GETPOS, 0, 0); if (0 != HIWORD(ulDays)) { fRet = FALSE; goto exit; } *pulDays = LOWORD(ulDays); EndDialog(hwndDlg, IDOK); fRet = TRUE; break; } break; } exit: return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FSelectPriorityDlgProc // // This is the main dialog proc for selecting the priority dialog // // hwndDlg - handle to the filter manager dialog // uMsg - the message to be acted upon // wParam - the 'word' parameter for the message // lParam - the 'long' parameter for the message // // Returns: TRUE, if the message was handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// INT_PTR CALLBACK CRuleDescriptUI::_FSelectPriorityDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; ULONG * pulPri = NULL; ULONG ulPri = 0; pulPri = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: // Grab the propvariant pointer pulPri = (ULONG *) lParam; if (NULL == pulPri) { fRet = FALSE; EndDialog(hwndDlg, -1); } // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulPri); // Set the default item CheckDlgButton(hwndDlg, (CRIT_DATA_LOPRI == *pulPri) ? idcCriteriaLowPri : idcCriteriaHighPri, BST_CHECKED); // We didn't set the focus so return TRUE fRet = TRUE; break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); fRet = TRUE; break; case IDOK: if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcCriteriaLowPri)) { ulPri = CRIT_DATA_LOPRI; } else { ulPri = CRIT_DATA_HIPRI; } *pulPri = ulPri; EndDialog(hwndDlg, IDOK); fRet = TRUE; break; } break; } return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FSelectSecureDlgProc // // This is the main dialog proc for selecting the security dialog // // hwndDlg - handle to the filter manager dialog // uMsg - the message to be acted upon // wParam - the 'word' parameter for the message // lParam - the 'long' parameter for the message // // Returns: TRUE, if the message was handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// INT_PTR CALLBACK CRuleDescriptUI::_FSelectSecureDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; ULONG * pulSec = NULL; ULONG ulSec = 0; UINT uiId = 0; pulSec = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: // Grab the propvariant pointer pulSec = (ULONG *) lParam; if (NULL == pulSec) { fRet = FALSE; EndDialog(hwndDlg, -1); } // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulSec); // Set the default item if (0 != ((*pulSec) & CRIT_DATA_ENCRYPTSECURE)) { uiId = idcCriteriaEncrypt; } else { uiId = idcCriteriaSigned; } CheckDlgButton(hwndDlg, uiId, BST_CHECKED); // We didn't set the focus so return TRUE fRet = TRUE; break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); fRet = TRUE; break; case IDOK: if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcCriteriaSigned)) { ulSec = CRIT_DATA_SIGNEDSECURE; } else { ulSec = CRIT_DATA_ENCRYPTSECURE; } *pulSec = ulSec; EndDialog(hwndDlg, IDOK); fRet = TRUE; break; } break; } return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FSelectThreadStateDlgProc // // This is the main dialog proc for selecting the thread state dialog // // hwndDlg - handle to the filter manager dialog // uMsg - the message to be acted upon // wParam - the 'word' parameter for the message // lParam - the 'long' parameter for the message // // Returns: TRUE, if the message was handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// INT_PTR CALLBACK CRuleDescriptUI::_FSelectThreadStateDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; ULONG * pulThread = NULL; ULONG ulThread = 0; UINT uiId = 0; pulThread = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: // Grab the propvariant pointer pulThread = (ULONG *) lParam; if (NULL == pulThread) { fRet = FALSE; EndDialog(hwndDlg, -1); } // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulThread); // Set the default item if (0 != ((*pulThread) & CRIT_DATA_IGNORETHREAD)) { uiId = idcCriteriaIgnoreThread; } else { uiId = idcCriteriaWatchThread; } CheckDlgButton(hwndDlg, uiId, BST_CHECKED); // We didn't set the focus so return TRUE fRet = TRUE; break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); fRet = TRUE; break; case IDOK: if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcCriteriaWatchThread)) { ulThread = CRIT_DATA_WATCHTHREAD; } else { ulThread = CRIT_DATA_IGNORETHREAD; } *pulThread = ulThread; EndDialog(hwndDlg, IDOK); fRet = TRUE; break; } break; } return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FSelectShowDlgProc // // This is the main dialog proc for selecting the security dialog // // hwndDlg - handle to the filter manager dialog // uMsg - the message to be acted upon // wParam - the 'word' parameter for the message // lParam - the 'long' parameter for the message // // Returns: TRUE, if the message was handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// INT_PTR CALLBACK CRuleDescriptUI::_FSelectShowDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; ULONG * pulVal = NULL; UINT uiId = 0; pulVal = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: // Grab the propvariant pointer pulVal = (ULONG *) lParam; if (NULL == pulVal) { fRet = FALSE; EndDialog(hwndDlg, -1); } // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulVal); // Set the default item if (ACT_DATA_HIDE == *pulVal) { uiId = idcCriteriaHide; } else { uiId = idcCriteriaShow; } CheckDlgButton(hwndDlg, uiId, BST_CHECKED); // We didn't set the focus so return TRUE fRet = TRUE; break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); fRet = TRUE; break; case IDOK: if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcCriteriaHide)) { *pulVal = ACT_DATA_HIDE; } else { *pulVal = ACT_DATA_SHOW; } EndDialog(hwndDlg, IDOK); fRet = TRUE; break; } break; } return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FSelectShowDlgProc // // This is the main dialog proc for selecting the security dialog // // hwndDlg - handle to the filter manager dialog // uMsg - the message to be acted upon // wParam - the 'word' parameter for the message // lParam - the 'long' parameter for the message // // Returns: TRUE, if the message was handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// INT_PTR CALLBACK CRuleDescriptUI::_FSelectLogicDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; CRIT_LOGIC * plogicCrit = NULL; UINT uiId = 0; plogicCrit = (CRIT_LOGIC *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: // Grab the propvariant pointer plogicCrit = (CRIT_LOGIC *) lParam; if (NULL == plogicCrit) { fRet = FALSE; EndDialog(hwndDlg, -1); } // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) plogicCrit); // Set the default item if (CRIT_LOGIC_OR == (*plogicCrit)) { uiId = idcCriteriaOr; } else { uiId = idcCriteriaAnd; } CheckDlgButton(hwndDlg, uiId, BST_CHECKED); // We didn't set the focus so return TRUE fRet = TRUE; break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); fRet = TRUE; break; case IDOK: if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcCriteriaAnd)) { *plogicCrit = CRIT_LOGIC_AND; } else { *plogicCrit = CRIT_LOGIC_OR; } EndDialog(hwndDlg, IDOK); fRet = TRUE; break; } break; } return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FSelectFlagDlgProc // // This is the main dialog proc for selecting the security dialog // // hwndDlg - handle to the filter manager dialog // uMsg - the message to be acted upon // wParam - the 'word' parameter for the message // lParam - the 'long' parameter for the message // // Returns: TRUE, if the message was handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// INT_PTR CALLBACK CRuleDescriptUI::_FSelectFlagDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; ULONG * pulVal = NULL; UINT uiId = 0; pulVal = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: // Grab the propvariant pointer pulVal = (ULONG *) lParam; if (NULL == pulVal) { fRet = FALSE; EndDialog(hwndDlg, -1); } // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulVal); // Set the default item if (0 != ((*pulVal) & CRIT_FLAG_INVERT)) { uiId = idcCriteriaNoFlag; } else { uiId = idcCriteriaFlag; } CheckDlgButton(hwndDlg, uiId, BST_CHECKED); // We didn't set the focus so return TRUE fRet = TRUE; break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); fRet = TRUE; break; case IDOK: if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcCriteriaNoFlag)) { *pulVal |= CRIT_FLAG_INVERT; } else { *pulVal &= ~CRIT_FLAG_INVERT; } EndDialog(hwndDlg, IDOK); fRet = TRUE; break; } break; } return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FSelectDownloadedDlgProc // // This is the main dialog proc for selecting the downloaded dialog // // hwndDlg - handle to the filter manager dialog // uMsg - the message to be acted upon // wParam - the 'word' parameter for the message // lParam - the 'long' parameter for the message // // Returns: TRUE, if the message was handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// INT_PTR CALLBACK CRuleDescriptUI::_FSelectDownloadedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; ULONG * pulVal = NULL; UINT uiId = 0; pulVal = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: // Grab the propvariant pointer pulVal = (ULONG *) lParam; if (NULL == pulVal) { fRet = FALSE; EndDialog(hwndDlg, -1); } // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulVal); // Set the default item if (0 != ((*pulVal) & CRIT_FLAG_INVERT)) { uiId = idcCriteriaNotDownloaded; } else { uiId = idcCriteriaDownloaded; } CheckDlgButton(hwndDlg, uiId, BST_CHECKED); // We didn't set the focus so return TRUE fRet = TRUE; break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); fRet = TRUE; break; case IDOK: if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcCriteriaNotDownloaded)) { *pulVal |= CRIT_FLAG_INVERT; } else { *pulVal &= ~CRIT_FLAG_INVERT; } EndDialog(hwndDlg, IDOK); fRet = TRUE; break; } break; } return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FSelectReadDlgProc // // This is the main dialog proc for selecting the read state dialog // // hwndDlg - handle to the filter manager dialog // uMsg - the message to be acted upon // wParam - the 'word' parameter for the message // lParam - the 'long' parameter for the message // // Returns: TRUE, if the message was handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// INT_PTR CALLBACK CRuleDescriptUI::_FSelectReadDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; ULONG * pulVal = NULL; UINT uiId = 0; pulVal = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: // Grab the propvariant pointer pulVal = (ULONG *) lParam; if (NULL == pulVal) { fRet = FALSE; EndDialog(hwndDlg, -1); } // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulVal); // Set the default item if (0 != ((*pulVal) & CRIT_FLAG_INVERT)) { uiId = idcCriteriaNotRead; } else { uiId = idcCriteriaRead; } CheckDlgButton(hwndDlg, uiId, BST_CHECKED); // We didn't set the focus so return TRUE fRet = TRUE; break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); fRet = TRUE; break; case IDOK: if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcCriteriaNotRead)) { *pulVal |= CRIT_FLAG_INVERT; } else { *pulVal &= ~CRIT_FLAG_INVERT; } EndDialog(hwndDlg, IDOK); fRet = TRUE; break; } break; } return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FSelectWatchDlgProc // // This is the main dialog proc for selecting the thread state dialog // // hwndDlg - handle to the filter manager dialog // uMsg - the message to be acted upon // wParam - the 'word' parameter for the message // lParam - the 'long' parameter for the message // // Returns: TRUE, if the message was handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// INT_PTR CALLBACK CRuleDescriptUI::_FSelectWatchDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; ULONG * pulThread = NULL; ULONG ulThread = 0; UINT uiId = 0; pulThread = (ULONG *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: // Grab the propvariant pointer pulThread = (ULONG *) lParam; if (NULL == pulThread) { fRet = FALSE; EndDialog(hwndDlg, -1); } // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pulThread); // Set the default item if (ACT_DATA_IGNORETHREAD == *pulThread) { uiId = idcActionsIgnoreThread; } else { uiId = idcActionsWatchThread; } CheckDlgButton(hwndDlg, uiId, BST_CHECKED); // We didn't set the focus so return TRUE fRet = TRUE; break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); fRet = TRUE; break; case IDOK: if (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcActionsWatchThread)) { ulThread = ACT_DATA_WATCHTHREAD; } else { ulThread = ACT_DATA_IGNORETHREAD; } *pulThread = ulThread; EndDialog(hwndDlg, IDOK); fRet = TRUE; break; } break; } return fRet; } // Class definitions class CEditPeopleOptionsUI { private: enum { STATE_UNINIT = 0x00000000, STATE_INITIALIZED = 0x00000001, STATE_DIRTY = 0x00000002 }; private: HWND m_hwndOwner; DWORD m_dwFlags; DWORD m_dwState; HWND m_hwndDlg; HWND m_hwndList; CRIT_ITEM * m_pCritItem; public: CEditPeopleOptionsUI() : m_hwndOwner(NULL), m_dwFlags(0), m_dwState(STATE_UNINIT), m_hwndDlg(NULL), m_hwndList(NULL), m_pCritItem(NULL) {} ~CEditPeopleOptionsUI(); // The main UI methods HRESULT HrInit(HWND hwndOwner, DWORD dwFlags); HRESULT HrShow(CRIT_ITEM * pCritItem); // The Rules Manager dialog function static INT_PTR CALLBACK FEditPeopleOptionsDlgProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam); // Message handling functions BOOL FOnInitDialog(HWND hwndDlg); BOOL FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl); BOOL FOnMeasureItem(HWND hwndDlg, UINT uiCtlId, MEASUREITEMSTRUCT * pmis); BOOL FOnDrawItem(UINT uiCtlId, DRAWITEMSTRUCT * pdis); private: BOOL _FLoadCtrls(VOID); BOOL _FOnOK(DWORD * pdwFlags); BOOL _AddTagLineToList(VOID); BOOL _FAddWordToList(DWORD dwFlags, LPCTSTR pszItem); }; typedef struct tagPEOPLEEDITTAG { CRIT_TYPE type; UINT uiNormal; UINT uiInverted; } PEOPLEEDITTAG, * PPEOPLEEDITTAG; static const PEOPLEEDITTAG g_rgpetTagLines[] = { {CRIT_TYPE_TO, idsCriteriaToEdit, idsCriteriaToNotEdit}, {CRIT_TYPE_CC, idsCriteriaCCEdit, idsCriteriaCCNotEdit}, {CRIT_TYPE_FROM, idsCriteriaFromEdit, idsCriteriaFromNotEdit}, {CRIT_TYPE_TOORCC, idsCriteriaToOrCCEdit, idsCriteriaToOrCCNotEdit}, {CRIT_TYPE_SUBJECT, idsCriteriaSubjectEdit, idsCriteriaSubjectNotEdit}, {CRIT_TYPE_BODY, idsCriteriaBodyEdit, idsCriteriaBodyNotEdit} }; static const int g_cpetTagLines = sizeof(g_rgpetTagLines) / sizeof(g_rgpetTagLines[0]); class CEditPeopleUI { private: enum { STATE_UNINIT = 0x00000000, STATE_INITIALIZED = 0x00000001, STATE_DIRTY = 0x00000002 }; private: HWND m_hwndOwner; DWORD m_dwFlags; DWORD m_dwState; HWND m_hwndDlg; HWND m_hwndPeople; HWND m_hwndList; ULONG m_cxMaxPixels; CRIT_ITEM * m_pCritItem; public: CEditPeopleUI() : m_hwndOwner(NULL), m_dwFlags(0), m_dwState(STATE_UNINIT), m_hwndDlg(NULL), m_hwndPeople(NULL), m_hwndList(NULL), m_cxMaxPixels(0), m_pCritItem(NULL) {} ~CEditPeopleUI(); HRESULT HrInit(HWND hwndOwner, DWORD dwFlags); HRESULT HrShow(CRIT_ITEM * pCritItem); static INT_PTR CALLBACK FEditPeopleDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam); // Message handling methods BOOL FOnInitDialog(HWND hwndDlg); BOOL FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl); BOOL FOnMeasureItem(HWND hwndDlg, UINT uiCtlId, MEASUREITEMSTRUCT * pmis); BOOL FOnDrawItem(UINT uiCtlId, DRAWITEMSTRUCT * pdis); private: BOOL _FLoadListCtrl(VOID); VOID _AddItemToList(VOID); VOID _AddItemsFromWAB(VOID); VOID _RemoveItemFromList(VOID); VOID _ChangeOptions(VOID); BOOL _FOnNameChange(VOID); BOOL _FOnOK(CRIT_ITEM * pCritItem); VOID _UpdateButtons(VOID); BOOL _AddTagLineToList(VOID); BOOL _FAddWordToList(DWORD dwFlags, LPCTSTR pszItem); }; CEditPeopleOptionsUI::~CEditPeopleOptionsUI() { } /////////////////////////////////////////////////////////////////////////////// // // HrInit // // This initializes us with the owner window and any flags we might have // // hwndOwner - handle to the owner window // dwFlags - flags to use for this instance // pBlob - the data to edit // // Returns: S_OK // /////////////////////////////////////////////////////////////////////////////// HRESULT CEditPeopleOptionsUI::HrInit(HWND hwndOwner, DWORD dwFlags) { HRESULT hr = S_OK; CHARFORMAT cf; // If we're already initialized, then fail if (0 != (m_dwState & STATE_INITIALIZED)) { hr = E_FAIL; goto exit; } // Save off the owner window m_hwndOwner = hwndOwner; // Save off the flags m_dwFlags = dwFlags; // We're done m_dwState |= STATE_INITIALIZED; // Set the return value hr = S_OK; exit: return hr; } /////////////////////////////////////////////////////////////////////////////// // // HrShow // // This initializes us with the owner window and any flags we might have // // hwndOwner - handle to the owner window // dwFlags - flags to use for this instance // pBlob - the data to edit // // Returns: S_OK // /////////////////////////////////////////////////////////////////////////////// HRESULT CEditPeopleOptionsUI::HrShow(CRIT_ITEM * pCritItem) { HRESULT hr = S_OK; int iRet = 0; UINT uiID = 0; // Check incoming params if (NULL == pCritItem) { hr = E_INVALIDARG; goto exit; } if (0 == (m_dwState & STATE_INITIALIZED)) { hr = E_UNEXPECTED; goto exit; } // Save off the data m_pCritItem = pCritItem; // Figure out which dialog template to use if (0 != (m_dwFlags & PUI_WORDS)) { uiID = iddCriteriaWordsOptions; } else { uiID = iddCriteriaPeopleOptions; } // Bring up the editor dialog iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(uiID), m_hwndOwner, CEditPeopleOptionsUI::FEditPeopleOptionsDlgProc, (LPARAM) this); if (-1 == iRet) { hr = E_FAIL; goto exit; } // Set the proper return code hr = (IDOK == iRet) ? S_OK : S_FALSE; exit: return hr; } INT_PTR CALLBACK CEditPeopleOptionsUI::FEditPeopleOptionsDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; CEditPeopleOptionsUI * pOptionsUI = NULL; pOptionsUI = (CEditPeopleOptionsUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uiMsg) { case WM_INITDIALOG: // Grab the UI object pointer pOptionsUI = (CEditPeopleOptionsUI *) lParam; // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pOptionsUI); if (FALSE == pOptionsUI->FOnInitDialog(hwndDlg)) { EndDialog(hwndDlg, -1); fRet = TRUE; goto exit; } // We set the focus fRet = TRUE; break; case WM_COMMAND: fRet = pOptionsUI->FOnCommand((UINT) HIWORD(wParam), (INT) LOWORD(wParam), (HWND) lParam); break; case WM_MEASUREITEM: fRet = pOptionsUI->FOnMeasureItem(hwndDlg, (UINT) wParam, (MEASUREITEMSTRUCT *) lParam); break; case WM_DRAWITEM: fRet = pOptionsUI->FOnDrawItem((UINT) wParam, (DRAWITEMSTRUCT *) lParam); break; } exit: return fRet; } /////////////////////////////////////////////////////////////////////////////// // // FOnInitDialog // // This handles the WM_INITDIALOG message for the edit people UI dialog // // hwndDlg - the handle to the dialog window // // Returns: TRUE, if it was successfully initialized // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleOptionsUI::FOnInitDialog(HWND hwndDlg) { BOOL fRet = FALSE; HRESULT hr = S_OK; // Check incoming params if (NULL == hwndDlg) { fRet = FALSE; goto exit; } // Save off the dialog window handle m_hwndDlg = hwndDlg; // Set the default font onto the dialog SetIntlFont(m_hwndDlg); // Save off some of the controls m_hwndList = GetDlgItem(hwndDlg, idcCriteriaList); if (NULL == m_hwndList) { fRet = FALSE; goto exit; } // Load the list view fRet = _FLoadCtrls(); if (FALSE == fRet) { goto exit; } // Everything's AOK fRet = TRUE; exit: return fRet; } /////////////////////////////////////////////////////////////////////////////// // // FOnCommand // // This handles the WM_COMMAND message for the view manager UI dialog // // Returns: TRUE, if it was successfully handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleOptionsUI::FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl) { BOOL fRet = FALSE; INT iSelected = 0; switch (iCtl) { case IDOK: if (FALSE != _FOnOK(&(m_pCritItem->dwFlags))) { EndDialog(m_hwndDlg, IDOK); fRet = TRUE; } break; case IDCANCEL: EndDialog(m_hwndDlg, IDCANCEL); fRet = TRUE; break; case idcCriteriaNotCont: case idcCriteriaContains: case idcCriteriaAnd: case idcCriteriaOr: if (BN_CLICKED == uiNotify) { // Make sure the list is redrawn InvalidateRect(m_hwndList, NULL, TRUE); } break; } return fRet; } /////////////////////////////////////////////////////////////////////////////// // // FOnMeasureItem // // This handles the WM_MEASUREITEM message for the view manager UI dialog // // Returns: TRUE, if it was successfully handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleOptionsUI::FOnMeasureItem(HWND hwndDlg, UINT uiCtlId, MEASUREITEMSTRUCT * pmis) { BOOL fRet = FALSE; HWND hwndList = NULL; HDC hdcList = NULL; TEXTMETRIC tm = {0}; // Get the window handle hwndList = GetDlgItem(hwndDlg, uiCtlId); if (NULL == hwndList) { fRet = FALSE; goto exit; } // Get the device context hdcList = GetDC(hwndList); if (NULL == hdcList) { fRet = FALSE; goto exit; } // Get the text metrics for the device context GetTextMetrics(hdcList, &tm); // Set the item height pmis->itemHeight = tm.tmHeight; fRet = TRUE; exit: if (NULL != hdcList) { ReleaseDC(hwndList, hdcList); } return fRet; } /////////////////////////////////////////////////////////////////////////////// // // FOnDrawItem // // This handles the WM_DRAWITEM message for the people editor UI dialog // // Returns: TRUE, if it was successfully handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleOptionsUI::FOnDrawItem(UINT uiCtlId, DRAWITEMSTRUCT * pdis) { BOOL fRet = FALSE; DWORD dwFlags = 0; INT cchText = 0; LPTSTR pszText = NULL; LPTSTR pszString = NULL; UINT uiID = 0; TCHAR rgchRes[CCHMAX_STRINGRES]; COLORREF crfBack = NULL; COLORREF crfText = NULL; ULONG ulIndex = 0; LPTSTR pszPrint = NULL; // Make sure this is the correct control if (ODT_LISTBOX != pdis->CtlType) { fRet = FALSE; goto exit; } // Get the flags from the dialog if (FALSE == _FOnOK(&dwFlags)) { fRet = FALSE; goto exit; } // Nothing else to do if it's the first item if (0 == pdis->itemID) { for (ulIndex = 0; ulIndex < g_cpetTagLines; ulIndex++) { if (g_rgpetTagLines[ulIndex].type == m_pCritItem->type) { if (0 != (dwFlags & CRIT_FLAG_INVERT)) { uiID = g_rgpetTagLines[ulIndex].uiInverted; } else { uiID = g_rgpetTagLines[ulIndex].uiNormal; } break; } } // Did we find anything? if (ulIndex >= g_cpetTagLines) { fRet = FALSE; goto exit; } // Load the item template if (NULL == AthLoadString(uiID, rgchRes, sizeof(rgchRes))) { fRet = FALSE; goto exit; } pszPrint = rgchRes; } else { // Get the size of the string for the item cchText = (INT) SendMessage(m_hwndList, LB_GETTEXTLEN, (WPARAM) (pdis->itemID), (LPARAM) 0); if (LB_ERR == cchText) { fRet = FALSE; goto exit; } // Allocate enough space to hold the the string for the item if (FAILED(HrAlloc((VOID **) &pszText, sizeof(*pszText) * (cchText + 1)))) { fRet = FALSE; goto exit; } // Get the string for the item cchText = (INT) SendMessage(m_hwndList, LB_GETTEXT, (WPARAM) (pdis->itemID), (LPARAM) pszText); if (LB_ERR == cchText) { fRet = FALSE; goto exit; } // Figure out which string template to use if (1 == pdis->itemID) { uiID = idsCriteriaEditFirst; } else { if (0 != (dwFlags & CRIT_FLAG_MULTIPLEAND)) { uiID = idsCriteriaEditAnd; } else { uiID = idsCriteriaEditOr; } } // Load the proper string template for the item if (NULL == AthLoadString(uiID, rgchRes, sizeof(rgchRes))) { fRet = FALSE; goto exit; } // Allocate enough space to hold the final string DWORD cchSize = (cchText + CCHMAX_STRINGRES + 1); if (FAILED(HrAlloc((VOID **) &pszString, sizeof(*pszString) * cchSize))) { fRet = FALSE; goto exit; } // Create the final string wnsprintf(pszString, cchSize, rgchRes, pszText); pszPrint = pszString; } // Determine Colors crfBack = SetBkColor(pdis->hDC, GetSysColor(COLOR_WINDOW)); crfText = SetTextColor(pdis->hDC, GetSysColor(COLOR_WINDOWTEXT)); // Clear the item ExtTextOut(pdis->hDC, pdis->rcItem.left, pdis->rcItem.top, ETO_OPAQUE, &(pdis->rcItem), NULL, 0, NULL); // Draw the new item DrawTextEx(pdis->hDC, pszPrint, lstrlen(pszPrint), &(pdis->rcItem), DT_BOTTOM | DT_NOPREFIX | DT_SINGLELINE, NULL); if (pdis->itemState & ODS_FOCUS) { DrawFocusRect(pdis->hDC, &(pdis->rcItem)); } // Reset Text Colors SetTextColor (pdis->hDC, crfText); SetBkColor (pdis->hDC, crfBack); // Set return value fRet = TRUE; exit: SafeMemFree(pszString); SafeMemFree(pszText); return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FLoadListCtrl // // This loads the list view with the current Mail rules // // Returns: TRUE, if it was successfully loaded // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleOptionsUI::_FLoadCtrls(VOID) { BOOL fRet = FALSE; UINT uiID = 0; LPTSTR pszWalk = NULL; Assert(NULL != m_hwndList); // Set the contains option if (0 != (m_pCritItem->dwFlags & CRIT_FLAG_INVERT)) { uiID = idcCriteriaNotCont; } else { uiID = idcCriteriaContains; } CheckRadioButton(m_hwndDlg, idcCriteriaContains, idcCriteriaNotCont, uiID); // Set the logic option if (0 != (m_pCritItem->dwFlags & CRIT_FLAG_MULTIPLEAND)) { uiID = idcCriteriaAnd; } else { uiID = idcCriteriaOr; } CheckRadioButton(m_hwndDlg, idcCriteriaAnd, idcCriteriaOr, uiID); // Remove all the items from the list control SendMessage(m_hwndList, LB_RESETCONTENT, (WPARAM) 0, (LPARAM) 0); // Add the tag line to the top of the list _AddTagLineToList(); // If we have some items, let's add them to the list if (0 != m_pCritItem->propvar.blob.cbSize) { // Add each item into the list for (pszWalk = (LPSTR) (m_pCritItem->propvar.blob.pBlobData); '\0' != pszWalk[0]; pszWalk += lstrlen(pszWalk) + 1) { if (FALSE == _FAddWordToList(0, pszWalk)) { fRet = FALSE; goto exit; } } } // If we don't have at least two names in the list if (3 > SendMessage(m_hwndList, LB_GETCOUNT, (WPARAM) 0, (LPARAM) 0)) { // Disable the And/Or buttons RuleUtil_FEnDisDialogItem(m_hwndDlg, idcCriteriaAnd, FALSE); RuleUtil_FEnDisDialogItem(m_hwndDlg, idcCriteriaOr, FALSE); } fRet = TRUE; exit: return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FOnOK // // This handles the user typing into the name field // // Returns: TRUE, we handled the edit message // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleOptionsUI::_FOnOK(DWORD * pdwFlags) { BOOL fRet = FALSE; Assert(NULL != m_hwndList); // Get the contains option if (BST_CHECKED == IsDlgButtonChecked(m_hwndDlg, idcCriteriaContains)) { *pdwFlags &= ~CRIT_FLAG_INVERT; } else { *pdwFlags |= CRIT_FLAG_INVERT; } // Get the logic option if (BST_CHECKED == IsDlgButtonChecked(m_hwndDlg, idcCriteriaAnd)) { *pdwFlags |= CRIT_FLAG_MULTIPLEAND; } else { *pdwFlags &= ~CRIT_FLAG_MULTIPLEAND; } // Set the return value fRet = TRUE; return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _AddTagLineToList // // This enables or disables the buttons in the people editor UI dialog // depending on what is selected. // // iSelected - the item that was selected, // -1 means that nothing was selected // // Returns: NONE // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleOptionsUI::_AddTagLineToList(VOID) { BOOL fRet = FALSE; Assert(NULL != m_hwndList); fRet = _FAddWordToList(0, " "); if (FALSE == fRet) { goto exit; } // Set the proper return value fRet = TRUE; exit: return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FAddWordToList // // This enables or disables the buttons in the people editor UI dialog // depending on what is selected. // // iSelected - the item that was selected, // -1 means that nothing was selected // // Returns: NONE // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleOptionsUI::_FAddWordToList(DWORD dwFlags, LPCTSTR pszItem) { BOOL fRet = FALSE; int cItems = 0; INT iRet = 0; Assert(NULL != m_hwndList); // Is there anything to do? if ((NULL == pszItem) || ('\0' == pszItem[0])) { fRet = FALSE; goto exit; } // Get the number of items in the list cItems = (INT) SendMessage(m_hwndList, LB_GETCOUNT, (WPARAM) 0, (LPARAM) 0); if (LB_ERR == cItems) { fRet = FALSE; goto exit; } // Set the data into the list iRet = (INT) SendMessage(m_hwndList, LB_ADDSTRING, (WPARAM) cItems, (LPARAM) pszItem); if ((LB_ERR == iRet) || (LB_ERRSPACE == iRet)) { fRet = FALSE; goto exit; } // Set the proper return value fRet = TRUE; exit: return fRet; } CEditPeopleUI::~CEditPeopleUI() { } /////////////////////////////////////////////////////////////////////////////// // // HrInit // // This initializes us with the owner window and any flags we might have // // hwndOwner - handle to the owner window // dwFlags - flags to use for this instance // pBlob - the data to edit // // Returns: S_OK // /////////////////////////////////////////////////////////////////////////////// HRESULT CEditPeopleUI::HrInit(HWND hwndOwner, DWORD dwFlags) { HRESULT hr = S_OK; CHARFORMAT cf; // If we're already initialized, then fail if (0 != (m_dwState & STATE_INITIALIZED)) { hr = E_FAIL; goto exit; } // Save off the owner window m_hwndOwner = hwndOwner; // Save off the flags m_dwFlags = dwFlags; // We're done m_dwState |= STATE_INITIALIZED; // Set the return value hr = S_OK; exit: return hr; } /////////////////////////////////////////////////////////////////////////////// // // HrInit // // This initializes us with the owner window and any flags we might have // // hwndOwner - handle to the owner window // dwFlags - flags to use for this instance // pBlob - the data to edit // // Returns: S_OK // /////////////////////////////////////////////////////////////////////////////// HRESULT CEditPeopleUI::HrShow(CRIT_ITEM * pCritItem) { HRESULT hr = S_OK; int iRet = 0; UINT uiID = 0; // Check incoming params if (NULL == pCritItem) { hr = E_INVALIDARG; goto exit; } if (0 == (m_dwState & STATE_INITIALIZED)) { hr = E_UNEXPECTED; goto exit; } // Save off the data m_pCritItem = pCritItem; // Figure out which dialog template to use if (0 != (m_dwFlags & PUI_WORDS)) { uiID = iddCriteriaWords; } else { uiID = iddCriteriaPeople; } // Bring up the editor dialog iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(uiID), m_hwndOwner, CEditPeopleUI::FEditPeopleDlgProc, (LPARAM) this); if (-1 == iRet) { hr = E_FAIL; goto exit; } // Set the proper return code hr = (IDOK == iRet) ? S_OK : S_FALSE; exit: return hr; } INT_PTR CALLBACK CEditPeopleUI::FEditPeopleDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; CEditPeopleUI * pPeopleUI = NULL; pPeopleUI = (CEditPeopleUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uiMsg) { case WM_INITDIALOG: // Grab the UI object pointer pPeopleUI = (CEditPeopleUI *) lParam; // Set it into the dialog so we can get it back SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pPeopleUI); if (FALSE == pPeopleUI->FOnInitDialog(hwndDlg)) { EndDialog(hwndDlg, -1); fRet = TRUE; goto exit; } // We set the focus fRet = TRUE; break; case WM_COMMAND: fRet = pPeopleUI->FOnCommand((UINT) HIWORD(wParam), (INT) LOWORD(wParam), (HWND) lParam); break; case WM_MEASUREITEM: fRet = pPeopleUI->FOnMeasureItem(hwndDlg, (UINT) wParam, (MEASUREITEMSTRUCT *) lParam); break; case WM_DRAWITEM: fRet = pPeopleUI->FOnDrawItem((UINT) wParam, (DRAWITEMSTRUCT *) lParam); break; } exit: return fRet; } /////////////////////////////////////////////////////////////////////////////// // // FOnInitDialog // // This handles the WM_INITDIALOG message for the edit people UI dialog // // hwndDlg - the handle to the dialog window // // Returns: TRUE, if it was successfully initialized // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleUI::FOnInitDialog(HWND hwndDlg) { BOOL fRet = FALSE; HRESULT hr = S_OK; // Check incoming params if (NULL == hwndDlg) { fRet = FALSE; goto exit; } // Save off the dialog window handle m_hwndDlg = hwndDlg; // Set the default font onto the dialog SetIntlFont(m_hwndDlg); // Save off some of the controls m_hwndList = GetDlgItem(hwndDlg, idcCriteriaList); m_hwndPeople = GetDlgItem(hwndDlg, idcCriteriaEdit); if ((NULL == m_hwndList) || (NULL == m_hwndPeople)) { fRet = FALSE; goto exit; } // Load the list view fRet = _FLoadListCtrl(); if (FALSE == fRet) { goto exit; } // Everything's AOK fRet = TRUE; exit: return fRet; } /////////////////////////////////////////////////////////////////////////////// // // FOnCommand // // This handles the WM_COMMAND message for the view manager UI dialog // // Returns: TRUE, if it was successfully handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleUI::FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl) { BOOL fRet = FALSE; INT iSelected = 0; switch (iCtl) { case IDOK: if (FALSE != _FOnOK(m_pCritItem)) { EndDialog(m_hwndDlg, IDOK); fRet = TRUE; } break; case IDCANCEL: EndDialog(m_hwndDlg, IDCANCEL); fRet = TRUE; break; case idcCriteriaEdit: if (EN_CHANGE == uiNotify) { _FOnNameChange(); } fRet = FALSE; break; case idcCriteriaAdd: _AddItemToList(); break; case idcCriteriaAddrBook: _AddItemsFromWAB(); break; case idcCriteriaRemove: _RemoveItemFromList(); break; case idcCriteriaOptions: _ChangeOptions(); break; case idcCriteriaList: if (LBN_SELCHANGE == uiNotify) { // Update the buttons _UpdateButtons(); } break; } return fRet; } /////////////////////////////////////////////////////////////////////////////// // // FOnMeasureItem // // This handles the WM_MEASUREITEM message for the view manager UI dialog // // Returns: TRUE, if it was successfully handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleUI::FOnMeasureItem(HWND hwndDlg, UINT uiCtlId, MEASUREITEMSTRUCT * pmis) { BOOL fRet = FALSE; HWND hwndList = NULL; HDC hdcList = NULL; TEXTMETRIC tm = {0}; // Get the window handle hwndList = GetDlgItem(hwndDlg, uiCtlId); if (NULL == hwndList) { fRet = FALSE; goto exit; } // Get the device context hdcList = GetDC(hwndList); if (NULL == hdcList) { fRet = FALSE; goto exit; } // Get the text metrics for the device context GetTextMetrics(hdcList, &tm); // Set the item height pmis->itemHeight = tm.tmHeight; fRet = TRUE; exit: if (NULL != hdcList) { ReleaseDC(hwndList, hdcList); } return fRet; } /////////////////////////////////////////////////////////////////////////////// // // FOnDrawItem // // This handles the WM_DRAWITEM message for the people editor UI dialog // // Returns: TRUE, if it was successfully handled // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleUI::FOnDrawItem(UINT uiCtlId, DRAWITEMSTRUCT * pdis) { BOOL fRet = FALSE; INT cchText = 0; LPTSTR pszText = NULL; LPTSTR pszString = NULL; UINT uiID = 0; TCHAR rgchRes[CCHMAX_STRINGRES]; COLORREF crfBack = NULL; COLORREF crfText = NULL; ULONG ulIndex = 0; LPTSTR pszPrint = NULL; // Make sure this is the correct control if (ODT_LISTBOX != pdis->CtlType) { fRet = FALSE; goto exit; } // Nothing else to do if it's the first item if (0 == pdis->itemID) { for (ulIndex = 0; ulIndex < g_cpetTagLines; ulIndex++) { if (g_rgpetTagLines[ulIndex].type == m_pCritItem->type) { if (0 != (m_pCritItem->dwFlags & CRIT_FLAG_INVERT)) { uiID = g_rgpetTagLines[ulIndex].uiInverted; } else { uiID = g_rgpetTagLines[ulIndex].uiNormal; } break; } } // Did we find anything? if (ulIndex >= g_cpetTagLines) { fRet = FALSE; goto exit; } // Load the item template if (NULL == AthLoadString(uiID, rgchRes, sizeof(rgchRes))) { fRet = FALSE; goto exit; } pszPrint = rgchRes; } else { // Get the size of the string for the item cchText = (INT) SendMessage(m_hwndList, LB_GETTEXTLEN, (WPARAM) (pdis->itemID), (LPARAM) 0); if (LB_ERR == cchText) { fRet = FALSE; goto exit; } // Allocate enough space to hold the the string for the item if (FAILED(HrAlloc((VOID **) &pszText, sizeof(*pszText) * (cchText + 1)))) { fRet = FALSE; goto exit; } // Get the string for the item cchText = (INT) SendMessage(m_hwndList, LB_GETTEXT, (WPARAM) (pdis->itemID), (LPARAM) pszText); if (LB_ERR == cchText) { fRet = FALSE; goto exit; } // Figure out which string template to use if (1 == pdis->itemID) { uiID = idsCriteriaEditFirst; } else { if (0 != (m_pCritItem->dwFlags & CRIT_FLAG_MULTIPLEAND)) { uiID = idsCriteriaEditAnd; } else { uiID = idsCriteriaEditOr; } } // Load the proper string template for the item if (NULL == AthLoadString(uiID, rgchRes, sizeof(rgchRes))) { fRet = FALSE; goto exit; } // Allocate enough space to hold the final string DWORD cchSize = (cchText + CCHMAX_STRINGRES + 1); if (FAILED(HrAlloc((VOID **) &pszString, sizeof(*pszString) * cchSize))) { fRet = FALSE; goto exit; } // Create the final string wnsprintf(pszString, cchSize, rgchRes, pszText); pszPrint = pszString; } // Determine Colors if (pdis->itemState & ODS_SELECTED) { crfBack = SetBkColor(pdis->hDC, GetSysColor(COLOR_HIGHLIGHT)); crfText = SetTextColor(pdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); } else { crfBack = SetBkColor(pdis->hDC, GetSysColor(COLOR_WINDOW)); crfText = SetTextColor(pdis->hDC, GetSysColor(COLOR_WINDOWTEXT)); } // Clear the item ExtTextOut(pdis->hDC, pdis->rcItem.left, pdis->rcItem.top, ETO_OPAQUE, &(pdis->rcItem), NULL, 0, NULL); // Draw the new item DrawTextEx(pdis->hDC, pszPrint, lstrlen(pszPrint), &(pdis->rcItem), DT_BOTTOM | DT_NOPREFIX | DT_SINGLELINE, NULL); if (pdis->itemState & ODS_FOCUS) { DrawFocusRect(pdis->hDC, &(pdis->rcItem)); } // Reset Text Colors SetTextColor (pdis->hDC, crfText); SetBkColor (pdis->hDC, crfBack); // Set return value fRet = TRUE; exit: SafeMemFree(pszString); SafeMemFree(pszText); return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FLoadListCtrl // // This loads the list view with the current Mail rules // // Returns: TRUE, if it was successfully loaded // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleUI::_FLoadListCtrl(VOID) { BOOL fRet = FALSE; LPSTR pszWalk = NULL; Assert(NULL != m_hwndList); // Remove all the items from the list control SendMessage(m_hwndList, LB_RESETCONTENT, (WPARAM) 0, (LPARAM) 0); // Add the tag line to the top of the list _AddTagLineToList(); // If we have some items, let's add them to the list if (0 != m_pCritItem->propvar.blob.cbSize) { // Add each item into the list for (pszWalk = (LPSTR) (m_pCritItem->propvar.blob.pBlobData); '\0' != pszWalk[0]; pszWalk += lstrlen(pszWalk) + 1) { fRet = _FAddWordToList(0, pszWalk); if (FALSE == fRet) goto exit; } } SendMessage(m_hwndDlg, DM_SETDEFID, IDOK, 0); // Enable the dialog buttons. _UpdateButtons(); fRet = TRUE; exit: return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _AddItemToList // // This handles the user typing into the name field // // Returns: TRUE, we handled the edit message // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// VOID CEditPeopleUI::_AddItemToList(VOID) { ULONG cchName = 0; LPTSTR pszItem = NULL; // Get the item from the edit well cchName = Edit_GetTextLength(m_hwndPeople) + 1; if (FAILED(HrAlloc((void **) &pszItem, cchName * sizeof(*pszItem)))) { goto exit; } pszItem[0] = '\0'; cchName = Edit_GetText(m_hwndPeople, pszItem, cchName); // Check to see if the name is valid if (0 == UlStripWhitespace(pszItem, TRUE, TRUE, NULL)) { // Put up a message saying something is busted AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail), MAKEINTRESOURCEW(idsEditPeopleErrorNoName), NULL, MB_OK | MB_ICONINFORMATION); goto exit; } _FAddWordToList(0, pszItem); // Clear out the edit well Edit_SetText(m_hwndPeople, ""); _UpdateButtons(); exit: SafeMemFree(pszItem); return; } /////////////////////////////////////////////////////////////////////////////// // // _AddItemsFromWAB // // This handles the user typing into the name field // // Returns: TRUE, we handled the edit message // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// VOID CEditPeopleUI::_AddItemsFromWAB(VOID) { ULONG cchName = 0; LPWSTR pwszAddrs = NULL; LPWSTR pwszWalk = NULL; LONG lRecipType = 0; UINT uidsWell = 0; // Set the proper tags switch(m_pCritItem->type) { case CRIT_TYPE_TO: lRecipType = MAPI_TO; uidsWell = idsRulePickTo; break; case CRIT_TYPE_CC: lRecipType = MAPI_CC; uidsWell = idsRulePickCC; break; case CRIT_TYPE_FROM: lRecipType = MAPI_ORIG; uidsWell = idsRulePickFrom; break; case CRIT_TYPE_TOORCC: lRecipType = MAPI_TO; uidsWell = idsRulePickToOrCC; break; default: goto exit; break; } if (FAILED(RuleUtil_HrGetAddressesFromWAB(m_hwndDlg, lRecipType, uidsWell, &pwszAddrs))) { goto exit; } // Loop through each of the addresses for (pwszWalk = pwszAddrs; '\0' != pwszWalk[0]; pwszWalk += lstrlenW(pwszWalk) + 1) { LPSTR pszWalk = NULL; // Addresses only have to be US ASCII so won't loose anything in this conversion. pszWalk = PszToANSI(CP_ACP, pwszWalk); if (!pszWalk) { TraceResult(E_OUTOFMEMORY); goto exit; } _FAddWordToList(0, pszWalk); MemFree(pszWalk); } _UpdateButtons(); exit: MemFree(pwszAddrs); return; } /////////////////////////////////////////////////////////////////////////////// // // _RemoveItemFromList // // This handles the user typing into the name field // // Returns: TRUE, we handled the edit message // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// VOID CEditPeopleUI::_RemoveItemFromList(VOID) { INT iSelected = 0; INT cItems = 0; Assert(NULL != m_hwndList); // Figure out which item is selected in the list iSelected = (INT) SendMessage(m_hwndList, LB_GETCURSEL, (WPARAM) 0, (LPARAM) 0); if (LB_ERR == iSelected) { goto exit; } // If it's the tag line, then fail if (0 == iSelected) { goto exit; } // Get the current number of items cItems = (INT) SendMessage(m_hwndList, LB_GETCOUNT, (WPARAM) 0, (LPARAM) 0); if (LB_ERR == cItems) { goto exit; } // Remove the item if (LB_ERR == (INT) SendMessage(m_hwndList, LB_DELETESTRING, (WPARAM) iSelected, (LPARAM) 0)) { goto exit; } // If we deleted the last item, select the new last item if (iSelected == (cItems - 1)) { iSelected--; } // Set the new selection if (0 != iSelected) { SideAssert(LB_ERR != (INT) SendMessage(m_hwndList, LB_SETCURSEL, (WPARAM) iSelected, (LPARAM) 0)); } _UpdateButtons(); exit: return; } /////////////////////////////////////////////////////////////////////////////// // // _ChangeOptions // // This handles the user typing into the name field // // Returns: TRUE, we handled the edit message // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// VOID CEditPeopleUI::_ChangeOptions(VOID) { HRESULT hr = S_OK; CEditPeopleOptionsUI * pOptionUI = NULL; CRIT_ITEM critItem; Assert(NULL != m_pCritItem); // Initialize local variables ZeroMemory(&critItem, sizeof(critItem)); // Create the options UI object pOptionUI = new CEditPeopleOptionsUI; if (NULL == pOptionUI) { goto exit; } // Initialize the options UI object hr = pOptionUI->HrInit(m_hwndDlg, m_dwFlags); if (FAILED(hr)) { goto exit; } // Create the parameters to pass to the options dialog critItem.type = m_pCritItem->type; critItem.dwFlags = m_pCritItem->dwFlags; critItem.propvar.vt = VT_BLOB; // Get the parameter from the dialog if (FALSE == _FOnOK(&critItem)) { goto exit; } // Show the options UI hr = pOptionUI->HrShow(&critItem); if (FAILED(hr)) { goto exit; } // If anything changed if (S_OK == hr) { // Set the new value m_pCritItem->dwFlags = critItem.dwFlags; // Make sure the list is redrawn InvalidateRect(m_hwndList, NULL, TRUE); // Mark us as dirty m_dwState |= STATE_DIRTY; } exit: PropVariantClear(&(critItem.propvar)); if (NULL != pOptionUI) { delete pOptionUI; } return; } /////////////////////////////////////////////////////////////////////////////// // // _FOnNameChange // // This handles the user typing into the name field // // Returns: TRUE, we handled the edit message // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleUI::_FOnNameChange(VOID) { BOOL fRet = FALSE; BOOL fIsText = FALSE; Assert(NULL != m_hwndPeople); // Note that we're dirty m_dwState |= STATE_DIRTY; fIsText = (0 != Edit_GetTextLength(m_hwndPeople)); // Disable the Add button if the name is empty fRet = RuleUtil_FEnDisDialogItem(m_hwndDlg, idcCriteriaAdd, fIsText); SendMessage(m_hwndDlg, DM_SETDEFID, (FALSE != fIsText) ? idcCriteriaAdd : IDOK, 0); return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FOnOK // // This handles the user typing into the name field // // Returns: TRUE, we handled the edit message // FALSE, otherwise // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleUI::_FOnOK(CRIT_ITEM * pCritItem) { BOOL fRet = FALSE; INT cItems = 0; INT iIndex = 0; INT iRet = 0; ULONG cchText = 0; LPTSTR pszText = NULL; LPTSTR pszWalk = NULL; Assert(NULL != m_hwndList); // Get the total number of items in the list cItems = (INT) SendMessage(m_hwndList, LB_GETCOUNT, (WPARAM) 0, (LPARAM) 0); if ((LB_ERR == cItems) || (2 > cItems)) { fRet = FALSE; goto exit; } // Loop through each item, calculating the space each would take for (iIndex = 1; iIndex < cItems; iIndex++) { // Get the space for the item iRet = (INT) SendMessage(m_hwndList, LB_GETTEXTLEN, (WPARAM) iIndex, (LPARAM) 0); if ((LB_ERR == iRet) || (0 == iRet)) { continue; } // Count the space needed cchText += iRet + 1; } // Add in space for the terminator cchText += 2; // Allocate space to hold the item if (FAILED(HrAlloc((VOID **) &pszText, sizeof(*pszText) * cchText))) { fRet = FALSE; goto exit; } // Loop through each item, calculating the space each would take pszWalk = pszText; for (iIndex = 1; iIndex < cItems; iIndex++) { // Get the space for the item iRet = (INT) SendMessage(m_hwndList, LB_GETTEXT, (WPARAM) iIndex, (LPARAM) pszWalk); if ((LB_ERR == iRet) || (0 == iRet)) { continue; } // Count the space needed pszWalk += iRet + 1; } // Add in space for the terminator pszWalk[0] = '\0'; pszWalk[1] = '\0'; // Set the new string in the blob SafeMemFree(pCritItem->propvar.blob.pBlobData); pCritItem->propvar.blob.pBlobData = (BYTE *) pszText; pszText = NULL; pCritItem->propvar.blob.cbSize = sizeof(*pszText) * cchText; // Set the return value fRet = TRUE; exit: SafeMemFree(pszText); return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _UpdateButtons // // This enables or disables the buttons in the people editor UI dialog // depending on what is selected. // // iSelected - the item that was selected, // -1 means that nothing was selected // // Returns: NONE // /////////////////////////////////////////////////////////////////////////////// void CEditPeopleUI::_UpdateButtons(VOID) { INT iSelected = 0; BOOL fSelected = FALSE; BOOL fEditable = FALSE; INT cItems = 0; Assert(NULL != m_hwndList); // Get the currently selected item iSelected = (INT) SendMessage(m_hwndList, LB_GETCURSEL, (WPARAM) 0, (LPARAM) 0); if (LB_ERR == iSelected) { iSelected = -1; } fSelected = (-1 != iSelected); fEditable = ((FALSE != fSelected) && (0 != iSelected)); cItems = (INT) SendMessage(m_hwndList, LB_GETCOUNT, (WPARAM) 0, (LPARAM) 0); // Enable the rule action buttons RuleUtil_FEnDisDialogItem(m_hwndDlg, idcCriteriaRemove, fSelected && fEditable); RuleUtil_FEnDisDialogItem(m_hwndDlg, idcCriteriaOptions, cItems > 1); RuleUtil_FEnDisDialogItem(m_hwndDlg, IDOK, cItems > 1); return; } /////////////////////////////////////////////////////////////////////////////// // // _AddTagLineToList // // This enables or disables the buttons in the people editor UI dialog // depending on what is selected. // // iSelected - the item that was selected, // -1 means that nothing was selected // // Returns: NONE // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleUI::_AddTagLineToList(VOID) { BOOL fRet = FALSE; Assert(NULL != m_hwndList); fRet = _FAddWordToList(0, " "); if (FALSE == fRet) { goto exit; } // Set the proper return value fRet = TRUE; exit: return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _FAddWordToList // // This enables or disables the buttons in the people editor UI dialog // depending on what is selected. // // iSelected - the item that was selected, // -1 means that nothing was selected // // Returns: NONE // /////////////////////////////////////////////////////////////////////////////// BOOL CEditPeopleUI::_FAddWordToList(DWORD dwFlags, LPCTSTR pszItem) { BOOL fRet = FALSE; int cItems = 0; INT iRet = 0; Assert(NULL != m_hwndList); // Is there anything to do? if ((NULL == pszItem) || (L'\0' == pszItem[0])) { fRet = FALSE; goto exit; } // Get the number of items in the list cItems = (INT) SendMessage(m_hwndList, LB_GETCOUNT, (WPARAM) 0, (LPARAM) 0); if (LB_ERR == cItems) { fRet = FALSE; goto exit; } // Set the data into the list iRet = (INT) SendMessage(m_hwndList, LB_ADDSTRING, (WPARAM) cItems, (LPARAM) pszItem); if ((LB_ERR == iRet) || (LB_ERRSPACE == iRet)) { fRet = FALSE; goto exit; } // Set the proper return value fRet = TRUE; exit: return fRet; } /////////////////////////////////////////////////////////////////////////////// // // _HrCriteriaEditPeople // // This creates a people editor. // // ppViewMenu - pointer to return the view menu // // Returns: S_OK, on success // E_OUTOFMEMORY, if can't create the View Menu object // /////////////////////////////////////////////////////////////////////////////// HRESULT _HrCriteriaEditPeople(HWND hwnd, CRIT_ITEM * pCritItem) { HRESULT hr = S_OK; CEditPeopleUI * pPeopleUI = NULL; // Check the incoming params if (NULL == pCritItem) { hr = E_INVALIDARG; goto exit; } // Create the view menu object pPeopleUI = new CEditPeopleUI; if (NULL == pPeopleUI) { hr = E_OUTOFMEMORY; goto exit; } // Initialize the view menu hr = pPeopleUI->HrInit(hwnd, 0); if (FAILED(hr)) { goto exit; } // Show the UI hr = pPeopleUI->HrShow(pCritItem); if (FAILED(hr)) { goto exit; } exit: if (NULL != pPeopleUI) { delete pPeopleUI; } return hr; } /////////////////////////////////////////////////////////////////////////////// // // _HrCriteriaEditWords // // This creates a words editor. // // ppViewMenu - pointer to return the view menu // // Returns: S_OK, on success // E_OUTOFMEMORY, if can't create the View Menu object // /////////////////////////////////////////////////////////////////////////////// HRESULT _HrCriteriaEditWords(HWND hwnd, CRIT_ITEM * pCritItem) { HRESULT hr = S_OK; CEditPeopleUI * pPeopleUI = NULL; // Check the incoming params if (NULL == pCritItem) { hr = E_INVALIDARG; goto exit; } // Create the view menu object pPeopleUI = new CEditPeopleUI; if (NULL == pPeopleUI) { hr = E_OUTOFMEMORY; goto exit; } // Initialize the view menu hr = pPeopleUI->HrInit(hwnd, PUI_WORDS); if (FAILED(hr)) { goto exit; } // Show the UI hr = pPeopleUI->HrShow(pCritItem); if (FAILED(hr)) { goto exit; } exit: if (NULL != pPeopleUI) { delete pPeopleUI; } return hr; }