|
|
/* Copyright (c) 1999 Microsoft Corporation */
#include "phonemgr.h"
#include <stdlib.h>
#include <stdio.h>
#include <wxdebug.h>
#ifdef _DBG
#define DEBUG(_x_) OutputDebugString(_x_)
#else
#define DEBUG(_x_)
#endif
ITRequest * g_pITRequest = NULL;
HRESULT InitAssistedTelephony(void) { HRESULT hr;
//
// Initialize COM.
//
printf("Initializing COM...\n");
hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
if ( FAILED(hr) ) { printf("CoInitialize failed - 0x%08x\n", hr);
return hr; }
//
// Cocreate the assisted telephony object.
//
printf("Creating RequestMakeCall object...\n");
hr = CoCreateInstance( CLSID_RequestMakeCall, NULL, CLSCTX_INPROC_SERVER, IID_ITRequest, (void **) & g_pITRequest );
if ( FAILED(hr) ) { printf("CoCreateInstance failed - 0x%08x\n", hr);
return hr; }
return S_OK; }
HRESULT MakeAssistedTelephonyCall(WCHAR * wszDestAddress) { HRESULT hr; BSTR bstrDestAddress = NULL; BSTR bstrAppName = NULL; BSTR bstrCalledParty = NULL; BSTR bstrComment = NULL;
bstrDestAddress = SysAllocString( wszDestAddress );
if ( bstrDestAddress == NULL ) { printf("SysAllocString failed");
return E_OUTOFMEMORY; }
//
// Make a call.
//
printf("Calling ITRequest::MakeCall...\n");
hr = g_pITRequest->MakeCall( bstrDestAddress, bstrAppName, bstrCalledParty, bstrComment );
SysFreeString( bstrDestAddress ); if ( FAILED(hr) ) { printf("ITRequest::MakeCall failed - 0x%08x\n", hr);
return hr; }
return S_OK; }
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { MSG msg; HWND hwnd, hwndEdit;
ghInst = hInstance; DialogBox( ghInst, MAKEINTRESOURCE(IDD_MAINDLG), NULL, MainWndProc );
return 0; }
INT_PTR CALLBACK MainWndProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
LPCTSTR lszAppName = _T("Generate DialTone"); DWORD dwNumDevs, i; LONG lResult; PHONEINITIALIZEEXPARAMS initExParams; PMYPHONE pNextPhone; PWCHAR szAddressToCall; ghDlg = hDlg;
switch (uMsg) { case WM_INITDIALOG: initExParams.dwTotalSize = sizeof (PHONEINITIALIZEEXPARAMS); initExParams.dwOptions = (DWORD) PHONEINITIALIZEEXOPTION_USEHIDDENWINDOW;
lResult = phoneInitializeEx( (LPHPHONEAPP) &ghPhoneApp, (HINSTANCE) ghInst, (PHONECALLBACK) tapiCallback, lszAppName, (LPDWORD) &dwNumDevs, (LPDWORD) &gdwAPIVersion, (LPPHONEINITIALIZEEXPARAMS) &initExParams );
if (lResult == 0) { gdwNumPhoneDevs = dwNumDevs; }
gpPhone = (PMYPHONE) LocalAlloc(LPTR,gdwNumPhoneDevs * sizeof(MYPHONE));
g_wszMsg = (LPWSTR) LocalAlloc(LPTR, sizeof(WCHAR) * 100 ); g_wszDest = (LPWSTR) LocalAlloc(LPTR, sizeof(WCHAR) * 100 );
// Opening all the phones
for(i = 0, pNextPhone = gpPhone; i < gdwNumPhoneDevs; i++, pNextPhone++) { CreatePhone(pNextPhone, i); }
SetStatusMessage(TEXT("Waiting for input from Phones"));
g_szDialStr = (LPWSTR) LocalAlloc(LPTR, 20 * sizeof(WCHAR)); lstrcpy(g_szDialStr, TEXT("Dial Number: ")); break;
case WM_COMMAND: if ( LOWORD(wParam) == IDCANCEL ) { //
// The close box or Exit button was pressed.
//
SetStatusMessage(TEXT("End Application"));
if(ghPhoneApp) { phoneShutdown(ghPhoneApp); } EndDialog( hDlg, 0 );
LocalFree(g_szDialStr); LocalFree(g_wszMsg); LocalFree(g_wszDest);
for( i=0; i<gdwNumPhoneDevs; i++ ) { FreePhone(&gpPhone[i]); } LocalFree(gpPhone);
} else if ( LOWORD(wParam) == IDC_MAKECALL ) { //
// The Make Call button was pressed.
//
//
// Stop dialtone.
// this only works for one phone.
// Should be fine as we don't have
// the window visible unless you have the phone off hook.
//
gpPhone[0].pTonePlayer->StopDialtone();
//
// Dial the dest address in the edit box.
//
const int ciMaxPhoneNumberSize = 400; WCHAR wszPhoneNumber[ciMaxPhoneNumberSize]; UINT uiResult; uiResult = GetDlgItemText( ghDlg, // handle to dialog box
IDC_DESTADDRESS, // identifier of control
wszPhoneNumber, // pointer to buffer for text (unicode)
ciMaxPhoneNumberSize // maximum size of string (in our buffer)
);
if ( uiResult == 0 ) { DoMessage(L"Could not get dialog item text; not making call"); } else { MakeAssistedTelephonyCall(wszPhoneNumber); } }
break;
default: break; }
return 0; }
VOID CALLBACK tapiCallback( DWORD hDevice, DWORD dwMsg, ULONG_PTR CallbackInstance, ULONG_PTR Param1, ULONG_PTR Param2, ULONG_PTR Param3 ) { PMYPHONE pPhone; DWORD i; BOOL bDialtone = FALSE;
if (hDevice != NULL) { pPhone = GetPhone((HPHONE) hDevice);
if (pPhone == NULL) { DEBUG(L"tapiCallback - phone not found\n"); return; } }
switch (dwMsg) { case PHONE_STATE: DEBUG(L"PHONE_STATE\n"); if (pPhone != NULL) { EnterCriticalSection(&pPhone->csdial); if ( Param1 == PHONESTATE_HANDSETHOOKSWITCH ) { if ( Param2 != PHONEHOOKSWITCHMODE_ONHOOK ) // if off hook
{ if ( FAILED(pPhone->pTonePlayer->StartDialtone()) ) { DoMessage(L"StartDialTone Failed"); }
// ZoltanS: show the window now
ShowWindow(ghDlg, SW_SHOWNORMAL);
pPhone->dwHandsetMode = PHONEHOOKSWITCHMODE_MICSPEAKER;
lstrcpy(pPhone->wszDialStr,TEXT("")); lstrcpy(g_wszMsg,TEXT("Generating Dialtone for phones: "));
for( i=0 ; i < gdwNumPhoneDevs; i++) { if ( gpPhone[i].pTonePlayer->IsInUse() ) { wsprintf(g_wszDest,TEXT("%d"),i); lstrcat(g_wszMsg,g_wszDest); } } SetStatusMessage(g_wszMsg); } else // on hook
{ pPhone->dwHandsetMode = PHONEHOOKSWITCHMODE_ONHOOK; lstrcpy(pPhone->wszDialStr,TEXT(""));
if ( pPhone->pTonePlayer->IsInUse() ) { pPhone->pTonePlayer->StopDialtone(); }
// ZoltanS: hide the window now
ShowWindow(ghDlg, SW_HIDE);
bDialtone = FALSE; lstrcpy(g_wszMsg,TEXT("Generating Dialtone for phones: ")); for( i = 0 ; i < gdwNumPhoneDevs; i++ ) { if ( gpPhone[i].pTonePlayer->DialtonePlaying() ) { wsprintf(g_wszDest,TEXT("%d"),i); lstrcat(g_wszMsg,g_wszDest); bDialtone = TRUE; } } if(!bDialtone) { SetStatusMessage(TEXT("Waiting for input from Phones")); } else { SetStatusMessage(g_wszMsg); } } } LeaveCriticalSection(&pPhone->csdial); } break;
case PHONE_BUTTON: DEBUG(L"PHONE_BUTTON\n"); if (pPhone != NULL) { EnterCriticalSection(&pPhone->csdial); if ( Param2 == PHONEBUTTONMODE_KEYPAD ) { if (pPhone->dwHandsetMode != PHONEHOOKSWITCHMODE_ONHOOK) { if ( Param3 == PHONEBUTTONSTATE_DOWN ) { if ( pPhone->pTonePlayer->IsInUse() ) { if ( ( (int)Param1 >= 0 ) && ( (int)Param1 <= 9 ) ) { //
// We have a dialed digit. Append it to the phone
// number we have so far.
//
wsprintf(g_wszDest, TEXT("%d"), Param1);
lstrcat(pPhone->wszDialStr, g_wszDest);
//
// Append the phone number so far to a standard prefix
// ("Phone number: ") and update the UI.
//
lstrcpy(g_wszMsg, g_szDialStr);
lstrcat(g_wszMsg,pPhone->wszDialStr);
SetStatusMessage(g_wszMsg);
//
// Generate a DTMF tone for this digit.
//
pPhone->pTonePlayer->GenerateDTMF( (long)Param1 ); } else if ( Param1 == 10 ) { //
// Generate a DTMF tone for "*". This will not count
// as part of the dialed number.
//
pPhone->pTonePlayer->GenerateDTMF( (long)Param1 ); } else if ( Param1 == 11 ) { //
// Generate a DTMF tone for "#". This will not count
// as part of the dialed number but it will tell us
// to make the call immediately.
//
pPhone->pTonePlayer->GenerateDTMF( (long)Param1 );
//
// Make the call.
//
if ( S_OK == MakeAssistedTelephonyCall(pPhone->wszDialStr) ) { SetStatusMessage(L"Call created"); } else { SetStatusMessage(L"Failed to create the call"); }
} } // if in use
} // if button down
} // if off hook
} // if keypad
LeaveCriticalSection(&pPhone->csdial); } break; // case phone_button
case PHONE_CLOSE: DEBUG(L"PHONE_CLOSE\n"); if (pPhone != NULL) { EnterCriticalSection(&pPhone->csdial);
phoneClose(pPhone->hPhone);
LeaveCriticalSection(&pPhone->csdial); } break;
case PHONE_REMOVE: DEBUG(L"PHONE_REMOVE\n"); pPhone = GetPhoneByID( (DWORD)Param1);
if (pPhone != NULL) { FreePhone(pPhone); RemovePhone(pPhone); } break;
case PHONE_CREATE: DEBUG(L"PHONE_CREATE\n");
pPhone = AddPhone(); CreatePhone(pPhone, (DWORD)Param1); break;
default: break; } }
//////////////////////////////////////////////////////////////////
// SetStatusMessage
//////////////////////////////////////////////////////////////////
void SetStatusMessage( LPWSTR pszMessage ) { SetDlgItemText( ghDlg, IDC_STATUS, pszMessage ); }
//////////////////////////////////////////////////////////////////
// CreatePhone
//////////////////////////////////////////////////////////////////
void CreatePhone( PMYPHONE pPhone, DWORD dwDevID ) { LRESULT lResult;
pPhone->hPhoneApp = ghPhoneApp; InitializeCriticalSection(&pPhone->csdial);
// won't detect overrun if dialing more than 100 digits
pPhone->wszDialStr = (LPWSTR) LocalAlloc(LPTR, 100 * sizeof(WCHAR)); pPhone->dwHandsetMode = PHONEHOOKSWITCHMODE_ONHOOK;
lResult = phoneOpen( ghPhoneApp, dwDevID, &pPhone->hPhone, gdwAPIVersion, 0, (DWORD_PTR) NULL, PHONEPRIVILEGE_OWNER );
//
// Save info about this phone that we can display later
//
pPhone->dwDevID = dwDevID; pPhone->dwAPIVersion = gdwAPIVersion; pPhone->dwPrivilege = PHONEPRIVILEGE_OWNER;
DWORD dwBigBuffSize = sizeof(VARSTRING) + sizeof(DWORD) * 5;
LPVOID pBuffer = LocalAlloc(LPTR,dwBigBuffSize);
LPVARSTRING lpDeviceID = (LPVARSTRING) pBuffer;
lpDeviceID->dwTotalSize = dwBigBuffSize;
LPWSTR lpszDeviceClass;
lpszDeviceClass = (LPWSTR) LocalAlloc(LPTR, sizeof(WCHAR) * 20); lstrcpy(lpszDeviceClass, TEXT("wave/in"));
lResult = phoneGetID( pPhone->hPhone, lpDeviceID, lpszDeviceClass );
if(lResult != 0) { pPhone->lCaptureID = WAVE_MAPPER; } else { CopyMemory( &pPhone->lCaptureID, (LPBYTE) lpDeviceID + lpDeviceID->dwStringOffset, lpDeviceID->dwStringSize ); }
lstrcpy(lpszDeviceClass, TEXT("wave/out")); lResult = phoneGetID( pPhone->hPhone, lpDeviceID, lpszDeviceClass );
if(lResult != 0) { pPhone->lRenderID = WAVE_MAPPER; } else { CopyMemory( &pPhone->lRenderID, (LPBYTE) lpDeviceID + lpDeviceID->dwStringOffset, lpDeviceID->dwStringSize ); }
LocalFree(lpszDeviceClass); LocalFree(pBuffer);
lResult = phoneSetStatusMessages( pPhone->hPhone, PHONESTATE_HANDSETHOOKSWITCH, PHONEBUTTONMODE_FEATURE | PHONEBUTTONMODE_KEYPAD, PHONEBUTTONSTATE_UP | PHONEBUTTONSTATE_DOWN );
pPhone->pTonePlayer = new CTonePlayer;
if ( (pPhone->pTonePlayer == NULL) || FAILED(pPhone->pTonePlayer->Initialize()) ) { DoMessage(L"Tone Player Initialization Failed"); } else if ( FAILED(pPhone->pTonePlayer->OpenWaveDevice( pPhone->lRenderID )) ) { DoMessage(L"OpenWaveDevice Failed"); }
if ( FAILED( InitAssistedTelephony() ) ) { DoMessage(L"InitAssistedTelephony Failed"); } }
//////////////////////////////////////////////////////////////////
// FreePhone
//////////////////////////////////////////////////////////////////
void FreePhone( PMYPHONE pPhone ) { EnterCriticalSection(&pPhone->csdial);
if ( pPhone->pTonePlayer->IsInUse() ) { pPhone->pTonePlayer->StopDialtone(); pPhone->pTonePlayer->CloseWaveDevice(); } LocalFree(pPhone->wszDialStr);
LeaveCriticalSection(&pPhone->csdial);
DeleteCriticalSection(&pPhone->csdial); }
///////////////////////////////////////////////////////////////////
// GetPhone
///////////////////////////////////////////////////////////////////
PMYPHONE GetPhone (HPHONE hPhone ) {
DWORD i; for(i = 0; i < gdwNumPhoneDevs; i++) { if(gpPhone[i].hPhone == hPhone) { return &gpPhone[i]; } } return (PMYPHONE) NULL; }
///////////////////////////////////////////////////////////////////
// GetPhoneByID
///////////////////////////////////////////////////////////////////
PMYPHONE GetPhoneByID (DWORD dwDevID ) {
DWORD i; for(i = 0; i < gdwNumPhoneDevs; i++) { if(gpPhone[i].dwDevID == dwDevID) { return &gpPhone[i]; } } return (PMYPHONE) NULL; }
///////////////////////////////////////////////////////////////////
// RemovePhone
///////////////////////////////////////////////////////////////////
void RemovePhone (PMYPHONE pPhone) { DWORD i,j; PMYPHONE pNewPhones;
pNewPhones = (PMYPHONE) LocalAlloc(LPTR,(gdwNumPhoneDevs-1) * sizeof(MYPHONE)); for(i = 0, j = 0; i < gdwNumPhoneDevs; i++) { if(&gpPhone[i] != pPhone) { CopyMemory( &pNewPhones[j], &gpPhone[i], sizeof(MYPHONE)); j++; } }
LocalFree(gpPhone); gpPhone = pNewPhones; gdwNumPhoneDevs--; }
///////////////////////////////////////////////////////////////////
// AddPhone
///////////////////////////////////////////////////////////////////
PMYPHONE AddPhone () { PMYPHONE pNewPhones;
pNewPhones = (PMYPHONE) LocalAlloc(LPTR,(gdwNumPhoneDevs+1) * sizeof(MYPHONE)); CopyMemory( pNewPhones, gpPhone, gdwNumPhoneDevs * sizeof(MYPHONE));
LocalFree(gpPhone); gpPhone = pNewPhones; gdwNumPhoneDevs++;
return &gpPhone[gdwNumPhoneDevs-1]; } ///////////////////////////////////////////////////////////////////
// DoMessage
///////////////////////////////////////////////////////////////////
void DoMessage( LPWSTR pszMessage ) { MessageBox( ghDlg, pszMessage, gszTapi30, MB_OK ); }
|