windows-nt/Source/XPSP1/NT/enduser/netmeeting/ui/conf/wab.cpp
2020-09-26 16:20:57 +08:00

455 lines
11 KiB
C++

// File: wab.cpp
#include "precomp.h"
#include "resource.h"
#include "dirutil.h"
#include "wab.h"
#include "wabtags.h"
#include "wabiab.h"
#include "lst.h"
#include "fnobjs.h"
static const int _rgIdMenu[] = {
IDM_DLGCALL_SPEEDDIAL,
0
};
// As of VC 6.0 on the Alpha, FreePsz couldn't be passed to a
// template taking an F&. There is an internal compiler error
// One day, this will be fixed. For now, this call should be
// identical
class FreePszFunctor
{public:
void operator()( LPTSTR sz ) { FreePsz( sz ); }
};
// There is only one instance of this object (for CreateWabEntry)
CWAB * CWAB::m_spThis = NULL;
/* C W A B */
/*-------------------------------------------------------------------------
%%Function: CWAB
-------------------------------------------------------------------------*/
CWAB::CWAB() :
CALV(IDS_DLGCALL_WAB, II_WAB, _rgIdMenu)
{
DbgMsg(iZONE_OBJECTS, "CWAB - Constructed(%08X)", this);
ASSERT(NULL == m_spThis);
m_spThis = this;
SetAvailable(NULL != m_pAdrBook);
}
CWAB::~CWAB()
{
m_spThis = NULL;
DbgMsg(iZONE_OBJECTS, "CWAB - Destroyed(%08X)", this);
}
///////////////////////////////////////////////////////////////////////////
// CALV methods
/* S H O W I T E M S */
/*-------------------------------------------------------------------------
%%Function: ShowItems
-------------------------------------------------------------------------*/
VOID CWAB::ShowItems(HWND hwnd)
{
CALV::SetHeader(hwnd, IDS_ADDRESS);
ShowNmEntires(hwnd);
}
HRESULT CWAB::ShowNmEntires(HWND hwnd)
{
HRESULT hr;
if (!FAvailable())
return S_FALSE; // nothing to show
hr = GetContainer();
if (FAILED(hr))
return hr;
hr = EnsurePropTags();
if (FAILED(hr))
return hr;
LPMAPITABLE pAB = NULL;
hr = m_pContainer->GetContentsTable(0, &pAB);
if (FAILED(hr) || (NULL == pAB))
return hr;
// reset the system to use the correct properties
ASSERT(NULL != m_pPropTags);
hr = pAB->SetColumns(GetTags(), 0);
if (SUCCEEDED(hr))
{
// Read all the rows of the table one by one
hr = pAB->SeekRow(BOOKMARK_BEGINNING, 0, NULL);
}
while (S_OK == hr)
{
LPSRowSet pRowAB = NULL;
hr = pAB->QueryRows(1, 0, &pRowAB);
if (FAILED(hr) || (NULL == pRowAB))
break;
int cNumRows = pRowAB->cRows;
hr = (0 != cNumRows) ? S_OK : S_FALSE;
if (S_OK == hr)
{
LPSPropValue lpProp = &(pRowAB->aRow[0].lpProps[ieidPR_NM_ADDRESS]);
if (Get_PR_NM_ADDRESS() == lpProp->ulPropTag)
{
LPSTR pszName = pRowAB->aRow[0].lpProps[ieidPR_DISPLAY_NAME].Value.lpszA;
SLPSTRArray * pMVszA = &(lpProp->Value.MVszA);
if (0 != pMVszA->cValues)
{
// Find the default entry
LPSPropValue lpPropDefault = &(pRowAB->aRow[0].lpProps[ieidPR_NM_DEFAULT]);
ULONG iDefault = (Get_PR_NM_DEFAULT() == lpPropDefault->ulPropTag)
? lpPropDefault->Value.ul : 0;
ASSERT(iDefault <= pMVszA->cValues);
LPCTSTR pszAddr = pMVszA->lppszA[iDefault];
pszAddr = PszSkipCallTo(pszAddr);
// This trick will only work if the sizeof(LPARAM) == sizeof(LPENTRYID)
LPARAM lParam;
if (sizeof(LPARAM) == pRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb)
{
lParam = * (LPARAM *) pRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb;
}
else
{
lParam = 0;
}
DlgCallAddItem(hwnd, pszName, pszAddr, II_WAB_CARD, lParam);
}
}
}
FreeProws(pRowAB);
}
pAB->Release();
return hr;
}
/* C M D P R O P E R T I E S */
/*-------------------------------------------------------------------------
%%Function: CmdProperties
-------------------------------------------------------------------------*/
VOID CWAB::CmdProperties(void)
{
int iItem = GetSelection();
if (-1 == iItem)
return;
LV_ITEM lvi;
ClearStruct(&lvi);
lvi.iItem = iItem;
lvi.mask = LVIF_PARAM;
if (!ListView_GetItem(GetHwnd(), &lvi))
return;
HWND hwnd = GetParent(GetHwnd());
m_pAdrBook->Details((LPULONG) &hwnd, NULL, NULL,
sizeof(LPARAM), (LPENTRYID) &lvi.lParam,
NULL, NULL, NULL, 0);
// this is because we may have changed something in the Details dlg.
CmdRefresh();
ListView_SetItemState(GetHwnd(), iItem,
LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
}
/* G E T A D D R I N F O */
/*-------------------------------------------------------------------------
%%Function: GetAddrInfo
-------------------------------------------------------------------------*/
RAI * CWAB::GetAddrInfo(void)
{
RAI* pRai = NULL;
lst<LPTSTR> PhoneNums;
lst<LPTSTR> EmailNames;
lst<LPTSTR> ILSServers;
int iItem = GetSelection();
if (-1 != iItem)
{
LV_ITEM lvi;
ClearStruct(&lvi);
lvi.iItem = iItem;
lvi.mask = LVIF_PARAM;
if (ListView_GetItem(GetHwnd(), &lvi))
{
LPMAPIPROP pMapiProp = NULL;
ULONG ulObjType = 0;
HRESULT hr = m_pContainer->OpenEntry( sizeof(LPARAM),
reinterpret_cast<LPENTRYID>(&lvi.lParam),
NULL,
0,
&ulObjType,
reinterpret_cast<LPUNKNOWN*>(&pMapiProp)
);
if (SUCCEEDED(hr))
{
// Email Name
if (FEnabledNmAddr(NM_ADDR_ALIAS_ID))
{
ULONG PropTags[] = { PR_EMAIL_ADDRESS };
_GetLPSTRProps( EmailNames, PropTags, pMapiProp, ARRAY_ELEMENTS( PropTags ) );
}
// Phone number
if (FEnabledNmAddr(NM_ADDR_ALIAS_E164) || FEnabledNmAddr(NM_ADDR_H323_GATEWAY))
{
ULONG PhoneNumPropTags[] = {
PR_BUSINESS_TELEPHONE_NUMBER,
PR_HOME_TELEPHONE_NUMBER,
PR_PRIMARY_TELEPHONE_NUMBER,
PR_BUSINESS2_TELEPHONE_NUMBER,
PR_CELLULAR_TELEPHONE_NUMBER,
PR_RADIO_TELEPHONE_NUMBER,
PR_CAR_TELEPHONE_NUMBER,
PR_OTHER_TELEPHONE_NUMBER,
PR_PAGER_TELEPHONE_NUMBER
};
_GetLPSTRProps( PhoneNums, PhoneNumPropTags, pMapiProp, ARRAY_ELEMENTS( PhoneNumPropTags ) );
}
if (FEnabledNmAddr(NM_ADDR_ULS))
{
enum { iPrNmAddress = 0, iDefaultServer = 1 };
ULONG PropTags[2];
PropTags[iPrNmAddress] = Get_PR_NM_ADDRESS();
PropTags[iDefaultServer] = Get_PR_NM_DEFAULT();
if( m_pWabObject )
{
BYTE* pb = new BYTE[ sizeof( SPropTagArray ) + sizeof( ULONG ) * ARRAY_ELEMENTS( PropTags ) ];
if( pb )
{
// Fill in the prop tags that we are interested in...
SPropTagArray* pProps = reinterpret_cast<SPropTagArray*>(pb);
pProps->cValues = ARRAY_ELEMENTS(PropTags);
for( UINT iCur = 0; iCur < pProps->cValues; iCur++ )
{
pProps->aulPropTag[iCur] = PropTags[iCur];
}
LPSPropValue pData = NULL;
ULONG cValues = ARRAY_ELEMENTS(PropTags);
if( SUCCEEDED( hr = pMapiProp->GetProps( pProps, 0, &cValues, &pData ) ) && pData )
{
// Get teh ILS Servers
if( LOWORD( pData[iPrNmAddress].ulPropTag ) != PT_ERROR )
{
for( ULONG iCurVal = 0; iCurVal < pData[iPrNmAddress].Value.MVszA.cValues; ++iCurVal )
{
LPSTR pStr = pData[iPrNmAddress].Value.MVszA.lppszA[iCurVal];
// Skip the callto://
pStr = const_cast<LPSTR>(PszSkipCallTo(pStr));
// Skip duplicate server names...
if( !FEmptySz(pStr) && ( ILSServers.end() == find( ILSServers, IsEqLPTSTR( pStr ) ) ) )
{
ILSServers.push_back( PszAlloc( pStr ) );
}
}
}
// Get the default Server
if( LOWORD( pData[iDefaultServer].ulPropTag ) != PT_ERROR )
{
// If the default server is not already in the front, put it there...
if( pData[iDefaultServer].Value.l != 0 )
{
// Find the default server in the list
lst<LPTSTR>::iterator I = ILSServers.begin();
for( long lCur = 0; ( I != ILSServers.end() ) && ( lCur != pData[iDefaultServer].Value.l ); ++I, ++lCur )
{ ; }
ASSERT( I != ILSServers.end() );
LPTSTR pszDefault = *I;
ILSServers.erase(I);
ILSServers.push_front( pszDefault );
}
}
m_pWabObject->FreeBuffer(pData);
}
delete [] pb;
}
else
{
hr = E_OUTOFMEMORY;
}
}
else
{
hr = E_FAIL;
}
}
if( PhoneNums.size() || EmailNames.size() || ILSServers.size() )
{
// Initialize the RAI struct
int nItems = PhoneNums.size() + EmailNames.size() + ILSServers.size();
DWORD cbLen = sizeof(RAI) + sizeof(DWSTR)* nItems;
pRai = reinterpret_cast<RAI*>(new BYTE[ cbLen ]);
ZeroMemory(pRai, cbLen);
pRai->cItems = nItems;
// This is the display name...
GetSzName(pRai->szName, CCHMAX(pRai->szName), iItem);
int iCur = 0;
// First copy the e-mail names
for( lst<LPTSTR>::iterator I = EmailNames.begin(); I != EmailNames.end(); ++I, ++iCur )
{
pRai->rgDwStr[iCur].dw = NM_ADDR_ALIAS_ID;
pRai->rgDwStr[iCur].psz = PszAlloc(*I);
}
for_each( EmailNames, FreePszFunctor() );
// Copy the phone numbirs
for( I = PhoneNums.begin(); I != PhoneNums.end(); ++I, ++iCur )
{
pRai->rgDwStr[iCur].dw = g_fGkEnabled ? NM_ADDR_ALIAS_E164 : NM_ADDR_H323_GATEWAY;
pRai->rgDwStr[iCur].psz = PszAlloc(*I);
}
for_each( PhoneNums, FreePszFunctor() );
// Copy the ils servers
for( I = ILSServers.begin(); I != ILSServers.end(); ++I, ++iCur )
{
pRai->rgDwStr[iCur].dw = NM_ADDR_ULS;
pRai->rgDwStr[iCur].psz = PszAlloc(*I);
}
for_each( ILSServers, FreePszFunctor() );
}
pMapiProp->Release();
}
}
}
return pRai;
}
HRESULT CWAB::_GetLPSTRProps( lst<LPSTR>& rLst, ULONG* paPropTags, LPMAPIPROP pMapiProp, int nProps )
{
HRESULT hr = S_OK;
if( m_pWabObject )
{
BYTE* pb = new BYTE[ sizeof( SPropTagArray ) + sizeof( ULONG ) * nProps ];
if( pb )
{
// Fill in the prop tags that we are interested in...
SPropTagArray* pProps = reinterpret_cast<SPropTagArray*>(pb);
pProps->cValues = nProps;
for( UINT iCur = 0; iCur < pProps->cValues; iCur++ )
{
pProps->aulPropTag[iCur] = paPropTags[iCur];
}
LPSPropValue pData = NULL;
ULONG cValues = nProps;
// Get the props
if( SUCCEEDED( hr = pMapiProp->GetProps( pProps, 0, &cValues, &pData ) ) && pData )
{
// Extract thet props
for( ULONG iCurVal = 0; iCurVal < cValues; ++iCurVal )
{
if( LOWORD( pData[iCurVal].ulPropTag ) != PT_ERROR )
{
if( !FEmptySz(pData[iCurVal].Value.lpszA) && ( rLst.end() == find( rLst, IsEqLPTSTR(
#ifdef UNICODE
pData[iCurVal].Value.lpszW
#else
pData[iCurVal].Value.lpszA
#endif
) ) ) )
{
rLst.push_back( PszAlloc( pData[iCurVal].Value.lpszA ) );
}
}
}
m_pWabObject->FreeBuffer(pData);
}
delete [] pb;
}
else
{
hr = E_OUTOFMEMORY;
}
}
else
{
hr = E_FAIL;
}
return hr;
}
/* C R E A T E W A B E N T R Y */
/*-------------------------------------------------------------------------
%%Function: CreateWabEntry
-------------------------------------------------------------------------*/
HRESULT CreateWabEntry(LPTSTR pszDisplay, LPTSTR pszFirst, LPTSTR pszLast,
LPTSTR pszEmail, LPTSTR pszLocation, LPTSTR pszPhoneNumber, LPTSTR pszComments,
LPTSTR pszServer)
{
CWAB * pWab = CWAB::GetInstance();
if (NULL == pWab)
return E_FAIL;
HWND hwnd = GetParent(pWab->GetHwnd());
return pWab->CreateWabEntry(hwnd, pszDisplay, pszFirst, pszLast, pszEmail,
pszLocation, pszPhoneNumber, pszComments, pszServer);
}