|
|
///////////////////////////////////////////////////////////////////////////////
//
// RuleDesc.cpp
//
///////////////////////////////////////////////////////////////////////////////
#include <pch.hxx>
#include "ruledesc.h"
#include "editrule.h"
#include "ruleutil.h"
#include <rulesdlg.h>
#include <newfldr.h>
#include <richedit.h>
#include <fontnsc.h>
#include <wabdefs.h>
#include <mimeolep.h>
#include <xpcomm.h>
#include "reutil.h"
#include "shlwapip.h"
#include <demand.h>
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; }
|