Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

6761 lines
200 KiB

///////////////////////////////////////////////////////////////////////////////
//
// 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)&paraFmt);
// 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;
}