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.
1267 lines
46 KiB
1267 lines
46 KiB
/**********************************************************************************
|
|
*
|
|
* dial.c - autodialer functionality for the wab
|
|
* created on 7/1/98 by t-jstaj
|
|
*
|
|
* Note: The reason for having this dialog in teh WAB was to integrate with
|
|
* the NT TAPI team .. we tried using TAPI3.0 which is debuting in
|
|
* NT5 but found it too unstable, subject to change, and hard to include
|
|
* in our standard headers .. hence the NT5_TAPI3.0 support is currently
|
|
* #ifdefed out _NT50_TAPI30 .. if you reenable that support you should
|
|
* test it since we havent been able to test the code much - vikramm
|
|
**********************************************************************************/
|
|
|
|
#include "_apipch.h"
|
|
#define MAX_PHONE_NUMS 10
|
|
#define MAX_PHONE_LEN 32
|
|
|
|
|
|
static DWORD rgDLDialHelpIDs[] =
|
|
{
|
|
// these are dummy for now, need to change at some point
|
|
IDC_NEWCALL_STATIC_CONTACT, IDH_WAB_DIALER_CONTACT,
|
|
IDC_NEWCALL_COMBO_CONTACT, IDH_WAB_DIALER_CONTACT,
|
|
IDC_NEWCALL_STATIC_PHNUM, IDH_WAB_DIALER_PHONE,
|
|
IDC_NEWCALL_COMBO_PHNUM, IDH_WAB_DIALER_PHONE,
|
|
IDC_NEWCALL_BUTTON_CALL, IDH_WAB_DIALER_CALL,
|
|
IDC_NEWCALL_BUTTON_PROPERTIES, IDH_WAB_DIALER_PROPERTIES,
|
|
IDC_NEWCALL_BUTTON_DIALPROP, IDH_WAB_DIALING_PROPERTIES,
|
|
IDC_NEWCALL_GROUP_DIALNUM, IDH_WAB_COMM_GROUPBOX,
|
|
IDC_NEWCALL_BUTTON_CLOSE, IDH_WAB_FIND_CLOSE,
|
|
0,0
|
|
};
|
|
|
|
// prototypes
|
|
#ifdef _NT50_TAPI30
|
|
HRESULT HrLPSZToBSTR(LPTSTR lpsz, BSTR *pbstr);
|
|
#endif //#ifdef _NT50_TAPI30
|
|
|
|
HRESULT HrConfigDialog( HWND );
|
|
UINT GetPhoneNumData( HWND , LPTSTR );
|
|
BOOL RetrieveData( HWND, LPTSTR szDestAddr, LPTSTR szAppName,
|
|
LPTSTR szCalledParty, LPTSTR szComment);
|
|
HRESULT HrSetComboText( HWND );
|
|
void SetNumbers( HWND, LPSBinary );
|
|
INT_PTR CALLBACK ShowNewCallDlg(HWND, UINT, WPARAM, LPARAM);
|
|
LONG HrStartCall(LPTSTR, LPTSTR, LPTSTR, LPTSTR);
|
|
void UpdateNewCall(HWND, BOOL);
|
|
void DisableCallBtnOnEmptyPhoneField(HWND);
|
|
HRESULT HrInitDialog(HWND);
|
|
HRESULT HrCallButtonActivate( HWND );
|
|
HRESULT HrPropButtonActivate( HWND );
|
|
HRESULT HrCloseBtnActivate ( HWND );
|
|
VOID FAR PASCAL lineCallbackFunc( DWORD, DWORD, DWORD_PTR, DWORD_PTR, DWORD_PTR, DWORD_PTR);
|
|
BOOL fContextExtCoinitForDial = FALSE;
|
|
typedef struct _IABSB
|
|
{
|
|
LPADRBOOK lpIAB;
|
|
LPSBinary lpSB;
|
|
|
|
} IABSB, * LPIABSB;
|
|
|
|
/**
|
|
HrExecDialog: entry point to Dialer Dialog
|
|
[IN] hWndLV - handle to the WAB's ListView
|
|
[IN] lpAdrBook - pointer to the IAdrBook object
|
|
*/
|
|
HRESULT HrExecDialDlg(HWND hWndLV, LPADRBOOK lpAdrBook )
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
LPRECIPIENT_INFO lpItem = NULL;
|
|
LPSPropValue lpPropArray = NULL;
|
|
ULONG ulcProps = 0;
|
|
UINT iItemIndex;
|
|
LPSBinary lpSB = NULL;
|
|
IABSB ptr_store;
|
|
int rVal, nCount = ListView_GetSelectedCount(hWndLV);
|
|
TCHAR szBuf[MAX_PATH*2];
|
|
ptr_store.lpIAB = lpAdrBook;
|
|
ptr_store.lpSB = NULL;
|
|
|
|
if( !lpAdrBook )
|
|
DebugTrace(TEXT("lpAdrbook is null in ExecDialDlg\n"));
|
|
|
|
if(nCount == 1)
|
|
{
|
|
iItemIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
|
|
lpItem = GetItemFromLV(hWndLV, iItemIndex);
|
|
if(lpItem && lpItem->cbEntryID != 0)
|
|
{
|
|
ListView_GetItemText( hWndLV, iItemIndex, 0, szBuf, CharSizeOf( szBuf ));
|
|
// what does this allocate space for SBinary
|
|
MAPIAllocateBuffer( sizeof(SBinary), (LPVOID *) &lpSB);
|
|
if( lpSB )
|
|
{
|
|
// allocate more space for lpb
|
|
MAPIAllocateMore(lpItem->cbEntryID, lpSB, (LPVOID *) &(lpSB->lpb) );
|
|
}
|
|
if( !lpSB->lpb)
|
|
{
|
|
MAPIFreeBuffer(lpSB);
|
|
goto out;
|
|
}
|
|
CopyMemory(lpSB->lpb, lpItem->lpEntryID, lpItem->cbEntryID);
|
|
lpSB->cb = lpItem->cbEntryID;
|
|
ptr_store.lpSB = lpSB;
|
|
}
|
|
else
|
|
{
|
|
DebugTrace(TEXT("Bad WAB info will not display\n"));
|
|
goto out;
|
|
}
|
|
}
|
|
// display the dialog box to prompt user to make call
|
|
if(!DialogBoxParam(hinstMapiX, MAKEINTRESOURCE(IDD_NEWCALL),
|
|
GetParent(hWndLV), ShowNewCallDlg, (LPARAM)&ptr_store) )
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
DebugTrace(TEXT("Dialer dialog creation failed:%d\n"), GetLastError());
|
|
}
|
|
|
|
out:
|
|
if(lpPropArray)
|
|
MAPIFreeBuffer(lpPropArray);
|
|
|
|
if( lpSB )
|
|
MAPIFreeBuffer(lpSB);
|
|
return hr;
|
|
}
|
|
|
|
/**
|
|
ShowNewCallDlg: process events
|
|
*/
|
|
|
|
INT_PTR CALLBACK ShowNewCallDlg(HWND hDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
HRESULT hr;
|
|
SetWindowLongPtr( hDlg, DWLP_USER, lParam );
|
|
hr = HrInitDialog(hDlg);
|
|
// [PaulHi] 12/3/98 Raid #56045
|
|
// Set up child window fonts with default GUI font
|
|
EnumChildWindows(hDlg, SetChildDefaultGUIFont, (LPARAM) 0);
|
|
return HR_FAILED( hr );
|
|
}
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam) )
|
|
{
|
|
case IDC_NEWCALL_COMBO_CONTACT:
|
|
/** only want to make a change if the user actually chooses a new contact
|
|
*/
|
|
if( HIWORD(wParam) == CBN_SELENDOK )
|
|
{
|
|
HRESULT hr;
|
|
UpdateNewCall(hDlg, TRUE);
|
|
hr = HrSetComboText( GetDlgItem(hDlg, IDC_NEWCALL_COMBO_PHNUM) );
|
|
if( HR_FAILED( hr ) )
|
|
{
|
|
DebugTrace(TEXT("unable to set text\n"));
|
|
SendMessage(hDlg, IDCANCEL, 0, 0);
|
|
}
|
|
}
|
|
return FALSE;
|
|
case IDC_NEWCALL_COMBO_PHNUM:
|
|
// want to set the text of the selected item when the box closes
|
|
if( HIWORD(wParam) == CBN_CLOSEUP )
|
|
{
|
|
HRESULT hr = HrSetComboText( GetDlgItem(hDlg, IDC_NEWCALL_COMBO_PHNUM) );
|
|
if( HR_FAILED( hr ) )
|
|
{
|
|
DebugTrace(TEXT("unable to set text in PHNUM closeup or selchange\n"));
|
|
SendMessage(hDlg, IDCANCEL, 0, 0);
|
|
}
|
|
return FALSE;
|
|
}
|
|
// reset all the values of the combobox before display since they
|
|
// were altered from the last time a selection was made.
|
|
else if( HIWORD(wParam) == CBN_DROPDOWN )
|
|
{
|
|
UpdateNewCall(hDlg, FALSE);
|
|
}
|
|
else if (HIWORD(wParam) == CBN_EDITUPDATE )
|
|
{
|
|
DisableCallBtnOnEmptyPhoneField(hDlg);
|
|
}
|
|
else if ( HIWORD(wParam) == CBN_SELCHANGE )
|
|
{
|
|
if( !SendDlgItemMessage( hDlg, IDC_NEWCALL_COMBO_PHNUM, CB_GETDROPPEDSTATE, (WPARAM)(0), (LPARAM)(0) ) )
|
|
{
|
|
HRESULT hr = HrSetComboText( GetDlgItem(hDlg, IDC_NEWCALL_COMBO_PHNUM) );
|
|
if( HR_FAILED( hr ) )
|
|
{
|
|
DebugTrace(TEXT("unable to set text in PHNUM closeup or selchange\n"));
|
|
SendMessage(hDlg, IDCANCEL, 0, 0);
|
|
}
|
|
return FALSE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
case IDC_NEWCALL_BUTTON_DIALPROP:
|
|
{
|
|
HRESULT hr = HrConfigDialog( hDlg );
|
|
if( HR_FAILED(hr) )
|
|
{
|
|
DebugTrace(TEXT("config dlg failed"));
|
|
DebugTrace(TEXT(" error was %x\n"), HRESULT_CODE(hr));
|
|
SendMessage(hDlg, IDCANCEL, 0, 0);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
case IDC_NEWCALL_BUTTON_CALL:
|
|
{
|
|
HRESULT hr = HrCallButtonActivate( hDlg );
|
|
if( HR_FAILED(hr) )
|
|
{
|
|
DebugTrace(TEXT("Unable to make call\n"));
|
|
SendMessage( hDlg, IDCANCEL, (WPARAM)(0), (LPARAM)(0) );
|
|
}
|
|
}
|
|
return FALSE;
|
|
case IDC_NEWCALL_BUTTON_PROPERTIES:
|
|
{
|
|
HRESULT hr = HrPropButtonActivate( hDlg );
|
|
if( HR_FAILED(hr) )
|
|
{
|
|
DebugTrace(TEXT("Unable to show properties\n"));
|
|
SendMessage( hDlg, IDCANCEL, (WPARAM)(0), (LPARAM)(0) );
|
|
}
|
|
return FALSE;
|
|
}
|
|
case IDCANCEL:
|
|
case IDC_NEWCALL_BUTTON_CLOSE:
|
|
{
|
|
HRESULT hr = HrCloseBtnActivate(hDlg);
|
|
return FALSE;
|
|
}
|
|
default:
|
|
return TRUE;
|
|
}
|
|
|
|
case WM_HELP:
|
|
WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
|
|
g_szWABHelpFileName,
|
|
HELP_WM_HELP,
|
|
(DWORD_PTR)(LPSTR) rgDLDialHelpIDs );
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
HrInitDialog: initializes the dialer dialog
|
|
*/
|
|
HRESULT HrInitDialog( HWND hDlg )
|
|
{
|
|
HRESULT hr = E_FAIL, hr2;
|
|
HWND hComboContact = GetDlgItem( hDlg, IDC_NEWCALL_COMBO_CONTACT);
|
|
ULONG lpcbEID, ulObjType = 0, ulResult;
|
|
LPENTRYID lpEID = NULL;
|
|
LPMAPITABLE lpAB = NULL;
|
|
LPSRowSet lpRow = NULL;
|
|
LPSRowSet lpRowAB = NULL;
|
|
LPABCONT lpContainer = NULL;
|
|
UINT cNumRows = 0;
|
|
UINT nRows = 0;
|
|
UINT i, cEntries = 0;
|
|
LPSBinary tVal;
|
|
LPIABSB lpPtrStore = (LPIABSB)GetWindowLongPtr( hDlg, DWLP_USER );
|
|
LPADRBOOK lpAdrBook = lpPtrStore->lpIAB;
|
|
AssertSz( (lpAdrBook != NULL), TEXT("lpAdrBook is NULL in shownewcall!\n"));
|
|
|
|
hr = (HRESULT) SendDlgItemMessage( hDlg, IDC_NEWCALL_COMBO_PHNUM, EM_SETLIMITTEXT, (WPARAM)(TAPIMAXDESTADDRESSSIZE), (LPARAM)(0) );
|
|
if( HR_FAILED(hr) )
|
|
{
|
|
DebugTrace(TEXT("unable to set text len in PHNUM\n"));
|
|
}
|
|
// get the default Container
|
|
hr = lpAdrBook->lpVtbl->GetPAB(lpAdrBook, &lpcbEID, &lpEID);
|
|
if( HR_FAILED(hr) )
|
|
{
|
|
DebugTrace(TEXT("Unable to get PAB\n"));
|
|
goto cleanup;
|
|
}
|
|
// open the entry
|
|
hr = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
|
|
lpcbEID,
|
|
(LPENTRYID)lpEID,
|
|
NULL,
|
|
0,
|
|
&ulObjType,
|
|
(LPUNKNOWN *)&lpContainer);
|
|
|
|
MAPIFreeBuffer(lpEID);
|
|
lpEID = NULL;
|
|
if( HR_FAILED(hr) )
|
|
{
|
|
DebugTrace(TEXT("Unable to open contents\n"));
|
|
goto cleanup;
|
|
}
|
|
// get the contents
|
|
hr = lpContainer->lpVtbl->GetContentsTable(lpContainer,
|
|
MAPI_UNICODE | WAB_PROFILE_CONTENTS | WAB_CONTENTTABLE_NODATA,
|
|
&lpAB );
|
|
|
|
if( HR_FAILED(hr) )
|
|
{
|
|
DebugTrace(TEXT("Unable to get contents table\n"));
|
|
goto cleanup;
|
|
}
|
|
|
|
// order the columns in the Table
|
|
// order will be displayname, entryid
|
|
// table MUST set columns in order requested
|
|
hr = lpAB->lpVtbl->SetColumns( lpAB, (LPSPropTagArray)&irnColumns, 0);
|
|
|
|
if( HR_FAILED(hr) )
|
|
{
|
|
DebugTrace(TEXT("Unable to set contents table\n"));
|
|
goto cleanup;
|
|
}
|
|
|
|
hr = lpAB->lpVtbl->SeekRow(lpAB, BOOKMARK_BEGINNING, 0, NULL);
|
|
|
|
if( HR_FAILED(hr) )
|
|
{
|
|
DebugTrace(TEXT("Unable to seekRow \n"));
|
|
goto cleanup;
|
|
}
|
|
|
|
do{
|
|
//loop over all the info in the selected rows
|
|
hr = lpAB->lpVtbl->QueryRows(lpAB, 1, 0, &lpRowAB);
|
|
if( HR_FAILED(hr) )
|
|
{
|
|
DebugTrace(TEXT("Unable to Query Rows\n"));
|
|
goto cleanup;
|
|
}
|
|
cNumRows = lpRowAB->cRows;
|
|
if( lpRowAB && cNumRows > 0) // temp fix to check for cNumRows
|
|
{
|
|
UINT recentIndex;
|
|
// store the name
|
|
LPTSTR lpsz = lpRowAB->aRow[0].lpProps[irnPR_DISPLAY_NAME].Value.LPSZ;
|
|
// store the entryID info
|
|
LPENTRYID lpEID = (LPENTRYID) lpRowAB->aRow[0].lpProps[irnPR_ENTRYID].Value.bin.lpb;
|
|
ULONG cbEID = lpRowAB->aRow[0].lpProps[irnPR_ENTRYID].Value.bin.cb;
|
|
LPSBinary lpSB = NULL;
|
|
// we can ignore non mail-users for our purposes
|
|
// since they won't have ph numbers
|
|
|
|
// will add strings to the combo box, and will associate the entryid with
|
|
// each entry with its entryID so that it will be easy to obtain the other entry fields
|
|
|
|
// what does this allocate space for SBinary
|
|
MAPIAllocateBuffer( sizeof(SBinary), (LPVOID *) &lpSB);
|
|
if( lpSB )
|
|
{
|
|
// allocate more space for lpb
|
|
MAPIAllocateMore(cbEID, lpSB, (LPVOID *) &(lpSB->lpb) );
|
|
}
|
|
|
|
if( !lpSB->lpb)
|
|
{
|
|
// because of memmangement in WAB this will free all
|
|
// the mem in SBinary( deep free )
|
|
MAPIFreeBuffer(lpSB);
|
|
continue;
|
|
}
|
|
CopyMemory(lpSB->lpb, lpEID, cbEID);
|
|
lpSB->cb = cbEID;
|
|
// next entry, list is sorted
|
|
recentIndex = (UINT) SendMessage( hComboContact, CB_ADDSTRING, (WPARAM)(0),
|
|
(LPARAM)(lpsz) );
|
|
// set the data as the pointer to entryid info for the item at that index
|
|
SendMessage( hComboContact, CB_SETITEMDATA,
|
|
(WPARAM)(recentIndex), (LPARAM)(lpSB));
|
|
cEntries++;
|
|
}
|
|
FreeProws(lpRowAB);
|
|
}while( SUCCEEDED(hr) && cNumRows && lpRowAB );
|
|
|
|
if( (LPVOID)lpPtrStore->lpSB )
|
|
{
|
|
for( i = 0; i < cEntries; i++)
|
|
{
|
|
tVal = (LPSBinary)(PULONG)SendMessage( hComboContact, CB_GETITEMDATA,
|
|
(WPARAM)(i), (LPARAM)(0) );
|
|
if( tVal && tVal->cb && tVal->cb == lpPtrStore->lpSB->cb )
|
|
{
|
|
if( memcmp((LPVOID)tVal->lpb,
|
|
(LPVOID)lpPtrStore->lpSB->lpb, (size_t)tVal->cb) == 0)
|
|
{
|
|
SendMessage(hComboContact, CB_SETCURSEL,
|
|
(WPARAM)(i), (LPARAM)(0) );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
SendMessage(hComboContact, CB_SETCURSEL, (WPARAM)(0), (LPARAM)(0) );
|
|
|
|
cleanup:
|
|
if( lpContainer )
|
|
lpContainer->lpVtbl->Release(lpContainer);
|
|
if( lpAB)
|
|
lpAB->lpVtbl->Release(lpAB);
|
|
|
|
UpdateNewCall(hDlg, TRUE);
|
|
hr2 = HrSetComboText( GetDlgItem(hDlg, IDC_NEWCALL_COMBO_PHNUM) );
|
|
DisableCallBtnOnEmptyPhoneField(hDlg);
|
|
|
|
if( HR_SUCCEEDED(hr) && HR_FAILED(hr2))
|
|
return hr2;
|
|
return hr;
|
|
}
|
|
|
|
/**
|
|
HrCallButtonActivate: initiates the dialing procedures for the dialer Dlg
|
|
*/
|
|
HRESULT HrCallButtonActivate( HWND hDlg )
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
TCHAR szDestAddr[TAPIMAXDESTADDRESSSIZE];
|
|
TCHAR szAppName[TAPIMAXAPPNAMESIZE];
|
|
TCHAR szCalledParty[TAPIMAXCALLEDPARTYSIZE];
|
|
TCHAR szComment[TAPIMAXCOMMENTSIZE];
|
|
BOOL fGotNum = RetrieveData( hDlg, szDestAddr, szAppName, szCalledParty, szComment);
|
|
if( !fGotNum )
|
|
{
|
|
ShowMessageBox( hDlg, idsNoDialerDataMsg, MB_OK | MB_ICONEXCLAMATION );
|
|
}
|
|
else
|
|
{
|
|
hr = HrStartCall(szDestAddr, szAppName, szCalledParty, szComment);
|
|
/** make call spawns it's own thread so hr only reflects
|
|
whether or not it was able to find the phone device and
|
|
initiate the calling sequence, not the status of the call.
|
|
*/
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/**
|
|
HrPropButtonActivate: displays the properties for the selected contact in the dialer Dlg
|
|
*/
|
|
HRESULT HrPropButtonActivate( HWND hDlg )
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
LONG iCurContactSel;
|
|
LPIABSB lpPtrStore = (LPIABSB)GetWindowLongPtr( hDlg, DWLP_USER );
|
|
LPADRBOOK lpAdrBook = lpPtrStore->lpIAB;
|
|
AssertSz((lpAdrBook != NULL), TEXT("lpAdrBook is NULL in SetNumbers\n"));
|
|
|
|
// first get the cached data for the contact currently selected
|
|
iCurContactSel = (LONG) SendDlgItemMessage( hDlg, IDC_NEWCALL_COMBO_CONTACT,
|
|
CB_GETCURSEL,(WPARAM)(0), (LPARAM)(0));
|
|
|
|
// if something is selected
|
|
if( iCurContactSel >= 0 )
|
|
{
|
|
LRESULT lpdata = SendDlgItemMessage( hDlg, IDC_NEWCALL_COMBO_CONTACT,
|
|
CB_GETITEMDATA, (WPARAM)(iCurContactSel), (LPARAM)(LPTSTR)(0));
|
|
// if we have a specially cached entryid ..
|
|
//
|
|
if( lpdata != CB_ERR && ((LPSBinary)lpdata)->cb && ((LPSBinary)lpdata)->lpb)
|
|
{
|
|
LPSBinary lpSB = (LPSBinary)lpdata;
|
|
hr = lpAdrBook->lpVtbl->Details(lpAdrBook, (PULONG_PTR) &hDlg,
|
|
NULL, NULL,
|
|
lpSB->cb,
|
|
(LPENTRYID) lpSB->lpb,
|
|
NULL, NULL,
|
|
NULL, 0);
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/**
|
|
HrCloseBtnActivate: Handles freeing memory from the combo boxes
|
|
*/
|
|
HRESULT HrCloseBtnActivate( HWND hDlg )
|
|
{
|
|
HRESULT hr = S_OK;
|
|
UINT i, nComboSize;
|
|
PULONG nData;
|
|
LPTSTR lpData;
|
|
HWND hComboItem = GetDlgItem (hDlg, IDC_NEWCALL_COMBO_CONTACT);
|
|
// loop through all the items in the box and free the address pointed
|
|
// to by the data item
|
|
nComboSize = (UINT) SendMessage( hComboItem, CB_GETCOUNT, (WPARAM) (0), (LPARAM) (0) );
|
|
for( i = 0; i < nComboSize; i++)
|
|
{
|
|
nData = (PULONG)SendMessage(hComboItem, CB_GETITEMDATA, (WPARAM)(i), (LPARAM)(0) );
|
|
if ((LRESULT)nData != CB_ERR && nData != NULL)
|
|
{
|
|
if( nData )
|
|
MAPIFreeBuffer( (LPSBinary)nData );
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
SendMessage( hComboItem, CB_RESETCONTENT, (WPARAM)(0), (LPARAM)(0));
|
|
hComboItem = GetDlgItem( hDlg, IDC_NEWCALL_COMBO_PHNUM);
|
|
nComboSize = (UINT) SendMessage( hComboItem, CB_GETCOUNT, (WPARAM)(0), (LPARAM)(0) );
|
|
for(i = 0; i < nComboSize; i++)
|
|
{
|
|
lpData = (LPTSTR)SendMessage(hComboItem, CB_GETITEMDATA, (WPARAM)(i), (LPARAM)(0) );
|
|
if( (LRESULT)lpData != CB_ERR && lpData != NULL )
|
|
{
|
|
if( lpData )
|
|
LocalFree( lpData );
|
|
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
// SendMessage( hComboItem, CB_RESETCONTENT, (WPARAM)(0), (LPARAM)(0));
|
|
EndDialog(hDlg, HR_SUCCEEDED(hr) );
|
|
return hr;
|
|
}
|
|
|
|
/**
|
|
HrStartCall: handles the TAPI calls required to dial a telephone number
|
|
[IN] szDestAddr - the destination telephone number to call
|
|
[IN] szAppName - (not used) the application to use in the dialing procedure
|
|
[IN] szCalledParty - the name of the person called (will be displayed by the TAPI UI)
|
|
[IN] szComment - (not used) a comment associated with this number
|
|
*/
|
|
HRESULT HrStartCall(LPTSTR szDestAddr, LPTSTR szAppName, LPTSTR szCalledParty, LPTSTR szComment)
|
|
{
|
|
typedef LONG (CALLBACK* LPFNTAPISTARTCALL)(LPSTR,LPSTR,LPSTR,LPSTR);
|
|
HINSTANCE hDLL;
|
|
LPFNTAPISTARTCALL lpfnTapi; // Function pointer
|
|
HRESULT lRetCode;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
#ifdef _NT50_TAPI30
|
|
ITRequest * pRequest = NULL;
|
|
// begin NT5 code
|
|
if( CoInitialize(NULL) == S_FALSE )
|
|
CoUninitialize();
|
|
else
|
|
fContextExtCoinitForDial = TRUE;
|
|
hr = CoCreateInstance(
|
|
&CLSID_RequestMakeCall,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
&IID_ITRequest,
|
|
(LPVOID *)&pRequest
|
|
);
|
|
|
|
if( HR_SUCCEEDED(hr) )
|
|
{
|
|
BSTR pDestAdr, pAppName, pCalledParty, pComment;
|
|
HrLPSZToBSTR(szDestAddr, &pDestAdr);
|
|
HrLPSZToBSTR(szAppName, &pAppName);
|
|
HrLPSZToBSTR(szCalledParty, &pCalledParty);
|
|
HrLPSZToBSTR(szComment, &pComment);
|
|
|
|
hr = pRequest->lpVtbl->MakeCall(pRequest, pDestAdr, pAppName, pCalledParty, pComment );
|
|
DebugTrace(TEXT("COM Environment\n"));
|
|
|
|
LocalFreeAndNull(&pDestAdr);
|
|
LocalFreeAndNull(&pAppName);
|
|
LocalFreeAndNull(&pCalledParty);
|
|
LocalFreeAndNull(&pComment);
|
|
|
|
if(fContextExtCoinitForDial)
|
|
{
|
|
CoUninitialize();
|
|
fContextExtCoinitForDial = FALSE;
|
|
}
|
|
return hr;
|
|
}
|
|
else
|
|
{
|
|
if( hr == REGDB_E_CLASSNOTREG )
|
|
{
|
|
DebugTrace(TEXT("Class not registered\n"));
|
|
}
|
|
else if ( hr == CLASS_E_NOAGGREGATION )
|
|
{
|
|
DebugTrace(TEXT("Not able to create class as part of aggregate"));
|
|
}
|
|
else
|
|
{
|
|
DebugTrace(TEXT("Undetermined error = %d"), hr);
|
|
}
|
|
// end NT 5 code
|
|
#endif // _NT50_TAPI30
|
|
|
|
//start making the call using TAPI
|
|
hDLL = LoadLibrary( TEXT("tapi32.dll"));
|
|
if (hDLL != NULL)
|
|
{
|
|
lpfnTapi = (LPFNTAPISTARTCALL)GetProcAddress(hDLL,
|
|
"tapiRequestMakeCall");
|
|
if (!lpfnTapi)
|
|
{
|
|
// handle the error
|
|
FreeLibrary(hDLL);
|
|
DebugTrace(TEXT("getprocaddr tapirequestmakecall failed\n"));
|
|
}
|
|
else
|
|
{
|
|
// call the function
|
|
// [PaulHi] 2/23/99 Raid 295116. The tapi32.dll, tapiRequestMakeCall()
|
|
// function takes single byte char strings, not double byte.
|
|
LPSTR pszDestAddr = ConvertWtoA(szDestAddr);
|
|
LPSTR pszCalledParty = ConvertWtoA(szCalledParty);
|
|
|
|
hr = lpfnTapi( pszDestAddr, NULL,
|
|
pszCalledParty, NULL);
|
|
if( HR_FAILED(hr) )
|
|
{
|
|
DebugTrace(TEXT("make call returned error of %x\n"), hr );
|
|
}
|
|
|
|
LocalFreeAndNull(&pszDestAddr);
|
|
LocalFreeAndNull(&pszCalledParty);
|
|
|
|
// free the resource
|
|
FreeLibrary(hDLL);
|
|
}
|
|
}
|
|
#ifdef _NT50_TAPI30
|
|
}
|
|
#endif // _NT50_TAPI30
|
|
return hr;
|
|
}
|
|
/**
|
|
UpdateNewCall: Updates the phone combo info (removing the description string)
|
|
[IN] fContactChanged - indicates whether or not it is necessary to select the first
|
|
entry in the PHNUM combo.
|
|
*/
|
|
void UpdateNewCall(HWND hDlg, BOOL fContactChanged)
|
|
{
|
|
HWND hContactCombo = GetDlgItem( hDlg, IDC_NEWCALL_COMBO_CONTACT);
|
|
LONG iCurContactSel, iCurPhSel;
|
|
iCurContactSel = (LONG) SendMessage( hContactCombo, CB_GETCURSEL,(WPARAM)(0), (LPARAM)(0));
|
|
// if something is selected
|
|
if( iCurContactSel >= 0 )
|
|
{
|
|
PULONG lpdata;
|
|
lpdata = (PULONG)SendMessage( hContactCombo, CB_GETITEMDATA,
|
|
(WPARAM)(iCurContactSel), (LPARAM)(LPTSTR)(0));
|
|
|
|
iCurPhSel = (LONG) SendDlgItemMessage( hDlg, IDC_NEWCALL_COMBO_PHNUM,
|
|
CB_GETCURSEL, (WPARAM)(0), (LPARAM)(0) );
|
|
// set the data in the combo boxes
|
|
AssertSz( (LRESULT)lpdata != CB_ERR, TEXT("No data cached for this entry\n") );
|
|
SetNumbers( hDlg, (LPSBinary)lpdata );
|
|
|
|
if( iCurPhSel < 0 || fContactChanged) iCurPhSel = 0;
|
|
SendDlgItemMessage( hDlg, IDC_NEWCALL_COMBO_PHNUM, CB_SETCURSEL, (WPARAM)(iCurPhSel), (LPARAM)(0));
|
|
}
|
|
DisableCallBtnOnEmptyPhoneField(hDlg);
|
|
}
|
|
|
|
/**
|
|
RetrieveData: retrieves dialing information from the NEWCALL dialog,
|
|
memory must have been allocated for the character buffers
|
|
[OUT] szDestAddr - the phone number to call, retrieved from the PHNUM combo
|
|
[OUT] szAppName - (not used) empty string returned
|
|
[OUT] szCalledParty - the contact to call, retrieved from the CONTACT combo
|
|
[OUT] szComment - (not used) empty string returned
|
|
|
|
returns TRUE if success, FALSE if failure
|
|
*/
|
|
BOOL RetrieveData( HWND hDlg, LPTSTR szDestAddr, LPTSTR szAppName,
|
|
LPTSTR szCalledParty, LPTSTR szComment)
|
|
{
|
|
LPARAM cchGetText;
|
|
|
|
// get the Contact name data
|
|
cchGetText = SendDlgItemMessage( hDlg, IDC_NEWCALL_COMBO_CONTACT, WM_GETTEXT,
|
|
(WPARAM)(TAPIMAXCALLEDPARTYSIZE), (LPARAM)(LPTSTR)(szCalledParty));
|
|
|
|
// store a default string in case there is no Party Name;
|
|
if( cchGetText == 0 )
|
|
lstrcpy(szCalledParty, TEXT("No Contact Name"));
|
|
//get the Phone number data
|
|
cchGetText = GetPhoneNumData( hDlg, szDestAddr );
|
|
lstrcpy(szAppName,szEmpty);
|
|
lstrcpy(szComment,szEmpty);
|
|
|
|
// return whether or not there was a phone number to dial
|
|
return ( cchGetText > 0 );
|
|
}
|
|
|
|
/**
|
|
HrConfigDialog: initiates the dialog to change phone settings
|
|
*/
|
|
HRESULT HrConfigDialog( HWND hWnd )
|
|
{
|
|
typedef LONG(CALLBACK* LPFNTAPIPHCONFIG)(HLINEAPP, DWORD, DWORD, HWND, LPTSTR);
|
|
// typedef LONG(CALLBACK* LPFNTAPILINEINIT)(LPHLINEAPP, HINSTANCE, LINECALLBACK,
|
|
// LPTSTR, LPDWORD, LPDWORD, LPLINEINITIALIZEEXPARAMS);
|
|
typedef LONG(CALLBACK* LPFNTAPILINEINIT)(LPHLINEAPP, HINSTANCE, LINECALLBACK, LPTSTR, LPDWORD);
|
|
typedef LONG(CALLBACK* LPFNTAPILINESHUTDOWN)(HLINEAPP);
|
|
HLINEAPP hLineApp = 0;
|
|
HINSTANCE hDLL;
|
|
LPFNTAPIPHCONFIG lpfnConfig; // Function pointer
|
|
LPFNTAPILINEINIT lpfnLineInit;
|
|
LPFNTAPILINESHUTDOWN lpfnLineShutdown;
|
|
LONG lRetCode;
|
|
DWORD dwDeviceID = 0X0;
|
|
DWORD dwAPIVersion = 0X00010004;
|
|
LPTSTR lpszDeviceClass = NULL;
|
|
//start config
|
|
HRESULT hr = E_FAIL;
|
|
hDLL = LoadLibrary( TEXT("tapi32.dll"));
|
|
if (!hDLL )
|
|
{
|
|
DebugTrace(TEXT("loading tapi32.lib failed\n"));
|
|
return hr;
|
|
}
|
|
|
|
lpfnConfig = (LPFNTAPIPHCONFIG)GetProcAddress(hDLL,
|
|
"lineTranslateDialog");
|
|
|
|
if (!lpfnConfig )
|
|
{
|
|
// handle the error
|
|
DebugTrace(TEXT("getprocaddr phoneConfigDialog failed\n"));
|
|
DebugTrace(TEXT("last error was %x\n"), GetLastError() );
|
|
}
|
|
else
|
|
{
|
|
lRetCode = lpfnConfig( 0, dwDeviceID, dwAPIVersion,
|
|
hWnd, lpszDeviceClass);
|
|
|
|
switch( lRetCode )
|
|
{
|
|
hr = HRESULT_FROM_WIN32(lRetCode);
|
|
case 0:
|
|
hr = S_OK;
|
|
break;
|
|
#ifdef DEBUG
|
|
case LINEERR_REINIT:
|
|
DebugTrace(TEXT("reeinitialize\n"));
|
|
break;
|
|
case LINEERR_INVALAPPNAME:
|
|
DebugTrace(TEXT("invalid app name\n"));
|
|
break;
|
|
case LINEERR_BADDEVICEID:
|
|
DebugTrace(TEXT("bad device id\n"));
|
|
break;
|
|
case LINEERR_INVALPARAM:
|
|
DebugTrace(TEXT("invalid param\n"));
|
|
break;
|
|
case LINEERR_INCOMPATIBLEAPIVERSION:
|
|
DebugTrace(TEXT("incompatible api ver\n"));
|
|
break;
|
|
case LINEERR_INVALPOINTER:
|
|
DebugTrace(TEXT("invalid ptr\n"));
|
|
break;
|
|
case LINEERR_INIFILECORRUPT:
|
|
DebugTrace(TEXT("ini file corrupt\n"));
|
|
break;
|
|
case LINEERR_NODRIVER:
|
|
DebugTrace(TEXT("no driver\n"));
|
|
break;
|
|
case LINEERR_INUSE:
|
|
DebugTrace(TEXT("in use\n"));
|
|
break;
|
|
case LINEERR_NOMEM:
|
|
DebugTrace(TEXT("no mem\n"));
|
|
break;
|
|
case LINEERR_INVALADDRESS:
|
|
DebugTrace(TEXT("invalid address\n"));
|
|
break;
|
|
case LINEERR_INVALAPPHANDLE:
|
|
DebugTrace(TEXT("invalid phone handle\n"));
|
|
break;
|
|
case LINEERR_OPERATIONFAILED:
|
|
DebugTrace(TEXT("op failed\n"));
|
|
break;
|
|
#endif // DEBUG
|
|
default:
|
|
DebugTrace(TEXT("(1)lpfnConfig returned a value of %x\n"), lRetCode);
|
|
// this had better be Win95!!
|
|
lpfnLineInit = (LPFNTAPILINEINIT)GetProcAddress(hDLL,
|
|
"lineInitialize");
|
|
if( !lpfnLineInit )
|
|
{
|
|
// handle the error
|
|
DebugTrace(TEXT("getprocaddr lineInitialize failed\n"));
|
|
DebugTrace(TEXT("last error was %x\n"), GetLastError() );
|
|
}
|
|
else
|
|
{
|
|
DWORD dwNumDevs = 0;
|
|
// call the function
|
|
lRetCode = lpfnLineInit(
|
|
&hLineApp,
|
|
hinstMapiX,
|
|
lineCallbackFunc,
|
|
NULL,
|
|
&dwNumDevs);
|
|
|
|
switch( lRetCode )
|
|
{
|
|
hr = HRESULT_FROM_WIN32(lRetCode);
|
|
case 0:
|
|
// shows config
|
|
lRetCode = lpfnConfig( hLineApp, dwDeviceID, dwAPIVersion,
|
|
hWnd, lpszDeviceClass);
|
|
switch( lRetCode )
|
|
{
|
|
hr = HRESULT_FROM_WIN32(lRetCode);
|
|
case 0:
|
|
// now shutdown line
|
|
lpfnLineShutdown = (LPFNTAPILINESHUTDOWN)GetProcAddress(hDLL,
|
|
"lineShutdown");
|
|
|
|
if( lpfnLineShutdown)
|
|
{
|
|
lpfnLineShutdown(hLineApp);
|
|
}
|
|
hr = S_OK;
|
|
break;
|
|
default:
|
|
DebugTrace(TEXT("(2)lpfnConfig returned a value of %x\n"), lRetCode);
|
|
break;
|
|
}
|
|
break;
|
|
// end shows config
|
|
#ifdef DEBUG
|
|
case LINEERR_REINIT:
|
|
DebugTrace(TEXT("reeinitialize\n"));
|
|
break;
|
|
case LINEERR_INVALAPPNAME:
|
|
DebugTrace(TEXT("invalid app name\n"));
|
|
break;
|
|
case LINEERR_BADDEVICEID:
|
|
DebugTrace(TEXT("bad device id\n"));
|
|
break;
|
|
case LINEERR_INVALPARAM:
|
|
DebugTrace(TEXT("invalid param\n"));
|
|
break;
|
|
case LINEERR_INCOMPATIBLEAPIVERSION:
|
|
DebugTrace(TEXT("incompatible api ver\n"));
|
|
break;
|
|
case LINEERR_INVALPOINTER:
|
|
DebugTrace(TEXT("invalid ptr\n"));
|
|
break;
|
|
case LINEERR_INIFILECORRUPT:
|
|
DebugTrace(TEXT("ini file corrupt\n"));
|
|
break;
|
|
case LINEERR_NODRIVER:
|
|
DebugTrace(TEXT("no driver\n"));
|
|
break;
|
|
case LINEERR_INUSE:
|
|
DebugTrace(TEXT("in use\n"));
|
|
break;
|
|
case LINEERR_NOMEM:
|
|
DebugTrace(TEXT("no mem\n"));
|
|
break;
|
|
case LINEERR_INVALADDRESS:
|
|
DebugTrace(TEXT("invalid address\n"));
|
|
break;
|
|
case LINEERR_INVALAPPHANDLE:
|
|
DebugTrace(TEXT("invalid phone handle\n"));
|
|
break;
|
|
case LINEERR_OPERATIONFAILED:
|
|
DebugTrace(TEXT("op failed\n"));
|
|
break;
|
|
#endif // DEBUG
|
|
default:
|
|
DebugTrace(TEXT("Initialize returned a value of %x\n"), GetLastError());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// free the resource
|
|
FreeLibrary(hDLL);
|
|
return hr;
|
|
|
|
}
|
|
/**
|
|
SetNumbers: updates the phone numbers in the PHNUM combo based on the selection
|
|
in the CONTACT combo
|
|
[IN] lpdata - LPSBinary that points to the data stored for the currently
|
|
selected contact
|
|
*/
|
|
void SetNumbers( HWND hWnd, LPSBinary lpdata)
|
|
{
|
|
ULONG ulObjType = 0;
|
|
UINT i, nLen;
|
|
LPMAILUSER lpMailUser = NULL;
|
|
HRESULT hr;
|
|
LPTSTR hData;
|
|
LPIABSB lpPtrStore = (LPIABSB)GetWindowLongPtr( hWnd, DWLP_USER );
|
|
LPADRBOOK lpAdrBook = lpPtrStore->lpIAB;
|
|
HWND hCombo = GetDlgItem(hWnd, IDC_NEWCALL_COMBO_PHNUM);
|
|
|
|
AssertSz((lpAdrBook != NULL), TEXT("lpAdrBook is NULL in SetNumbers\n"));
|
|
// clear all the data in the phnum combo
|
|
nLen = (UINT) SendMessage( hCombo, CB_GETCOUNT, (WPARAM)(0), (LPARAM)(0));
|
|
for( i = 0; i < nLen; i++)
|
|
{
|
|
hData = (LPTSTR)(PULONG)SendMessage( hCombo, CB_GETITEMDATA, (WPARAM)(i), (LPARAM)(0));
|
|
if( (LRESULT)hData != CB_ERR && hData != NULL)
|
|
LocalFree( hData );
|
|
}
|
|
SendMessage( hCombo, CB_RESETCONTENT, (WPARAM)(0), (LPARAM)(0));
|
|
// get the ph num
|
|
hr = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
|
|
lpdata->cb,
|
|
(LPENTRYID) lpdata->lpb,
|
|
NULL,
|
|
0,
|
|
&ulObjType,
|
|
(LPUNKNOWN *)&lpMailUser);
|
|
if( HR_SUCCEEDED(hr) && lpMailUser )
|
|
{
|
|
LPSPropValue lpPropArray;
|
|
ULONG ulcValues;
|
|
ULONG i;
|
|
ULONG ulTempProptag;
|
|
TCHAR szStr[MAX_PATH];
|
|
LONG cCopied = 0;
|
|
|
|
hr = lpMailUser->lpVtbl->GetProps(lpMailUser,NULL, MAPI_UNICODE, &ulcValues, &lpPropArray);
|
|
if ( HR_SUCCEEDED(hr) )
|
|
{
|
|
|
|
for(i=0;i<ulcValues;i++)
|
|
{
|
|
cCopied = 0;
|
|
ulTempProptag = lpPropArray[i].ulPropTag;
|
|
switch( lpPropArray[i].ulPropTag )
|
|
{
|
|
case PR_HOME_TELEPHONE_NUMBER:
|
|
cCopied = LoadString( hinstMapiX, idsPhoneLabelHome,
|
|
szStr, CharSizeOf(szStr) );
|
|
break;
|
|
case PR_OFFICE_TELEPHONE_NUMBER:
|
|
cCopied = LoadString( hinstMapiX, idsPhoneLabelBus,
|
|
szStr, CharSizeOf(szStr) );
|
|
break;
|
|
case PR_BUSINESS2_TELEPHONE_NUMBER:
|
|
cCopied = LoadString( hinstMapiX, idsPhoneLabelBus2,
|
|
szStr, CharSizeOf(szStr) );
|
|
break;
|
|
case PR_MOBILE_TELEPHONE_NUMBER:
|
|
cCopied = LoadString( hinstMapiX, idsPhoneLabelMobile,
|
|
szStr, CharSizeOf(szStr) );
|
|
break;
|
|
case PR_RADIO_TELEPHONE_NUMBER:
|
|
cCopied = LoadString( hinstMapiX, idsPhoneLabelRadio,
|
|
szStr, CharSizeOf(szStr) );
|
|
break;
|
|
case PR_CAR_TELEPHONE_NUMBER:
|
|
cCopied = LoadString( hinstMapiX, idsPhoneLabelCar,
|
|
szStr, CharSizeOf(szStr) );
|
|
break;
|
|
case PR_OTHER_TELEPHONE_NUMBER:
|
|
cCopied = LoadString( hinstMapiX, idsPhoneLabelOther,
|
|
szStr, CharSizeOf(szStr) );
|
|
break;
|
|
case PR_PAGER_TELEPHONE_NUMBER:
|
|
cCopied = LoadString( hinstMapiX, idsPhoneLabelPager,
|
|
szStr, CharSizeOf(szStr) );
|
|
break;
|
|
case PR_ASSISTANT_TELEPHONE_NUMBER:
|
|
cCopied = LoadString( hinstMapiX, idsPhoneLabelAst,
|
|
szStr, CharSizeOf(szStr) );
|
|
break;
|
|
case PR_HOME2_TELEPHONE_NUMBER:
|
|
cCopied = LoadString( hinstMapiX, idsPhoneLabelHome2,
|
|
szStr, CharSizeOf(szStr) );
|
|
break;
|
|
case PR_COMPANY_MAIN_PHONE_NUMBER:
|
|
cCopied = LoadString( hinstMapiX, idsPhoneLabelCompMain,
|
|
szStr, CharSizeOf(szStr) );
|
|
break;
|
|
case PR_BUSINESS_FAX_NUMBER:
|
|
cCopied = LoadString( hinstMapiX, idsPhoneLabelFaxBus,
|
|
szStr, CharSizeOf(szStr) );
|
|
break;
|
|
case PR_HOME_FAX_NUMBER:
|
|
cCopied = LoadString( hinstMapiX, idsPhoneLabelFaxHome,
|
|
szStr, CharSizeOf(szStr) );
|
|
break;
|
|
default:
|
|
if(lpPropArray[i].ulPropTag == PR_WAB_IPPHONE)
|
|
cCopied = LoadString( hinstMapiX, idsPhoneLabelIPPhone, szStr, CharSizeOf(szStr) );
|
|
break;
|
|
}
|
|
if( cCopied > 0 )
|
|
{
|
|
LRESULT iItem;
|
|
LPTSTR lpCompletePhNum = NULL;
|
|
LPTSTR lpPhNum;
|
|
int len = lstrlen( lpPropArray[i].Value.LPSZ ) + 1;
|
|
lpPhNum = LocalAlloc(LMEM_ZEROINIT, sizeof( TCHAR ) * len );
|
|
if( !lpPhNum )
|
|
{
|
|
DebugTrace(TEXT("cannot allocate memory for lpPhNum\n"));
|
|
SendMessage(hWnd, IDCANCEL, (WPARAM)(0), (LPARAM)(0) );
|
|
}
|
|
lstrcpy(lpPhNum, lpPropArray[i].Value.LPSZ);
|
|
|
|
FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
|
szStr, 0, 0, (LPTSTR)&lpCompletePhNum, 0, (va_list *)&lpPropArray[i].Value.LPSZ);
|
|
|
|
if( lpCompletePhNum )
|
|
{
|
|
iItem = SendDlgItemMessage( hWnd, IDC_NEWCALL_COMBO_PHNUM,
|
|
CB_ADDSTRING, (WPARAM)(0), (LPARAM)(LPCTSTR)(lpCompletePhNum));
|
|
}
|
|
else
|
|
iItem = CB_ERR;
|
|
|
|
if( iItem == CB_ERR )
|
|
{
|
|
DebugTrace(TEXT("ERROR adding string %s"), lpCompletePhNum);
|
|
}
|
|
|
|
SendDlgItemMessage( hWnd, IDC_NEWCALL_COMBO_PHNUM,
|
|
CB_SETITEMDATA, (WPARAM)(iItem), (LPARAM)(lpPhNum) );
|
|
LocalFree(lpCompletePhNum);
|
|
}
|
|
}
|
|
MAPIFreeBuffer(lpPropArray);
|
|
}
|
|
lpMailUser->lpVtbl->Release(lpMailUser);
|
|
}
|
|
}
|
|
|
|
/**
|
|
GetPhoneNumData: copies the data from the PHNUM combo to the szDestAddr buffer
|
|
memory must have been allocated for szDestAddr
|
|
|
|
[OUT] szDestAddr - buffer to be filled with the data from the comboBox
|
|
|
|
returns the number of characters copied from combo_box to szDestAddr buffer
|
|
*/
|
|
UINT GetPhoneNumData( HWND hDlg, LPTSTR szDestAddr)
|
|
{
|
|
LRESULT iIndex, iData;
|
|
UINT cch = 0;
|
|
TCHAR szBuff[MAX_PATH];
|
|
|
|
// determine which index was selected
|
|
iIndex = SendDlgItemMessage( hDlg, IDC_NEWCALL_COMBO_PHNUM,
|
|
CB_GETCURSEL, (WPARAM)(0), (LPARAM)(0));
|
|
|
|
// if nothing is selected then copy everything in the buffer
|
|
// if( iIndex == CB_ERR)
|
|
// {
|
|
cch = (UINT) SendDlgItemMessage( hDlg, IDC_NEWCALL_COMBO_PHNUM, WM_GETTEXT,
|
|
(WPARAM)(TAPIMAXDESTADDRESSSIZE), (LPARAM)(LPTSTR)(szDestAddr));
|
|
/** }
|
|
else
|
|
{
|
|
// otherwise obtain the data for the selected item
|
|
iData = SendDlgItemMessage( hDlg, IDC_NEWCALL_COMBO_PHNUM,
|
|
CB_GETITEMDATA, (WPARAM)(iIndex), (LPARAM)(0) );
|
|
if( iData == CB_ERR )
|
|
{
|
|
cch = -1;
|
|
DebugTrace(TEXT("Unable to obtain data from ComboBox entry that should have data associated\n"));
|
|
}
|
|
else
|
|
{
|
|
// copy the item to a temp buffer
|
|
lstrcpy( szDestAddr, (LPCTSTR)iData);
|
|
DebugTrace(TEXT("String is %s\n"), szDestAddr );
|
|
DebugTrace(TEXT("Index was %d\n"), iIndex );
|
|
}
|
|
}
|
|
*/
|
|
// a character count of 0 indicates there was no data for a particular item
|
|
return cch;
|
|
}
|
|
|
|
/**
|
|
HrSetComboText: a helper function that will set the text entry of the PHNUM combo
|
|
with just the telephone number (removing the description)
|
|
[IN] hCombo - the combo box to update, this must be the PHNUM combo.
|
|
*/
|
|
HRESULT HrSetComboText(HWND hCombo)
|
|
{
|
|
LRESULT iIndex;
|
|
LPTSTR szData;
|
|
HRESULT hr = S_OK;
|
|
TCHAR szBuff[MAX_PATH], szDestAddr[TAPIMAXDESTADDRESSSIZE];
|
|
// determine which index was selected
|
|
iIndex = SendMessage( hCombo, CB_GETCURSEL, (WPARAM)(0), (LPARAM)(0));
|
|
if( iIndex != CB_ERR)
|
|
{
|
|
// obtain the data for the selected item
|
|
szData = (LPTSTR)SendMessage( hCombo, CB_GETITEMDATA, (WPARAM)(iIndex), (LPARAM)(0) );
|
|
if( (LRESULT)szData == CB_ERR )
|
|
{
|
|
DebugTrace(TEXT("Unable to obtain data from ComboBox entry that should have data associated\n"));
|
|
szData = szEmpty;
|
|
hr = E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
LRESULT lr;
|
|
LPVOID lpData;
|
|
if( !szData )
|
|
szData = szEmpty;
|
|
// only copy the data after the offset stored for the item
|
|
lr = SendMessage( hCombo, CB_INSERTSTRING, (WPARAM)(iIndex), (LPARAM)(LPTSTR)(szData));
|
|
if( lr == CB_ERR || lr == CB_ERRSPACE)
|
|
{
|
|
DebugTrace(TEXT("unable to insert string = %s at index = %d \n"), szData, iIndex);
|
|
hr = E_FAIL;
|
|
}
|
|
lpData = (LPVOID)SendMessage( hCombo, CB_GETITEMDATA, (WPARAM)(iIndex+1), (LPARAM)(0) );
|
|
if( (LRESULT)lpData == CB_ERR )
|
|
{
|
|
DebugTrace(TEXT("unable to get data for %d"), iIndex+1);
|
|
hr = E_FAIL;
|
|
}
|
|
lr = SendMessage( hCombo, CB_SETITEMDATA, (WPARAM)(iIndex), (LPARAM)(lpData) );
|
|
if( lr == CB_ERR )
|
|
{
|
|
DebugTrace(TEXT("unable to set data at %d"), iIndex);
|
|
hr = E_FAIL;
|
|
}
|
|
lr = SendMessage( hCombo, CB_DELETESTRING, (WPARAM)(iIndex+1), (LPARAM)(0) );
|
|
if( lr == CB_ERR )
|
|
{
|
|
DebugTrace(TEXT("unable to delete string at %d"), iIndex+1);
|
|
hr = E_FAIL;
|
|
}
|
|
lr = SendMessage( hCombo, CB_SETCURSEL, (WPARAM)(iIndex), (LPARAM)(0) );
|
|
if( lr == CB_ERR )
|
|
{
|
|
DebugTrace(TEXT("unable to set selection at %d"), iIndex);
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
|
|
if( HR_FAILED(hr) )
|
|
DebugTrace(TEXT("settext failed\n"));
|
|
return hr;
|
|
}
|
|
|
|
/**
|
|
DisableCallBtnOnEmptyPhoneField: Will disable the call button if there is no text in
|
|
in the PHNUM combo box. Will enable the button if
|
|
text is present. Does not check to see if button is
|
|
already enabled/disabled, but enabling an enabled btn
|
|
should be fine.
|
|
*/
|
|
void DisableCallBtnOnEmptyPhoneField(HWND hDlg)
|
|
{
|
|
HWND hComboItem = GetDlgItem( hDlg, IDC_NEWCALL_COMBO_PHNUM);
|
|
LRESULT iCurSel, iCurContSel;
|
|
iCurSel = SendMessage( hComboItem, CB_GETCURSEL, 0L, 0L );
|
|
iCurContSel = SendDlgItemMessage(hDlg, IDC_NEWCALL_COMBO_CONTACT, CB_GETCURSEL, (WPARAM)(0), (LPARAM)(0) );
|
|
if( iCurContSel < 0 || iCurContSel == CB_ERR)
|
|
SendMessage(hComboItem, CB_RESETCONTENT, 0L, 0L);
|
|
if( iCurSel < 0 || iCurSel == CB_ERR )
|
|
{
|
|
LRESULT cch;
|
|
TCHAR szBuf[MAX_PATH];
|
|
cch = SendMessage( hComboItem, WM_GETTEXT, (WPARAM)(CharSizeOf( szBuf) ),
|
|
(LPARAM)(szBuf) );
|
|
|
|
|
|
if( (INT)cch <= 0 || cch == CB_ERR)
|
|
{
|
|
// content will be empty at this point so can safely add
|
|
int cCopied;
|
|
LRESULT iIndex;
|
|
TCHAR szBuf[MAX_PATH];
|
|
cCopied = LoadString( hinstMapiX, idsNoPhoneNumAvailable,
|
|
szBuf, CharSizeOf(szBuf) );
|
|
iIndex = SendMessage(hComboItem, CB_ADDSTRING, (WPARAM)(0), (LPARAM)(szBuf));
|
|
SendMessage(hComboItem, CB_SETITEMDATA, (WPARAM)(0), (LPARAM)(0));
|
|
EnableWindow( GetDlgItem(hDlg, IDC_NEWCALL_BUTTON_CALL), FALSE);
|
|
return;
|
|
}
|
|
}
|
|
EnableWindow( GetDlgItem(hDlg, IDC_NEWCALL_BUTTON_CALL), TRUE);
|
|
}
|
|
|
|
VOID FAR PASCAL lineCallbackFunc( DWORD a, DWORD b, DWORD_PTR c, DWORD_PTR d, DWORD_PTR e, DWORD_PTR f)
|
|
{}
|
|
|
|
|
|
#ifdef _NT50_TAPI30
|
|
|
|
/**
|
|
HrLPSZCPToBSTR: (BSTR helper) helper to convert LPTSTR -> BST
|
|
*/
|
|
HRESULT HrLPSZCPToBSTR(UINT cp, LPTSTR lpsz, BSTR *pbstr)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
BSTR bstr=0;
|
|
ULONG cch = 0, ccb,
|
|
cchRet;
|
|
|
|
if (!IsValidCodePage(cp))
|
|
cp = GetACP();
|
|
|
|
// get byte count
|
|
ccb = lstrlen(lpsz);
|
|
|
|
// get character count - DBCS string ccb may not equal to cch
|
|
cch=MultiByteToWideChar(cp, 0, lpsz, ccb, NULL, 0);
|
|
if(cch==0 && ccb!=0)
|
|
{
|
|
AssertSz(cch, TEXT("MultiByteToWideChar failed"));
|
|
hr=E_FAIL;
|
|
goto error;
|
|
}
|
|
// allocate a wide-string with enough character to hold string - use character count
|
|
bstr = (BSTR)LocalFree(LMEM_ZEROINIT, sizeof( BSTR ) * cch + 1);
|
|
|
|
if(!bstr)
|
|
{
|
|
hr=E_OUTOFMEMORY;
|
|
goto error;
|
|
}
|
|
|
|
cchRet=MultiByteToWideChar(cp, 0, lpsz, ccb, (LPWSTR)bstr, cch);
|
|
if(cchRet==0 && ccb!=0)
|
|
{
|
|
hr=E_FAIL;
|
|
goto error;
|
|
}
|
|
|
|
*pbstr = bstr;
|
|
bstr=0; // freed by caller
|
|
|
|
error:
|
|
if(bstr)
|
|
LocalFree(bstr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
/**
|
|
HrLPSZToBSTR: Converts a LPTSTR to a BSTR using a helper function
|
|
*/
|
|
HRESULT HrLPSZToBSTR(LPTSTR lpsz, BSTR *pbstr)
|
|
{
|
|
// GetACP so that it works on non-US platform
|
|
return HrLPSZCPToBSTR(GetACP(), lpsz, pbstr);
|
|
}
|
|
|
|
#endif //#ifdef _NT50_TAPI30
|