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.
 
 
 
 
 
 

2094 lines
52 KiB

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
abobj.cpp
Abstract:
Interface to the common address book.
Environment:
Fax send wizard
Revision History:
09/02/99 -v-sashab-
Created it.
mm/dd/yy -author-
description
--*/
#include <windows.h>
#include <prsht.h>
#include <tchar.h>
#include <assert.h>
#include <mbstring.h>
#include <mapix.h>
#include "faxui.h"
#include "abobj.h"
#define PR_EMS_AB_PROXY_ADDRESSES PROP_TAG( PT_MV_TSTRING, 0x800F)
#define PR_EMS_AB_PROXY_ADDRESSES_A PROP_TAG( PT_MV_STRING8, 0x800F)
#define PR_EMS_AB_PROXY_ADDRESSES_W PROP_TAG( PT_MV_UNICODE, 0x800F)
static SizedSPropTagArray(10, sPropTagsW) =
{
10,
{
PR_ADDRTYPE_W,
PR_EMAIL_ADDRESS_W,
PR_DISPLAY_NAME_W,
PR_PRIMARY_FAX_NUMBER_W,
PR_HOME_FAX_NUMBER_W,
PR_BUSINESS_FAX_NUMBER_W,
PR_COUNTRY_W,
PR_OBJECT_TYPE,
PR_EMS_AB_PROXY_ADDRESSES_W,
PR_ENTRYID
}
};
static SizedSPropTagArray(10, sPropTagsA) =
{
10,
{
PR_ADDRTYPE_A,
PR_EMAIL_ADDRESS_A,
PR_DISPLAY_NAME_A,
PR_PRIMARY_FAX_NUMBER_A,
PR_HOME_FAX_NUMBER_A,
PR_BUSINESS_FAX_NUMBER_A,
PR_COUNTRY_A,
PR_OBJECT_TYPE,
PR_EMS_AB_PROXY_ADDRESSES_A,
PR_ENTRYID
}
};
HINSTANCE CCommonAbObj::m_hInstance = NULL;
/*
Comparison operator 'less'
Compare two PRECIPIENT by recipient's name and fax number
*/
bool
CRecipCmp::operator()(
const PRECIPIENT pcRecipient1,
const PRECIPIENT pcRecipient2) const
{
bool bRes = false;
int nFaxNumberCpm = 0;
if(!pcRecipient1 ||
!pcRecipient2 ||
!pcRecipient1->pAddress ||
!pcRecipient2->pAddress)
{
assert(false);
return bRes;
}
nFaxNumberCpm = _tcscmp(pcRecipient1->pAddress, pcRecipient2->pAddress);
if(nFaxNumberCpm < 0)
{
bRes = true;
}
else if(nFaxNumberCpm == 0)
{
//
// The fax numbers are same
// lets compare the names
//
if(pcRecipient1->pName && pcRecipient2->pName)
{
bRes = (_tcsicmp(pcRecipient1->pName, pcRecipient2->pName) < 0);
}
else
{
bRes = (pcRecipient1->pName < pcRecipient2->pName);
}
}
return bRes;
} // CRecipCmp::operator()
CCommonAbObj::CCommonAbObj(HINSTANCE hInstance) :
m_lpAdrBook(NULL),
m_lpMailUser(NULL),
m_bUnicode(FALSE)
/*++
Routine Description:
Constructor for CCommonAbObj class
Arguments:
hInstance - Instance handle
Return Value:
NONE
--*/
{
m_hInstance = hInstance;
} // CCommonAbObj::CCommonAbObj()
CCommonAbObj::~CCommonAbObj()
/*++
Routine Description:
Destructor for CCommonAbObj class
Arguments:
NONE
Return Value:
NONE
--*/
{
}
BOOL
CCommonAbObj::Address(
HWND hWnd,
PRECIPIENT pOldRecipList,
PRECIPIENT* ppNewRecipList
)
/*++
Routine Description:
Bring up the address book UI. Prepopulate the to box with the entries in
pRecipient. Return the modified entries in ppNewRecip.
Arguments:
hWnd - window handle to parent window
pOldRecipList - list of recipients to look up
ppNewRecipList - list of new/modified recipients
Return Value:
TRUE if all recipients had a fax number.
FALSE if one or more of them didn't.
--*/
{
ADRPARM AdrParms = { 0 };
HRESULT hr;
DWORD i;
DWORD nRecips;
PRECIPIENT tmpRecipient;
ULONG DestComps[1] = { MAPI_TO };
DWORD cDropped = 0;
DWORD dwRes = ERROR_SUCCESS;
TCHAR tszCaption[MAX_PATH] = {0};
nRecips = 0;
tmpRecipient = pOldRecipList;
m_hWnd = hWnd;
//
// count recipients and set up initial address list
//
while (tmpRecipient)
{
nRecips++;
tmpRecipient = (PRECIPIENT) tmpRecipient->pNext;
}
//
// Allocate address list
//
m_lpAdrList = NULL;
if (nRecips > 0)
{
hr = ABAllocateBuffer( CbNewADRLIST( nRecips ), (LPVOID *) &m_lpAdrList );
if(!m_lpAdrList)
{
goto exit;
}
ZeroMemory(m_lpAdrList, CbNewADRLIST( nRecips ));
m_lpAdrList->cEntries = nRecips;
}
//
// Allocate SPropValue arrays for each address entry
//
for (i = 0, tmpRecipient = pOldRecipList; i < nRecips; i++, tmpRecipient = tmpRecipient->pNext)
{
if(!GetRecipientProps(tmpRecipient,
&(m_lpAdrList->aEntries[i].rgPropVals),
&(m_lpAdrList->aEntries[i].cValues)))
{
goto error;
}
} // for
if(GetAddrBookCaption(tszCaption, ARR_SIZE(tszCaption)))
{
AdrParms.lpszCaption = tszCaption;
}
AdrParms.cDestFields = 1;
AdrParms.ulFlags = StrCoding() | DIALOG_MODAL | AB_RESOLVE;
AdrParms.nDestFieldFocus = 0;
AdrParms.lpulDestComps = DestComps;
//
// Bring up the address book UI
//
hr = m_lpAdrBook->Address((ULONG_PTR*)&hWnd,
&AdrParms,
&m_lpAdrList);
//
// IAddrBook::Address returns always S_OK (according to MSDN, July 1999), but ...
//
if (FAILED (hr) || !m_lpAdrList || m_lpAdrList->cEntries == 0)
{
//
// in this case the user pressed cancel, so we skip resolving
// any of our addresses that aren't listed in the AB
//
goto exit;
}
exit:
if (m_lpAdrList)
{
m_lpMailUser = NULL;
try
{
m_setRecipients.clear();
}
catch (std::bad_alloc&)
{
goto error;
}
for (i = cDropped = 0; i < m_lpAdrList->cEntries; i++)
{
LPADRENTRY lpAdrEntry = &m_lpAdrList->aEntries[i];
dwRes = InterpretAddress(lpAdrEntry->rgPropVals,
lpAdrEntry->cValues,
ppNewRecipList,
pOldRecipList);
if(ERROR_SUCCESS == dwRes)
{
continue;
}
else if(ERROR_INVALID_DATA == dwRes)
{
++cDropped;
}
else
{
break;
}
} // for
error:
if(m_lpMailUser)
{
m_lpMailUser->Release();
m_lpMailUser = NULL;
}
//
// Clean up
//
for (ULONG iEntry = 0; iEntry < m_lpAdrList->cEntries; ++iEntry)
{
if(m_lpAdrList->aEntries[iEntry].rgPropVals)
{
ABFreeBuffer(m_lpAdrList->aEntries[iEntry].rgPropVals);
}
}
ABFreeBuffer(m_lpAdrList);
m_lpAdrList = NULL;
} // if (m_lpAdrList)
m_hWnd = NULL;
return cDropped == 0;
} // CCommonAbObj::Address
BOOL
CCommonAbObj::GetRecipientProps(
PRECIPIENT pRecipient,
LPSPropValue* pMapiProps,
DWORD* pdwPropsNum
)
/*++
Routine Description:
Allocate SPropValue array and fill it with recipient info
According to MSDN "Managing Memory for ADRLIST and SRowSet Structures"
Arguments:
pRecipient - [in] recipient info struct
pMapiProps - [out] allocated SPropValue array
pdwPropsNum - [out] SPropValue array size
Return Value:
TRUE if success
FALSE otherwize
--*/
{
BOOL bRes = FALSE;
if(!pRecipient || !pMapiProps || !pdwPropsNum)
{
return FALSE;
}
HRESULT hr;
LPTSTR pName = NULL;
DWORD dwNameSize=0; // size of pName
LPTSTR pAddress = NULL;
DWORD dwAddressSize=0; // size of pAddress
LPENTRYID lpEntryId = NULL;
ULONG cbEntryId = 0; // size of lpEntryId
UINT ucPropertiesNum = pRecipient->bFromAddressBook ? 5 : 4;
enum FaxMapiProp { FXS_DISPLAY_NAME,
FXS_RECIPIENT_TYPE,
FXS_PRIMARY_FAX_NUMBER,
FXS_ENTRYID,
FXS_OBJECT_TYPE
};
//
// Convert strings to the address book encoding
//
if(pRecipient->pAddress)
{
pAddress = StrToAddrBk(pRecipient->pAddress, &dwAddressSize);
if(!pAddress)
{
goto exit;
}
}
if(pRecipient->pName)
{
pName = StrToAddrBk(pRecipient->pName, &dwNameSize);
if(!pName)
{
goto exit;
}
}
//
// Get entry ID
//
if (pRecipient->bFromAddressBook)
{
assert(pRecipient->lpEntryId);
lpEntryId = (LPENTRYID)pRecipient->lpEntryId;
cbEntryId = pRecipient->cbEntryId;
}
else
{
LPTSTR pAddrType = NULL;
if(!(pAddrType = StrToAddrBk(TEXT("FAX"))))
{
goto exit;
}
hr = m_lpAdrBook->CreateOneOff(pName,
pAddrType,
pAddress,
StrCoding(),
&cbEntryId,
&lpEntryId);
if (FAILED(hr))
{
goto exit;
}
MemFree(pAddrType);
}
//
// Allocate MAPI prop array
//
LPSPropValue mapiProps = NULL;
DWORD dwPropArrSize = sizeof( SPropValue ) * ucPropertiesNum;
DWORD dwPropSize = dwPropArrSize + dwAddressSize + dwNameSize + cbEntryId;
hr = ABAllocateBuffer( dwPropSize, (LPVOID *) &mapiProps );
if(!mapiProps)
{
goto exit;
}
ZeroMemory(mapiProps, dwPropSize);
//
// Set memory pointer to the end of the SPropValue prop array
//
LPBYTE pMem = (LPBYTE)mapiProps;
pMem += dwPropArrSize;
//
// Copy fax number
//
if(dwAddressSize)
{
CopyMemory(pMem, pAddress, dwAddressSize);
if(m_bUnicode)
{
mapiProps[FXS_PRIMARY_FAX_NUMBER].Value.lpszW = (LPWSTR)pMem;
}
else
{
mapiProps[FXS_PRIMARY_FAX_NUMBER].Value.lpszA = (LPSTR)pMem;
}
pMem += dwAddressSize;
}
mapiProps[FXS_PRIMARY_FAX_NUMBER].ulPropTag = m_bUnicode ? PR_PRIMARY_FAX_NUMBER_W : PR_PRIMARY_FAX_NUMBER_A;
//
// Copy display name
//
if(dwNameSize)
{
CopyMemory(pMem, pName, dwNameSize);
if(m_bUnicode)
{
mapiProps[FXS_DISPLAY_NAME].Value.lpszW = (LPWSTR)pMem;
}
else
{
mapiProps[FXS_DISPLAY_NAME].Value.lpszA = (LPSTR)pMem;
}
pMem += dwNameSize;
}
mapiProps[FXS_DISPLAY_NAME].ulPropTag = m_bUnicode ? PR_DISPLAY_NAME_W : PR_DISPLAY_NAME_A;
//
// Copy entry ID
//
if(cbEntryId)
{
CopyMemory(pMem, lpEntryId, cbEntryId);
mapiProps[FXS_ENTRYID].Value.bin.lpb = (LPBYTE)pMem;
}
mapiProps[FXS_ENTRYID].ulPropTag = PR_ENTRYID;
mapiProps[FXS_ENTRYID].Value.bin.cb = cbEntryId;
//
// Recipient type
//
mapiProps[FXS_RECIPIENT_TYPE].ulPropTag = PR_RECIPIENT_TYPE;
mapiProps[FXS_RECIPIENT_TYPE].Value.l = MAPI_TO;
//
// Object type
//
if (pRecipient->bFromAddressBook)
{
mapiProps[FXS_OBJECT_TYPE].ulPropTag = PR_OBJECT_TYPE;
mapiProps[FXS_OBJECT_TYPE].Value.l = MAPI_MAILUSER;
}
*pdwPropsNum = ucPropertiesNum;
*pMapiProps = mapiProps;
bRes = TRUE;
exit:
MemFree(pName);
MemFree(pAddress);
if (!pRecipient->bFromAddressBook && lpEntryId)
{
ABFreeBuffer(lpEntryId);
}
return bRes;
} // CCommonAbObj::GetRecipientProps
LPTSTR
CCommonAbObj::AddressEmail(
HWND hWnd
)
/*++
Routine Description:
Bring up the address book UI. Returns an E-mail address.
Arguments:
hWnd - window handle to parent window
Return Value:
A choosen E-mail address.
NULL otherwise.
--*/
{
ADRPARM AdrParms = { 0 };
HRESULT hr;
LPTSTR lptstrEmailAddress = NULL;
TCHAR tszCaption[MAX_PATH] = {0};
m_hWnd = hWnd;
m_lpAdrList = NULL;
AdrParms.ulFlags = StrCoding() | DIALOG_MODAL | ADDRESS_ONE | AB_RESOLVE ;
if(GetAddrBookCaption(tszCaption, ARR_SIZE(tszCaption)))
{
AdrParms.lpszCaption = tszCaption;
}
//
// Bring up the address book UI
//
hr = m_lpAdrBook->Address((ULONG_PTR *) &hWnd, &AdrParms, &m_lpAdrList);
//
// IAddrBook::Address returns always S_OK (according to MSDN, July 1999), but ...
//
if (FAILED(hr))
{
return NULL;
}
if (!m_lpAdrList)
{
assert(m_lpAdrList->cEntries==1);
}
if (m_lpAdrList && (m_lpAdrList->cEntries != 0) )
{
LPADRENTRY lpAdrEntry = &m_lpAdrList->aEntries[0];
lptstrEmailAddress = InterpretEmailAddress( lpAdrEntry->rgPropVals, lpAdrEntry->cValues);
ABFreeBuffer(m_lpAdrList->aEntries[0].rgPropVals);
ABFreeBuffer(m_lpAdrList);
m_lpAdrList = NULL;
}
m_hWnd = NULL;
return lptstrEmailAddress;
} // CCommonAbObj::AddressEmail
DWORD
CCommonAbObj::InterpretAddress(
LPSPropValue SPropVal,
ULONG cValues,
PRECIPIENT *ppNewRecipList,
PRECIPIENT pOldRecipList
)
/*++
Routine Description:
Interpret the address book entry represented by SPropVal.
Arguments:
SPropVal - Property values for address book entry.
cValues - number of property values
ppNewRecip - new recipient list
Return Value:
ERROR_SUCCESS - if all of the entries have a fax number.
ERROR_CANCELLED - the operation was canceled by user
ERROR_INVALID_DATA - otherwise.
--*/
{
DWORD dwRes = ERROR_INVALID_DATA;
LPSPropValue lpSPropVal;
RECIPIENT NewRecipient = {0};
//
// get the object type
//
lpSPropVal = FindProp( SPropVal, cValues, PR_OBJECT_TYPE );
if (lpSPropVal)
{
//
// If the object is a mail user, get the fax numbers and add the recipient
// to the list. If the object is a distribtion list, process it.
//
switch (lpSPropVal->Value.l)
{
case MAPI_MAILUSER:
dwRes = GetRecipientInfo(SPropVal,
cValues,
&NewRecipient,
pOldRecipList);
if(ERROR_SUCCESS == dwRes)
{
dwRes = AddRecipient(ppNewRecipList,
&NewRecipient,
TRUE);
}
break;
case MAPI_DISTLIST:
dwRes = InterpretDistList( SPropVal,
cValues,
ppNewRecipList,
pOldRecipList);
}
return dwRes;
}
else
{
//
// If there is no object type then this is valid entry that we queried on that went unresolved.
// We know that there is a fax number so add it.
//
if(GetOneOffRecipientInfo( SPropVal,
cValues,
&NewRecipient,
pOldRecipList))
{
dwRes = AddRecipient(ppNewRecipList,
&NewRecipient,
FALSE);
}
}
return dwRes;
} // CCommonAbObj::InterpretAddress
LPTSTR
CCommonAbObj::InterpretEmailAddress(
LPSPropValue SPropVal,
ULONG cValues
)
/*++
Routine Description:
Interpret the address book entry represented by SPropVal.
Arguments:
SPropVal - Property values for address book entry.
cValues - number of property values
Return Value:
A choosen E-mail address
NULL otherwise.
--*/
{
LPSPropValue lpSPropVal;
LPTSTR lptstrEmailAddress = NULL;
BOOL rVal = FALSE;
TCHAR tszBuffer[MAX_STRING_LEN];
//
// get the object type
//
lpSPropVal = FindProp( SPropVal, cValues, PR_OBJECT_TYPE );
if(!lpSPropVal)
{
assert(FALSE);
return NULL;
}
if (lpSPropVal->Value.l == MAPI_MAILUSER)
{
lptstrEmailAddress = GetEmail( SPropVal, cValues);
return lptstrEmailAddress;
}
else
{
if (!::LoadString((HINSTANCE )m_hInstance, IDS_ERROR_RECEIPT_DL,tszBuffer, MAX_STRING_LEN))
{
assert(FALSE);
}
else
{
AlignedMessageBox( m_hWnd, tszBuffer, NULL, MB_ICONSTOP | MB_OK);
}
}
return lptstrEmailAddress;
} // CCommonAbObj::InterpretEmailAddress
DWORD
CCommonAbObj::InterpretDistList(
LPSPropValue SPropVal,
ULONG cValues,
PRECIPIENT* ppNewRecipList,
PRECIPIENT pOldRecipList
)
/*++
Routine Description:
Process a distribution list.
Arguments:
SPropVal - Property values for distribution list.
cValues - Number of properties.
ppNewRecipList - New recipient list.
pOldRecipList - Old recipient list.
Return Value:
ERROR_SUCCESS - if all of the entries have a fax number.
ERROR_CANCELLED - the operation was canceled by user
ERROR_INVALID_DATA - otherwise.
--*/
#define EXIT_IF_FAILED(hr) { if (FAILED(hr)) goto ExitDistList; }
{
LPSPropValue lpPropVals;
LPSRowSet pRows = NULL;
LPDISTLIST lpMailDistList = NULL;
LPMAPITABLE pMapiTable = NULL;
ULONG ulObjType, cRows;
HRESULT hr;
DWORD dwEntriesSuccessfullyProcessed = 0;
DWORD dwRes = ERROR_INVALID_DATA;
lpPropVals = FindProp( SPropVal, cValues, PR_ENTRYID );
if (lpPropVals)
{
LPENTRYID lpEntryId = (LPENTRYID) lpPropVals->Value.bin.lpb;
DWORD cbEntryId = lpPropVals->Value.bin.cb;
//
// Open the recipient entry
//
hr = m_lpAdrBook->OpenEntry(
cbEntryId,
lpEntryId,
(LPCIID) NULL,
0,
&ulObjType,
(LPUNKNOWN *) &lpMailDistList
);
EXIT_IF_FAILED(hr);
//
// Get the contents table of the address entry
//
hr = lpMailDistList->GetContentsTable(StrCoding(),
&pMapiTable);
EXIT_IF_FAILED(hr);
//
// Limit the query to only the properties we're interested in
//
hr = pMapiTable->SetColumns(m_bUnicode ? (LPSPropTagArray)&sPropTagsW : (LPSPropTagArray)&sPropTagsA, 0);
EXIT_IF_FAILED(hr);
//
// Get the total number of rows
//
hr = pMapiTable->GetRowCount(0, &cRows);
EXIT_IF_FAILED(hr);
//
// Get the individual entries of the distribution list
//
hr = pMapiTable->SeekRow(BOOKMARK_BEGINNING, 0, NULL);
EXIT_IF_FAILED(hr);
hr = pMapiTable->QueryRows(cRows, 0, &pRows);
EXIT_IF_FAILED(hr);
hr = S_OK;
if (pRows && pRows->cRows)
{
//
// Handle each entry of the distribution list in turn:
// for simple entries, call InterpretAddress
// for embedded distribution list, call this function recursively
//
for (cRows = 0; cRows < pRows->cRows; cRows++)
{
LPSPropValue lpProps = pRows->aRow[cRows].lpProps;
ULONG cRowValues = pRows->aRow[cRows].cValues;
lpPropVals = FindProp( lpProps, cRowValues, PR_OBJECT_TYPE );
if (lpPropVals)
{
switch (lpPropVals->Value.l)
{
case MAPI_MAILUSER:
{
dwRes = InterpretAddress( lpProps,
cRowValues,
ppNewRecipList,
pOldRecipList);
if (ERROR_SUCCESS == dwRes)
{
dwEntriesSuccessfullyProcessed++;
}
break;
}
case MAPI_DISTLIST:
{
dwRes = InterpretDistList( lpProps,
cRowValues,
ppNewRecipList,
pOldRecipList);
if (ERROR_SUCCESS == dwRes)
{
dwEntriesSuccessfullyProcessed++;
}
break;
}
} // End of switch
} // End of property
} // End of properties loop
} // End of row
} // End of values
ExitDistList:
//
// Perform necessary clean up before returning to caller
//
if (pRows)
{
for (cRows = 0; cRows < pRows->cRows; cRows++)
{
ABFreeBuffer(pRows->aRow[cRows].lpProps);
}
ABFreeBuffer(pRows);
}
if (pMapiTable)
{
pMapiTable->Release();
}
if (lpMailDistList)
{
lpMailDistList->Release();
}
//
// We only care if we successfully processed at least one object.
// Return ERROR_SUCCESS if we did.
//
return dwEntriesSuccessfullyProcessed ? ERROR_SUCCESS : dwRes;
} // CCommonAbObj::InterpretDistList
INT_PTR
CALLBACK
ChooseFaxNumberDlgProc(
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
/*++
Routine Description:
Dialog proc for choose fax number dialog.
Arguments:
lParam - pointer to PickFax structure.
Return Value:
Control id of selection.
--*/
{
PPICKFAX pPickFax = (PPICKFAX) lParam;
switch (uMsg)
{
case WM_INITDIALOG:
{
TCHAR szTitle[MAX_PATH] = {0};
TCHAR szFormat[MAX_PATH] = {0};
if(LoadString(CCommonAbObj::m_hInstance,
IDS_CHOOSE_FAX_NUMBER,
szFormat,
MAX_PATH-1))
{
_sntprintf(szTitle, MAX_PATH-1, szFormat, pPickFax->DisplayName);
SetDlgItemText(hDlg, IDC_DISPLAY_NAME, szTitle);
}
else
{
assert(FALSE);
}
if(pPickFax->BusinessFax)
{
SetDlgItemText(hDlg, IDC_BUSINESS_FAX_NUM, pPickFax->BusinessFax);
CheckDlgButton(hDlg, IDC_BUSINESS_FAX, BST_CHECKED);
}
else
{
EnableWindow(GetDlgItem(hDlg, IDC_BUSINESS_FAX), FALSE);
}
if(pPickFax->HomeFax)
{
SetDlgItemText(hDlg, IDC_HOME_FAX_NUM, pPickFax->HomeFax);
if(!pPickFax->BusinessFax)
{
CheckDlgButton(hDlg, IDC_HOME_FAX, BST_CHECKED);
}
}
else
{
EnableWindow(GetDlgItem(hDlg, IDC_HOME_FAX), FALSE);
}
if(pPickFax->OtherFax)
{
SetDlgItemText(hDlg, IDC_OTHER_FAX_NUM, pPickFax->OtherFax);
}
else
{
EnableWindow(GetDlgItem(hDlg, IDC_OTHER_FAX), FALSE);
}
return TRUE;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDOK:
DWORD dwRes;
if(IsDlgButtonChecked( hDlg, IDC_BUSINESS_FAX ))
{
dwRes = IDC_BUSINESS_FAX;
}
else if(IsDlgButtonChecked( hDlg, IDC_HOME_FAX ))
{
dwRes = IDC_HOME_FAX;
}
else
{
dwRes = IDC_OTHER_FAX;
}
EndDialog( hDlg, dwRes);
return TRUE;
case IDCANCEL:
EndDialog( hDlg, IDCANCEL);
return TRUE;
}
}
default:
return FALSE;
}
return FALSE;
} // ChooseFaxNumberDlgProc
PRECIPIENT
CCommonAbObj::FindRecipient(
PRECIPIENT pRecipient,
PRECIPIENT pRecipList
)
/*++
Routine Description:
Find recipient (pRecipient) in the recipient list (pRecipList)
by recipient name and fax number
Arguments:
pRecipList - pointer to recipient list
pRecipient - pointer to recipient data
Return Value:
pointer to RECIPIENT structure if found
NULL - otherwise.
--*/
{
if(!pRecipient || !pRecipList || !pRecipient->pName || !pRecipient->pAddress)
{
return NULL;
}
while(pRecipList)
{
if(pRecipList->pName && pRecipList->pAddress &&
!_tcscmp(pRecipList->pName, pRecipient->pName) &&
!_tcscmp(pRecipList->pAddress, pRecipient->pAddress))
{
return pRecipList;
}
pRecipList = pRecipList->pNext;
}
return NULL;
} // CCommonAbObj::FindRecipient
PRECIPIENT
CCommonAbObj::FindRecipient(
PRECIPIENT pRecipList,
PICKFAX* pPickFax
)
/*++
Routine Description:
Find recipient (pPickFax) in the recipient list (pRecipList)
by recipient name and fax number
Arguments:
pRecipList - pointer to recipient list
pPickFax - pointer to recipient data
Return Value:
pointer to RECIPIENT structure if found
NULL - otherwise.
--*/
{
if(!pRecipList || !pPickFax || !pPickFax->DisplayName)
{
return NULL;
}
while(pRecipList)
{
if(pRecipList->pName && pRecipList->pAddress &&
!_tcscmp(pRecipList->pName, pPickFax->DisplayName))
{
if((pPickFax->BusinessFax &&
!_tcscmp(pRecipList->pAddress, pPickFax->BusinessFax)) ||
(pPickFax->HomeFax &&
!_tcscmp(pRecipList->pAddress, pPickFax->HomeFax)) ||
(pPickFax->OtherFax &&
!_tcscmp(pRecipList->pAddress, pPickFax->OtherFax)))
{
return pRecipList;
}
}
pRecipList = pRecipList->pNext;
}
return NULL;
} // CCommonAbObj::FindRecipient
BOOL
CCommonAbObj::StrPropOk(LPSPropValue lpPropVals)
{
if(!lpPropVals)
{
return FALSE;
}
#ifdef UNIOCODE
if(!m_bUnicode)
{
return (lpPropVals->Value.lpszA && *lpPropVals->Value.lpszA);
}
#endif
return (lpPropVals->Value.LPSZ && *lpPropVals->Value.LPSZ);
} // CCommonAbObj::StrPropOk
DWORD
CCommonAbObj::GetRecipientInfo(
LPSPropValue SPropVals,
ULONG cValues,
PRECIPIENT pNewRecip,
PRECIPIENT pOldRecipList
)
/*++
Routine Description:
Get the fax number and display name properties.
Arguments:
SPropVal - Property values for distribution list.
cValues - Number of properties.
pNewRecip - [out] pointer to the new recipient
pOldRecipList - [in] pointer to the old recipient list
Return Value:
ERROR_SUCCESS - if there is a fax number and display name.
ERROR_CANCELLED - the operation was canceled by user
ERROR_INVALID_DATA - otherwise.
--*/
{
DWORD dwRes = ERROR_SUCCESS;
LPSPropValue lpPropVals;
LPSPropValue lpPropArray;
BOOL Result = FALSE;
PICKFAX PickFax = { 0 };
DWORD dwFaxes = 0;
assert(pNewRecip);
ZeroMemory(pNewRecip, sizeof(RECIPIENT));
//
// Get the entryid and open the entry.
//
lpPropVals = FindProp( SPropVals, cValues, PR_ENTRYID );
if (lpPropVals)
{
ULONG lpulObjType;
LPMAILUSER lpMailUser = NULL;
HRESULT hr;
ULONG countValues;
pNewRecip->cbEntryId = lpPropVals->Value.bin.cb;
ABAllocateBuffer(pNewRecip->cbEntryId, (LPVOID *)&pNewRecip->lpEntryId);
if(!pNewRecip->lpEntryId)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
else
{
memcpy(pNewRecip->lpEntryId, lpPropVals->Value.bin.lpb, pNewRecip->cbEntryId);
}
hr = m_lpAdrBook->OpenEntry(pNewRecip->cbEntryId,
(ENTRYID*)pNewRecip->lpEntryId,
(LPCIID) NULL,
0,
&lpulObjType,
(LPUNKNOWN *) &lpMailUser);
if (HR_SUCCEEDED(hr))
{
//
// Get the properties.
//
hr = ((IMailUser *)lpMailUser)->GetProps(m_bUnicode ? (LPSPropTagArray)&sPropTagsW : (LPSPropTagArray)&sPropTagsA,
StrCoding(),
&countValues,
&lpPropArray );
if (HR_SUCCEEDED(hr))
{
lpPropVals = FindProp(lpPropArray, countValues, PR_PRIMARY_FAX_NUMBER);
if (StrPropOk( lpPropVals ))
{
PickFax.OtherFax = StrFromAddrBk(lpPropVals);
if(PickFax.OtherFax && _tcslen(PickFax.OtherFax))
{
++dwFaxes;
}
}
lpPropVals = FindProp(lpPropArray, countValues, PR_BUSINESS_FAX_NUMBER);
if (StrPropOk( lpPropVals ))
{
PickFax.BusinessFax = StrFromAddrBk(lpPropVals);
if(PickFax.BusinessFax && _tcslen(PickFax.BusinessFax))
{
++dwFaxes;
}
}
lpPropVals = FindProp(lpPropArray, countValues, PR_HOME_FAX_NUMBER);
if (StrPropOk( lpPropVals ))
{
PickFax.HomeFax = StrFromAddrBk(lpPropVals);
if(PickFax.HomeFax && _tcslen(PickFax.HomeFax))
{
++dwFaxes;
}
}
lpPropVals = FindProp(lpPropArray, countValues, PR_DISPLAY_NAME);
if (StrPropOk( lpPropVals ))
{
pNewRecip->pName = PickFax.DisplayName = StrFromAddrBk(lpPropVals);
}
lpPropVals = FindProp(lpPropArray, countValues, PR_COUNTRY);
if (StrPropOk( lpPropVals ))
{
pNewRecip->pCountry = PickFax.Country = StrFromAddrBk(lpPropVals);
}
if (0 == dwFaxes)
{
lpPropVals = FindProp(lpPropArray, countValues, PR_ADDRTYPE);
if(lpPropVals && ABStrCmp(lpPropVals, TEXT("FAX")))
{
lpPropVals = FindProp(lpPropArray, countValues, PR_EMAIL_ADDRESS);
if (StrPropOk( lpPropVals ))
{
pNewRecip->pAddress = StrFromAddrBk(lpPropVals);
if(pNewRecip->pAddress)
{
++dwFaxes;
}
}
}
}
PRECIPIENT pRecip = FindRecipient(pOldRecipList, &PickFax);
if(pRecip)
{
pNewRecip->pAddress = StringDup(pRecip->pAddress);
pNewRecip->dwCountryId = pRecip->dwCountryId;
pNewRecip->bUseDialingRules = pRecip->bUseDialingRules;
MemFree(PickFax.BusinessFax);
PickFax.BusinessFax = NULL;
MemFree(PickFax.HomeFax);
PickFax.HomeFax = NULL;
MemFree(PickFax.OtherFax);
PickFax.OtherFax = NULL;
dwFaxes = 1;
}
//
// If there are more then 1 fax numbers, ask the user to pick one.
//
if (dwFaxes > 1)
{
INT_PTR nResult;
nResult = DialogBoxParam((HINSTANCE) m_hInstance,
MAKEINTRESOURCE( IDD_CHOOSE_FAXNUMBER ),
m_hWnd,
ChooseFaxNumberDlgProc,
(LPARAM) &PickFax);
switch( nResult )
{
case IDC_BUSINESS_FAX:
pNewRecip->pAddress = PickFax.BusinessFax;
MemFree(PickFax.HomeFax);
PickFax.HomeFax = NULL;
MemFree(PickFax.OtherFax);
PickFax.OtherFax = NULL;
break;
case IDC_HOME_FAX:
pNewRecip->pAddress = PickFax.HomeFax;
MemFree(PickFax.BusinessFax);
PickFax.BusinessFax = NULL;
MemFree(PickFax.OtherFax);
PickFax.OtherFax = NULL;
break;
case IDC_OTHER_FAX:
pNewRecip->pAddress = PickFax.OtherFax;
MemFree(PickFax.BusinessFax);
PickFax.BusinessFax = NULL;
MemFree(PickFax.HomeFax);
PickFax.HomeFax = NULL;
break;
case IDCANCEL:
MemFree(PickFax.BusinessFax);
PickFax.BusinessFax = NULL;
MemFree(PickFax.HomeFax);
PickFax.HomeFax = NULL;
MemFree(PickFax.OtherFax);
PickFax.OtherFax = NULL;
dwRes = ERROR_CANCELLED;
break;
}
}
}
ABFreeBuffer( lpPropArray );
}
if(!m_lpMailUser)
{
//
// Remember the first MailUser and do not release it
// to avoid release of the MAPI DLLs
// m_lpMailUser should be released later
//
m_lpMailUser = lpMailUser;
}
else if(lpMailUser)
{
lpMailUser->Release();
lpMailUser = NULL;
}
}
if (0 == dwFaxes)
{
lpPropVals = FindProp(SPropVals, cValues, PR_ADDRTYPE);
if(lpPropVals && ABStrCmp(lpPropVals, TEXT("FAX")))
{
lpPropVals = FindProp(SPropVals, cValues, PR_EMAIL_ADDRESS);
if (StrPropOk( lpPropVals ))
{
TCHAR* pAddress = StrFromAddrBk(lpPropVals);
if(pAddress)
{
TCHAR* ptr = _tcschr(pAddress, TEXT('@'));
if(ptr)
{
ptr = _tcsinc(ptr);
pNewRecip->pAddress = StringDup(ptr);
MemFree(pAddress);
}
else
{
pNewRecip->pAddress = pAddress;
}
}
}
lpPropVals = FindProp(SPropVals, cValues, PR_DISPLAY_NAME);
if (StrPropOk( lpPropVals ))
{
MemFree(pNewRecip->pName);
pNewRecip->pName = NULL;
pNewRecip->pName = StrFromAddrBk(lpPropVals);
}
}
}
if (PickFax.BusinessFax)
{
pNewRecip->pAddress = PickFax.BusinessFax;
}
else if (PickFax.HomeFax)
{
pNewRecip->pAddress = PickFax.HomeFax;
}
else if (PickFax.OtherFax)
{
pNewRecip->pAddress = PickFax.OtherFax;
}
if (ERROR_CANCELLED != dwRes &&
(!pNewRecip->pAddress || !pNewRecip->pName))
{
dwRes = ERROR_INVALID_DATA;
}
if(ERROR_SUCCESS != dwRes)
{
MemFree(pNewRecip->pName);
MemFree(pNewRecip->pAddress);
MemFree(pNewRecip->pCountry);
ABFreeBuffer(pNewRecip->lpEntryId);
ZeroMemory(pNewRecip, sizeof(RECIPIENT));
}
return dwRes;
} // CCommonAbObj::GetRecipientInfo
BOOL
CCommonAbObj::GetOneOffRecipientInfo(
LPSPropValue SPropVals,
ULONG cValues,
PRECIPIENT pNewRecip,
PRECIPIENT pOldRecipList
)
/*++
Routine Description:
Get the fax number and display name properties.
Arguments:
SPropVal - Property values for distribution list.
cValues - Number of properties.
pNewRecip - [out] pointer to a new recipient
pOldRecipList - pointer to the old recipient list
Return Value:
TRUE if there is a fax number and display name.
FALSE otherwise.
--*/
{
PRECIPIENT pRecip = NULL;
LPSPropValue lpPropVals;
assert(!pNewRecip);
lpPropVals = FindProp(SPropVals, cValues, PR_PRIMARY_FAX_NUMBER);
if (lpPropVals)
{
if (!(pNewRecip->pAddress = StrFromAddrBk(lpPropVals)))
{
goto error;
}
}
lpPropVals = FindProp(SPropVals, cValues, PR_DISPLAY_NAME);
if (lpPropVals)
{
if (!(pNewRecip->pName = StrFromAddrBk(lpPropVals)))
{
goto error;
}
}
pRecip = FindRecipient(pNewRecip, pOldRecipList);
if(pRecip)
{
pNewRecip->dwCountryId = pRecip->dwCountryId;
pNewRecip->bUseDialingRules = pRecip->bUseDialingRules;
}
return TRUE;
error:
MemFree(pNewRecip->pAddress);
MemFree(pNewRecip->pName);
return FALSE;
} // CCommonAbObj::GetOneOffRecipientInfo
LPTSTR
CCommonAbObj::GetEmail(
LPSPropValue SPropVals,
ULONG cValues
)
/*++
Routine Description:
Get e-mail address
Arguments:
SPropVal - Property values for distribution list.
cValues - Number of properties.
Return Value:
A choosen E-mail address
NULL otherwise.
--*/
{
LPSPropValue lpPropVals = NULL;
LPSPropValue lpPropArray = NULL;
BOOL Result = FALSE;
LPTSTR lptstrEmailAddress = NULL;
TCHAR tszBuffer[MAX_STRING_LEN];
ULONG lpulObjType = 0;
LPMAILUSER lpMailUser = NULL;
LPENTRYID lpEntryId = NULL;
DWORD cbEntryId = 0;
HRESULT hr;
ULONG countValues = 0;
//
// Get the entryid and open the entry.
//
lpPropVals = FindProp( SPropVals, cValues, PR_ENTRYID );
if (!lpPropVals)
{
goto exit;
}
lpEntryId = (LPENTRYID)lpPropVals->Value.bin.lpb;
cbEntryId = lpPropVals->Value.bin.cb;
hr = m_lpAdrBook->OpenEntry(cbEntryId,
lpEntryId,
(LPCIID) NULL,
0,
&lpulObjType,
(LPUNKNOWN *) &lpMailUser);
if (HR_FAILED(hr))
{
goto exit;
}
//
// Get the properties.
//
hr = ((IMailUser*)lpMailUser)->GetProps(m_bUnicode ? (LPSPropTagArray)&sPropTagsW : (LPSPropTagArray)&sPropTagsA,
StrCoding(),
&countValues,
&lpPropArray);
if (HR_FAILED(hr))
{
goto exit;
}
lpPropVals = FindProp(lpPropArray, countValues, PR_ADDRTYPE);
if (lpPropVals && ABStrCmp(lpPropVals, TEXT("SMTP")))
{
lpPropVals = FindProp(lpPropArray, countValues, PR_EMAIL_ADDRESS);
if (StrPropOk( lpPropVals ))
{
lptstrEmailAddress = StrFromAddrBk(lpPropVals);
}
}
else if (lpPropVals && ABStrCmp(lpPropVals, TEXT("EX")))
{
lpPropVals = FindProp(lpPropArray, countValues, PR_EMS_AB_PROXY_ADDRESSES);
if (lpPropVals)
{
DWORD dwArrSize = m_bUnicode ? lpPropVals->Value.MVszW.cValues : lpPropVals->Value.MVszA.cValues;
for(DWORD dw=0; dw < dwArrSize; ++dw)
{
if(m_bUnicode)
{
if(wcsstr(lpPropVals->Value.MVszW.lppszW[dw], L"SMTP:"))
{
WCHAR* ptr = wcschr(lpPropVals->Value.MVszW.lppszW[dw], L':');
ptr++;
SPropValue propVal = {0};
propVal.Value.lpszW = ptr;
lptstrEmailAddress = StrFromAddrBk(&propVal);
break;
}
}
else // ANSII
{
if(strstr(lpPropVals->Value.MVszA.lppszA[dw], "SMTP:"))
{
CHAR* ptr = strchr(lpPropVals->Value.MVszA.lppszA[dw], ':');
ptr++;
SPropValue propVal = {0};
propVal.Value.lpszA = ptr;
lptstrEmailAddress = StrFromAddrBk(&propVal);
break;
}
}
}
}
}
exit:
if(lpPropArray)
{
ABFreeBuffer( lpPropArray );
}
if (lpMailUser)
{
lpMailUser->Release();
}
if(!lptstrEmailAddress)
{
if (!::LoadString((HINSTANCE )m_hInstance, IDS_ERROR_RECEIPT_SMTP,tszBuffer, MAX_STRING_LEN))
{
assert(FALSE);
}
else
{
AlignedMessageBox( m_hWnd, tszBuffer, NULL, MB_ICONSTOP | MB_OK);
}
}
return lptstrEmailAddress;
} // CCommonAbObj::GetEmail
LPSPropValue
CCommonAbObj::FindProp(
LPSPropValue rgprop,
ULONG cprop,
ULONG ulPropTag
)
/*++
Routine Description:
Searches for a given property tag in a propset. If the given
property tag has type PT_UNSPECIFIED, matches only on the
property ID; otherwise, matches on the entire tag.
Arguments:
rgprop - Property values.
cprop - Number of properties.
ulPropTag - Property to search for.
Return Value:
Pointer to property desired property value or NULL.
--*/
{
if (!cprop || !rgprop)
{
return NULL;
}
LPSPropValue pprop = rgprop;
#ifdef UNICODE
if(!m_bUnicode)
{
//
// If the Address Book does not support Unicode
// change the property type to ANSII
//
if(PROP_TYPE(ulPropTag) == PT_UNICODE)
{
ulPropTag = PROP_TAG( PT_STRING8, PROP_ID(ulPropTag));
}
if(PROP_TYPE(ulPropTag) == PT_MV_UNICODE)
{
ulPropTag = PROP_TAG( PT_MV_STRING8, PROP_ID(ulPropTag));
}
}
#endif
while (cprop--)
{
if (pprop->ulPropTag == ulPropTag)
{
return pprop;
}
++pprop;
}
return NULL;
} // CCommonAbObj::FindProp
DWORD
CCommonAbObj::AddRecipient(
PRECIPIENT *ppNewRecipList,
PRECIPIENT pRecipient,
BOOL bFromAddressBook
)
/*++
Routine Description:
Add a recipient to the recipient list.
Arguments:
ppNewRecip - pointer to pointer to list to add item to.
pRecipient - pointer to the new recipient data
bFromAddressBook - boolean says if this recipient is from address book
Return Value:
NA
--*/
{
DWORD dwRes = ERROR_SUCCESS;
PRECIPIENT pNewRecip = NULL;
pNewRecip = (PRECIPIENT)MemAllocZ(sizeof(RECIPIENT));
if(!pNewRecip)
{
dwRes = ERROR_NOT_ENOUGH_MEMORY;
goto error;
}
else
{
pNewRecip->pName = pRecipient->pName;
pNewRecip->pAddress = pRecipient->pAddress;
pNewRecip->pCountry = pRecipient->pCountry;
pNewRecip->cbEntryId = pRecipient->cbEntryId;
pNewRecip->lpEntryId = pRecipient->lpEntryId;
pNewRecip->dwCountryId = pRecipient->dwCountryId;
pNewRecip->bUseDialingRules = pRecipient->bUseDialingRules;
pNewRecip->bFromAddressBook = bFromAddressBook;
pNewRecip->pNext = *ppNewRecipList;
}
try
{
//
// Try to insert a recipient into the set
//
if(m_setRecipients.insert(pNewRecip).second == false)
{
//
// Such recipient already exists
//
goto error;
}
}
catch (std::bad_alloc&)
{
dwRes = ERROR_NOT_ENOUGH_MEMORY;
goto error;
}
//
// Add the recipient into the list
//
*ppNewRecipList = pNewRecip;
return dwRes;
error:
MemFree(pRecipient->pName);
MemFree(pRecipient->pAddress);
MemFree(pRecipient->pCountry);
ABFreeBuffer(pRecipient->lpEntryId);
ZeroMemory(pRecipient, sizeof(RECIPIENT));
MemFree(pNewRecip);
return dwRes;
} // CCommonAbObj::AddRecipient
LPTSTR
CCommonAbObj::StrToAddrBk(
LPCTSTR szStr,
DWORD* pdwSize /* = NULL*/
)
/*++
Routine Description:
Allocate string converted to the Address book encoding
Arguments:
szStr - [in] source string
pdwSize - [out] optional size of new string in bytes
Return Value:
Pointer to the converted string
Should be released by MemFree()
--*/
{
if(!szStr)
{
Assert(FALSE);
return NULL;
}
#ifdef UNICODE
if(!m_bUnicode)
{
//
// The address book does not support Unicode
//
INT nSize;
LPSTR pAnsii;
//
// Figure out how much memory to allocate for the multi-byte string
//
if (! (nSize = WideCharToMultiByte(CP_ACP, 0, szStr, -1, NULL, 0, NULL, NULL)) ||
! (pAnsii = (LPSTR)MemAlloc(nSize)))
{
return NULL;
}
//
// Convert Unicode string to multi-byte string
//
WideCharToMultiByte(CP_ACP, 0, szStr, -1, pAnsii, nSize, NULL, NULL);
if(pdwSize)
{
*pdwSize = nSize;
}
return (LPTSTR)pAnsii;
}
#endif // UNICODE
LPTSTR pNewStr = StringDup(szStr);
if(pdwSize && pNewStr)
{
*pdwSize = (_tcslen(pNewStr)+1) * sizeof(TCHAR);
}
return pNewStr;
} // CCommonAbObj::StrToAddrBk
LPTSTR
CCommonAbObj::StrFromAddrBk(LPSPropValue pValue)
/*++
Routine Description:
Allocate string converted from the Address book encoding
Arguments:
pValue - [in] MAPI property
Return Value:
Pointer to the converted string
Should be released by MemFree()
--*/
{
if(!pValue)
{
Assert(FALSE);
return NULL;
}
#ifdef UNICODE
if(!m_bUnicode)
{
//
// The address book does not support Unicode
//
if(!pValue->Value.lpszA)
{
Assert(FALSE);
return NULL;
}
INT nSize;
LPWSTR pUnicodeStr;
if (! (nSize = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pValue->Value.lpszA, -1, NULL, 0)) ||
! (pUnicodeStr = (LPWSTR) MemAlloc( nSize * sizeof(WCHAR))))
{
return NULL;
}
//
// Convert multi-byte string to Unicode string
//
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pValue->Value.lpszA, -1, pUnicodeStr, nSize);
return pUnicodeStr;
}
#endif // UNICODE
if(!pValue->Value.LPSZ)
{
Assert(FALSE);
return NULL;
}
LPTSTR pNewStr = StringDup(pValue->Value.LPSZ);
return pNewStr;
} // CCommonAbObj::StrFromAddrBk
BOOL
CCommonAbObj::ABStrCmp(LPSPropValue lpPropVals, LPTSTR pStr)
/*++
Routine Description:
Compare string with MAPI property value according to the address book encoding
Arguments:
lpPropVals - [in] MAPI property
pStr - [in] string to compare
Return Value:
TRUE if the strings are equal
FALSE otherwise
--*/
{
BOOL bRes = FALSE;
if(!lpPropVals || !pStr)
{
Assert(FALSE);
return bRes;
}
#ifdef UNICODE
if(!m_bUnicode)
{
LPSTR pAnsii = (LPSTR)StrToAddrBk(pStr);
if(pAnsii)
{
bRes = !strcmp(lpPropVals->Value.lpszA, pAnsii);
MemFree(pAnsii);
}
return bRes;
}
#endif
bRes = !_tcscmp(lpPropVals->Value.LPSZ, pStr);
return bRes;
} // CCommonAbObj::ABStrCmp
BOOL
CCommonAbObj::GetAddrBookCaption(
LPTSTR szCaption,
DWORD dwSize
)
/*++
Routine Description:
Get address book dialog caption according to the ANSII/Unicode capability
Arguments:
szCaption - [out] caption buffer
dwSize - [in] caption buffer size in characters
Return Value:
TRUE if success
FALSE otherwise
--*/
{
if(!szCaption || !dwSize)
{
Assert(FALSE);
return FALSE;
}
TCHAR tszStr[MAX_PATH] = {0};
if(!LoadString(m_hInstance, IDS_ADDRESS_BOOK_CAPTION, tszStr, ARR_SIZE(tszStr)))
{
return FALSE;
}
_tcsncpy(szCaption, tszStr, dwSize);
#ifdef UNICODE
if(!m_bUnicode || GetABType() == AB_MAPI)
{
//
// MAPI interpret lpszCaption as ANSII anyway
//
char szAnsiStr[MAX_PATH] = {0};
if(!WideCharToMultiByte(CP_ACP,
0,
tszStr,
-1,
szAnsiStr,
ARR_SIZE(szAnsiStr),
NULL,
NULL))
{
return FALSE;
}
memcpy(szCaption, szAnsiStr, min(dwSize, strlen(szAnsiStr)+1));
}
#endif // UNICODE
return TRUE;
} // CCommonAbObj::GetAddrBookCaption