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.
1944 lines
58 KiB
1944 lines
58 KiB
#include "pch.hxx"
|
|
#include <shlwapi.h>
|
|
#include <shlwapip.h>
|
|
#include <resource.h>
|
|
#include <options.h>
|
|
#include <optres.h>
|
|
#include <goptions.h>
|
|
#include <strconst.h>
|
|
#include <error.h>
|
|
#include "sigs.h"
|
|
#include "mimeolep.h"
|
|
#include "demand.h"
|
|
#include "menures.h"
|
|
#include <mailnews.h>
|
|
|
|
typedef struct tagSIG
|
|
{
|
|
IOptionBucket *pBckt;
|
|
char szName[MAXSIGNAME];
|
|
LPWSTR wszFile;
|
|
LPSTR szText;
|
|
DWORD type;
|
|
BOOL fDelete;
|
|
} SIG;
|
|
|
|
typedef struct tagACCTSIG
|
|
{
|
|
IImnAccount *pAcct;
|
|
ACCTTYPE type;
|
|
int iSig;
|
|
} ACCTSIG;
|
|
|
|
typedef struct tagSIGOPT
|
|
{
|
|
SIG *pSig;
|
|
int cSig;
|
|
int cSigBuf;
|
|
|
|
ACCTSIG *pAcctSig;
|
|
int cAcctSig;
|
|
|
|
int iDefSig;
|
|
int iInvalidSig; // needed for commctrl
|
|
BOOL fNoDirty;
|
|
|
|
int iSelSig; // used by the advanced sig dialog
|
|
} SIGOPT;
|
|
|
|
HRESULT ValidateSig(HWND hwnd, HWND hwndList, int iSig, SIGOPT *pSigOpt);
|
|
INT_PTR CALLBACK AdvSigDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
void EnableSigOptions(HWND hwnd, BOOL fEnable);
|
|
|
|
CSignatureManager *g_pSigMgr = NULL;
|
|
|
|
const OPTIONINFO c_rgSigInfo[] =
|
|
{
|
|
{SIG_ID, VT_LPSTR, 0, NULL, NULL, 0, 0, MAXSIGID - 1, 0},
|
|
{SIG_NAME, VT_LPSTR, 0, c_szSigName, NULL, 0, 0, MAXSIGNAME - 1, 0},
|
|
{SIG_FILE, VT_LPWSTR, 0, c_szSigFile, NULL, 0, 0, MAX_PATH - 1, 0},
|
|
{SIG_TEXT, VT_LPSTR, 0, c_szSigText, NULL, 0, 0, MAXSIGTEXT - 1, 0},
|
|
{SIG_TYPE, VT_UI4, 0, c_szSigType, (LPCSTR)SIGTYPE_TEXT, 0, 0, 0, 0}
|
|
};
|
|
|
|
HRESULT InitSignatureManager(HKEY hkey, LPCSTR szRegRoot)
|
|
{
|
|
HRESULT hr;
|
|
|
|
Assert(g_pSigMgr == NULL);
|
|
Assert(g_pOpt != NULL);
|
|
|
|
g_pSigMgr = new CSignatureManager(hkey, szRegRoot);
|
|
if (g_pSigMgr == NULL)
|
|
hr = E_OUTOFMEMORY;
|
|
else
|
|
hr = S_OK;
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT DeinitSignatureManager()
|
|
{
|
|
if (g_pSigMgr != NULL)
|
|
{
|
|
g_pSigMgr->Release();
|
|
g_pSigMgr = NULL;
|
|
}
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
CSignatureManager::CSignatureManager(HKEY hkey, LPCSTR pszRegKeyRoot)
|
|
{
|
|
m_cRef = 1;
|
|
m_fInit = FALSE;
|
|
m_hkey = hkey;
|
|
wnsprintf(m_szRegRoot, ARRAYSIZE(m_szRegRoot), c_szPathFileFmt, pszRegKeyRoot, c_szSigs);
|
|
m_pBckt = NULL;
|
|
m_cBckt = 0;
|
|
m_cBcktBuf = 0;
|
|
}
|
|
|
|
CSignatureManager::~CSignatureManager(void)
|
|
{
|
|
int i;
|
|
|
|
if (m_pBckt != NULL)
|
|
{
|
|
for (i = 0; i < m_cBckt; i++)
|
|
{
|
|
if (m_pBckt[i].pBckt != NULL)
|
|
m_pBckt[i].pBckt->Release();
|
|
}
|
|
|
|
MemFree(m_pBckt);
|
|
}
|
|
}
|
|
|
|
ULONG CSignatureManager::AddRef(void)
|
|
{
|
|
return((ULONG)InterlockedIncrement(&m_cRef));
|
|
}
|
|
|
|
ULONG CSignatureManager::Release(void)
|
|
{
|
|
LONG cRef = InterlockedDecrement(&m_cRef);
|
|
if (0 == cRef)
|
|
delete this;
|
|
return((ULONG)cRef);
|
|
}
|
|
|
|
#define CSIGREALLOC 8
|
|
|
|
HRESULT CSignatureManager::Initialize()
|
|
{
|
|
HKEY hkey;
|
|
HRESULT hr;
|
|
BOOL fDef;
|
|
DWORD cSig, cSigBuf, cb, i;
|
|
SIGBUCKET *pBckt;
|
|
|
|
hr = S_OK;
|
|
|
|
if (!m_fInit)
|
|
{
|
|
if (ERROR_SUCCESS == RegCreateKeyEx(m_hkey, m_szRegRoot, 0, NULL, REG_OPTION_NON_VOLATILE,
|
|
KEY_READ, NULL, &hkey, &cb))
|
|
{
|
|
fDef = FALSE;
|
|
|
|
cb = sizeof(m_szDefSigID);
|
|
RegQueryValueEx(hkey, c_szRegDefSig, NULL, &i, (LPBYTE)m_szDefSigID, &cb);
|
|
|
|
if (ERROR_SUCCESS == RegQueryInfoKey (hkey, NULL, NULL, NULL, &cSig, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL))
|
|
{
|
|
cSigBuf = cSig + CSIGREALLOC;
|
|
cb = cSigBuf * sizeof(SIGBUCKET);
|
|
if (!MemAlloc((void **)&m_pBckt, cb))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
{
|
|
ZeroMemory(m_pBckt, cb);
|
|
m_cBcktBuf = cSigBuf;
|
|
|
|
for (i = 0, pBckt = m_pBckt; i < cSig; i++, pBckt++)
|
|
{
|
|
cb = sizeof(pBckt->szID);
|
|
if (ERROR_SUCCESS != RegEnumKeyEx(hkey, i, pBckt->szID, &cb, NULL, NULL, NULL, NULL))
|
|
{
|
|
// TODO: what if this fails????
|
|
break;
|
|
}
|
|
|
|
if (!fDef &&
|
|
*m_szDefSigID != 0 &&
|
|
0 == lstrcmpi(m_szDefSigID, pBckt->szID))
|
|
fDef = TRUE;
|
|
|
|
m_cBckt++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!fDef && m_cBckt > 0)
|
|
{
|
|
// there was no default or it was bogus, so just set it to the 1st sig
|
|
StrCpyN(m_szDefSigID, m_pBckt->szID, ARRAYSIZE(m_szDefSigID));
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
m_fInit = TRUE;
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CSignatureManager::GetBucket(SIGBUCKET *pSigBckt)
|
|
{
|
|
OPTBCKTINIT init;
|
|
char szKey[MAX_PATH];
|
|
IOptionBucketEx *pBcktEx;
|
|
HRESULT hr;
|
|
PROPVARIANT var;
|
|
|
|
Assert(pSigBckt != NULL);
|
|
Assert(pSigBckt->pBckt == NULL);
|
|
|
|
hr = CreateOptionBucketEx(&pBcktEx);
|
|
if (FAILED(hr))
|
|
return(hr);
|
|
|
|
ZeroMemory(&init, sizeof(OPTBCKTINIT));
|
|
init.rgInfo = c_rgSigInfo;
|
|
init.cInfo = ARRAYSIZE(c_rgSigInfo);
|
|
init.hkey = m_hkey;
|
|
wnsprintf(szKey, ARRAYSIZE(szKey), c_szPathFileFmt, m_szRegRoot, pSigBckt->szID);
|
|
init.pszRegKeyBase = szKey;
|
|
|
|
var.vt = VT_LPSTR;
|
|
var.pszVal = pSigBckt->szID;
|
|
|
|
if (FAILED(hr = pBcktEx->Initialize(&init)) ||
|
|
FAILED(hr = pBcktEx->SetProperty(MAKEPROPSTRING(SIG_ID), &var, 0)))
|
|
{
|
|
pBcktEx->Release();
|
|
return(hr);
|
|
}
|
|
|
|
hr = pBcktEx->QueryInterface(IID_IOptionBucket, (void **)&pSigBckt->pBckt);
|
|
Assert(SUCCEEDED(hr));
|
|
|
|
pBcktEx->Release();
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CSignatureManager::GetSignature(LPCSTR szID, IOptionBucket **ppBckt)
|
|
{
|
|
HRESULT hr;
|
|
SIGBUCKET *pBckt;
|
|
int i;
|
|
|
|
Assert(szID != NULL);
|
|
Assert(ppBckt != NULL);
|
|
AssertSz(m_cBckt, "Someone didn't check to see if we had any sigs");
|
|
|
|
*ppBckt = NULL;
|
|
|
|
hr = Initialize();
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = E_FAIL;
|
|
|
|
for (i = 0, pBckt = m_pBckt; i < m_cBckt; i++, pBckt++)
|
|
{
|
|
if (0 == lstrcmpi(pBckt->szID, szID))
|
|
{
|
|
hr = S_OK;
|
|
|
|
if (pBckt->pBckt == NULL)
|
|
hr = GetBucket(pBckt);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
*ppBckt = pBckt->pBckt;
|
|
(*ppBckt)->AddRef();
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CSignatureManager::GetSignatureCount(int *pcSig)
|
|
{
|
|
HRESULT hr;
|
|
|
|
Assert(pcSig != NULL);
|
|
|
|
hr = Initialize();
|
|
if (SUCCEEDED(hr))
|
|
*pcSig = m_cBckt;
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CSignatureManager::EnumSignatures(int index, IOptionBucket **ppBckt)
|
|
{
|
|
HRESULT hr;
|
|
SIGBUCKET *pBckt;
|
|
|
|
Assert(ppBckt != NULL);
|
|
|
|
*ppBckt = NULL;
|
|
|
|
hr = Initialize();
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (index >= m_cBckt)
|
|
return(S_FALSE);
|
|
|
|
hr = S_OK;
|
|
pBckt = &m_pBckt[index];
|
|
|
|
if (pBckt->pBckt == NULL)
|
|
hr = GetBucket(pBckt);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
*ppBckt = pBckt->pBckt;
|
|
(*ppBckt)->AddRef();
|
|
}
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
static const char c_szIDFmt[] = "%08lx";
|
|
|
|
HRESULT CSignatureManager::CreateSignature(IOptionBucket **ppBckt)
|
|
{
|
|
HRESULT hr;
|
|
int cAlloc;
|
|
DWORD id, dwDisp;
|
|
HKEY hkey;
|
|
SIGBUCKET *pBckt;
|
|
char szKey[MAX_PATH], szID[MAXSIGID];
|
|
|
|
Assert(ppBckt != NULL);
|
|
|
|
*ppBckt = NULL;
|
|
|
|
hr = Initialize();
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = E_FAIL;
|
|
|
|
if (m_cBckt == m_cBcktBuf)
|
|
{
|
|
cAlloc = m_cBcktBuf + CSIGREALLOC;
|
|
if (!MemRealloc((void **)&m_pBckt, cAlloc * sizeof(SIGBUCKET)))
|
|
return(E_OUTOFMEMORY);
|
|
|
|
m_cBcktBuf = cAlloc;
|
|
ZeroMemory(&m_pBckt[m_cBckt], CSIGREALLOC * sizeof(SIGBUCKET));
|
|
}
|
|
|
|
pBckt = &m_pBckt[m_cBckt];
|
|
id = 0;
|
|
while (TRUE)
|
|
{
|
|
wnsprintf(szID, ARRAYSIZE(szID), c_szIDFmt, id);
|
|
wnsprintf(szKey, ARRAYSIZE(szKey), c_szPathFileFmt, m_szRegRoot, szID);
|
|
if (ERROR_SUCCESS == RegCreateKeyEx(m_hkey, szKey, 0, NULL, REG_OPTION_NON_VOLATILE,
|
|
KEY_READ, NULL, &hkey, &dwDisp))
|
|
{
|
|
RegCloseKey(hkey);
|
|
|
|
if (dwDisp == REG_OPENED_EXISTING_KEY)
|
|
{
|
|
id++;
|
|
continue;
|
|
}
|
|
|
|
StrCpyN(pBckt->szID, szID, ARRAYSIZE(pBckt->szID));
|
|
hr = GetBucket(pBckt);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
m_cBckt++;
|
|
*ppBckt = pBckt->pBckt;
|
|
(*ppBckt)->AddRef();
|
|
}
|
|
else
|
|
{
|
|
RegDeleteKey(m_hkey, szKey);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CSignatureManager::DeleteSignature(LPCSTR szID)
|
|
{
|
|
HRESULT hr;
|
|
char sz[MAX_PATH],
|
|
szSigID[MAXSIGID];
|
|
int i;
|
|
SIGBUCKET *pBckt;
|
|
ACCTTYPE type;
|
|
IImnAccount *pAcct;
|
|
IImnEnumAccounts *pEnum;
|
|
BOOL fDeletingDefault = FALSE;
|
|
|
|
hr = Initialize();
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = E_FAIL;
|
|
|
|
for (i = 0, pBckt = m_pBckt; i < m_cBckt; i++, pBckt++)
|
|
{
|
|
if (0 == lstrcmpi(pBckt->szID, szID))
|
|
{
|
|
fDeletingDefault = (0 == lstrcmpi(pBckt->szID, m_szDefSigID));
|
|
|
|
wnsprintf(sz, ARRAYSIZE(sz), c_szPathFileFmt, m_szRegRoot, szID);
|
|
if (ERROR_SUCCESS == SHDeleteKey(m_hkey, sz))
|
|
{
|
|
if (pBckt->pBckt != NULL)
|
|
{
|
|
pBckt->pBckt->Release();
|
|
pBckt->pBckt = NULL;
|
|
}
|
|
if (i + 1 < m_cBckt)
|
|
MoveMemory(&m_pBckt[i], &m_pBckt[i + 1], (m_cBckt - (i + 1)) * sizeof(SIGBUCKET));
|
|
m_cBckt--;
|
|
m_pBckt[m_cBckt].pBckt = NULL;
|
|
hr = S_OK;
|
|
|
|
Assert(g_pAcctMan != NULL);
|
|
if (SUCCEEDED(g_pAcctMan->Enumerate(SRV_MAIL | SRV_NNTP, &pEnum)))
|
|
{
|
|
Assert(pEnum != NULL);
|
|
|
|
while (SUCCEEDED(pEnum->GetNext(&pAcct)))
|
|
{
|
|
Assert(pAcct != NULL);
|
|
hr = pAcct->GetAccountType(&type);
|
|
Assert(SUCCEEDED(hr));
|
|
|
|
if (SUCCEEDED(pAcct->GetPropSz(type == ACCT_MAIL ? AP_SMTP_SIGNATURE : AP_NNTP_SIGNATURE, szSigID, ARRAYSIZE(szSigID))) &&
|
|
0 == lstrcmpi(szSigID, szID))
|
|
{
|
|
pAcct->SetPropSz(type == ACCT_MAIL ? AP_SMTP_SIGNATURE : AP_NNTP_SIGNATURE, NULL);
|
|
pAcct->SaveChanges();
|
|
}
|
|
|
|
pAcct->Release();
|
|
}
|
|
|
|
pEnum->Release();
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
if (fDeletingDefault)
|
|
{
|
|
if (m_cBckt > 0)
|
|
SetDefaultSignature(m_pBckt->szID);
|
|
else
|
|
SetDefaultSignature("");
|
|
}
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CSignatureManager::GetDefaultSignature(LPSTR pszID, DWORD cchSize)
|
|
{
|
|
HRESULT hr;
|
|
|
|
AssertSz(m_cBckt, "Someone didn't check to see if we had any sigs");
|
|
|
|
hr = Initialize();
|
|
if (SUCCEEDED(hr))
|
|
StrCpyN(pszID, m_szDefSigID, cchSize);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CSignatureManager::SetDefaultSignature(LPCSTR szID)
|
|
{
|
|
HRESULT hr;
|
|
|
|
Assert(szID != NULL);
|
|
Assert(lstrlen(szID) < MAXSIGID);
|
|
|
|
hr = Initialize();
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (ERROR_SUCCESS == SHSetValue(m_hkey, m_szRegRoot, c_szRegDefSig, REG_SZ, szID, lstrlen(szID) + 1))
|
|
StrCpyN(m_szDefSigID, szID, ARRAYSIZE(m_szDefSigID));
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
// TODO: error handling would be useful
|
|
SIGOPT *InitSigOpt(void)
|
|
{
|
|
HRESULT hr;
|
|
int i, cSig;
|
|
SIG *pSig;
|
|
char szDef[MAXSIGID];
|
|
PROPVARIANT var;
|
|
SIGOPT *pSigOpt = NULL;
|
|
|
|
Assert(g_pSigMgr != NULL);
|
|
|
|
if (MemAlloc((void **)&pSigOpt, sizeof(SIGOPT)))
|
|
{
|
|
ZeroMemory(pSigOpt, sizeof(SIGOPT));
|
|
|
|
pSigOpt->iDefSig = -1;
|
|
pSigOpt->iInvalidSig = -1;
|
|
|
|
hr = g_pSigMgr->GetSignatureCount(&cSig);
|
|
Assert(SUCCEEDED(hr));
|
|
if (cSig > 0)
|
|
{
|
|
pSigOpt->cSigBuf = cSig + CSIGREALLOC;
|
|
if (MemAlloc((void **)&pSigOpt->pSig, pSigOpt->cSigBuf * sizeof(SIG)))
|
|
{
|
|
ZeroMemory(pSigOpt->pSig, pSigOpt->cSigBuf * sizeof(SIG));
|
|
|
|
hr = g_pSigMgr->GetDefaultSignature(szDef, ARRAYSIZE(szDef));
|
|
Assert(SUCCEEDED(hr));
|
|
Assert(szDef[0] != 0);
|
|
|
|
for (i = 0, pSig = pSigOpt->pSig; i < cSig; i++, pSig++)
|
|
{
|
|
hr = g_pSigMgr->EnumSignatures(i, &pSig->pBckt);
|
|
if (hr != S_OK)
|
|
break;
|
|
|
|
Assert(pSig->pBckt != NULL);
|
|
|
|
if (pSigOpt->iDefSig == -1)
|
|
{
|
|
hr = pSig->pBckt->GetProperty(MAKEPROPSTRING(SIG_ID), &var, 0);
|
|
Assert(SUCCEEDED(hr));
|
|
Assert(var.vt == VT_LPSTR);
|
|
Assert(var.pszVal != NULL);
|
|
if (0 == lstrcmpi(szDef, var.pszVal))
|
|
pSigOpt->iDefSig = i;
|
|
MemFree(var.pszVal);
|
|
}
|
|
|
|
hr = pSig->pBckt->GetProperty(MAKEPROPSTRING(SIG_NAME), &var, 0);
|
|
Assert(SUCCEEDED(hr));
|
|
Assert(var.vt == VT_LPSTR);
|
|
Assert(var.pszVal != NULL);
|
|
StrCpyN(pSig->szName, var.pszVal, ARRAYSIZE(pSig->szName));
|
|
MemFree(var.pszVal);
|
|
|
|
hr = pSig->pBckt->GetProperty(MAKEPROPSTRING(SIG_TYPE), &var, 0);
|
|
Assert(SUCCEEDED(hr));
|
|
Assert(var.vt == VT_UI4);
|
|
pSig->type = var.ulVal;
|
|
|
|
if (pSig->type == SIGTYPE_TEXT)
|
|
{
|
|
hr = pSig->pBckt->GetProperty(MAKEPROPSTRING(SIG_TEXT), &var, 0);
|
|
Assert(SUCCEEDED(hr));
|
|
Assert(var.vt == VT_LPSTR);
|
|
Assert(var.pszVal != NULL);
|
|
pSig->szText = var.pszVal;
|
|
}
|
|
else
|
|
{
|
|
Assert(pSig->type == SIGTYPE_FILE);
|
|
hr = pSig->pBckt->GetProperty(MAKEPROPSTRING(SIG_FILE), &var, 0);
|
|
Assert(SUCCEEDED(hr));
|
|
Assert(var.vt == VT_LPWSTR);
|
|
Assert(var.pwszVal != NULL);
|
|
pSig->wszFile = var.pwszVal;
|
|
}
|
|
|
|
pSigOpt->cSig++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return(pSigOpt);
|
|
}
|
|
|
|
void DeinitSigOpt(SIGOPT *pSigOpt)
|
|
{
|
|
int i;
|
|
SIG *pSig;
|
|
ACCTSIG *pAcctSig;
|
|
|
|
if (pSigOpt != NULL)
|
|
{
|
|
if (pSigOpt->pSig != NULL)
|
|
{
|
|
for (i = 0, pSig = pSigOpt->pSig; i < pSigOpt->cSig; i++, pSig++)
|
|
{
|
|
if (pSig->wszFile != NULL)
|
|
MemFree(pSig->wszFile);
|
|
if (pSig->szText != NULL)
|
|
MemFree(pSig->szText);
|
|
if (pSig->pBckt != NULL)
|
|
pSig->pBckt->Release();
|
|
}
|
|
|
|
MemFree(pSigOpt->pSig);
|
|
}
|
|
|
|
if (pSigOpt->pAcctSig != NULL)
|
|
{
|
|
for (i = 0, pAcctSig = pSigOpt->pAcctSig; i < pSigOpt->cAcctSig; i++, pAcctSig++)
|
|
{
|
|
if (pAcctSig->pAcct != NULL)
|
|
pAcctSig->pAcct->Release();
|
|
}
|
|
|
|
MemFree(pSigOpt->pAcctSig);
|
|
}
|
|
|
|
MemFree(pSigOpt);
|
|
}
|
|
}
|
|
|
|
int InsertSig(HWND hwndList, SIG *pSig, int i)
|
|
{
|
|
int index;
|
|
LV_ITEM lvi;
|
|
|
|
Assert(pSig != NULL);
|
|
|
|
lvi.mask = LVIF_TEXT | LVIF_PARAM;
|
|
lvi.iItem = i;
|
|
lvi.iSubItem = 0;
|
|
lvi.pszText = pSig->szName;
|
|
lvi.lParam = i;
|
|
index = ListView_InsertItem(hwndList, &lvi);
|
|
Assert(index != -1);
|
|
|
|
return(index);
|
|
}
|
|
|
|
void SetDefault(HWND hwndList, int iOldDef, int iNewDef)
|
|
{
|
|
char sz[64];
|
|
LV_FINDINFO lvfi;
|
|
int i;
|
|
|
|
if (iOldDef >= 0)
|
|
{
|
|
lvfi.flags = LVFI_PARAM;
|
|
lvfi.lParam = iOldDef;
|
|
i = ListView_FindItem(hwndList, -1, &lvfi);
|
|
|
|
ListView_SetItemText(hwndList, i, 1, (LPSTR)c_szEmpty);
|
|
}
|
|
|
|
lvfi.flags = LVFI_PARAM;
|
|
lvfi.lParam = iNewDef;
|
|
i = ListView_FindItem(hwndList, -1, &lvfi);
|
|
|
|
AthLoadString(idsDefaultSignature, sz, ARRAYSIZE(sz));
|
|
ListView_SetItemText(hwndList, i, 1, sz);
|
|
}
|
|
|
|
void EnableSignatureWindows(HWND hwnd, BOOL fEnable)
|
|
{
|
|
EnableWindow(GetDlgItem(hwnd, IDC_REMOVE_BUTTON), fEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_RENAME_BUTTON), fEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_TEXT_RADIO), fEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_TEXT_EDIT), fEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_FILE_RADIO), fEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_FILE_EDIT), fEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_BROWSE_BUTTON), fEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_DEFAULT_BUTTON), fEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_ADV_BUTTON), fEnable);
|
|
|
|
if (!fEnable)
|
|
{
|
|
CheckDlgButton(hwnd, IDC_TEXT_RADIO, BST_UNCHECKED);
|
|
SetDlgItemText(hwnd, IDC_TEXT_EDIT, c_szEmpty);
|
|
CheckDlgButton(hwnd, IDC_FILE_RADIO, BST_UNCHECKED);
|
|
SetDlgItemText(hwnd, IDC_FILE_EDIT, c_szEmpty);
|
|
|
|
if (!IsWindowEnabled(GetFocus()))
|
|
SetFocus(GetDlgItem(hwnd, IDC_NEW_BUTTON));
|
|
}
|
|
}
|
|
|
|
WNDPROC g_SigListUnicodeProc = NULL;
|
|
LRESULT CALLBACK SigListANSIProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return(CallWindowProc(g_SigListUnicodeProc, hwnd, msg, wParam, lParam));
|
|
}
|
|
|
|
void InitSigDlg(HWND hwnd, SIGOPT *pSigOpt, OPTINFO *poi)
|
|
{
|
|
HWND hwndList, hwndT;
|
|
RECT rc;
|
|
int i;
|
|
DWORD dw;
|
|
LV_COLUMN lvc;
|
|
SIG *pSig;
|
|
|
|
Assert(pSigOpt != NULL);
|
|
|
|
hwndT = GetDlgItem(hwnd, IDC_TEXT_EDIT);
|
|
SetIntlFont(hwndT);
|
|
SendMessage(hwndT, EM_LIMITTEXT, MAXSIGTEXT - 1, 0);
|
|
|
|
hwndT = GetDlgItem(hwnd, IDC_FILE_EDIT);
|
|
SetIntlFont(hwndT);
|
|
SendMessage(hwndT, EM_LIMITTEXT, MAX_PATH - 1, 0);
|
|
|
|
dw = IDwGetOption(poi->pOpt, OPT_SIGNATURE_FLAGS);
|
|
CheckDlgButton(hwnd, IDC_ADDSIG_CHECK,
|
|
!!(dw & SIGFLAG_AUTONEW) ? BST_CHECKED : BST_UNCHECKED);
|
|
CheckDlgButton(hwnd, IDC_ADDREPLY_CHECK,
|
|
!(dw & SIGFLAG_AUTOREPLY) ? BST_CHECKED : BST_UNCHECKED);
|
|
|
|
if (!(dw & SIGFLAG_AUTONEW))
|
|
EnableWindow(GetDlgItem(hwnd, IDC_ADDREPLY_CHECK), FALSE);
|
|
|
|
hwndList = GetDlgItem(hwnd, IDC_SIG_LIST);
|
|
g_SigListUnicodeProc = (WNDPROC) SetWindowLongPtr(hwndList, GWLP_WNDPROC, (LONG_PTR)SigListANSIProc);
|
|
GetClientRect(hwndList, &rc);
|
|
rc.right = rc.right - GetSystemMetrics(SM_CXVSCROLL);
|
|
rc.right = rc.right / 2;
|
|
|
|
lvc.mask = LVCF_WIDTH;
|
|
lvc.cx = rc.right;
|
|
ListView_InsertColumn(hwndList, 0, &lvc);
|
|
ListView_InsertColumn(hwndList, 1, &lvc);
|
|
|
|
for (i = 0, pSig = pSigOpt->pSig; i < pSigOpt->cSig; i++, pSig++)
|
|
InsertSig(hwndList, pSig, i);
|
|
|
|
if (pSigOpt->iDefSig >= 0)
|
|
SetDefault(hwndList, -1, pSigOpt->iDefSig);
|
|
|
|
if (pSigOpt->cSig > 0)
|
|
{
|
|
ListView_SetItemState(hwndList, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
|
|
}
|
|
else
|
|
{
|
|
EnableSignatureWindows(hwnd, FALSE);
|
|
EnableSigOptions(hwnd, FALSE);
|
|
}
|
|
|
|
// Pictures
|
|
HICON hIcon;
|
|
|
|
hIcon = ImageList_GetIcon(poi->himl, ID_SIGNATURES, ILD_TRANSPARENT);
|
|
SendDlgItemMessage(hwnd, IDC_SIG_SETTINGS_ICON, STM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon);
|
|
|
|
hIcon = ImageList_GetIcon(poi->himl, ID_SIG_LIST, ILD_TRANSPARENT);
|
|
SendDlgItemMessage(hwnd, IDC_SIGLIST_ICON, STM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon);
|
|
|
|
hIcon = ImageList_GetIcon(poi->himl, ID_SIG_EDIT, ILD_TRANSPARENT);
|
|
SendDlgItemMessage(hwnd, IDC_SIG_EDIT_ICON, STM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon);
|
|
}
|
|
|
|
BOOL IsUniqueSigName(LPCSTR szName, SIGOPT *pSigOpt)
|
|
{
|
|
int i;
|
|
SIG *pSig;
|
|
|
|
for (i = 0, pSig = pSigOpt->pSig; i < pSigOpt->cSig; i++, pSig++)
|
|
{
|
|
if (!pSig->fDelete &&
|
|
0 == lstrcmpi(szName, pSig->szName))
|
|
return(FALSE);
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
int GetItemIndex(HWND hwndList, int i)
|
|
{
|
|
LV_ITEM lvi;
|
|
|
|
if (i == -1)
|
|
{
|
|
// get the selected item's index
|
|
i = ListView_GetNextItem(hwndList, -1, LVNI_ALL | LVNI_FOCUSED);
|
|
Assert(i >= 0);
|
|
}
|
|
|
|
lvi.iItem = i;
|
|
lvi.iSubItem = 0;
|
|
lvi.mask = LVIF_PARAM;
|
|
ListView_GetItem(hwndList, &lvi);
|
|
|
|
return((int)(INT_PTR)(lvi.lParam));
|
|
}
|
|
|
|
HRESULT HandleNewSig(HWND hwnd, SIGOPT *pSigOpt)
|
|
{
|
|
HRESULT hr;
|
|
SIG *pSig;
|
|
char sz[MAXSIGNAME];
|
|
int i, cSig, cAlloc;
|
|
HWND hwndList;
|
|
|
|
hwndList = GetDlgItem(hwnd, IDC_SIG_LIST);
|
|
|
|
cSig = ListView_GetItemCount(hwndList);
|
|
if (cSig > 0)
|
|
{
|
|
i = GetItemIndex(hwndList, -1);
|
|
if (i >= 0)
|
|
{
|
|
hr = ValidateSig(hwnd, hwndList, i, pSigOpt);
|
|
if (FAILED(hr))
|
|
return(E_FAIL);
|
|
}
|
|
}
|
|
|
|
if (pSigOpt->cSig == pSigOpt->cSigBuf)
|
|
{
|
|
cAlloc = pSigOpt->cSigBuf + CSIGREALLOC;
|
|
if (!MemRealloc((void **)&pSigOpt->pSig, cAlloc * sizeof(SIG)))
|
|
return(E_OUTOFMEMORY);
|
|
|
|
ZeroMemory(&pSigOpt->pSig[pSigOpt->cSig], CSIGREALLOC * sizeof(SIG));
|
|
pSigOpt->cSigBuf = cAlloc;
|
|
}
|
|
|
|
pSig = &pSigOpt->pSig[pSigOpt->cSig];
|
|
|
|
AthLoadString(idsSigNameFmt, sz, ARRAYSIZE(sz));
|
|
for (i = 1; i < 10000; i++)
|
|
{
|
|
wnsprintf(pSig->szName, ARRAYSIZE(pSig->szName), sz, i);
|
|
if (IsUniqueSigName(pSig->szName, pSigOpt))
|
|
break;
|
|
}
|
|
|
|
if (i == 10000)
|
|
return(E_FAIL);
|
|
|
|
pSig->type = SIGTYPE_TEXT;
|
|
|
|
i = InsertSig(hwndList, pSig, pSigOpt->cSig);
|
|
if (pSigOpt->iDefSig == -1)
|
|
{
|
|
SetDefault(hwndList, -1, pSigOpt->cSig);
|
|
pSigOpt->iDefSig = pSigOpt->cSig;
|
|
}
|
|
|
|
pSigOpt->cSig++;
|
|
|
|
if (cSig == 0)
|
|
{
|
|
EnableSignatureWindows(hwnd, TRUE);
|
|
EnableSigOptions(hwnd, TRUE);
|
|
}
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDC_DEFAULT_BUTTON), pSigOpt->iDefSig != GetItemIndex(hwndList, i));
|
|
|
|
ListView_SetItemState(hwndList, i, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
|
|
ListView_EnsureVisible(hwndList, i, FALSE);
|
|
SetFocus(GetDlgItem(hwnd, IDC_TEXT_EDIT));
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
HRESULT HandleDeleteSig(HWND hwnd, SIGOPT *pSigOpt)
|
|
{
|
|
int i, iSig, iNewSel, cSig;
|
|
HWND hwndList;
|
|
SIG *pSig;
|
|
|
|
hwndList = GetDlgItem(hwnd, IDC_SIG_LIST);
|
|
|
|
i = ListView_GetNextItem(hwndList, -1, LVNI_ALL | LVNI_FOCUSED);
|
|
Assert(i >= 0);
|
|
|
|
iSig = GetItemIndex(hwndList, i);
|
|
|
|
pSig = &pSigOpt->pSig[iSig];
|
|
Assert(!pSig->fDelete);
|
|
pSig->fDelete = TRUE;
|
|
|
|
ListView_DeleteItem(hwndList, i);
|
|
|
|
cSig = ListView_GetItemCount(hwndList);
|
|
if (cSig == 0)
|
|
iNewSel = -1;
|
|
else if (i == 0)
|
|
iNewSel = 0;
|
|
else
|
|
iNewSel = i - 1;
|
|
|
|
Assert(pSigOpt->iDefSig >= 0);
|
|
if (iSig == pSigOpt->iDefSig)
|
|
{
|
|
if (iNewSel >= 0)
|
|
{
|
|
iSig = GetItemIndex(hwndList, iNewSel);
|
|
|
|
SetDefault(hwndList, -1, iSig);
|
|
pSigOpt->iDefSig = iSig;
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDC_DEFAULT_BUTTON), FALSE);
|
|
}
|
|
else
|
|
{
|
|
pSigOpt->iDefSig = -1;
|
|
}
|
|
}
|
|
|
|
if (iNewSel >= 0)
|
|
{
|
|
ListView_SetItemState(hwndList, iNewSel, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
|
|
ListView_EnsureVisible(hwndList, iNewSel, FALSE);
|
|
}
|
|
else
|
|
{
|
|
EnableSignatureWindows(hwnd, FALSE);
|
|
EnableSigOptions(hwnd, FALSE);
|
|
}
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
HRESULT HandleSigRename(HWND hwnd, LV_DISPINFO *pdi, SIGOPT *pSigOpt)
|
|
{
|
|
HWND hwndList;
|
|
SIG *pSig, *pSigT;
|
|
LPSTR pszText = NULL;
|
|
HRESULT hr = S_OK;
|
|
int i;
|
|
|
|
Assert(pdi != NULL);
|
|
Assert(pSigOpt != NULL);
|
|
|
|
IF_TRUEEXIT((pdi->item.pszText == NULL || FIsEmpty(pdi->item.pszText)), S_FALSE);
|
|
|
|
if(IsWindowUnicode(hwnd))
|
|
pszText = PszToANSI(CP_ACP, (WCHAR*)(pdi->item.pszText));
|
|
else
|
|
pszText = StrDupA(pdi->item.pszText);
|
|
|
|
IF_NULLEXIT(pszText);
|
|
IF_TRUEEXIT((lstrlen(pszText) >= MAXSIGNAME), S_FALSE);
|
|
|
|
pSig = &pSigOpt->pSig[pdi->item.lParam];
|
|
Assert(!pSig->fDelete);
|
|
Assert(pSig->szName[0] != 0);
|
|
|
|
IF_TRUEEXIT((0 == lstrcmpi(pSig->szName, pszText)), S_FALSE);
|
|
|
|
for (i = 0, pSigT = pSigOpt->pSig; i < pSigOpt->cSig; i++, pSigT++)
|
|
{
|
|
if (pSigT->fDelete)
|
|
continue;
|
|
|
|
IF_TRUEEXIT((0 == lstrcmpi(pSigT->szName, pszText)), S_FALSE);
|
|
}
|
|
|
|
StrCpyN(pSig->szName, pszText, ARRAYSIZE(pSig->szName));
|
|
|
|
exit:
|
|
MemFree(pszText);
|
|
return hr;
|
|
}
|
|
|
|
static const int c_rgidsFilter[] =
|
|
{
|
|
idsTextFileFilter,
|
|
idsHtmlFileFilter,
|
|
idsAllFilesFilter
|
|
};
|
|
|
|
HRESULT HandleBrowseButton(HWND hwnd)
|
|
{
|
|
OPENFILENAMEW ofnw;
|
|
WCHAR wszFilter[MAX_PATH], wszFile[MAX_PATH], wszDir[MAX_PATH];
|
|
HRESULT hr;
|
|
int cch;
|
|
LPWSTR pwszFile;
|
|
|
|
hr = S_FALSE;
|
|
*wszFilter = 0;
|
|
*wszFile = 0;
|
|
|
|
ZeroMemory(&ofnw, sizeof(ofnw));
|
|
ofnw.lStructSize = sizeof(ofnw);
|
|
|
|
cch = GetDlgItemTextWrapW(hwnd, IDC_FILE_EDIT, wszDir, ARRAYSIZE(wszDir));
|
|
if (cch > 0)
|
|
{
|
|
if (PathIsDirectoryW(wszDir))
|
|
{
|
|
ofnw.lpstrInitialDir = wszDir;
|
|
}
|
|
else if (PathFileExistsW(wszDir))
|
|
{
|
|
pwszFile = PathFindFileNameW(wszDir);
|
|
if (pwszFile != NULL)
|
|
StrCpyNW(wszFile, pwszFile, ARRAYSIZE(wszFile));
|
|
|
|
*pwszFile = 0;
|
|
|
|
if (*wszDir != 0)
|
|
ofnw.lpstrInitialDir = wszDir;
|
|
|
|
}
|
|
else if (PathIsFileSpecW(wszDir))
|
|
{
|
|
StrCpyNW(wszFile, wszDir, ARRAYSIZE(wszFile));
|
|
}
|
|
}
|
|
|
|
CombineFiltersW((int *)c_rgidsFilter, ARRAYSIZE(c_rgidsFilter), wszFilter);
|
|
ofnw.hwndOwner = hwnd;
|
|
ofnw.lpstrFile = wszFile;
|
|
ofnw.lpstrFilter = wszFilter;
|
|
ofnw.nMaxFile = ARRAYSIZE(wszFile);
|
|
ofnw.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NONETWORKBUTTON | OFN_NOCHANGEDIR | OFN_EXPLORER;
|
|
if (HrAthGetFileNameW(&ofnw, TRUE)==S_OK)
|
|
{
|
|
SetDlgItemTextWrapW(hwnd, IDC_FILE_EDIT, wszFile);
|
|
hr = S_OK;
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT ValidateSig(HWND hwnd, HWND hwndList, int iSig, SIGOPT *pSigOpt)
|
|
{
|
|
SIG *pSig;
|
|
BOOL fText;
|
|
HWND hwndT;
|
|
int cch, id, i;
|
|
char **ppsz, *psz;
|
|
|
|
Assert(pSigOpt != NULL);
|
|
Assert(iSig < pSigOpt->cSig);
|
|
|
|
pSig = &pSigOpt->pSig[iSig];
|
|
if (pSig->fDelete)
|
|
return(S_OK);
|
|
|
|
fText = (IsDlgButtonChecked(hwnd, IDC_TEXT_RADIO) == BST_CHECKED);
|
|
id = fText ? IDC_TEXT_EDIT : IDC_FILE_EDIT;
|
|
hwndT = GetDlgItem(hwnd, id);
|
|
cch = GetWindowTextLength(hwndT);
|
|
if (cch == 0)
|
|
{
|
|
i = ListView_GetNextItem(hwndList, -1, LVNI_ALL | LVNI_FOCUSED);
|
|
ListView_SetItemState(hwndList, i, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
|
|
InvalidOptionProp(hwnd, id, fText ? idsEnterSigText : idsEnterSigFile, iddOpt_Signature);
|
|
return(E_FAIL);
|
|
}
|
|
|
|
cch++;
|
|
if (!fText)
|
|
{
|
|
WCHAR *pwsz = NULL;
|
|
|
|
if (!MemAlloc((void **)&pwsz, cch * sizeof(*pwsz)))
|
|
return(E_OUTOFMEMORY);
|
|
|
|
GetWindowTextWrapW(hwndT, pwsz, cch);
|
|
if (!PathFileExistsW(pwsz) || PathIsDirectoryW(pwsz))
|
|
{
|
|
MemFree(pwsz);
|
|
i = ListView_GetNextItem(hwndList, -1, LVNI_ALL | LVNI_FOCUSED);
|
|
ListView_SetItemState(hwndList, i, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
|
|
InvalidOptionProp(hwnd, id, idsSigFileNoExistError, iddOpt_Signature);
|
|
return(E_FAIL);
|
|
}
|
|
else
|
|
{
|
|
//Free the previous sig file
|
|
MemFree(pSig->wszFile);
|
|
pSig->wszFile = pwsz;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!MemAlloc((void **)&psz, cch))
|
|
return(E_OUTOFMEMORY);
|
|
GetWindowText(hwndT, psz, cch);
|
|
|
|
//Free the previous sig text
|
|
MemFree(pSig->szText);
|
|
|
|
pSig->szText = psz;
|
|
}
|
|
|
|
pSig->type = fText ? SIGTYPE_TEXT : SIGTYPE_FILE;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
HRESULT SaveSigs(HWND hwnd, SIGOPT *pSigOpt)
|
|
{
|
|
int cSigT, cSig, i;
|
|
SIG *pSig;
|
|
ACCTSIG *pAcctSig;
|
|
PROPVARIANT var;
|
|
HRESULT hr;
|
|
HWND hwndList;
|
|
char *szSigID;
|
|
|
|
Assert(pSigOpt != NULL);
|
|
Assert(g_pSigMgr != NULL);
|
|
|
|
hwndList = GetDlgItem(hwnd, IDC_SIG_LIST);
|
|
cSig = ListView_GetItemCount(hwndList);
|
|
|
|
cSigT = 0;
|
|
for (i = 0, pSig = pSigOpt->pSig; i < pSigOpt->cSig; i++, pSig++)
|
|
{
|
|
if (pSig->fDelete)
|
|
{
|
|
if (pSig->pBckt != NULL)
|
|
{
|
|
if (SUCCEEDED(pSig->pBckt->GetProperty(MAKEPROPSTRING(SIG_ID), &var, 0)) && var.pszVal != NULL)
|
|
{
|
|
g_pSigMgr->DeleteSignature(var.pszVal);
|
|
MemFree(var.pszVal);
|
|
}
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
if (pSig->pBckt == NULL)
|
|
{
|
|
hr = g_pSigMgr->CreateSignature(&pSig->pBckt);
|
|
Assert(SUCCEEDED(hr));
|
|
Assert(pSig->pBckt != NULL);
|
|
}
|
|
|
|
if (pSigOpt->iDefSig == i)
|
|
{
|
|
if (SUCCEEDED(pSig->pBckt->GetProperty(MAKEPROPSTRING(SIG_ID), &var, 0)) && var.pszVal)
|
|
{
|
|
g_pSigMgr->SetDefaultSignature(var.pszVal);
|
|
MemFree(var.pszVal);
|
|
}
|
|
}
|
|
|
|
var.vt = VT_LPSTR;
|
|
var.pszVal = pSig->szName;
|
|
hr = pSig->pBckt->SetProperty(MAKEPROPSTRING(SIG_NAME), &var, 0);
|
|
AssertSz(SUCCEEDED(hr), "Sig name failed to be set");
|
|
|
|
var.vt = VT_UI4;
|
|
var.ulVal = pSig->type;
|
|
hr = pSig->pBckt->SetProperty(MAKEPROPSTRING(SIG_TYPE), &var, 0);
|
|
AssertSz(SUCCEEDED(hr), "Sig type failed to be set");
|
|
|
|
var.vt = VT_LPSTR;
|
|
AssertSz(((SIGTYPE_TEXT == pSig->type) ? (NULL != pSig->szText) : TRUE), "Text should be set.");
|
|
var.pszVal = (SIGTYPE_TEXT == pSig->type) ? pSig->szText : (LPSTR)c_szEmpty;
|
|
hr = pSig->pBckt->SetProperty(MAKEPROPSTRING(SIG_TEXT), &var, 0);
|
|
AssertSz(SUCCEEDED(hr), "Sig text failed to be set");
|
|
|
|
var.vt = VT_LPWSTR;
|
|
var.pwszVal = (pSig->type == SIGTYPE_FILE) ? pSig->wszFile : (LPWSTR)c_wszEmpty;
|
|
hr = pSig->pBckt->SetProperty(MAKEPROPSTRING(SIG_FILE), &var, 0);
|
|
AssertSz(SUCCEEDED(hr), "Sig filename failed to be set");
|
|
|
|
cSigT++;
|
|
}
|
|
}
|
|
|
|
Assert(cSig == cSigT);
|
|
|
|
for (i = 0, pAcctSig = pSigOpt->pAcctSig; i < pSigOpt->cAcctSig; i++, pAcctSig++)
|
|
{
|
|
szSigID = NULL;
|
|
if (pAcctSig->iSig >= 0)
|
|
{
|
|
pSig = &pSigOpt->pSig[pAcctSig->iSig];
|
|
if (!pSig->fDelete)
|
|
{
|
|
hr = pSig->pBckt->GetProperty(MAKEPROPSTRING(SIG_ID), &var, 0);
|
|
Assert(SUCCEEDED(hr));
|
|
Assert(var.pszVal != NULL);
|
|
szSigID = var.pszVal;
|
|
}
|
|
}
|
|
|
|
hr = pAcctSig->pAcct->SetPropSz(pAcctSig->type == ACCT_MAIL ? AP_SMTP_SIGNATURE : AP_NNTP_SIGNATURE, szSigID);
|
|
Assert(SUCCEEDED(hr));
|
|
hr = pAcctSig->pAcct->SaveChanges();
|
|
Assert(SUCCEEDED(hr));
|
|
|
|
if (szSigID != NULL)
|
|
MemFree(szSigID);
|
|
}
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
void EnableSigWindows(HWND hwnd, BOOL fText)
|
|
{
|
|
HWND focus;
|
|
|
|
focus = GetFocus();
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDC_TEXT_EDIT), fText);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_FILE_EDIT), !fText);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_BROWSE_BUTTON), !fText);
|
|
|
|
// don't disable button that has the focus
|
|
if (!IsWindowEnabled(focus))
|
|
SetFocus(GetDlgItem(hwnd, fText ? IDC_TEXT_EDIT : IDC_FILE_EDIT));
|
|
}
|
|
|
|
void EnableSigOptions(HWND hwnd, BOOL fEnable)
|
|
{
|
|
HWND hwndT;
|
|
|
|
hwndT = GetDlgItem(hwnd, IDC_ADDSIG_CHECK);
|
|
|
|
EnableWindow(hwndT, fEnable);
|
|
|
|
if (fEnable)
|
|
fEnable = (SendMessage(hwndT, BM_GETCHECK, 0, 0) == BST_CHECKED);
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDC_ADDREPLY_CHECK), fEnable);
|
|
}
|
|
|
|
static const HELPMAP g_rgCtxMapSigs[] = {
|
|
{IDC_ADDSIG_CHECK, 353569},
|
|
{IDC_ADDREPLY_CHECK, 35610},
|
|
{IDC_SIG_LIST, 35594},
|
|
{IDC_NEW_BUTTON, 35591},
|
|
{IDC_REMOVE_BUTTON, 35592},
|
|
{IDC_RENAME_BUTTON, 35593},
|
|
{IDC_TEXT_EDIT, 35595},
|
|
{IDC_FILE_EDIT, 35600},
|
|
{IDC_DEFAULT_BUTTON, 35596},
|
|
{IDC_ADV_BUTTON, 35597},
|
|
{IDC_BROWSE_BUTTON, 35605},
|
|
{idcStatic1, IDH_NEWS_COMM_GROUPBOX},
|
|
{idcStatic2, IDH_NEWS_COMM_GROUPBOX},
|
|
{idcStatic3, IDH_NEWS_COMM_GROUPBOX},
|
|
{idcStatic4, IDH_NEWS_COMM_GROUPBOX},
|
|
{idcStatic5, IDH_NEWS_COMM_GROUPBOX},
|
|
{idcStatic6, IDH_NEWS_COMM_GROUPBOX},
|
|
{IDC_SIG_SETTINGS_ICON, IDH_NEWS_COMM_GROUPBOX},
|
|
{IDC_SIGLIST_ICON, IDH_NEWS_COMM_GROUPBOX},
|
|
{IDC_SIG_EDIT_ICON, IDH_NEWS_COMM_GROUPBOX},
|
|
{0, 0}
|
|
};
|
|
|
|
WNDPROC g_SigRenameEditUnicodeProc = NULL;
|
|
LRESULT CALLBACK SigRenameEditANSIProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return(CallWindowProc(g_SigRenameEditUnicodeProc, hwnd, msg, wParam, lParam));
|
|
}
|
|
|
|
INT_PTR CALLBACK SigDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
SIGOPT *pSigOpt;
|
|
WORD code, id;
|
|
SIG *pSig;
|
|
int i, cSig;
|
|
DWORD dw;
|
|
OPTINFO *poi;
|
|
LPNMHDR pnmh;
|
|
NM_LISTVIEW *pnmlv;
|
|
HRESULT hr;
|
|
HWND hwndList;
|
|
BOOL fEnable, fRet = TRUE;
|
|
|
|
pSigOpt = (SIGOPT *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
|
poi = (OPTINFO *)GetWindowLongPtr(hwnd, DWLP_USER);
|
|
hwndList = GetDlgItem(hwnd, IDC_SIG_LIST);
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
Assert(poi == NULL);
|
|
poi = (OPTINFO *)(((PROPSHEETPAGE *)lParam)->lParam);
|
|
Assert(poi != NULL);
|
|
SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM)poi);
|
|
|
|
pSigOpt = InitSigOpt();
|
|
Assert(pSigOpt != NULL);
|
|
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LPARAM)pSigOpt);
|
|
|
|
InitSigDlg(hwnd, pSigOpt, poi);
|
|
|
|
PropSheet_UnChanged(GetParent(hwnd), hwnd);
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
FreeIcon(hwnd, IDC_SIG_SETTINGS_ICON);
|
|
FreeIcon(hwnd, IDC_SIGLIST_ICON);
|
|
FreeIcon(hwnd, IDC_SIG_EDIT_ICON);
|
|
|
|
if (pSigOpt != NULL)
|
|
{
|
|
DeinitSigOpt(pSigOpt);
|
|
SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
|
|
}
|
|
|
|
SetWindowLongPtr(hwndList, GWLP_WNDPROC, (LONG_PTR)g_SigListUnicodeProc);
|
|
g_SigListUnicodeProc = NULL;
|
|
break;
|
|
|
|
case WM_HELP:
|
|
case WM_CONTEXTMENU:
|
|
return OnContextHelp(hwnd, msg, wParam, lParam, g_rgCtxMapSigs);
|
|
|
|
case WM_COMMAND:
|
|
if (poi == NULL)
|
|
break;
|
|
|
|
code = HIWORD(wParam);
|
|
id = LOWORD(wParam);
|
|
switch (id)
|
|
{
|
|
case IDC_FILE_EDIT:
|
|
case IDC_TEXT_EDIT:
|
|
if (code == EN_CHANGE && !pSigOpt->fNoDirty)
|
|
SetPageDirty(poi, hwnd, PAGE_SIGS);
|
|
break;
|
|
|
|
case IDC_FILE_RADIO:
|
|
case IDC_TEXT_RADIO:
|
|
if (code == BN_CLICKED)
|
|
{
|
|
EnableSigWindows(hwnd, id == IDC_TEXT_RADIO);
|
|
SetPageDirty(poi, hwnd, PAGE_SIGS);
|
|
}
|
|
break;
|
|
|
|
case IDC_ADDREPLY_CHECK:
|
|
case IDC_SIGBOTTOM_CHECK:
|
|
if (code == BN_CLICKED)
|
|
SetPageDirty(poi, hwnd, PAGE_SIGS);
|
|
break;
|
|
|
|
case IDC_ADDSIG_CHECK:
|
|
if (code == BN_CLICKED)
|
|
{
|
|
fEnable = (IsDlgButtonChecked(hwnd, IDC_ADDSIG_CHECK) == BST_CHECKED);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_ADDREPLY_CHECK), fEnable);
|
|
|
|
SetPageDirty(poi, hwnd, PAGE_SIGS);
|
|
}
|
|
break;
|
|
|
|
case IDC_NEW_BUTTON:
|
|
if (code == BN_CLICKED)
|
|
{
|
|
if (SUCCEEDED(HandleNewSig(hwnd, pSigOpt)))
|
|
SetPageDirty(poi, hwnd, PAGE_SIGS);
|
|
}
|
|
break;
|
|
|
|
case IDC_REMOVE_BUTTON:
|
|
if (code == BN_CLICKED)
|
|
{
|
|
if (SUCCEEDED(HandleDeleteSig(hwnd, pSigOpt)))
|
|
SetPageDirty(poi, hwnd, PAGE_SIGS);
|
|
}
|
|
break;
|
|
|
|
case IDC_RENAME_BUTTON:
|
|
if (code == BN_CLICKED)
|
|
{
|
|
i = ListView_GetNextItem(hwndList, -1, LVNI_ALL | LVNI_FOCUSED);
|
|
Assert(i >= 0);
|
|
SetFocus(hwndList);
|
|
ListView_EditLabel(hwndList, i);
|
|
}
|
|
break;
|
|
|
|
case IDC_DEFAULT_BUTTON:
|
|
if (code == BN_CLICKED)
|
|
{
|
|
i = GetItemIndex(hwndList, -1);
|
|
if (i != pSigOpt->iDefSig)
|
|
{
|
|
SetDefault(hwndList, pSigOpt->iDefSig, i);
|
|
pSigOpt->iDefSig = i;
|
|
SetPageDirty(poi, hwnd, PAGE_SIGS);
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDC_DEFAULT_BUTTON), FALSE);
|
|
if (!IsWindowEnabled(GetFocus()))
|
|
SetFocus(GetDlgItem(hwnd, IDC_NEW_BUTTON));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDC_BROWSE_BUTTON:
|
|
if (code == BN_CLICKED)
|
|
{
|
|
if (S_OK == HandleBrowseButton(hwnd))
|
|
SetPageDirty(poi, hwnd, PAGE_SIGS);
|
|
}
|
|
break;
|
|
|
|
case IDC_ADV_BUTTON:
|
|
if (code == BN_CLICKED)
|
|
{
|
|
pSigOpt->iSelSig = GetItemIndex(hwndList, -1);
|
|
Assert(pSigOpt->iSelSig >= 0);
|
|
if (IDOK == DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddAdvSig), hwnd, AdvSigDlgProc, (LPARAM)pSigOpt))
|
|
SetPageDirty(poi, hwnd, PAGE_SIGS);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
pnmh = (LPNMHDR)lParam;
|
|
switch (pnmh->code)
|
|
{
|
|
case PSN_APPLY:
|
|
Assert(poi != NULL);
|
|
|
|
cSig = ListView_GetItemCount(hwndList);
|
|
if (cSig > 0)
|
|
{
|
|
i = GetItemIndex(hwndList, -1);
|
|
hr = ValidateSig(hwnd, hwndList, i, pSigOpt);
|
|
if (hr != S_OK)
|
|
{
|
|
SetDlgMsgResult(hwnd, WM_NOTIFY, PSNRET_INVALID_NOCHANGEPAGE);
|
|
return (PSNRET_INVALID_NOCHANGEPAGE);
|
|
}
|
|
}
|
|
|
|
dw = 0;
|
|
if (cSig > 0 &&
|
|
IsDlgButtonChecked(hwnd, IDC_ADDSIG_CHECK) == BST_CHECKED)
|
|
{
|
|
dw = SIGFLAG_AUTONEW;
|
|
if (IsDlgButtonChecked(hwnd, IDC_ADDREPLY_CHECK) == BST_UNCHECKED)
|
|
dw |= SIGFLAG_AUTOREPLY;
|
|
}
|
|
ISetDwOption(poi->pOpt, OPT_SIGNATURE_FLAGS, dw, NULL, 0);
|
|
|
|
SaveSigs(hwnd, pSigOpt);
|
|
|
|
PropSheet_UnChanged(GetParent(hwnd), hwnd);
|
|
break;
|
|
|
|
|
|
case LVN_BEGINLABELEDITW:
|
|
{
|
|
HWND hwndEdit;
|
|
|
|
hwndEdit = ListView_GetEditControl(hwndList);
|
|
if(hwndEdit)
|
|
g_SigRenameEditUnicodeProc = (WNDPROC) SetWindowLongPtr(hwndEdit, GWLP_WNDPROC, (LONG_PTR)SigRenameEditANSIProc);
|
|
}
|
|
case LVN_BEGINLABELEDITA:
|
|
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case LVN_ENDLABELEDITW:
|
|
{
|
|
HWND hwndEdit;
|
|
|
|
hwndEdit = ListView_GetEditControl(hwndList);
|
|
|
|
if(hwndEdit)
|
|
{
|
|
SetWindowLongPtr(hwndEdit, GWLP_WNDPROC, (LONG_PTR)g_SigRenameEditUnicodeProc);
|
|
g_SigRenameEditUnicodeProc = NULL;
|
|
}
|
|
}
|
|
case LVN_ENDLABELEDITA:
|
|
hr = HandleSigRename(hwnd, (LV_DISPINFO *)pnmh, pSigOpt);
|
|
if (hr == S_OK)
|
|
SetPageDirty(poi, hwnd, PAGE_SIGS);
|
|
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, hr == S_OK);
|
|
break;
|
|
|
|
case LVN_ITEMCHANGING:
|
|
pnmlv = (NM_LISTVIEW *)pnmh;
|
|
if (!!(pnmlv->uOldState & LVIS_FOCUSED) &&
|
|
!(pnmlv->uNewState & LVIS_FOCUSED) &&
|
|
pnmlv->iItem != -1)
|
|
{
|
|
// item is losing selection
|
|
|
|
if (pSigOpt->iInvalidSig != -1)
|
|
{
|
|
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE);
|
|
pSigOpt->iInvalidSig = -1;
|
|
break;
|
|
}
|
|
|
|
hr = ValidateSig(hwnd, hwndList, (int)pnmlv->lParam, pSigOpt);
|
|
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, hr != S_OK);
|
|
if (hr != S_OK)
|
|
pSigOpt->iInvalidSig = pnmlv->iItem;
|
|
}
|
|
break;
|
|
|
|
case LVN_ITEMCHANGED:
|
|
pnmlv = (NM_LISTVIEW *)pnmh;
|
|
if (!(pnmlv->uOldState & LVIS_FOCUSED) &&
|
|
!!(pnmlv->uNewState & LVIS_FOCUSED) &&
|
|
pnmlv->iItem != -1)
|
|
{
|
|
// item is becoming the selection
|
|
|
|
Assert(pSigOpt->iInvalidSig == -1);
|
|
|
|
pSigOpt->fNoDirty = TRUE;
|
|
|
|
pSig = &pSigOpt->pSig[pnmlv->lParam];
|
|
if (pSig->type == SIGTYPE_TEXT)
|
|
{
|
|
CheckDlgButton(hwnd, IDC_TEXT_RADIO, BST_CHECKED);
|
|
SetDlgItemText(hwnd, IDC_TEXT_EDIT, pSig->szText != NULL ? pSig->szText : c_szEmpty);
|
|
CheckDlgButton(hwnd, IDC_FILE_RADIO, BST_UNCHECKED);
|
|
SetDlgItemText(hwnd, IDC_FILE_EDIT, c_szEmpty);
|
|
}
|
|
else
|
|
{
|
|
Assert(pSig->type == SIGTYPE_FILE);
|
|
CheckDlgButton(hwnd, IDC_FILE_RADIO, BST_CHECKED);
|
|
SetDlgItemTextWrapW(hwnd, IDC_FILE_EDIT, pSig->wszFile != NULL ? pSig->wszFile : c_wszEmpty);
|
|
CheckDlgButton(hwnd, IDC_TEXT_RADIO, BST_UNCHECKED);
|
|
SetDlgItemText(hwnd, IDC_TEXT_EDIT, c_szEmpty);
|
|
}
|
|
EnableSigWindows(hwnd, pSig->type == SIGTYPE_TEXT);
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDC_DEFAULT_BUTTON), pSigOpt->iDefSig != GetItemIndex(hwndList, pnmlv->iItem));
|
|
|
|
pSigOpt->fNoDirty = FALSE;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
fRet = FALSE;
|
|
break;
|
|
}
|
|
|
|
return(fRet);
|
|
}
|
|
|
|
HRESULT FillSignatureMenu(HMENU hmenu, LPCSTR szAcct)
|
|
{
|
|
HRESULT hr;
|
|
int i, cSig, iDef;
|
|
char *psz, szDef[MAXSIGID], sz[MAXSIGNAME + 64], szT[64];
|
|
IOptionBucket *pSig;
|
|
PROPVARIANT var;
|
|
|
|
Assert(g_pSigMgr != NULL);
|
|
|
|
hr = g_pSigMgr->GetSignatureCount(&cSig);
|
|
Assert(SUCCEEDED(hr));
|
|
Assert(cSig > 0);
|
|
|
|
hr = g_pSigMgr->GetDefaultSignature(szDef, ARRAYSIZE(szDef));
|
|
Assert(SUCCEEDED(hr));
|
|
Assert(szDef[0] != 0);
|
|
|
|
iDef = -1;
|
|
for (i = 0; i < cSig; i++)
|
|
{
|
|
hr = g_pSigMgr->EnumSignatures(i, &pSig);
|
|
if (hr != S_OK)
|
|
break;
|
|
|
|
Assert(pSig != NULL);
|
|
|
|
if (iDef == -1)
|
|
{
|
|
hr = pSig->GetProperty(MAKEPROPSTRING(SIG_ID), &var, 0);
|
|
Assert(SUCCEEDED(hr));
|
|
Assert(var.vt == VT_LPSTR);
|
|
Assert(var.pszVal != NULL);
|
|
if (0 == lstrcmpi(szDef, var.pszVal))
|
|
iDef = i;
|
|
MemFree(var.pszVal);
|
|
}
|
|
|
|
hr = pSig->GetProperty(MAKEPROPSTRING(SIG_NAME), &var, 0);
|
|
Assert(SUCCEEDED(hr));
|
|
Assert(var.vt == VT_LPSTR);
|
|
Assert(var.pszVal != NULL);
|
|
|
|
if (i == iDef)
|
|
{
|
|
AthLoadString(idsDefaultAccount, szT, ARRAYSIZE(szT));
|
|
wnsprintf(sz, ARRAYSIZE(sz), c_szSpaceCatFmt, var.pszVal, szT);
|
|
psz = sz;
|
|
}
|
|
else
|
|
{
|
|
psz = var.pszVal;
|
|
}
|
|
|
|
InsertMenu(hmenu, i, MF_BYPOSITION | MF_STRING, ID_SIGNATURE_FIRST + i, psz);
|
|
|
|
MemFree(var.pszVal);
|
|
}
|
|
|
|
Assert(iDef != -1);
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
HRESULT InitSigPopupMenu(HMENU hmenu, LPCSTR szAcct)
|
|
{
|
|
int cSig;
|
|
HRESULT hr;
|
|
|
|
Assert(g_pSigMgr != NULL);
|
|
hr = g_pSigMgr->GetSignatureCount(&cSig);
|
|
|
|
if (FAILED(hr))
|
|
return(hr);
|
|
|
|
if (cSig > 0)
|
|
{
|
|
HMENU hmenuOld = NULL, hmenuSig = NULL;
|
|
MENUITEMINFO mii;
|
|
|
|
ZeroMemory(&mii, sizeof(mii));
|
|
mii.cbSize = sizeof(MENUITEMINFO);
|
|
mii.fMask = MIIM_SUBMENU;
|
|
SideAssert(GetMenuItemInfo(hmenu, ID_INSERT_SIGNATURE, FALSE, &mii));
|
|
hmenuOld = mii.hSubMenu;
|
|
|
|
if (cSig > 1)
|
|
{
|
|
hmenuSig = CreatePopupMenu();
|
|
Assert(hmenuSig != NULL);
|
|
|
|
hr = FillSignatureMenu(hmenuSig, szAcct);
|
|
if (FAILED(hr))
|
|
return(hr);
|
|
}
|
|
|
|
mii.hSubMenu = hmenuSig;
|
|
|
|
// Set the menu item
|
|
SideAssert(SetMenuItemInfo(hmenu, ID_INSERT_SIGNATURE, FALSE, &mii));
|
|
|
|
if (hmenuOld != NULL)
|
|
DestroyMenu(hmenuOld);
|
|
}
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
void DeinitSigPopupMenu(HWND hwnd)
|
|
{
|
|
HMENU hmenu;
|
|
MENUITEMINFO mii;
|
|
|
|
hmenu = GetMenu(hwnd);
|
|
if (hmenu != NULL)
|
|
{
|
|
ZeroMemory(&mii, sizeof(mii));
|
|
mii.cbSize = sizeof(MENUITEMINFO);
|
|
mii.fMask = MIIM_SUBMENU;
|
|
if (GetMenuItemInfo(hmenu, ID_INSERT_SIGNATURE, FALSE, &mii) &&
|
|
mii.hSubMenu != NULL)
|
|
DestroyMenu(mii.hSubMenu);
|
|
}
|
|
}
|
|
|
|
HRESULT GetSigFromCmd(int id, char * pszID, DWORD cchSize)
|
|
{
|
|
HRESULT hr;
|
|
IOptionBucket *pSig;
|
|
PROPVARIANT var;
|
|
|
|
Assert(pszID != NULL);
|
|
|
|
Assert(id >= ID_SIGNATURE_FIRST && id <= ID_SIGNATURE_LAST);
|
|
id = id - ID_SIGNATURE_FIRST;
|
|
|
|
Assert(g_pSigMgr != NULL);
|
|
hr = g_pSigMgr->EnumSignatures(id, &pSig);
|
|
if (hr != S_OK)
|
|
return(E_FAIL);
|
|
|
|
Assert(pSig != NULL);
|
|
|
|
hr = pSig->GetProperty(MAKEPROPSTRING(SIG_ID), &var, 0);
|
|
Assert(SUCCEEDED(hr));
|
|
Assert(var.vt == VT_LPSTR);
|
|
Assert(var.pszVal != NULL);
|
|
StrCpyN(pszID, var.pszVal, cchSize);
|
|
MemFree(var.pszVal);
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
void InitAcctSig(SIGOPT *pSigOpt)
|
|
{
|
|
IImnEnumAccounts *pEnum;
|
|
IImnAccount *pAcct;
|
|
ACCTSIG *pAcctSig;
|
|
HRESULT hr;
|
|
ULONG cAcct;
|
|
SIG *pSig;
|
|
int i, cmp;
|
|
PROPVARIANT var;
|
|
char szSigID[MAXSIGID];
|
|
|
|
Assert(pSigOpt != NULL);
|
|
|
|
if (pSigOpt->pAcctSig != NULL)
|
|
return;
|
|
|
|
Assert(g_pAcctMan != NULL);
|
|
if (SUCCEEDED(g_pAcctMan->Enumerate(SRV_MAIL | SRV_NNTP, &pEnum)))
|
|
{
|
|
Assert(pEnum != NULL);
|
|
|
|
hr = pEnum->GetCount(&cAcct);
|
|
Assert(SUCCEEDED(hr));
|
|
|
|
if (cAcct > 0 &&
|
|
MemAlloc((void **)&pSigOpt->pAcctSig, cAcct * sizeof(ACCTSIG)))
|
|
{
|
|
for (cAcct = 0, pAcctSig = pSigOpt->pAcctSig; SUCCEEDED(pEnum->GetNext(&pAcct)); cAcct++, pAcctSig++)
|
|
{
|
|
Assert(pAcct != NULL);
|
|
pAcctSig->pAcct = pAcct;
|
|
pAcctSig->iSig = -1;
|
|
hr = pAcct->GetAccountType(&pAcctSig->type);
|
|
Assert(SUCCEEDED(hr));
|
|
|
|
if (SUCCEEDED(pAcct->GetPropSz(pAcctSig->type == ACCT_MAIL ? AP_SMTP_SIGNATURE : AP_NNTP_SIGNATURE, szSigID, ARRAYSIZE(szSigID))) &&
|
|
!FIsEmpty(szSigID))
|
|
{
|
|
for (i = 0, pSig = pSigOpt->pSig; i < pSigOpt->cSig; i++, pSig++)
|
|
{
|
|
if (pSig->pBckt != NULL)
|
|
{
|
|
hr = pSig->pBckt->GetProperty(MAKEPROPSTRING(SIG_ID), &var, 0);
|
|
Assert(SUCCEEDED(hr));
|
|
Assert(var.vt == VT_LPSTR);
|
|
Assert(var.pszVal != NULL);
|
|
cmp = lstrcmpi(szSigID, var.pszVal);
|
|
MemFree(var.pszVal);
|
|
|
|
if (cmp == 0)
|
|
{
|
|
pAcctSig->iSig = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pSigOpt->cAcctSig = cAcct;
|
|
}
|
|
|
|
pEnum->Release();
|
|
}
|
|
}
|
|
|
|
void InitAdvSigDlg(HWND hwnd, SIGOPT *pSigOpt)
|
|
{
|
|
SIG *pSig;
|
|
ACCTSIG *pAcctSig;
|
|
char *psz, *pszT;
|
|
int cch, i, index;
|
|
LV_COLUMN lvc;
|
|
RECT rc;
|
|
HIMAGELIST himl;
|
|
HWND hwndT, hwndList;
|
|
LV_ITEM lvi;
|
|
|
|
Assert(pSigOpt != NULL);
|
|
Assert(pSigOpt->iSelSig < pSigOpt->cSig);
|
|
pSig = &pSigOpt->pSig[pSigOpt->iSelSig];
|
|
Assert(!pSig->fDelete);
|
|
|
|
InitAcctSig(pSigOpt);
|
|
|
|
hwndT = GetDlgItem(hwnd, IDC_ADVSIG_STATIC);
|
|
cch = GetWindowTextLength(hwndT) + 1;
|
|
DWORD cchTotal = (cch * 2 + MAXSIGNAME);
|
|
if (!MemAlloc((void **)&psz, cchTotal))
|
|
return;
|
|
|
|
pszT = psz + cch;
|
|
GetWindowText(hwndT, psz, cchTotal);
|
|
wnsprintf(pszT, (cchTotal - cch), psz, pSig->szName);
|
|
SetWindowText(hwndT, pszT);
|
|
|
|
hwndList = GetDlgItem(hwnd, IDC_ACCOUNT_LIST);
|
|
ListView_SetExtendedListViewStyle(hwndList, LVS_EX_CHECKBOXES);
|
|
|
|
GetClientRect(hwndList, &rc);
|
|
rc.right = rc.right - GetSystemMetrics(SM_CXVSCROLL);
|
|
rc.right = rc.right / 2;
|
|
|
|
lvc.mask = LVCF_WIDTH | LVCF_TEXT;
|
|
lvc.cx = rc.right;
|
|
lvc.pszText = psz;
|
|
// account column
|
|
AthLoadString(idsAccount, psz, cch);
|
|
ListView_InsertColumn(hwndList, 0, &lvc);
|
|
// type column
|
|
AthLoadString(idsType, psz, cch);
|
|
ListView_InsertColumn(hwndList, 1, &lvc);
|
|
|
|
// Add Folders Imagelist
|
|
himl = ImageList_LoadBitmap(g_hLocRes, MAKEINTRESOURCE(idbFolders), 16, 0, RGB(255, 0, 255));
|
|
ListView_SetImageList(hwndList, himl, LVSIL_SMALL);
|
|
|
|
for (i = 0, pAcctSig = pSigOpt->pAcctSig; i < pSigOpt->cAcctSig; i++, pAcctSig++)
|
|
{
|
|
Assert(pAcctSig->pAcct != NULL);
|
|
|
|
if (SUCCEEDED(pAcctSig->pAcct->GetPropSz(AP_ACCOUNT_NAME, psz, cch)))
|
|
{
|
|
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
|
|
lvi.iItem = i;
|
|
lvi.iSubItem = 0;
|
|
lvi.pszText = psz;
|
|
lvi.iImage = (pAcctSig->type == ACCT_MAIL) ? iMailServer : iNewsServer;
|
|
lvi.lParam = i;
|
|
lvi.stateMask = LVIS_STATEIMAGEMASK;
|
|
index = ListView_InsertItem(hwndList, &lvi);
|
|
Assert(index != -1);
|
|
|
|
AthLoadString((pAcctSig->type == ACCT_MAIL) ? idsMail : idsNews, psz, cch);
|
|
lvi.mask = LVIF_TEXT;
|
|
lvi.iItem = index;
|
|
lvi.iSubItem = 1;
|
|
lvi.pszText = psz;
|
|
ListView_SetItem(hwndList, &lvi);
|
|
|
|
if (pAcctSig->iSig == pSigOpt->iSelSig)
|
|
ListView_SetItemState(hwndList, index, INDEXTOSTATEIMAGEMASK(2), LVIS_STATEIMAGEMASK); // 1 unchecked, 2 checked
|
|
}
|
|
}
|
|
|
|
if (pSigOpt->cAcctSig > 0)
|
|
ListView_SetItemState(hwndList, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
|
|
|
|
MemFree(psz);
|
|
}
|
|
|
|
void SaveAcctSigSettings(HWND hwnd, SIGOPT *pSigOpt)
|
|
{
|
|
int i, iAcctSig;
|
|
ACCTSIG *pAcctSig;
|
|
HWND hwndList;
|
|
BOOL fCheck;
|
|
|
|
Assert(pSigOpt != NULL);
|
|
|
|
hwndList = GetDlgItem(hwnd, IDC_ACCOUNT_LIST);
|
|
for (i = 0; i < pSigOpt->cAcctSig; i++)
|
|
{
|
|
iAcctSig = GetItemIndex(hwndList, i);
|
|
Assert(iAcctSig >= 0 && iAcctSig < pSigOpt->cAcctSig);
|
|
|
|
pAcctSig = &pSigOpt->pAcctSig[iAcctSig];
|
|
fCheck = ListView_GetCheckState(hwndList, i);
|
|
|
|
if (pSigOpt->iSelSig == pAcctSig->iSig)
|
|
{
|
|
if (!fCheck)
|
|
pAcctSig->iSig = -1;
|
|
}
|
|
else
|
|
{
|
|
if (fCheck)
|
|
pAcctSig->iSig = pSigOpt->iSelSig;
|
|
}
|
|
}
|
|
}
|
|
|
|
INT_PTR CALLBACK AdvSigDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
SIGOPT *pSigOpt;
|
|
WORD id;
|
|
HWND hwndList;
|
|
BOOL fRet = TRUE;
|
|
|
|
pSigOpt = (SIGOPT *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
|
hwndList = GetDlgItem(hwnd, IDC_ACCOUNT_LIST);
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
Assert(pSigOpt == NULL);
|
|
pSigOpt = (SIGOPT *)lParam;
|
|
Assert(pSigOpt != NULL);
|
|
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LPARAM)pSigOpt);
|
|
|
|
Assert(pSigOpt->iSelSig >= 0 && pSigOpt->iSelSig < pSigOpt->cSig);
|
|
InitAdvSigDlg(hwnd, pSigOpt);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
id = LOWORD(wParam);
|
|
switch (id)
|
|
{
|
|
case IDOK:
|
|
SaveAcctSigSettings(hwnd, pSigOpt);
|
|
// fall through...
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hwnd, id);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
fRet = FALSE;
|
|
break;
|
|
}
|
|
|
|
return(fRet);
|
|
}
|