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

4056 lines
110 KiB

///////////////////////////////////////////////////////////////////////////////
//
// SpamUI.cpp
//
///////////////////////////////////////////////////////////////////////////////
#include <pch.hxx>
#include "oerules.h"
#include "spamui.h"
#include "junkrule.h"
#include "rule.h"
#include "ruleutil.h"
#include <rulesdlg.h>
#include <imagelst.h>
#include <msoejunk.h>
#include "shlwapip.h"
#include <ipab.h>
#include <demand.h>
// Type definitions
typedef struct tagEDIT_EXCPT
{
DWORD dwFlags;
LPSTR pszExcpt;
} EDIT_EXCPT, * PEDIT_EXCPT;
// Class definitions
class CEditExceptionUI
{
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_hwndExcpt;
EDIT_EXCPT * m_pEditExcpt;
public:
CEditExceptionUI() : m_hwndOwner(NULL), m_dwFlags(0), m_dwState(STATE_UNINIT),
m_hwndDlg(NULL), m_hwndExcpt(NULL), m_pEditExcpt(NULL) {}
~CEditExceptionUI();
HRESULT HrInit(HWND hwndOwner, DWORD dwFlags, EDIT_EXCPT * pEditExcpt);
HRESULT HrShow(VOID);
static INT_PTR CALLBACK FEditExcptDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);
// Message handling methods
BOOL FOnInitDialog(HWND hwndDlg);
BOOL FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl);
};
// global data
const static HELPMAP g_rgCtxMapJunkRules[] = {
{idcJunkMail, idhJunkMail},
{idbExceptions, idhExceptions},
{idcJunkSlider, idhJunkSlider},
{idcJunkDelete, idhJunkDelete},
{0, 0}};
const static HELPMAP g_rgCtxMapSenderRules[] = {
{idbAddSender, idhAddSender},
{idbModifySender, idhModifySender},
{idbRemoveSender, idhRemoveSender},
{0, 0}};
CEditSenderUI::~CEditSenderUI()
{
if ((NULL != m_pEditSender) && (NULL != m_pEditSender->pszSender))
{
MemFree(m_pEditSender->pszSender);
}
}
///////////////////////////////////////////////////////////////////////////////
//
// HrInit
//
// This initializes the edit sender UI dialog
//
// hwndOwner - the handle to the owner window of this dialog
// dwFlags - modifiers on how this dialog should act
// pEditSender - the edit sender parameters
//
// Returns: S_OK, if it was successfully initialized
//
///////////////////////////////////////////////////////////////////////////////
HRESULT CEditSenderUI::HrInit(HWND hwndOwner, DWORD dwFlags, EDIT_SENDER * pEditSender)
{
HRESULT hr = S_OK;
// Check incoming params
if ((NULL == hwndOwner) || (NULL == pEditSender))
{
hr = E_INVALIDARG;
goto exit;
}
if (0 != (m_dwState & STATE_INITIALIZED))
{
hr = E_UNEXPECTED;
goto exit;
}
m_hwndOwner = hwndOwner;
m_dwFlags = dwFlags;
m_pEditSender = pEditSender;
m_dwState |= STATE_INITIALIZED;
hr = S_OK;
exit:
return hr;
}
///////////////////////////////////////////////////////////////////////////////
//
// HrShow
//
// This brings up the edit sender UI dialog
//
// Returns: S_OK, if the sender was successfully entered
// S_FALSE, if the dialog was canceled
//
///////////////////////////////////////////////////////////////////////////////
HRESULT CEditSenderUI::HrShow(VOID)
{
HRESULT hr = S_OK;
int iRet = 0;
if (0 == (m_dwState & STATE_INITIALIZED))
{
hr = E_UNEXPECTED;
goto exit;
}
iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddEditSender),
m_hwndOwner, CEditSenderUI::FEditSendersDlgProc,
(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;
}
///////////////////////////////////////////////////////////////////////////////
//
// FEditSendersDlgProc
//
// This is the main dialog proc for entering a sender
//
// 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 CEditSenderUI::FEditSendersDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
BOOL fRet = FALSE;
CEditSenderUI * pEditSenderUI = NULL;
pEditSenderUI = (CEditSenderUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch (uiMsg)
{
case WM_INITDIALOG:
pEditSenderUI = (CEditSenderUI *) lParam;
if (NULL == pEditSenderUI)
{
fRet = FALSE;
EndDialog(hwndDlg, -1);
goto exit;
}
// Set it into the dialog so we can get it back
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LPARAM) pEditSenderUI);
if (FALSE == pEditSenderUI->FOnInitDialog(hwndDlg))
{
EndDialog(hwndDlg, -1);
fRet = TRUE;
goto exit;
}
// We didn't set the focus so return TRUE
fRet = TRUE;
break;
case WM_COMMAND:
fRet = pEditSenderUI->FOnCommand((UINT) HIWORD(wParam), (INT) LOWORD(wParam), (HWND) lParam);
break;
}
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FOnInitDialog
//
// This handles the WM_INITDIALOG message for the edit senders dialog
//
// hwndDlg - the handle to the dialog window
//
// Returns: TRUE, if it was successfully initialized
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CEditSenderUI::FOnInitDialog(HWND hwndDlg)
{
BOOL fRet = FALSE;
UINT uiCtrl = 0;
HWND hwndCtrl = NULL;
CHAR szRes[CCHMAX_STRINGRES];
UINT uiTitle = 0;
// Check incoming params
if (NULL == hwndDlg)
{
fRet = FALSE;
goto exit;
}
// If we haven't been initialized yet...
if (0 == (m_dwState & STATE_INITIALIZED))
{
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_hwndSender = GetDlgItem(hwndDlg, idedtSender);
if (NULL == m_hwndSender)
{
fRet = FALSE;
goto exit;
}
// If we have a sender, then set it into the list
if (NULL != m_pEditSender->pszSender)
{
// Misformatted sender?
if (SNDF_NONE == m_pEditSender->dwFlags)
{
fRet = FALSE;
goto exit;
}
// Set the sender into the dialog
Edit_SetText(m_hwndSender, m_pEditSender->pszSender);
// Set the proper
if ((SNDF_MAIL | SNDF_NEWS) == m_pEditSender->dwFlags)
{
uiCtrl = idcBlockBoth;
}
else if (SNDF_NEWS == m_pEditSender->dwFlags)
{
uiCtrl = idcBlockNews;
}
else
{
uiCtrl = idcBlockMail;
}
uiTitle = idsEditBlockSender;
}
else
{
Edit_SetText(m_hwndSender, c_szEmpty);
uiCtrl = idcBlockMail;
uiTitle = idsAddBlockSender;
}
// Get the window title
AthLoadString(uiTitle, szRes, sizeof(szRes));
// Set the window title
SetWindowText(m_hwndDlg, szRes);
hwndCtrl = GetDlgItem(m_hwndDlg, uiCtrl);
if (NULL == hwndCtrl)
{
fRet = FALSE;
goto exit;
}
SendMessage(hwndCtrl, BM_SETCHECK, (WPARAM) BST_CHECKED, (LPARAM) 0);
// Everything's AOK
fRet = TRUE;
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FOnCommand
//
// This handles the WM_COMMAND message for the senders UI dialog
//
// Returns: TRUE, if it was successfully handled
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CEditSenderUI::FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl)
{
BOOL fRet = FALSE;
ULONG cchSender = 0;
LPSTR pszSender = NULL;
CHAR szRes[CCHMAX_STRINGRES];
LPSTR pszText = NULL;
// Deal with the edit control notifications
if ((EN_CHANGE == uiNotify) && (idedtSender == iCtl))
{
Assert(NULL != m_hwndSender);
Assert((HWND) hwndCtl == m_hwndSender);
RuleUtil_FEnDisDialogItem(m_hwndDlg, IDOK, 0 != Edit_GetTextLength(m_hwndSender));
goto exit;
}
// We only handle menu and accelerator commands
if ((0 != uiNotify) && (1 != uiNotify))
{
fRet = FALSE;
goto exit;
}
switch (iCtl)
{
case IDCANCEL:
EndDialog(m_hwndDlg, IDCANCEL);
fRet = TRUE;
break;
case IDOK:
// Get the sender from the edit well
cchSender = Edit_GetTextLength(m_hwndSender) + 1;
if (FAILED(HrAlloc((void **) &pszSender, cchSender * sizeof(*pszSender))))
{
fRet = FALSE;
goto exit;
}
pszSender[0] = '\0';
cchSender = Edit_GetText(m_hwndSender, pszSender, cchSender);
// Check to see if the sender is valid
if (0 == UlStripWhitespace(pszSender, TRUE, TRUE, NULL))
{
// Put up a message saying something is busted
AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail),
MAKEINTRESOURCEW(idsSenderBlank), NULL,
MB_OK | MB_ICONINFORMATION);
fRet = FALSE;
goto exit;
}
if (FALSE != SendMessage(m_hwndOwner, WM_OE_FIND_DUP, (WPARAM) (m_pEditSender->lSelected), (LPARAM) pszSender))
{
AthLoadString(idsSenderDupWarn, szRes, sizeof(szRes));
DWORD cchSize = (lstrlen(pszSender) * 2 + lstrlen(szRes) + 1);
if (FAILED(HrAlloc((VOID **) &pszText, cchSize * sizeof(*pszText))))
{
fRet = FALSE;
goto exit;
}
wnsprintf(pszText, cchSize, szRes, pszSender, pszSender);
// Put up a message saying something is busted
if (IDYES != AthMessageBox(m_hwndDlg, MAKEINTRESOURCE(idsAthenaMail),
pszText, NULL, MB_YESNO | MB_ICONINFORMATION))
{
fRet = FALSE;
goto exit;
}
}
// Save off the sender
SafeMemFree(m_pEditSender->pszSender);
m_pEditSender->pszSender = pszSender;
pszSender = NULL;
if (BST_CHECKED == SendMessage(GetDlgItem(m_hwndDlg, idcBlockMail),
BM_GETCHECK, (WPARAM) 0, (LPARAM) 0))
{
m_pEditSender->dwFlags = SNDF_MAIL;
}
else if (BST_CHECKED == SendMessage(GetDlgItem(m_hwndDlg, idcBlockNews),
BM_GETCHECK, (WPARAM) 0, (LPARAM) 0))
{
m_pEditSender->dwFlags = SNDF_NEWS;
}
else if (BST_CHECKED == SendMessage(GetDlgItem(m_hwndDlg, idcBlockBoth),
BM_GETCHECK, (WPARAM) 0, (LPARAM) 0))
{
m_pEditSender->dwFlags = SNDF_MAIL | SNDF_NEWS;
}
EndDialog(m_hwndDlg, IDOK);
fRet = TRUE;
break;
}
exit:
SafeMemFree(pszText);
SafeMemFree(pszSender);
return fRet;
}
// This is for editing the exceptions from the exceptions list UI
///////////////////////////////////////////////////////////////////////////////
//
// ~CEditExceptionUI
//
// This is the default destructor for the Exception editor
//
// Returns: None
//
///////////////////////////////////////////////////////////////////////////////
CEditExceptionUI::~CEditExceptionUI()
{
if ((NULL != m_pEditExcpt) && (NULL != m_pEditExcpt->pszExcpt))
{
MemFree(m_pEditExcpt->pszExcpt);
}
}
///////////////////////////////////////////////////////////////////////////////
//
// HrInit
//
// This initializes the edit exception UI dialog
//
// hwndOwner - the handle to the owner window of this dialog
// dwFlags - modifiers on how this dialog should act
// pEditExcpt - the edit exception parameters
//
// Returns: S_OK, if it was successfully initialized
//
///////////////////////////////////////////////////////////////////////////////
HRESULT CEditExceptionUI::HrInit(HWND hwndOwner, DWORD dwFlags, EDIT_EXCPT * pEditExcpt)
{
HRESULT hr = S_OK;
// Check incoming params
if ((NULL == hwndOwner) || (NULL == pEditExcpt))
{
hr = E_INVALIDARG;
goto exit;
}
if (0 != (m_dwState & STATE_INITIALIZED))
{
hr = E_UNEXPECTED;
goto exit;
}
m_hwndOwner = hwndOwner;
m_dwFlags = dwFlags;
m_pEditExcpt = pEditExcpt;
m_dwState |= STATE_INITIALIZED;
hr = S_OK;
exit:
return hr;
}
///////////////////////////////////////////////////////////////////////////////
//
// HrShow
//
// This brings up the edit exception UI dialog
//
// Returns: S_OK, if the sender was successfully entered
// S_FALSE, if the dialog was canceled
//
///////////////////////////////////////////////////////////////////////////////
HRESULT CEditExceptionUI::HrShow(VOID)
{
HRESULT hr = S_OK;
int iRet = 0;
if (0 == (m_dwState & STATE_INITIALIZED))
{
hr = E_UNEXPECTED;
goto exit;
}
iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddEditException),
m_hwndOwner, CEditExceptionUI::FEditExcptDlgProc,
(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;
}
///////////////////////////////////////////////////////////////////////////////
//
// FEditExcptDlgProc
//
// This is the main dialog proc for entering an exception
//
// 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 CEditExceptionUI::FEditExcptDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
BOOL fRet = FALSE;
CEditExceptionUI * pEditExcptUI = NULL;
pEditExcptUI = (CEditExceptionUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch (uiMsg)
{
case WM_INITDIALOG:
pEditExcptUI = (CEditExceptionUI *) lParam;
if (NULL == pEditExcptUI)
{
fRet = FALSE;
EndDialog(hwndDlg, -1);
goto exit;
}
// Set it into the dialog so we can get it back
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LPARAM) pEditExcptUI);
if (FALSE == pEditExcptUI->FOnInitDialog(hwndDlg))
{
EndDialog(hwndDlg, -1);
fRet = TRUE;
goto exit;
}
// We didn't set the focus so return TRUE
fRet = TRUE;
break;
case WM_COMMAND:
fRet = pEditExcptUI->FOnCommand((UINT) HIWORD(wParam), (INT) LOWORD(wParam), (HWND) lParam);
break;
}
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FOnInitDialog
//
// This handles the WM_INITDIALOG message for the edit exception dialog
//
// hwndDlg - the handle to the dialog window
//
// Returns: TRUE, if it was successfully initialized
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CEditExceptionUI::FOnInitDialog(HWND hwndDlg)
{
BOOL fRet = FALSE;
UINT uiCtrl = 0;
HWND hwndCtrl = NULL;
CHAR szRes[CCHMAX_STRINGRES];
UINT uiTitle = 0;
// Check incoming params
if (NULL == hwndDlg)
{
fRet = FALSE;
goto exit;
}
// If we haven't been initialized yet...
if (0 == (m_dwState & STATE_INITIALIZED))
{
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_hwndExcpt = GetDlgItem(hwndDlg, idedtException);
if (NULL == m_hwndExcpt)
{
fRet = FALSE;
goto exit;
}
// If we have a sender, then set it into the list
if (NULL != m_pEditExcpt->pszExcpt)
{
// Set the sender into the dialog
Edit_SetText(m_hwndExcpt, m_pEditExcpt->pszExcpt);
uiTitle = idsEditException;
}
else
{
Edit_SetText(m_hwndExcpt, c_szEmpty);
uiTitle = idsAddException;
}
// Get the window title
AthLoadString(uiTitle, szRes, sizeof(szRes));
// Set the window title
SetWindowText(m_hwndDlg, szRes);
// Everything's AOK
fRet = TRUE;
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FOnCommand
//
// This handles the WM_COMMAND message for the exception UI dialog
//
// Returns: TRUE, if it was successfully handled
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CEditExceptionUI::FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl)
{
BOOL fRet = FALSE;
ULONG cchExcpt = 0;
LPSTR pszExcpt = NULL;
// Deal with the edit control notifications
if ((EN_CHANGE == uiNotify) && (idedtException == iCtl))
{
Assert(NULL != m_hwndExcpt);
Assert((HWND) hwndCtl == m_hwndExcpt);
RuleUtil_FEnDisDialogItem(m_hwndDlg, IDOK, 0 != Edit_GetTextLength(m_hwndExcpt));
goto exit;
}
// We only handle menu and accelerator commands
if ((0 != uiNotify) && (1 != uiNotify))
{
fRet = FALSE;
goto exit;
}
switch (iCtl)
{
case IDCANCEL:
EndDialog(m_hwndDlg, IDCANCEL);
fRet = TRUE;
break;
case IDOK:
// Get the sender from the edit well
cchExcpt = Edit_GetTextLength(m_hwndExcpt) + 1;
if (FAILED(HrAlloc((void **) &pszExcpt, cchExcpt * sizeof(*pszExcpt))))
{
fRet = FALSE;
goto exit;
}
pszExcpt[0] = '\0';
cchExcpt = Edit_GetText(m_hwndExcpt, pszExcpt, cchExcpt);
// Check to see if the sender is valid
if (0 == UlStripWhitespace(pszExcpt, TRUE, TRUE, NULL))
{
// Put up a message saying something is busted
AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail),
MAKEINTRESOURCEW(idsExceptionBlank), NULL,
MB_OK | MB_ICONINFORMATION);
MemFree(pszExcpt);
fRet = FALSE;
goto exit;
}
// Save off the sender
SafeMemFree(m_pEditExcpt->pszExcpt);
m_pEditExcpt->pszExcpt = pszExcpt;
EndDialog(m_hwndDlg, IDOK);
fRet = TRUE;
break;
}
exit:
return fRet;
}
// Default destructor for the Junk Rules UI
COEJunkRulesPageUI::~COEJunkRulesPageUI()
{
if (NULL != m_himl)
{
ImageList_Destroy(m_himl);
}
if (NULL != m_pExceptionsUI)
{
delete m_pExceptionsUI;
m_pExceptionsUI = NULL;
}
SafeRelease(m_pIRuleJunk);
}
///////////////////////////////////////////////////////////////////////////////
//
// HrInit
//
// This initializes the junk UI dialog
//
// hwndOwner - the handle to the owner window of this dialog
// dwFlags - modifiers on how this dialog should act
//
// Returns: S_OK, if it was successfully initialized
//
///////////////////////////////////////////////////////////////////////////////
HRESULT COEJunkRulesPageUI::HrInit(HWND hwndOwner, DWORD dwFlags)
{
HRESULT hr = S_OK;
// Check incoming params
if (NULL == hwndOwner)
{
hr = E_INVALIDARG;
goto exit;
}
if (0 != (m_dwState & STATE_INITIALIZED))
{
hr = E_UNEXPECTED;
goto exit;
}
m_hwndOwner = hwndOwner;
m_dwFlags = dwFlags;
// Let's create the Exception List UI
m_pExceptionsUI = new CExceptionsListUI;
if (NULL == m_pExceptionsUI)
{
hr = E_OUTOFMEMORY;
goto exit;
}
m_dwState |= STATE_INITIALIZED;
hr = S_OK;
exit:
return hr;
}
///////////////////////////////////////////////////////////////////////////////
//
// HrCommitChanges
//
// This commits the changes to the rules
//
// dwFlags - modifiers on how we should commit the changes
// fClearDirty - should we clear the dirty state
//
// Returns: S_OK, if it was successfully committed
//
///////////////////////////////////////////////////////////////////////////////
HRESULT COEJunkRulesPageUI::HrCommitChanges(DWORD dwFlags, BOOL fClearDirty)
{
HRESULT hr = S_OK;
BOOL fJunkEnable = FALSE;
DWORD dwVal = 0;
RULEINFO infoRule = {0};
// Check incoming params
if (0 != dwFlags)
{
hr = E_INVALIDARG;
goto exit;
}
// Fail if we weren't initialized
if (0 == (m_dwState & STATE_INITIALIZED))
{
hr = E_UNEXPECTED;
goto exit;
}
// If we aren't dirty, then there's
// nothing to do
if (0 == (m_dwState & STATE_DIRTY))
{
hr = S_FALSE;
goto exit;
}
// Save the junk mail rule settings
if (FALSE == _FSaveJunkSettings())
{
hr = E_FAIL;
goto exit;
}
// Initialize the rule info
infoRule.ridRule = RULEID_JUNK;
infoRule.pIRule = m_pIRuleJunk;
// Set the rules into the rules manager
hr = g_pRulesMan->SetRules(SETF_JUNK, RULE_TYPE_MAIL, &infoRule, 1);
if (FAILED(hr))
{
goto exit;
}
// Should we delete items from the Junk folder
dwVal = (BST_CHECKED == Button_GetCheck(GetDlgItem(m_hwndDlg, idcJunkDelete))) ? 1 : 0;
SetDwOption(OPT_DELETEJUNK, dwVal, NULL, 0);
// How many days should we wait?
dwVal = (DWORD) SendMessage(GetDlgItem(m_hwndDlg, idcJunkDeleteSpin), UDM_GETPOS, (WPARAM) 0, (LPARAM) 0);
if (0 == HIWORD(dwVal))
{
SetDwOption(OPT_DELETEJUNKDAYS, dwVal, NULL, 0);
}
// Should we clear the dirty state
if (FALSE != fClearDirty)
{
m_dwState &= ~STATE_DIRTY;
}
hr = S_OK;
exit:
return hr;
}
INT_PTR CALLBACK COEJunkRulesPageUI::FJunkRulesPageDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
BOOL fRet = FALSE;
COEJunkRulesPageUI * pJunkUI = NULL;
pJunkUI = (COEJunkRulesPageUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch (uiMsg)
{
case WM_INITDIALOG:
// Grab the UI object pointer
pJunkUI = (COEJunkRulesPageUI *) lParam;
// Set it into the dialog so we can get it back
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LPARAM) pJunkUI);
if (FALSE == pJunkUI->FOnInitDialog(hwndDlg))
{
EndDialog(hwndDlg, -1);
fRet = TRUE;
goto exit;
}
// We didn't set the focus so return TRUE
fRet = TRUE;
break;
case WM_COMMAND:
if (NULL != pJunkUI)
{
fRet = pJunkUI->FOnCommand((UINT) HIWORD(wParam), (INT) LOWORD(wParam), (HWND) lParam);
}
break;
case WM_NOTIFY:
if (NULL != pJunkUI)
{
fRet = pJunkUI->FOnNotify((INT) LOWORD(wParam), (NMHDR *) lParam);
}
break;
case WM_HSCROLL:
if (NULL != pJunkUI)
{
fRet = pJunkUI->FOnHScroll((INT) LOWORD(wParam), (short int) HIWORD(wParam), (HWND) lParam);
}
break;
case WM_DESTROY:
if (NULL != pJunkUI)
{
fRet = pJunkUI->FOnDestroy();
}
break;
case WM_HELP:
case WM_CONTEXTMENU:
fRet = OnContextHelp(hwndDlg, uiMsg, wParam, lParam, g_rgCtxMapJunkRules);
break;
}
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FGetRules
//
// This brings up the edit UI for the selected rule from the mail rules list
//
// fBegin - is this for the LVN_BEGINLABELEDIT notification
// pdi - the display info for the message
//
// Returns: TRUE, if the message was handled
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL COEJunkRulesPageUI::FGetRules(RULE_TYPE typeRule, RULENODE ** pprnode)
{
BOOL fRet = FALSE;
IOERule * pIRule = NULL;
RULENODE * prnodeNew = NULL;
HRESULT hr = S_OK;
PROPVARIANT propvar = {0};
if (NULL == pprnode)
{
fRet = FALSE;
goto exit;
}
// Fail if we weren't initialized
if (0 == (m_dwState & STATE_INITIALIZED))
{
fRet = FALSE;
goto exit;
}
// Initialize the outgoing param
*pprnode = NULL;
// Make sure we don't lose any changes
// Get the correct rule
if (RULE_TYPE_MAIL == typeRule)
{
if (FALSE != _FSaveJunkSettings())
{
pIRule = m_pIRuleJunk;
}
}
else
{
fRet = FALSE;
goto exit;
}
// Nothing to do if we don't have a rule
if (NULL == pIRule)
{
fRet = TRUE;
goto exit;
}
// Skip over invalid rules
hr = pIRule->Validate(0);
if (FAILED(hr) || (S_FALSE == hr))
{
fRet = FALSE;
goto exit;
}
// Skip over the junk rule if it is disabled
hr = pIRule->GetProp(RULE_PROP_DISABLED, 0, &propvar);
if ((FAILED(hr)) || (FALSE != propvar.boolVal))
{
fRet = FALSE;
goto exit;
}
// Create a new rule node
prnodeNew = new RULENODE;
if (NULL == prnodeNew)
{
fRet = FALSE;
goto exit;
}
prnodeNew->pNext = NULL;
prnodeNew->pIRule = pIRule;
prnodeNew->pIRule->AddRef();
// Set the outgoing param
*pprnode = prnodeNew;
prnodeNew = NULL;
fRet = TRUE;
exit:
PropVariantClear(&propvar);
if (NULL != prnodeNew)
{
if (NULL != prnodeNew->pIRule)
{
prnodeNew->pIRule->Release();
}
delete prnodeNew; // MemFree(prnodeNew);
}
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FOnInitDialog
//
// This handles the WM_INITDIALOG message for the junk UI dialog
//
// hwndDlg - the handle to the dialog window
//
// Returns: TRUE, if it was successfully initialized
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL COEJunkRulesPageUI::FOnInitDialog(HWND hwndDlg)
{
BOOL fRet = FALSE;
CHAR szRes[CCHMAX_STRINGRES];
// Check incoming params
if (NULL == hwndDlg)
{
fRet = FALSE;
goto exit;
}
// If we haven't been initialized yet...
if (0 == (m_dwState & STATE_INITIALIZED))
{
fRet = FALSE;
goto exit;
}
// Save off the dialog window handle
m_hwndDlg = hwndDlg;
// Set the default font onto the dialog
SetIntlFont(m_hwndDlg);
// Initialize the controls
fRet = _FInitCtrls();
if (FALSE == fRet)
{
goto exit;
}
// Initialize the Exceptions List
if (FAILED(m_pExceptionsUI->HrInit(m_hwndDlg, m_dwFlags)))
{
fRet = FALSE;
goto exit;
}
if (FALSE != FIsIMAPOrHTTPAvailable())
{
AthLoadString(idsJunkMailNoIMAP, szRes, sizeof(szRes));
SetDlgItemText(m_hwndDlg, idcJunkTitle, szRes);
}
// Update the buttons
_EnableButtons();
// Everything's AOK
fRet = TRUE;
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FOnCommand
//
// This handles the WM_COMMAND message for the junk UI dialog
//
// Returns: TRUE, if it was successfully handled
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL COEJunkRulesPageUI::FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl)
{
BOOL fRet = FALSE;
HRESULT hr = S_OK;
switch (iCtl)
{
case idcJunkMail:
if (BST_CHECKED == Button_GetCheck(GetDlgItem(m_hwndDlg, idcJunkMail)))
{
if (NULL == m_pIRuleJunk)
{
hr = HrCreateJunkRule(&m_pIRuleJunk);
if (FAILED(hr))
{
fRet = FALSE;
SafeRelease(m_pIRuleJunk);
goto exit;
}
}
}
// Fall through
case idcJunkDelete:
// Update the buttons
_EnableButtons();
// Note that the state has changed
m_dwState |= STATE_DIRTY;
fRet = FALSE;
break;
case idedtJunkDelete:
if ((0 != (m_dwState & STATE_CTRL_INIT)) && (EN_CHANGE == uiNotify))
{
// Note that the state has changed
m_dwState |= STATE_DIRTY;
fRet = FALSE;
}
break;
case idbExceptions:
if (S_OK == m_pExceptionsUI->HrShow(m_pIRuleJunk))
{
// Note that the state has changed
m_dwState |= STATE_DIRTY;
fRet = FALSE;
}
break;
}
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FOnNotify
//
// This handles the WM_NOTIFY message for the junk UI dialog
//
// Returns: TRUE, if it was successfully destroyed
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL COEJunkRulesPageUI::FOnNotify(INT iCtl, NMHDR * pnmhdr)
{
BOOL fRet = FALSE;
NMLISTVIEW * pnmlv = NULL;
NMLVKEYDOWN * pnmlvkd = NULL;
INT iSelected = 0;
LVHITTESTINFO lvh;
// We only handle notifications for the list control
if (idcJunkDeleteSpin != pnmhdr->idFrom)
{
fRet = FALSE;
goto exit;
}
pnmlv = (LPNMLISTVIEW) pnmhdr;
switch (pnmlv->hdr.code)
{
case UDN_DELTAPOS:
// Note that the state has changed
m_dwState |= STATE_DIRTY;
fRet = FALSE;
break;
}
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FOnHScroll
//
// This handles the WM_NOTIFY message for the junk UI dialog
//
// Returns: TRUE, if it was successfully handled
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL COEJunkRulesPageUI::FOnHScroll(INT iScrollCode, short int iPos, HWND hwndCtl)
{
BOOL fRet = FALSE;
// We only handle messags for the slider control
if (GetDlgItem(m_hwndDlg, idcJunkSlider) != hwndCtl)
{
fRet = FALSE;
goto exit;
}
// Note that the state has changed
m_dwState |= STATE_DIRTY;
fRet = FALSE;
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _FInitCtrls
//
// This initializes the controls in the junk UI dialog
//
// Returns: TRUE, on successful initialization
// FALSE, otherwise.
//
///////////////////////////////////////////////////////////////////////////////
BOOL COEJunkRulesPageUI::_FInitCtrls(VOID)
{
BOOL fRet = FALSE;
DWORD dwJunkPct = 0;
BOOL fEnableDelete = FALSE;
HICON hIcon = NULL;
IOERule * pIRuleOrig = NULL;
IOERule * pIRule = NULL;
HRESULT hr = S_OK;
// Get the icons
m_himl = ImageList_LoadBitmap(g_hLocRes, MAKEINTRESOURCE(idbRules), 32, 0,
RGB(255, 0, 255));
if (NULL == m_himl)
{
fRet = FALSE;
goto exit;
}
// Set the icons into the dialog
hIcon = ImageList_GetIcon(m_himl, ID_JUNK_SCALE, ILD_TRANSPARENT);
SendDlgItemMessage(m_hwndDlg, idcJunkSliderIcon, STM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon);
hIcon = ImageList_GetIcon(m_himl, ID_JUNK_DELETE, ILD_TRANSPARENT);
SendDlgItemMessage(m_hwndDlg, idcJunkDeleteIcon, STM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon);
// Set the range of the slider
SendDlgItemMessage(m_hwndDlg, idcJunkSlider, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG(0, 4));
// Get the junk mail rule
Assert(NULL != g_pRulesMan);
hr = g_pRulesMan->GetRule(RULEID_JUNK, RULE_TYPE_MAIL, 0, &pIRuleOrig);
if (FAILED(hr))
{
fRet = FALSE;
goto exit;
}
// Save off the junk mail rule
Assert (NULL == m_pIRuleJunk);
hr = pIRuleOrig->Clone(&pIRule);
if (FAILED(hr))
{
fRet = FALSE;
goto exit;
}
m_pIRuleJunk = pIRule;
pIRule = NULL;
// Get the setings from the junk rule
_FLoadJunkSettings();
// Do we want to delete the junk mail
fEnableDelete = !!DwGetOption(OPT_DELETEJUNK);
Button_SetCheck(GetDlgItem(m_hwndDlg, idcJunkDelete), fEnableDelete ? BST_CHECKED : BST_UNCHECKED);
// Set the range of the spinner
SendDlgItemMessage(m_hwndDlg, idcJunkDeleteSpin, UDM_SETRANGE, (WPARAM) 0, (LPARAM) MAKELONG(999, 1));
// How many days should we wait?
SendDlgItemMessage(m_hwndDlg, idcJunkDeleteSpin, UDM_SETPOS, (WPARAM) 0,
(LPARAM) MAKELONG(DwGetOption(OPT_DELETEJUNKDAYS), 0));
if (FALSE == fEnableDelete)
{
EnableWindow(GetDlgItem(m_hwndDlg, idcJunkDeleteSpin), FALSE);
EnableWindow(GetDlgItem(m_hwndDlg, idedtJunkDelete), FALSE);
}
m_dwState |= STATE_CTRL_INIT;
// We worked
fRet = TRUE;
exit:
SafeRelease(pIRule);
SafeRelease(pIRuleOrig);
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _FLoadJunkSettings
//
// This load the senders from the rule and inserts them into the senders list.
//
// Returns: TRUE, if it was successfully loaded
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL COEJunkRulesPageUI::_FLoadJunkSettings()
{
BOOL fRet = FALSE;
PROPVARIANT propvar = {0};
int iEnabled = 0;
DWORD dwJunkPct = 0;
Assert(NULL != m_pIRuleJunk);
// Get the Junk detection enabled state
iEnabled = BST_UNCHECKED;
if ((SUCCEEDED(m_pIRuleJunk->GetProp(RULE_PROP_DISABLED, 0, &propvar))))
{
Assert(VT_BOOL == propvar.vt);
iEnabled = (FALSE == propvar.boolVal) ? BST_CHECKED : BST_UNCHECKED;
}
// Set the junk mail flag
Button_SetCheck(GetDlgItem(m_hwndDlg, idcJunkMail), iEnabled);
// Get the Junk percent
dwJunkPct = 2;
if (SUCCEEDED(m_pIRuleJunk->GetProp(RULE_PROP_JUNKPCT, 0, &propvar)))
{
Assert(VT_UI4 == propvar.vt);
dwJunkPct = propvar.ulVal;
}
// Set the Junk percent
SendDlgItemMessage(m_hwndDlg, idcJunkSlider, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) dwJunkPct);
fRet = TRUE;
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _FSaveJunkSettings
//
// This load the senders from the rule and inserts them into the senders list.
//
// Returns: TRUE, if it was successfully loaded
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL COEJunkRulesPageUI::_FSaveJunkSettings()
{
BOOL fRet = FALSE;
PROPVARIANT propvar = {0};
BOOL fDisabled = 0;
DWORD dwJunkPct = 0;
HRESULT hr = S_OK;
Assert(NULL != m_pIRuleJunk);
// Get the Junk detection enabled state
fDisabled = !!(BST_UNCHECKED == Button_GetCheck(GetDlgItem(m_hwndDlg, idcJunkMail)));
// Set the disabled state
propvar.vt = VT_BOOL;
propvar.boolVal = (VARIANT_BOOL) !!fDisabled;
if (FAILED(m_pIRuleJunk->SetProp(RULE_PROP_DISABLED, 0, &propvar)))
{
fRet = FALSE;
goto exit;
}
// Get the Junk percent
dwJunkPct = (DWORD) SendMessage(GetDlgItem(m_hwndDlg, idcJunkSlider), TBM_GETPOS, (WPARAM) 0, (LPARAM) 0);
// Set the Junk percent
propvar.vt = VT_UI4;
propvar.ulVal = dwJunkPct;
if (FAILED(m_pIRuleJunk->SetProp(RULE_PROP_JUNKPCT, 0, &propvar)))
{
fRet = FALSE;
goto exit;
}
// Set the return value
fRet = TRUE;
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _EnableButtons
//
// This enables or disables the buttons in the junk UI dialog
// depending on what is selected.
//
// iSelected - the item that was selected,
// -1 means that nothing was selected
//
// Returns: NONE
//
///////////////////////////////////////////////////////////////////////////////
VOID COEJunkRulesPageUI::_EnableButtons(VOID)
{
int cRules = 0;
BOOL fEnableJunk = FALSE;
BOOL fEnableDelete = FALSE;
// Get the enabled state of Junk
fEnableJunk = !!(BST_CHECKED == Button_GetCheck(GetDlgItem(m_hwndDlg, idcJunkMail)));
// Get the enabled state of Delete
fEnableDelete = !!(BST_CHECKED == Button_GetCheck(GetDlgItem(m_hwndDlg, idcJunkDelete)));
// Enable the senders action buttons
RuleUtil_FEnDisDialogItem(m_hwndDlg, idcJunkDays, fEnableJunk);
RuleUtil_FEnDisDialogItem(m_hwndDlg, idcJunkDeleteSpin, (fEnableDelete && fEnableJunk));
RuleUtil_FEnDisDialogItem(m_hwndDlg, idedtJunkDelete, (fEnableDelete && fEnableJunk));
RuleUtil_FEnDisDialogItem(m_hwndDlg, idcJunkDelete, fEnableJunk);
RuleUtil_FEnDisDialogItem(m_hwndDlg, idcJunkSliderMore, fEnableJunk);
RuleUtil_FEnDisDialogItem(m_hwndDlg, idcJunkSlider, fEnableJunk);
RuleUtil_FEnDisDialogItem(m_hwndDlg, idcJunkSliderLess, fEnableJunk);
RuleUtil_FEnDisDialogItem(m_hwndDlg, idbExceptions, fEnableJunk);
return;
}
const COLUMNITEM COESendersRulesPageUI::m_rgcitem[] =
{
{idsCaptionMail, 50},
{idsCaptionNews, 50},
{idsSenderDesc, 105}
};
const UINT COESendersRulesPageUI::m_crgcitem = ARRAYSIZE(COESendersRulesPageUI::m_rgcitem);
// Default destructor for the Mail Rules UI
COESendersRulesPageUI::~COESendersRulesPageUI()
{
SafeRelease(m_pIRuleMail);
SafeRelease(m_pIRuleNews);
}
///////////////////////////////////////////////////////////////////////////////
//
// HrInit
//
// This initializes the senders UI dialog
//
// hwndOwner - the handle to the owner window of this dialog
// dwFlags - modifiers on how this dialog should act
//
// Returns: S_OK, if it was successfully initialized
//
///////////////////////////////////////////////////////////////////////////////
HRESULT COESendersRulesPageUI::HrInit(HWND hwndOwner, DWORD dwFlags)
{
HRESULT hr = S_OK;
// Check incoming params
if (NULL == hwndOwner)
{
hr = E_INVALIDARG;
goto exit;
}
if (0 != (m_dwState & STATE_INITIALIZED))
{
hr = E_UNEXPECTED;
goto exit;
}
m_hwndOwner = hwndOwner;
m_dwFlags = dwFlags;
m_dwState |= STATE_INITIALIZED;
hr = S_OK;
exit:
return hr;
}
///////////////////////////////////////////////////////////////////////////////
//
// HrCommitChanges
//
// This commits the changes to the rules
//
// dwFlags - modifiers on how we should commit the changes
// fClearDirty - should we clear the dirty state
//
// Returns: S_OK, if it was successfully committed
//
///////////////////////////////////////////////////////////////////////////////
HRESULT COESendersRulesPageUI::HrCommitChanges(DWORD dwFlags, BOOL fClearDirty)
{
HRESULT hr = S_OK;
RULEINFO infoRule = {0};
Assert(NULL != m_hwndList);
// Check incoming params
if (0 != dwFlags)
{
hr = E_INVALIDARG;
goto exit;
}
// Fail if we weren't initialized
if (0 == (m_dwState & STATE_INITIALIZED))
{
hr = E_UNEXPECTED;
goto exit;
}
// If we aren't dirty, then there's
// nothing to do
if (0 == (m_dwState & STATE_DIRTY))
{
hr = S_FALSE;
goto exit;
}
// Save the mail senders
if (FALSE == _FSaveSenders(RULE_TYPE_MAIL))
{
hr = E_FAIL;
goto exit;
}
// Initialize the rule info
infoRule.ridRule = RULEID_SENDERS;
infoRule.pIRule = m_pIRuleMail;
// Set the rules into the rules manager
hr = g_pRulesMan->SetRules(SETF_SENDER, RULE_TYPE_MAIL, &infoRule, 1);
if (FAILED(hr))
{
goto exit;
}
// Save the news senders
if (FALSE == _FSaveSenders(RULE_TYPE_NEWS))
{
hr = E_FAIL;
goto exit;
}
// Initialize the rule info
infoRule.ridRule = RULEID_SENDERS;
infoRule.pIRule = m_pIRuleNews;
// Set the rules into the rules manager
hr = g_pRulesMan->SetRules(SETF_SENDER, RULE_TYPE_NEWS, &infoRule, 1);
if (FAILED(hr))
{
goto exit;
}
// Should we clear the dirty state
if (FALSE != fClearDirty)
{
m_dwState &= ~STATE_DIRTY;
}
hr = S_OK;
exit:
return hr;
}
INT_PTR CALLBACK COESendersRulesPageUI::FSendersRulesPageDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
BOOL fRet = FALSE;
COESendersRulesPageUI * pSendersUI = NULL;
pSendersUI = (COESendersRulesPageUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch (uiMsg)
{
case WM_INITDIALOG:
// Grab the UI object pointer
pSendersUI = (COESendersRulesPageUI *) lParam;
// Set it into the dialog so we can get it back
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LPARAM) pSendersUI);
if (FALSE == pSendersUI->FOnInitDialog(hwndDlg))
{
EndDialog(hwndDlg, -1);
fRet = TRUE;
goto exit;
}
// We didn't set the focus so return TRUE
fRet = TRUE;
break;
case WM_COMMAND:
fRet = pSendersUI->FOnCommand((UINT) HIWORD(wParam), (INT) LOWORD(wParam), (HWND) lParam);
break;
case WM_NOTIFY:
fRet = pSendersUI->FOnNotify((INT) LOWORD(wParam), (NMHDR *) lParam);
break;
case WM_DESTROY:
fRet = pSendersUI->FOnDestroy();
break;
case WM_HELP:
case WM_CONTEXTMENU:
fRet = OnContextHelp(hwndDlg, uiMsg, wParam, lParam, g_rgCtxMapSenderRules);
break;
case WM_OE_FIND_DUP:
fRet = pSendersUI->FFindItem((LPCSTR) lParam, (LONG) wParam);
break;
}
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FGetRules
//
// This brings up the edit UI for the selected rule from the mail rules list
//
// fBegin - is this for the LVN_BEGINLABELEDIT notification
// pdi - the display info for the message
//
// Returns: TRUE, if the message was handled
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL COESendersRulesPageUI::FGetRules(RULE_TYPE typeRule, RULENODE ** pprnode)
{
BOOL fRet = FALSE;
IOERule * pIRule = NULL;
RULENODE * prnodeNew = NULL;
HRESULT hr = S_OK;
if (NULL == pprnode)
{
fRet = FALSE;
goto exit;
}
// Fail if we weren't initialized
if ((0 == (m_dwState & STATE_INITIALIZED)) || (NULL == m_hwndList))
{
fRet = FALSE;
goto exit;
}
// Initialize the outgoing param
*pprnode = NULL;
// Make sure we don't loose any changes
_FSaveSenders(typeRule);
if (RULE_TYPE_MAIL == typeRule)
{
pIRule = m_pIRuleMail;
}
else if (RULE_TYPE_NEWS == typeRule)
{
pIRule = m_pIRuleNews;
}
else
{
fRet = FALSE;
goto exit;
}
// Nothing to do if we don't have a rule
if (NULL == pIRule)
{
fRet = TRUE;
goto exit;
}
// Skip over invalid rules
hr = pIRule->Validate(0);
if (FAILED(hr) || (S_FALSE == hr))
{
fRet = FALSE;
goto exit;
}
// Create a new rule node
prnodeNew = new RULENODE;
if (NULL == prnodeNew)
{
fRet = FALSE;
goto exit;
}
prnodeNew->pNext = NULL;
prnodeNew->pIRule = pIRule;
prnodeNew->pIRule->AddRef();
// Set the outgoing param
*pprnode = prnodeNew;
prnodeNew = NULL;
fRet = TRUE;
exit:
if (NULL != prnodeNew)
{
if (NULL != prnodeNew->pIRule)
{
prnodeNew->pIRule->Release();
}
delete prnodeNew; // MemFree(prnodeNew);
}
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FOnInitDialog
//
// This handles the WM_INITDIALOG message for the senders UI dialog
//
// hwndDlg - the handle to the dialog window
//
// Returns: TRUE, if it was successfully initialized
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL COESendersRulesPageUI::FOnInitDialog(HWND hwndDlg)
{
BOOL fRet = FALSE;
CHAR szRes[CCHMAX_STRINGRES];
// Check incoming params
if (NULL == hwndDlg)
{
fRet = FALSE;
goto exit;
}
// If we haven't been initialized yet...
if (0 == (m_dwState & STATE_INITIALIZED))
{
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, idlvSenderList);
if (NULL == m_hwndList)
{
fRet = FALSE;
goto exit;
}
// Initialize the list view
fRet = _FInitListCtrl();
if (FALSE == fRet)
{
goto exit;
}
// Load the list view
fRet = _FLoadListCtrl();
if (FALSE == fRet)
{
goto exit;
}
if (FALSE != FIsIMAPOrHTTPAvailable())
{
AthLoadString(idsBlockSenderNoIMAP, szRes, sizeof(szRes));
SetDlgItemText(m_hwndDlg, idcSenderTitle, szRes);
}
// Everything's AOK
fRet = TRUE;
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FOnCommand
//
// This handles the WM_COMMAND message for the senders UI dialog
//
// Returns: TRUE, if it was successfully handled
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL COESendersRulesPageUI::FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl)
{
BOOL fRet = FALSE;
LVITEM lvitem;
INT iSelected = 0;
// We only handle menu and accelerator commands
if ((0 != uiNotify) && (1 != uiNotify))
{
fRet = FALSE;
goto exit;
}
switch (iCtl)
{
case idbAddSender:
_NewSender();
fRet = TRUE;
break;
case idbModifySender:
// Get the selected item from the rule list
iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
if (-1 != iSelected)
{
// Bring up the rule editor for that item
_EditSender(iSelected);
fRet = TRUE;
}
break;
case idbRemoveSender:
// Get the selected item from the rule list
iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
if (-1 != iSelected)
{
// Remove the rule from the list
_RemoveSender(iSelected);
fRet = TRUE;
}
break;
}
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FOnNotify
//
// This handles the WM_NOTIFY message for the senders UI dialog
//
// Returns: TRUE, if it was successfully destroyed
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL COESendersRulesPageUI::FOnNotify(INT iCtl, NMHDR * pnmhdr)
{
BOOL fRet = FALSE;
NMLISTVIEW * pnmlv = NULL;
NMLVKEYDOWN * pnmlvkd = NULL;
INT iSelected = 0;
LVHITTESTINFO lvh;
// We only handle notifications for the list control
if (idlvSenderList != pnmhdr->idFrom)
{
fRet = FALSE;
goto exit;
}
pnmlv = (LPNMLISTVIEW) pnmhdr;
switch (pnmlv->hdr.code)
{
case NM_CLICK:
// Did we click on an item?
if (-1 != pnmlv->iItem)
{
ZeroMemory(&lvh, sizeof(lvh));
lvh.pt = pnmlv->ptAction;
iSelected = ListView_SubItemHitTest(m_hwndList, &lvh);
if (-1 != iSelected)
{
// Did we click on the enable field?
if ((0 != (lvh.flags & LVHT_ONITEMICON)) &&
(0 == (lvh.flags & LVHT_ONITEMLABEL)))
{
// Make sure this item is selected
ListView_SetItemState(m_hwndList, iSelected,
LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
// Set the proper enable state
if (2 != lvh.iSubItem)
{
_EnableSender((0 != lvh.iSubItem) ? RULE_TYPE_NEWS : RULE_TYPE_MAIL, iSelected);
}
}
}
}
else
{
// Disable the buttons
_EnableButtons(pnmlv->iItem);
}
break;
case NM_DBLCLK:
// Did we click on an item?
if (-1 != pnmlv->iItem)
{
ZeroMemory(&lvh, sizeof(lvh));
lvh.pt = pnmlv->ptAction;
iSelected = ListView_SubItemHitTest(pnmlv->hdr.hwndFrom, &lvh);
if (-1 != iSelected)
{
// Did we click on the rule name?
if (((0 == (lvh.flags & LVHT_ONITEMICON)) &&
(0 != (lvh.flags & LVHT_ONITEMLABEL))) || (2 == lvh.iSubItem))
{
// Edit the rule
_EditSender(iSelected);
}
}
}
else
{
// Disable the buttons
_EnableButtons(pnmlv->iItem);
}
break;
case LVN_ITEMCHANGED:
// If an item's state changed to selected..
if ((-1 != pnmlv->iItem) &&
(0 != (pnmlv->uChanged & LVIF_STATE)) &&
(0 == (pnmlv->uOldState & LVIS_SELECTED)) &&
(0 != (pnmlv->uNewState & LVIS_SELECTED)))
{
// Enable the buttons
_EnableButtons(pnmlv->iItem);
}
break;
case LVN_KEYDOWN:
pnmlvkd = (NMLVKEYDOWN *) pnmhdr;
// The delete key removes the rule from the list view
if (VK_DELETE == pnmlvkd->wVKey)
{
// Are we on a rule?
iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
if (-1 != iSelected)
{
// Remove the rule from the list
_RemoveSender(iSelected);
}
}
break;
}
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FFindItem
//
//
///////////////////////////////////////////////////////////////////////////////
BOOL COESendersRulesPageUI::FFindItem(LPCSTR pszFind, LONG lSkip)
{
BOOL fRet = FALSE;
fRet = _FFindSender(pszFind, lSkip, NULL);
// Tell the dialog it's aok to proceed
SetDlgMsgResult(m_hwndDlg, WM_OE_FIND_DUP, fRet);
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _FInitListCtrl
//
// This initializes the list view control in the senders dialog
//
// Returns: TRUE, on successful initialization
// FALSE, otherwise.
//
///////////////////////////////////////////////////////////////////////////////
BOOL COESendersRulesPageUI::_FInitListCtrl(VOID)
{
BOOL fRet = FALSE;
LVCOLUMN lvc;
TCHAR szRes[CCHMAX_STRINGRES];
RECT rc;
UINT ulIndex = 0;
HIMAGELIST himl = NULL;
Assert(NULL != m_hwndList);
// Initialize the list view structure
ZeroMemory(&lvc, sizeof(lvc));
lvc.mask = LVCF_TEXT | LVCF_WIDTH;
lvc.fmt = LVCFMT_LEFT;
lvc.pszText = szRes;
// Calculate the size of the list view
GetClientRect(m_hwndList, &rc);
rc.right = rc.right - GetSystemMetrics(SM_CXVSCROLL);
// Add the columns to the list view
for (ulIndex = 0; ulIndex < m_crgcitem; ulIndex++)
{
Assert(g_hLocRes);
LoadString(g_hLocRes, m_rgcitem[ulIndex].uidsName, szRes, ARRAYSIZE(szRes));
lvc.cchTextMax = lstrlen(szRes);
if (ulIndex != (m_crgcitem - 1))
{
lvc.cx = m_rgcitem[ulIndex].uiWidth;
rc.right -= lvc.cx;
}
else
{
lvc.cx = rc.right;
}
ListView_InsertColumn(m_hwndList, ulIndex, &lvc);
}
// Set the state image list
himl = ImageList_LoadBitmap(g_hLocRes, MAKEINTRESOURCE(idb16x16st), 16, 0, RGB(255, 0, 255));
if (NULL != himl)
{
ListView_SetImageList(m_hwndList, himl, LVSIL_SMALL);
}
// Full row selection and subitem images on listview
ListView_SetExtendedListViewStyle(m_hwndList, LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES);
// We worked
fRet = TRUE;
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _FLoadListCtrl
//
// This loads the list view with the current senders
//
// Returns: TRUE, if it was successfully loaded
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL COESendersRulesPageUI::_FLoadListCtrl(VOID)
{
BOOL fRet = FALSE;
HRESULT hr = S_OK;
DWORD dwListIndex = 0;
IOERule * pIRuleOrig = NULL;
IOERule * pIRule = NULL;
Assert(NULL != m_hwndList);
// Remove all the items from the list control
ListView_DeleteAllItems(m_hwndList);
// Get the mail sender rule
Assert(NULL != g_pRulesMan);
hr = g_pRulesMan->GetRule(RULEID_SENDERS, RULE_TYPE_MAIL, 0, &pIRuleOrig);
if (SUCCEEDED(hr))
{
// If the block sender rule exist
if (FALSE != _FLoadSenders(RULE_TYPE_MAIL, pIRuleOrig))
{
Assert (NULL == m_pIRuleMail);
hr = pIRuleOrig->Clone(&pIRule);
if (FAILED(hr))
{
fRet = FALSE;
goto exit;
}
m_pIRuleMail = pIRule;
pIRule = NULL;
}
}
SafeRelease(pIRuleOrig);
// Get the news sender rule
Assert(NULL != g_pRulesMan);
hr = g_pRulesMan->GetRule(RULEID_SENDERS, RULE_TYPE_NEWS, 0, &pIRuleOrig);
if (SUCCEEDED(hr))
{
// If the block sender rule exist
if (FALSE != _FLoadSenders(RULE_TYPE_NEWS, pIRuleOrig))
{
Assert (NULL == m_pIRuleNews);
hr = pIRuleOrig->Clone(&pIRule);
if (FAILED(hr))
{
fRet = FALSE;
goto exit;
}
m_pIRuleNews = pIRule;
pIRule = NULL;
}
}
SafeRelease(pIRuleOrig);
// Select the first item in the list
if ((NULL != m_pIRuleMail) || (NULL != m_pIRuleNews))
{
ListView_SetItemState(m_hwndList, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
}
// Enable the dialog buttons.
_EnableButtons(((NULL != m_pIRuleMail) || (NULL != m_pIRuleNews)) ? 0 : -1);
fRet = TRUE;
exit:
SafeRelease(pIRule);
SafeRelease(pIRuleOrig);
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _FAddRuleToList
//
// This adds the filter passed in to the list view
//
// dwIndex - the index on where to add the filter to into the list
// pIRule - the actual rule
//
// Returns: TRUE, if it was successfully added
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL COESendersRulesPageUI::_FAddSenderToList(RULE_TYPE type, LPSTR pszSender)
{
BOOL fRet = FALSE;
LONG lIndex = 0;
LVITEM lvitem = {0};
ULONG cchSender = 0;
Assert(NULL != m_hwndList);
// If there's nothing to do...
if (NULL == pszSender)
{
fRet = FALSE;
goto exit;
}
lvitem.mask = LVIF_IMAGE;
// Insert it if we didn't find it
if (FALSE == _FFindSender(pszSender, -1, &lIndex))
{
lvitem.iItem = ListView_GetItemCount(m_hwndList);
lvitem.iImage = iiconStateUnchecked;
lIndex = ListView_InsertItem(m_hwndList, &lvitem);
if (-1 == lIndex)
{
fRet = FALSE;
goto exit;
}
lvitem.iItem = lIndex;
lvitem.iSubItem = 1;
if (-1 == ListView_SetItem(m_hwndList, &lvitem))
{
fRet = FALSE;
goto exit;
}
ListView_SetItemText(m_hwndList, lIndex, 2, pszSender);
cchSender = lstrlen(pszSender) + 1;
if (cchSender > m_cchLabelMax)
{
m_cchLabelMax = cchSender;
}
}
// Enable the proper type
lvitem.iItem = lIndex;
lvitem.iImage = iiconStateChecked;
lvitem.iSubItem = (RULE_TYPE_MAIL != type) ? 1 : 0;
ListView_SetItem(m_hwndList, &lvitem);
fRet = TRUE;
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _EnableButtons
//
// This enables or disables the buttons in the senders UI dialog
// depending on what is selected.
//
// iSelected - the item that was selected,
// -1 means that nothing was selected
//
// Returns: NONE
//
///////////////////////////////////////////////////////////////////////////////
void COESendersRulesPageUI::_EnableButtons(INT iSelected)
{
int cRules = 0;
BOOL fSelected = FALSE;
Assert(NULL != m_hwndList);
fSelected = (-1 != iSelected);
// Enable the senders action buttons
RuleUtil_FEnDisDialogItem(m_hwndDlg, idbRemoveSender, fSelected);
RuleUtil_FEnDisDialogItem(m_hwndDlg, idbModifySender, fSelected);
return;
}
///////////////////////////////////////////////////////////////////////////////
//
// _EnableRule
//
// This switches the current enabled state of the list view item
// and updates the UI
//
// iSelected - index of the item in the listview to work on
//
// Returns: NONE
//
///////////////////////////////////////////////////////////////////////////////
VOID COESendersRulesPageUI::_EnableSender(RULE_TYPE type, int iSelected)
{
HRESULT hr = S_OK;
LVITEM lvi;
IOERule * pIRule = NULL;
BOOL fBlockNews = FALSE;
BOOL fBlockMail = FALSE;
PROPVARIANT propvar;
Assert(NULL != m_hwndList);
// Are we blocking mail?
ZeroMemory(&lvi, sizeof(lvi));
lvi.mask = LVIF_IMAGE;
lvi.iItem = iSelected;
if (FALSE == ListView_GetItem(m_hwndList, &lvi))
{
goto exit;
}
fBlockMail = (iiconStateUnchecked != lvi.iImage);
// Are we blocking news?
lvi.iSubItem = 1;
if (FALSE == ListView_GetItem(m_hwndList, &lvi))
{
goto exit;
}
fBlockNews = (iiconStateUnchecked != lvi.iImage);
// Disallow disabling both mail and news
if (((RULE_TYPE_MAIL == type) && (FALSE != fBlockMail) && (FALSE == fBlockNews)) ||
((RULE_TYPE_NEWS == type) && (FALSE != fBlockNews) && (FALSE == fBlockMail)))
{
// Put up a message saying something is busted
AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail),
MAKEINTRESOURCEW(idsRuleSenderErrorNone), NULL,
MB_OK | MB_ICONERROR);
goto exit;
}
// Set the UI to the opposite enabled state
lvi.iSubItem = (RULE_TYPE_MAIL != type) ? 1 : 0;
lvi.iImage = (RULE_TYPE_MAIL != type) ?
((FALSE != fBlockNews) ? iiconStateUnchecked : iiconStateChecked) :
((FALSE != fBlockMail) ? iiconStateUnchecked : iiconStateChecked);
ListView_SetItem(m_hwndList, &lvi);
// Mark the rule list as dirty
m_dwState |= STATE_DIRTY;
exit:
return;
}
///////////////////////////////////////////////////////////////////////////////
//
// _FLoadSenders
//
// This load the senders from the rule and inserts them into the senders list.
//
// type - the type of senders these are
// pIRule - the rule to get the senders from
//
// Returns: TRUE, if it was successfully loaded
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL COESendersRulesPageUI::_FLoadSenders(RULE_TYPE type, IOERule * pIRule)
{
BOOL fRet = FALSE;
PROPVARIANT propvar;
CRIT_ITEM * pCritItem = NULL;
ULONG cCritItem = 0;
ULONG ulIndex = 0;
if (NULL == pIRule)
{
fRet = FALSE;
goto exit;
}
// Get the list of senders from the rule
if (FAILED(pIRule->GetProp(RULE_PROP_CRITERIA, 0, &propvar)))
{
fRet = FALSE;
goto exit;
}
if (0 != propvar.blob.cbSize)
{
Assert(VT_BLOB == propvar.vt);
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;
// Add each sender to the list
for (ulIndex = 0; ulIndex < cCritItem; ulIndex++)
{
if ((CRIT_TYPE_SENDER == pCritItem[ulIndex].type) &&
(VT_LPSTR == pCritItem[ulIndex].propvar.vt) &&
(NULL != pCritItem[ulIndex].propvar.pszVal))
{
_FAddSenderToList(type, pCritItem[ulIndex].propvar.pszVal);
}
}
}
fRet = TRUE;
exit:
RuleUtil_HrFreeCriteriaItem(pCritItem, cCritItem);
SafeMemFree(pCritItem);
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _FSaveSenders
//
// This save the senders from the list into the rule.
//
// type - the type of senders to save
//
// Returns: TRUE, if it was successfully saved
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL COESendersRulesPageUI::_FSaveSenders(RULE_TYPE type)
{
BOOL fRet = FALSE;
ULONG cSender = 0;
LPSTR pszSender = NULL;
CRIT_ITEM * pcitemList = NULL;
ULONG ccitemList = 0;
LVITEM lvitem;
ULONG ulIndex = 0;
IOERule * pIRule = NULL;
ACT_ITEM aitem;
PROPVARIANT propvar;
TCHAR szRes[CCHMAX_STRINGRES];
HRESULT hr = S_OK;
Assert(NULL != m_hwndList);
ZeroMemory(&propvar, sizeof(propvar));
// Figure out how many senders we have
cSender = ListView_GetItemCount(m_hwndList);
if (0 != cSender)
{
// Allocate space to hold the sender
if (FAILED(HrAlloc((void **) &pszSender, m_cchLabelMax)))
{
fRet = FALSE;
goto exit;
}
pszSender[0] = '\0';
// Allocate space to hold the criteria
if (FAILED(HrAlloc((void **) &pcitemList, cSender * sizeof(*pcitemList))))
{
fRet = FALSE;
goto exit;
}
ZeroMemory(pcitemList, cSender * sizeof(*pcitemList));
}
ZeroMemory(&lvitem, sizeof(lvitem));
lvitem.mask = LVIF_IMAGE;
ccitemList = 0;
for (ulIndex = 0; ulIndex < cSender; ulIndex++)
{
lvitem.iItem = ulIndex;
lvitem.iSubItem = (RULE_TYPE_MAIL != type) ? 1 : 0;
if (FALSE == ListView_GetItem(m_hwndList, &lvitem))
{
continue;
}
if (FALSE != (iiconStateUnchecked != lvitem.iImage))
{
// Grab the sender from the list
pszSender[0] ='\0';
ListView_GetItemText(m_hwndList, ulIndex, 2, pszSender, m_cchLabelMax);
if ('\0' != pszSender[0])
{
// Grab a copy of the sender
pcitemList[ccitemList].propvar.pszVal = PszDupA(pszSender);
if (NULL == pcitemList[ccitemList].propvar.pszVal)
{
fRet = FALSE;
goto exit;
}
// Set the criteria specifics
pcitemList[ccitemList].type = CRIT_TYPE_SENDER;
pcitemList[ccitemList].logic = CRIT_LOGIC_OR;
pcitemList[ccitemList].dwFlags = CRIT_FLAG_DEFAULT;
pcitemList[ccitemList].propvar.vt = VT_LPSTR;
ccitemList++;
}
}
}
if (0 != ccitemList)
{
// Which rule are we looking at
pIRule = (RULE_TYPE_MAIL != type) ? m_pIRuleNews : m_pIRuleMail;
// Check the state
if (NULL == pIRule)
{
// Create the new rule
if (FAILED(RuleUtil_HrCreateSendersRule(0, &pIRule)))
{
fRet = FALSE;
goto exit;
}
}
else
{
pIRule->AddRef();
}
// Set the new criteria in the rule
ZeroMemory(&propvar, sizeof(propvar));
propvar.vt = VT_BLOB;
propvar.blob.cbSize = sizeof(CRIT_ITEM) * ccitemList;
propvar.blob.pBlobData = (BYTE *) pcitemList;
// Grab the list of criteria from the rule
if (FAILED(pIRule->SetProp(RULE_PROP_CRITERIA, 0, &propvar)))
{
fRet = FALSE;
goto exit;
}
}
if (RULE_TYPE_MAIL != type)
{
SafeRelease(m_pIRuleNews);
m_pIRuleNews = pIRule;
}
else
{
SafeRelease(m_pIRuleMail);
m_pIRuleMail = pIRule;
}
pIRule = NULL;
// Set the proper return value
fRet = TRUE;
exit:
RuleUtil_HrFreeCriteriaItem(pcitemList, ccitemList);
SafeMemFree(pcitemList);
SafeMemFree(pszSender);
SafeRelease(pIRule);
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _FFindSender
//
// This brings up the edit UI to create a new sender for the senders list
//
// Returns: NONE
//
///////////////////////////////////////////////////////////////////////////////
BOOL COESendersRulesPageUI::_FFindSender(LPCSTR pszSender, LONG iSkip, LONG * plSender)
{
BOOL fRet = FALSE;
LONG cSenders = 0;
LPSTR pszLabel = NULL;
LVITEM lvitem = {0};
LONG lIndex = 0;
// Check incoming params
if (NULL == pszSender)
{
goto exit;
}
// Initialize the outgoing param
if (NULL != plSender)
{
*plSender = -1;
}
// Get the number of senders
cSenders = ListView_GetItemCount(m_hwndList);
if (0 == cSenders)
{
goto exit;
}
if (FAILED(HrAlloc((void **) &pszLabel, m_cchLabelMax * sizeof(*pszLabel))))
{
goto exit;
}
// Set up the
lvitem.iSubItem = 2;
lvitem.pszText = pszLabel;
lvitem.cchTextMax = m_cchLabelMax;
for (lIndex = 0; lIndex < cSenders; lIndex++)
{
// We need to skip over the selected item
if (lIndex == iSkip)
{
continue;
}
if (0 != SendMessage(m_hwndList, LVM_GETITEMTEXT, (WPARAM) lIndex, (LPARAM) &lvitem))
{
if (0 == lstrcmpi(pszLabel, pszSender))
{
fRet = TRUE;
break;
}
}
}
if (NULL != plSender)
{
if (lIndex < cSenders)
{
*plSender = lIndex;
}
}
exit:
SafeMemFree(pszLabel);
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _NewSender
//
// This brings up the edit UI to create a new sender for the senders list
//
// Returns: NONE
//
///////////////////////////////////////////////////////////////////////////////
VOID COESendersRulesPageUI::_NewSender(VOID)
{
HRESULT hr = S_OK;
EDIT_SENDER editsndr = {0};
CEditSenderUI * pEditSenderUI = NULL;
LVITEM lvitem = {0};
LONG iIndex = 0;
ULONG cchSender = 0;
Assert(NULL != m_hwndList);
editsndr.lSelected = -1;
// Create the sender editor
pEditSenderUI = new CEditSenderUI;
if (NULL == pEditSenderUI)
{
goto exit;
}
// Initialize the editor object
if (FAILED(pEditSenderUI->HrInit(m_hwndDlg, 0, &editsndr)))
{
goto exit;
}
// Bring up the sender editor UI
hr = pEditSenderUI->HrShow();
if (FAILED(hr))
{
goto exit;
}
// If the sender changed, make sure we change the label
if (S_OK == hr)
{
lvitem.mask = LVIF_IMAGE;
lvitem.iImage = (0 != (editsndr.dwFlags & SNDF_MAIL)) ?
iiconStateChecked : iiconStateUnchecked;
// Are we inserting or replacing?
if (FALSE == _FFindSender(editsndr.pszSender, -1, &iIndex))
{
lvitem.iItem = ListView_GetItemCount(m_hwndList);
iIndex = ListView_InsertItem(m_hwndList, &lvitem);
if (-1 == iIndex)
{
goto exit;
}
}
else
{
lvitem.iItem = iIndex;
if (-1 == ListView_SetItem(m_hwndList, &lvitem))
{
goto exit;
}
}
lvitem.iItem = iIndex;
lvitem.iSubItem = 1;
lvitem.iImage = (0 != (editsndr.dwFlags & SNDF_NEWS)) ?
iiconStateChecked : iiconStateUnchecked;
if (-1 == ListView_SetItem(m_hwndList, &lvitem))
{
goto exit;
}
ListView_SetItemText(m_hwndList, iIndex, 2, editsndr.pszSender);
// Make sure the new item is selected
ListView_SetItemState(m_hwndList, iIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
// Let's make sure we can see this new item
ListView_EnsureVisible(m_hwndList, iIndex, FALSE);
// Mark the rule list as dirty
m_dwState |= STATE_DIRTY;
cchSender = lstrlen(editsndr.pszSender) + 1;
if (cchSender > m_cchLabelMax)
{
m_cchLabelMax = cchSender;
}
}
exit:
SafeMemFree(editsndr.pszSender);
if (NULL != pEditSenderUI)
{
delete pEditSenderUI;
}
return;
}
///////////////////////////////////////////////////////////////////////////////
//
// _EditSender
//
// This brings up the edit UI for the selected sender from the senders list
//
// iSelected - index of the item in the listview to work on
//
// Returns: NONE
//
///////////////////////////////////////////////////////////////////////////////
VOID COESendersRulesPageUI::_EditSender(int iSelected)
{
HRESULT hr = S_OK;
EDIT_SENDER editsndr = {0};
LVITEM lvitem = {0};
CEditSenderUI * pEditSenderUI = NULL;
ULONG cchSender = 0;
LONG lItemDelete = 0;
Assert(NULL != m_hwndList);
editsndr.lSelected = iSelected;
// Allocate space to hold the sender
hr = HrAlloc((void **) &(editsndr.pszSender), m_cchLabelMax);
if (FAILED(hr))
{
goto exit;
}
// Grab the sender from the list
lvitem.iSubItem = 2;
lvitem.pszText = editsndr.pszSender;
lvitem.cchTextMax = m_cchLabelMax;
if (0 == SendMessage(m_hwndList, LVM_GETITEMTEXT, (WPARAM) iSelected, (LPARAM) &lvitem))
{
goto exit;
}
// Are we blocking mail?
ZeroMemory(&lvitem, sizeof(lvitem));
lvitem.mask = LVIF_IMAGE;
lvitem.iItem = iSelected;
if (FALSE == ListView_GetItem(m_hwndList, &lvitem))
{
goto exit;
}
if (FALSE != (iiconStateUnchecked != lvitem.iImage))
{
editsndr.dwFlags |= SNDF_MAIL;
}
// Are we blocking news?
lvitem.iSubItem = 1;
if (FALSE == ListView_GetItem(m_hwndList, &lvitem))
{
goto exit;
}
if (FALSE != (iiconStateUnchecked != lvitem.iImage))
{
editsndr.dwFlags |= SNDF_NEWS;
}
// Create the rules editor
pEditSenderUI = new CEditSenderUI;
if (NULL == pEditSenderUI)
{
goto exit;
}
// Initialize the editor object
if (FAILED(pEditSenderUI->HrInit(m_hwndDlg, 0, &editsndr)))
{
goto exit;
}
// Bring up the sender editor UI
hr = pEditSenderUI->HrShow();
if (FAILED(hr))
{
goto exit;
}
// If the sender changed, make sure we change the label
if (S_OK == hr)
{
// Do we want to remove a copy of the item
(VOID) _FFindSender(editsndr.pszSender, iSelected, &lItemDelete);
ZeroMemory(&lvitem, sizeof(lvitem));
lvitem.iItem = iSelected;
lvitem.mask = LVIF_IMAGE;
lvitem.iImage = (0 != (editsndr.dwFlags & SNDF_MAIL)) ?
iiconStateChecked : iiconStateUnchecked;
if (-1 == ListView_SetItem(m_hwndList, &lvitem))
{
goto exit;
}
lvitem.iSubItem = 1;
lvitem.iImage = (0 != (editsndr.dwFlags & SNDF_NEWS)) ?
iiconStateChecked : iiconStateUnchecked;
if (-1 == ListView_SetItem(m_hwndList, &lvitem))
{
goto exit;
}
ListView_SetItemText(m_hwndList, iSelected, 2, editsndr.pszSender);
// Make sure we remove the dup item
if (-1 != lItemDelete)
{
// Remove the item from the list
ListView_DeleteItem(m_hwndList, lItemDelete);
}
// Mark the rule list as dirty
m_dwState |= STATE_DIRTY;
cchSender = lstrlen(editsndr.pszSender) + 1;
if (cchSender > m_cchLabelMax)
{
m_cchLabelMax = cchSender;
}
}
exit:
SafeMemFree(editsndr.pszSender);
if (NULL != pEditSenderUI)
{
delete pEditSenderUI;
}
return;
}
///////////////////////////////////////////////////////////////////////////////
//
// _RemoveSender
//
// This removes the selected sender from the senders list
//
// iSelected - index of the item in the listview to work on
//
// Returns: NONE
//
///////////////////////////////////////////////////////////////////////////////
VOID COESendersRulesPageUI::_RemoveSender(int iSelected)
{
TCHAR szRes[CCHMAX_STRINGRES];
ULONG cchRes = 0;
LPSTR pszSender = NULL;
LVITEM lvitem;
LPSTR pszMessage = NULL;
int cSenders = 0;
Assert(NULL != m_hwndList);
// Get the string template to display
cchRes = LoadString(g_hLocRes, idsRuleSenderWarnDelete, szRes, ARRAYSIZE(szRes));
if (0 == cchRes)
{
goto exit;
}
// Allocate space to hold the sender
if (FAILED(HrAlloc((void **) &pszSender, m_cchLabelMax)))
{
goto exit;
}
// Grab the sender from the list
ZeroMemory(&lvitem, sizeof(lvitem));
lvitem.iSubItem = 2;
lvitem.pszText = pszSender;
lvitem.cchTextMax = m_cchLabelMax;
if (0 == SendMessage(m_hwndList, LVM_GETITEMTEXT, (WPARAM) iSelected, (LPARAM) &lvitem))
{
goto exit;
}
// Allocate space to hold the final display string
DWORD cchSize = (cchRes + lstrlen(pszSender) + 1);
if (FAILED(HrAlloc((void ** ) &pszMessage, cchSize)))
{
goto exit;
}
// Build up the string and display it
wnsprintf(pszMessage, cchSize, szRes, pszSender);
if (IDNO == AthMessageBox(m_hwndDlg, MAKEINTRESOURCE(idsAthenaMail), pszMessage,
NULL, MB_YESNO | MB_ICONINFORMATION))
{
goto exit;
}
// Remove the item from the list
ListView_DeleteItem(m_hwndList, iSelected);
// Let's make sure we have a selection in the list
cSenders = ListView_GetItemCount(m_hwndList);
if (cSenders > 0)
{
// Did we delete the last item in the list
if (iSelected >= cSenders)
{
// Move the selection to the new last item in the list
iSelected = cSenders - 1;
}
// Set the new selection
ListView_SetItemState(m_hwndList, iSelected, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
// Let's make sure we can see this new item
ListView_EnsureVisible(m_hwndList, iSelected, FALSE);
}
else
{
// Make sure we clear out all of the buttons
_EnableButtons(-1);
}
// Mark the rule list as dirty
m_dwState |= STATE_DIRTY;
exit:
SafeMemFree(pszSender);
SafeMemFree(pszMessage);
return;
}
// Default destructor for the Exceptions List UI
CExceptionsListUI::~CExceptionsListUI()
{
}
///////////////////////////////////////////////////////////////////////////////
//
// HrInit
//
// This initializes the Exceptions List UI dialog
//
// hwndOwner - the handle to the owner window of this dialog
// dwFlags - modifiers on how this dialog should act
//
// Returns: S_OK, if it was successfully initialized
//
///////////////////////////////////////////////////////////////////////////////
HRESULT CExceptionsListUI::HrInit(HWND hwndOwner, DWORD dwFlags)
{
HRESULT hr = S_OK;
// Check incoming params
if (NULL == hwndOwner)
{
hr = E_INVALIDARG;
goto exit;
}
if (0 != (m_dwState & STATE_INITIALIZED))
{
hr = E_UNEXPECTED;
goto exit;
}
m_hwndOwner = hwndOwner;
m_dwFlags = dwFlags;
m_dwState |= STATE_INITIALIZED;
hr = S_OK;
exit:
return hr;
}
///////////////////////////////////////////////////////////////////////////////
//
// HrShow
//
// This brings up the Exceptions List UI dialog
//
// Returns: S_OK, if the sender was successfully entered
// S_FALSE, if the dialog was canceled
//
///////////////////////////////////////////////////////////////////////////////
HRESULT CExceptionsListUI::HrShow(IOERule * pIRule)
{
HRESULT hr = S_OK;
int iRet = 0;
// Check incoming params
if (NULL == pIRule)
{
hr = E_INVALIDARG;
goto exit;
}
if (0 == (m_dwState & STATE_INITIALIZED))
{
hr = E_UNEXPECTED;
goto exit;
}
// Save off the item
m_pIRule = pIRule;
iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddExceptionsList),
m_hwndOwner, CExceptionsListUI::FExceptionsListDlgProc,
(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 CExceptionsListUI::FExceptionsListDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
BOOL fRet = FALSE;
CExceptionsListUI * pExceptionsUI = NULL;
pExceptionsUI = (CExceptionsListUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch (uiMsg)
{
case WM_INITDIALOG:
// Grab the UI object pointer
pExceptionsUI = (CExceptionsListUI *) lParam;
// Set it into the dialog so we can get it back
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LPARAM) pExceptionsUI);
if (FALSE == pExceptionsUI->FOnInitDialog(hwndDlg))
{
EndDialog(hwndDlg, -1);
fRet = TRUE;
goto exit;
}
// We didn't set the focus so return TRUE
fRet = FALSE;
break;
case WM_COMMAND:
fRet = pExceptionsUI->FOnCommand((UINT) HIWORD(wParam), (INT) LOWORD(wParam), (HWND) lParam);
break;
case WM_NOTIFY:
fRet = pExceptionsUI->FOnNotify((INT) LOWORD(wParam), (NMHDR *) lParam);
break;
}
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FOnInitDialog
//
// This handles the WM_INITDIALOG message for the Exceptions List UI dialog
//
// hwndDlg - the handle to the dialog window
//
// Returns: TRUE, if it was successfully initialized
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CExceptionsListUI::FOnInitDialog(HWND hwndDlg)
{
BOOL fRet = FALSE;
// Check incoming params
if (NULL == hwndDlg)
{
fRet = FALSE;
goto exit;
}
// If we haven't been initialized yet...
if (0 == (m_dwState & STATE_INITIALIZED))
{
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, idlvExceptions);
if (NULL == m_hwndList)
{
fRet = FALSE;
goto exit;
}
// Initialize the list view
fRet = _FInitCtrls();
if (FALSE == fRet)
{
goto exit;
}
// Load the list view
fRet = _FLoadListCtrl();
if (FALSE == fRet)
{
goto exit;
}
// Set the focus into the list
SetFocus(m_hwndList);
// Everything's AOK
fRet = TRUE;
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FOnCommand
//
// This handles the WM_COMMAND message for the Exceptions List UI dialog
//
// Returns: TRUE, if it was successfully handled
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CExceptionsListUI::FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl)
{
BOOL fRet = FALSE;
LVITEM lvitem;
INT iSelected = 0;
// We only handle menu and accelerator commands
if ((0 != uiNotify) && (1 != uiNotify))
{
fRet = FALSE;
goto exit;
}
switch (iCtl)
{
case idcAddException:
_NewException();
fRet = TRUE;
break;
case idcModifyException:
// Get the selected item from the rule list
iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
if (-1 != iSelected)
{
// Bring up the rule editor for that item
_EditException(iSelected);
fRet = TRUE;
}
break;
case idcRemoveException:
// Get the selected item from the rule list
iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
if (-1 != iSelected)
{
// Remove the rule from the list
_RemoveException(iSelected);
fRet = TRUE;
}
break;
case idcExceptionsWAB:
// Mark the dialog as dirty
m_dwState |= STATE_DIRTY;
break;
case IDOK:
if (FALSE != _FOnOK())
{
EndDialog(m_hwndDlg, IDOK);
fRet = TRUE;
}
break;
case IDCANCEL:
EndDialog(m_hwndDlg, IDCANCEL);
fRet = TRUE;
break;
}
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// FOnNotify
//
// This handles the WM_NOTIFY message for the Exceptions List UI dialog
//
// Returns: TRUE, if it was successfully destroyed
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CExceptionsListUI::FOnNotify(INT iCtl, NMHDR * pnmhdr)
{
BOOL fRet = FALSE;
NMLISTVIEW * pnmlv = NULL;
NMLVKEYDOWN * pnmlvkd = NULL;
INT iSelected = 0;
LVHITTESTINFO lvh = {0};
// We only handle notifications for the list control
if (idlvExceptions != pnmhdr->idFrom)
{
fRet = FALSE;
goto exit;
}
pnmlv = (LPNMLISTVIEW) pnmhdr;
switch (pnmlv->hdr.code)
{
case NM_CLICK:
// Did we click on an item?
if (-1 == pnmlv->iItem)
{
// Disable the buttons
_EnableButtons(pnmlv->iItem);
}
break;
case NM_DBLCLK:
// Did we click on an item?
if (-1 != pnmlv->iItem)
{
ZeroMemory(&lvh, sizeof(lvh));
lvh.pt = pnmlv->ptAction;
iSelected = ListView_HitTest(pnmlv->hdr.hwndFrom, &lvh);
if (-1 != iSelected)
{
// Did we click on the exception name?
if (0 != (lvh.flags & LVHT_ONITEMLABEL))
{
// Edit the rule
_EditException(iSelected);
}
}
}
else
{
// Disable the buttons
_EnableButtons(pnmlv->iItem);
}
break;
case LVN_ITEMCHANGED:
// If an item's state changed to selected..
if ((-1 != pnmlv->iItem) &&
(0 != (pnmlv->uChanged & LVIF_STATE)) &&
(0 == (pnmlv->uOldState & LVIS_SELECTED)) &&
(0 != (pnmlv->uNewState & LVIS_SELECTED)))
{
// Enable the buttons
_EnableButtons(pnmlv->iItem);
}
break;
case LVN_KEYDOWN:
pnmlvkd = (NMLVKEYDOWN *) pnmhdr;
// The delete key removes the rule from the list view
if (VK_DELETE == pnmlvkd->wVKey)
{
// Are we on a rule?
iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
if (-1 != iSelected)
{
// Remove the rule from the list
_RemoveException(iSelected);
}
}
break;
}
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _NewException
//
// This brings up the edit UI to create a new exception for the Exception List
//
// Returns: NONE
//
///////////////////////////////////////////////////////////////////////////////
VOID CExceptionsListUI::_NewException(VOID)
{
HRESULT hr = S_OK;
CEditExceptionUI * pEditExcptUI = NULL;
EDIT_EXCPT editexcpt = {0};
ULONG ulIndex = 0;
Assert(NULL != m_hwndList);
// Create the sender editor
pEditExcptUI = new CEditExceptionUI;
if (NULL == pEditExcptUI)
{
goto exit;
}
// Initialize the editor object
if (FAILED(pEditExcptUI->HrInit(m_hwndDlg, 0, &editexcpt)))
{
goto exit;
}
// Bring up the sender editor UI
hr = pEditExcptUI->HrShow();
if (FAILED(hr))
{
goto exit;
}
// If the exception changed, make sure we change the label
if (S_OK == hr)
{
if (FALSE == _FAddExceptionToList(editexcpt.pszExcpt, &ulIndex))
{
goto exit;
}
// Make sure the new item is selected
ListView_SetItemState(m_hwndList, ulIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
// Let's make sure we can see this new item
ListView_EnsureVisible(m_hwndList, ulIndex, FALSE);
// Mark the rule list as dirty
m_dwState |= STATE_DIRTY;
}
exit:
SafeMemFree(editexcpt.pszExcpt);
if (NULL != pEditExcptUI)
{
delete pEditExcptUI;
}
return;
}
///////////////////////////////////////////////////////////////////////////////
//
// _EditException
//
// This brings up the edit UI for the selected exception from the Execption List
//
// iSelected - index of the item in the listview to work on
//
// Returns: NONE
//
///////////////////////////////////////////////////////////////////////////////
VOID CExceptionsListUI::_EditException(int iSelected)
{
HRESULT hr = S_OK;
EDIT_EXCPT editexcpt = {0};
LVITEM lvitem = {0};
CEditExceptionUI * pEditExcptUI = NULL;
ULONG cchExcpt = 0;
LONG lIndex = 0;
LVFINDINFO lvfi = {0};
Assert(NULL != m_hwndList);
// Allocate space to hold the exception
hr = HrAlloc((void **) &(editexcpt.pszExcpt), m_cchLabelMax);
if (FAILED(hr))
{
goto exit;
}
// Grab the exception from the list
lvitem.pszText = editexcpt.pszExcpt;
lvitem.cchTextMax = m_cchLabelMax;
if (0 == SendMessage(m_hwndList, LVM_GETITEMTEXT, (WPARAM) iSelected, (LPARAM) &lvitem))
{
goto exit;
}
// Create the exception editor
pEditExcptUI = new CEditExceptionUI;
if (NULL == pEditExcptUI)
{
goto exit;
}
// Initialize the editor object
if (FAILED(pEditExcptUI->HrInit(m_hwndDlg, 0, &editexcpt)))
{
goto exit;
}
// Bring up the exception editor UI
hr = pEditExcptUI->HrShow();
if (FAILED(hr))
{
goto exit;
}
// If the exception changed, make sure we change the label
if (S_OK == hr)
{
lvfi.flags = LVFI_STRING;
lvfi.psz = editexcpt.pszExcpt;
// Check to see if the item already exists
lIndex = ListView_FindItem(m_hwndList, -1, &lvfi);
// If the item already exists
if ((-1 != lIndex) && (iSelected != lIndex))
{
// Make sure the duplicate item is selected
ListView_SetItemState(m_hwndList, lIndex,
LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
// Let's make sure we can see this new item
ListView_EnsureVisible(m_hwndList, lIndex, FALSE);
// Remove the item from the list
ListView_DeleteItem(m_hwndList, iSelected);
}
else
{
ListView_SetItemText(m_hwndList, iSelected, 0, editexcpt.pszExcpt);
cchExcpt = lstrlen(editexcpt.pszExcpt) + 1;
if (cchExcpt > m_cchLabelMax)
{
m_cchLabelMax = cchExcpt;
}
}
// Mark the rule list as dirty
m_dwState |= STATE_DIRTY;
}
exit:
SafeMemFree(editexcpt.pszExcpt);
if (NULL != pEditExcptUI)
{
delete pEditExcptUI;
}
return;
}
///////////////////////////////////////////////////////////////////////////////
//
// _RemoveException
//
// This removes the selected exception from the Exception List
//
// iSelected - index of the item in the listview to work on
//
// Returns: NONE
//
///////////////////////////////////////////////////////////////////////////////
VOID CExceptionsListUI::_RemoveException(int iSelected)
{
TCHAR szRes[CCHMAX_STRINGRES];
ULONG cchRes = 0;
LPSTR pszExcpt = NULL;
LVITEM lvitem = {0};
LPSTR pszMessage = NULL;
int cExcpts = 0;
Assert(NULL != m_hwndList);
// Get the string template to display
cchRes = LoadString(g_hLocRes, idsRuleExcptWarnDelete, szRes, ARRAYSIZE(szRes));
if (0 == cchRes)
{
goto exit;
}
// Allocate space to hold the execptions
if (FAILED(HrAlloc((void **) &pszExcpt, m_cchLabelMax)))
{
goto exit;
}
// Grab the exception from the list
lvitem.pszText = pszExcpt;
lvitem.cchTextMax = m_cchLabelMax;
if (0 == SendMessage(m_hwndList, LVM_GETITEMTEXT, (WPARAM) iSelected, (LPARAM) &lvitem))
{
goto exit;
}
// Allocate space to hold the final display string
DWORD cchSize = (cchRes + lstrlen(pszExcpt) + 1);
if (FAILED(HrAlloc((void ** ) &pszMessage, cchSize)))
{
goto exit;
}
// Build up the string and display it
wnsprintf(pszMessage, cchSize, szRes, pszExcpt);
if (IDNO == AthMessageBox(m_hwndDlg, MAKEINTRESOURCE(idsAthenaMail), pszMessage,
NULL, MB_YESNO | MB_ICONINFORMATION))
{
goto exit;
}
// Remove the item from the list
ListView_DeleteItem(m_hwndList, iSelected);
// Let's make sure we have a selection in the list
cExcpts = ListView_GetItemCount(m_hwndList);
if (cExcpts > 0)
{
// Did we delete the last item in the list
if (iSelected >= cExcpts)
{
// Move the selection to the new last item in the list
iSelected = cExcpts - 1;
}
// Set the new selection
ListView_SetItemState(m_hwndList, iSelected, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
// Let's make sure we can see this new item
ListView_EnsureVisible(m_hwndList, iSelected, FALSE);
}
else
{
// Make sure we clear out all of the buttons
_EnableButtons(-1);
}
// Mark the rule list as dirty
m_dwState |= STATE_DIRTY;
exit:
SafeMemFree(pszExcpt);
SafeMemFree(pszMessage);
return;
}
///////////////////////////////////////////////////////////////////////////////
//
// _FOnOK
//
// This initializes the controls in the Exceptions List UI dialog
//
// Returns: TRUE, on successful initialization
// FALSE, otherwise.
//
///////////////////////////////////////////////////////////////////////////////
BOOL CExceptionsListUI::_FOnOK(VOID)
{
BOOL fRet = FALSE;
BOOL fWABEnable = FALSE;
PROPVARIANT propvar = {0};
// Save of the list of addresses
if (FALSE == _FSaveListCtrl())
{
fRet = FALSE;
goto exit;
}
// Are we supposed to check the WAB?
fWABEnable = !!(BST_CHECKED == Button_GetCheck(GetDlgItem(m_hwndDlg, idcExceptionsWAB)));
// Save of the state of the Check WAB button
propvar.vt = VT_BOOL;
propvar.boolVal = (VARIANT_BOOL) !!fWABEnable;
if (FAILED(m_pIRule->SetProp(RULE_PROP_EXCPT_WAB, 0, &propvar)))
{
fRet = FALSE;
goto exit;
}
// Everything's fine
fRet = TRUE;
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _FInitCtrls
//
// This initializes the controls in the Exceptions List UI dialog
//
// Returns: TRUE, on successful initialization
// FALSE, otherwise.
//
///////////////////////////////////////////////////////////////////////////////
BOOL CExceptionsListUI::_FInitCtrls(VOID)
{
BOOL fRet = FALSE;
LVCOLUMN lvc = {0};
RECT rc = {0};
PROPVARIANT propvar = {0};
Assert(NULL != m_hwndList);
if (FAILED(m_pIRule->GetProp(RULE_PROP_EXCPT_WAB, 0, &propvar)))
{
fRet = FALSE;
goto exit;
}
// Set the Check WAB button
Button_SetCheck(GetDlgItem(m_hwndDlg, idcExceptionsWAB),
(FALSE != propvar.boolVal) ? BST_CHECKED : BST_UNCHECKED);
// Initialize the list view structure
lvc.mask = LVCF_WIDTH;
lvc.fmt = LVCFMT_LEFT;
// Calculate the size of the list view
GetClientRect(m_hwndList, &rc);
lvc.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL);
// Add the column to the list view
ListView_InsertColumn(m_hwndList, 0, &lvc);
// Full row selection and subitem images on listview
ListView_SetExtendedListViewStyle(m_hwndList, LVS_EX_FULLROWSELECT);
fRet = TRUE;
exit:
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _FLoadListCtrl
//
// This loads the list view with the current exceptions
//
// Returns: TRUE, if it was successfully loaded
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CExceptionsListUI::_FLoadListCtrl(VOID)
{
BOOL fRet = FALSE;
ULONG ulIndex = 0;
IOERuleAddrList * pIAddrList = NULL;
RULEADDRLIST * pralList = NULL;
ULONG cralList = 0;
Assert(NULL != m_hwndList);
// Remove all the items from the list control
ListView_DeleteAllItems(m_hwndList);
// Get the exceptions list from the rule
if (FAILED(m_pIRule->QueryInterface(IID_IOERuleAddrList, (VOID **) &pIAddrList)))
{
fRet = FALSE;
goto exit;
}
// Get the list of exceptions from the address list
if (FAILED(pIAddrList->GetList(0, &pralList, &cralList)))
{
fRet = FALSE;
goto exit;
}
// Add each item into the list
for (ulIndex = 0; ulIndex < cralList; ulIndex++)
{
// Verify the item
if (RALF_MAIL != pralList[ulIndex].dwFlags)
{
fRet = FALSE;
goto exit;
}
// Add the item
if (FALSE == _FAddExceptionToList(pralList[ulIndex].pszAddr, NULL))
{
fRet = FALSE;
goto exit;
}
}
// Select the first item in the list
if (0 != cralList)
{
ListView_SetItemState(m_hwndList, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
}
// Enable the dialog buttons.
_EnableButtons((0 != cralList) ? 0 : -1);
fRet = TRUE;
exit:
FreeRuleAddrList(pralList, cralList);
SafeMemFree(pralList);
SafeRelease(pIAddrList);
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _FSaveListCtrl
//
// This save the exceptions from the list view
//
// Returns: TRUE, if it was successfully saved
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CExceptionsListUI::_FSaveListCtrl(VOID)
{
BOOL fRet = FALSE;
ULONG cExcpts = 0;
LPSTR pszAddr = NULL;
RULEADDRLIST * pralList = NULL;
ULONG ulIndex = 0;
IOERuleAddrList * pIAddrList = NULL;
Assert(NULL != m_hwndList);
// Figure out how many exceptions are in the list
cExcpts = ListView_GetItemCount(m_hwndList);
// If there are exceptions
if (0 != cExcpts)
{
// Allocate space to hold the exceptions
if (FAILED(HrAlloc((VOID **) &pszAddr, (m_cchLabelMax + 1))))
{
fRet = FALSE;
goto exit;
}
// Initialize the exception buffer
pszAddr[0] = '\0';
// Allocate space to hold the exception list
if (FAILED(HrAlloc((VOID **) &pralList, cExcpts * sizeof(*pralList))))
{
fRet = FALSE;
goto exit;
}
// Initialize the list of exceptions
ZeroMemory(pralList, cExcpts * sizeof(*pralList));
// Save each exception from the list
for (ulIndex = 0; ulIndex < cExcpts; ulIndex++)
{
// Get the item from the list
pszAddr[0] = '\0';
ListView_GetItemText(m_hwndList, ulIndex, 0, pszAddr, m_cchLabelMax + 1);
// Verify it isn't empty
if ('\0' == pszAddr[0])
{
fRet = FALSE;
goto exit;
}
// Set the flags
pralList[ulIndex].dwFlags = RALF_MAIL;
// Save the item
pralList[ulIndex].pszAddr = PszDupA(pszAddr);
if (NULL == pralList[ulIndex].pszAddr)
{
fRet = FALSE;
goto exit;
}
}
}
// Get the exceptions list from the rule
if (FAILED(m_pIRule->QueryInterface(IID_IOERuleAddrList, (VOID **) &pIAddrList)))
{
fRet = FALSE;
goto exit;
}
// Get the list of exceptions from the address list
if (FAILED(pIAddrList->SetList(0, pralList, cExcpts)))
{
fRet = FALSE;
goto exit;
}
// Set the proper return value
fRet = TRUE;
exit:
SafeRelease(pIAddrList);
FreeRuleAddrList(pralList, cExcpts);
SafeMemFree(pralList);
SafeMemFree(pszAddr);
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _FAddExceptionToList
//
// This adds the exception passed in to the list view
//
// pszExcpt - the actual exception
// pulIndex - the index where the item was added
//
// Returns: TRUE, if it was successfully added
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CExceptionsListUI::_FAddExceptionToList(LPSTR pszExcpt, ULONG * pulIndex)
{
BOOL fRet = FALSE;
ULONG cExcpts = 0;
LPSTR pszLabel = NULL;
ULONG ulIndex = 0;
LVITEM lvitem = {0};
ULONG cchExcpt = 0;
Assert(NULL != m_hwndList);
// If there's nothing to do...
if (NULL == pszExcpt)
{
fRet = FALSE;
goto exit;
}
// Initialize the outgoing param
if (NULL != pulIndex)
{
*pulIndex = 0;
}
cExcpts = ListView_GetItemCount(m_hwndList);
// Figure out the maximum size of the buffer needed get the string
if (0 != cExcpts)
{
if (FAILED(HrAlloc((void **) &pszLabel, m_cchLabelMax * sizeof(*pszLabel))))
{
fRet = FALSE;
goto exit;
}
// See if the exception is already in the list
lvitem.pszText = pszLabel;
lvitem.cchTextMax = m_cchLabelMax;
for (ulIndex = 0; ulIndex < cExcpts; ulIndex++)
{
if (0 != SendMessage(m_hwndList, LVM_GETITEMTEXT, (WPARAM) ulIndex, (LPARAM) &lvitem))
{
if (0 == lstrcmpi(pszLabel, pszExcpt))
{
break;
}
}
}
}
// Insert it if we didn't find it
if (ulIndex == cExcpts)
{
ZeroMemory(&lvitem, sizeof(lvitem));
lvitem.mask = LVIF_TEXT;
lvitem.iItem = ulIndex;
lvitem.pszText = pszExcpt;
ulIndex = ListView_InsertItem(m_hwndList, &lvitem);
if (-1 == ulIndex)
{
fRet = FALSE;
goto exit;
}
// Figure out the new maximum
cchExcpt = lstrlen(pszExcpt) + 1;
if (cchExcpt > m_cchLabelMax)
{
m_cchLabelMax = cchExcpt;
}
}
// Set the outgoing param
if (NULL != pulIndex)
{
*pulIndex = ulIndex;
}
// Set the proper return value
fRet = TRUE;
exit:
SafeMemFree(pszLabel);
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// _EnableButtons
//
// This enables or disables the buttons in the Exceptions List UI dialog
// depending on what is selected.
//
// iSelected - the item that was selected,
// -1 means that nothing was selected
//
// Returns: NONE
//
///////////////////////////////////////////////////////////////////////////////
void CExceptionsListUI::_EnableButtons(INT iSelected)
{
int cExcpts = 0;
BOOL fSelected = FALSE;
Assert(NULL != m_hwndList);
fSelected = (-1 != iSelected);
// Enable the senders action buttons
RuleUtil_FEnDisDialogItem(m_hwndDlg, idcRemoveException, fSelected);
RuleUtil_FEnDisDialogItem(m_hwndDlg, idcModifyException, fSelected);
return;
}