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.
 
 
 
 
 
 

4029 lines
134 KiB

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
dialer.c
--*/
#include "dialer.h"
#include "string.h"
#include "tchar.h"
#include "stdlib.h"
#include "shellapi.h"
#define DIALER_REGISTRY_PATH TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Dialer")
#define DIALER_REGISTRY_ROOT HKEY_CURRENT_USER
#define ISDIGIT(x) (((x) - TEXT('0')) >= 0) && (((x) - TEXT('0')) <= 9)
enum NumberTypes
{
LOCAL_NUMBER = 7,
EXTENDED_LOCAL_NUMBER,
LONG_DISTANCE_NUMBER = 10,
EXTENDED_LONG_DISTANCE_NUMBER
};
// structs
typedef struct tagLINEINFO
{
DWORD nAddr; // Number of avail. addresses on the line
BOOL fVoiceLine; // Is this a voice line?
DWORD dwAPIVersion; // API version which the line supports
HLINE hLine; // line handle returned by lineOpen
DWORD dwPermanentLineID; // Permanent line ID retreived from devcaps
TCHAR szLineName[MAXBUFSIZE]; // the line's name
} LINEINFO, *LPLINEINFO;
// Global variables
// window/instance variables
HWND ghWndMain;
HWND ghWndDialing = NULL;
HINSTANCE ghInst = 0;
// file name vars.
static TCHAR gszAppName[64];
static TCHAR gszINIfilename [] = TEXT("DIALER.INI";)
static TCHAR gszHELPfilename [] = TEXT("DIALER.HLP");
static TCHAR gszDialerClassName[] = TEXT("DialerClass");
TCHAR const gszNULL[] = TEXT("");
// window item variables
HLINEAPP ghLineApp = 0; // Dialer's usage handle (regist. w/TAPI)
HCALL ghCall = 0; // call handle for Dialer's call
LPTSTR gszCurrentNumber = NULL; // number of destination of current call
LPTSTR gszCurrentName = NULL; // name of destination of current call
BOOL gfRegistered; // was lineRegisterRequestRecipient()
// successful?
BOOL gfNeedToReinit = FALSE; // does Dialer need to re-initialize?
BOOL gfCallRequest = FALSE; // Does a Simple TAPI app want a call?
BOOL gfCurrentLineAvail = TRUE; // Simple TAPI requests are only carried
// out if the current chosen line is avail.
BOOL gfMakeCallReplyPending = FALSE;
LONG gMakeCallRequestID = 0; // request ID returned by async TAPI fns.
LONG gDropCallRequestID = 0; // request ID returned by async TAPI fns.
DWORD gnAvailDevices = 0; // # of line devices avail. to Dialer
LINEINFO gCurrentLineInfo;
DWORD * gnAddr;
// global to remember where the cursor is in the edit control
DWORD gdwStartSel;
DWORD gdwEndSel;
DWORD * gdwPLID; // current line's permanent line ID
DWORD giCurrentLine = (DWORD)-1; // the line selected by the user
DWORD giCurrentAddress = 0; // the address selected by the user
// + 1 so we can work 1-based rather than 0-based (for convenience only)
// global varibles to hold the names and address of the
TCHAR gszSDNumber[ NSPEEDDIALS + 1 ][ TAPIMAXDESTADDRESSSIZE ] = {0};
// Function declarations
// button related functions
VOID DisableDialButtons(BOOL fDisable);
VOID FitTextToButton( HWND, INT, LPTSTR );
// Callback functions
INT_PTR CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK DialingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK AboutProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK ConnectUsingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK LineInUseProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK SpeedDial1Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK SpeedDial2Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
VOID CALLBACK tapiCallback (
DWORD hDevice, DWORD dwMsg,
DWORD dwCallbackInstance,
DWORD dwParam1, DWORD dwParam2,
DWORD dwParam3
);
// tapi related functions
VOID ManageAssistedTelephony(VOID);
VOID InitiateCall(LPCTSTR szNumber, LPCTSTR szName);
VOID DialerLineClose(VOID);
VOID DialerCleanup(VOID);
VOID CloseTAPI(VOID);
DWORD GetLineInfo(DWORD iLine, LPLINEINFO lpLineInfo);
VOID GetLineInfoFailed (
DWORD iLine, LPLINEDEVCAPS lpDevCaps,
LPLINEINFO lpLineInfo
);
LPTSTR GetAddressName(DWORD iLine, DWORD iAddress);
BOOL MakeCanonicalNumber( LPCTSTR szName, LPTSTR szCanNumber );
// misc. helper functions
VOID ReadINI(VOID);
int errString(HWND hWnd, UINT errCode, UINT uFlags);
VOID AddToRedialList(LPCTSTR szNumber);
BOOL InitializeLineBox(HWND hwndLineBox);
BOOL InitializeAddressBox(HWND hwndLineBox, HWND hwndAddressBox);
BOOL Is911 ( LPLINETRANSLATEOUTPUT lpTransOut );
VOID AmpersandCompensate( LPCTSTR lpszSrc, LPTSTR lpszDst );
VOID AmpersandDeCompensate( LPCTSTR lpszSrc, LPTSTR lpszDst );
// Dialer memory management functions
LPVOID DialerAlloc(size_t cbToAlloc);
LPVOID DialerFree(LPVOID lpMem);
// Function definitions
//***************************************************************************
//***************************************************************************
//***************************************************************************
DWORD InitializeTAPI (VOID)
{
INT cvLine;
DWORD iLine;
DWORD dwPreferredPLID, dwID = (DWORD) -1;
MSG msg;
LPLINEINFO lpLineInfo = NULL; // LINEINFO for each available line
DWORD errCode;
DWORD tc = GetTickCount();
DWORD dwReturn = ERR_NONE;
TCHAR szBuffer[MAXBUFSIZE]; // to read in dwPreferredPLID as a string first
DWORD dwTapiVersion = TAPI_CURRENT_VERSION;
LINEINITIALIZEEXPARAMS lip = {sizeof (LINEINITIALIZEEXPARAMS),
sizeof (LINEINITIALIZEEXPARAMS),
sizeof (LINEINITIALIZEEXPARAMS),
LINEINITIALIZEEXOPTION_USEHIDDENWINDOW};
HKEY hKey = NULL;
DWORD dwSize;
errCode = lineInitializeEx (
&ghLineApp,
ghInst,
(LINECALLBACK) tapiCallback,
gszAppName,
&gnAvailDevices,
&dwTapiVersion,
&lip
);
if ( errCode == LINEERR_REINIT )
{
// take away dialer functionality
EnableWindow( ghWndMain, FALSE );
DisableDialButtons(TRUE);
// keep trying until the user cancels
// or we stop getting LINEERR_REINIT
while ( ( errCode = lineInitializeEx (
&ghLineApp,
ghInst,
(LINECALLBACK)tapiCallback,
gszAppName,
&gnAvailDevices,
&dwTapiVersion,
&lip
) )
== LINEERR_REINIT )
{
// flush queue & yield
while ( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
// bring up the box if 5 seconds have passed since
if(GetTickCount() > 5000 + tc)
{
if ( errString( ghWndMain, ikszWarningTapiReInit, MB_RETRYCANCEL )
== IDCANCEL )
{
break;
}
// reset the relative counter
tc = GetTickCount();
}
}
// give back dialer functionality
DisableDialButtons( FALSE );
EnableWindow( ghWndMain, TRUE );
}
if ( errCode )
{
dwReturn = errCode;
goto tapiinit_exit;
}
RegOpenKeyEx (DIALER_REGISTRY_ROOT, DIALER_REGISTRY_PATH, 0, KEY_READ, &hKey);
// retrieve preferred line info from INI file
dwSize = sizeof (szBuffer);
szBuffer[0] = 0;
if (ERROR_SUCCESS ==
RegQueryValueEx (hKey, TEXT("Preferred Line"), NULL, NULL, (LPBYTE)szBuffer, &dwSize))
{
dwPreferredPLID = (DWORD) _ttoi( szBuffer );
}
else
{
dwPreferredPLID = (DWORD) -1;
}
// -1 default - tells us if it ever gets set
giCurrentLine = (DWORD) -1;
// allocate buffer for storing LINEINFO for all of the available lines
// always allocate space for at least one line
if ( gnAvailDevices == 0 )
{
gnAddr = (DWORD *) DialerAlloc( sizeof( DWORD ) );
gdwPLID = (DWORD *) DialerAlloc( sizeof( DWORD ) );
lpLineInfo = (LPLINEINFO) DialerAlloc( sizeof( LINEINFO ) );
}
else
{
gnAddr = (DWORD *) DialerAlloc( sizeof( DWORD ) * (int)gnAvailDevices);
gdwPLID = (DWORD *) DialerAlloc( sizeof( DWORD ) * (int)gnAvailDevices);
lpLineInfo = (LPLINEINFO) DialerAlloc( sizeof( LINEINFO ) * (int)gnAvailDevices );
}
// if no space was set aside...
if ( lpLineInfo == NULL || gnAddr == NULL )
{
dwReturn = LINEERR_NOMEM;
goto tapiinit_exit;
}
// fill lpLineInfo[] and open each line
for ( iLine = 0, cvLine = 0; iLine < gnAvailDevices; ++iLine )
{
// skip remaining processing for this if it didn't open
if ( GetLineInfo( iLine, &lpLineInfo[iLine] ) != ERR_NONE )
continue;
gnAddr [ iLine ] = lpLineInfo[iLine].nAddr;
gdwPLID[ iLine ] = lpLineInfo[iLine].dwPermanentLineID;
if ( lpLineInfo[iLine].dwPermanentLineID == dwPreferredPLID )
giCurrentLine = iLine;
// note number of lines with Interactive voice caps.
// used to select a preferred line by default
if ( lpLineInfo [ iLine ].fVoiceLine )
{
cvLine++;
dwID = iLine;
}
}
// if we couldn't find the preferred line,
// try and assign one by default
// else bring up connect using dialog
if ( giCurrentLine == (DWORD)-1 )
{
// check if there is only one line
// that has interactive voice caps,
// make it default line
if ( cvLine == 1 )
{
giCurrentLine = dwID;
// if the preferred address read from the INI file
// was different i.e we are changing setting, inform
// the user
if ( dwPreferredPLID != -1 )
{
errString( ghWndMain, ERR_NEWDEFAULT, MB_ICONEXCLAMATION | MB_OK );
}
}
else
{
gCurrentLineInfo = lpLineInfo[0];
if ( DialogBoxParam (
ghInst,
MAKEINTRESOURCE(IDD_CONNECTUSING),
ghWndMain,
ConnectUsingProc,
INVALID_LINE
)
== -1)
{
dwReturn = (DWORD) -1;
}
else
{
dwReturn = ERR_NONE;
}
goto tapiinit_exit;
}
}
gCurrentLineInfo = lpLineInfo[ giCurrentLine ];
// select default address
giCurrentAddress = 0;
// get the name of the preferred address from ini file
dwSize = sizeof (szBuffer);
szBuffer[0] = 0;
if (ERROR_SUCCESS ==
RegQueryValueEx (hKey, TEXT("Preferred Address"), NULL, NULL, (LPBYTE)szBuffer, &dwSize))
{
giCurrentAddress = (DWORD) _ttoi( szBuffer );
// if the address is invalid, set default
if ( giCurrentAddress >= gCurrentLineInfo.nAddr )
giCurrentAddress = 0;
}
tapiinit_exit:
if (NULL != hKey)
{
RegCloseKey (hKey);
}
if (lpLineInfo)
{
DialerFree(lpLineInfo);
}
return dwReturn;;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
int WINAPI WinMain (
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
HACCEL hAccel;
MSG msg;
DWORD errCode;
HANDLE hImHere;
ghInst = GetModuleHandle( NULL );
LoadString( ghInst, ikszAppFriendlyName, gszAppName, sizeof(gszAppName)/sizeof(TCHAR) );
//
// Now, let's see if we've already got an instance of ourself
hImHere = CreateMutex(NULL, TRUE, TEXT("DialersIveBeenStartedMutex"));
//
// Is there another one of us already here?
if ( ERROR_ALREADY_EXISTS == GetLastError() )
{
HWND hDialerWnd;
hDialerWnd = FindWindow(gszDialerClassName,
NULL);
SetForegroundWindow(hDialerWnd);
CloseHandle( hImHere );
return 0;
}
{
WNDCLASS wc;
wc.style = CS_DBLCLKS | CS_SAVEBITS | CS_BYTEALIGNWINDOW;
wc.lpfnWndProc = DefDlgProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = ghInst;
wc.hIcon = LoadIcon(ghInst, MAKEINTRESOURCE(IDI_DIALER) );
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject (COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = gszDialerClassName;
RegisterClass(&wc);
}
// create the dialog box and set it with info
// from the .INI file
ghWndMain = CreateDialog (
ghInst,
MAKEINTRESOURCE(IDD_DIALER),
(HWND)NULL,
MainWndProc
);
ReadINI();
ShowWindow(ghWndMain, SW_SHOW);
UpdateWindow(ghWndMain);
// limit text in Number field to TAPIMAXDESTADDRESSSIZE
SendDlgItemMessage (
ghWndMain,
IDD_DCOMBO,
CB_LIMITTEXT,
(WPARAM)TAPIMAXDESTADDRESSSIZE,
0
);
// 0 (ERR_NONE) error code registers success - otherwise terminate
errCode = InitializeTAPI();
if(errCode)
{
errString(ghWndMain, errCode, MB_APPLMODAL | MB_ICONEXCLAMATION );
DialerCleanup();
return errCode;
}
errCode = lineRegisterRequestRecipient (
ghLineApp,
0, // registration instance
LINEREQUESTMODE_MAKECALL,
TRUE
);
if(errCode)
{
gfRegistered = FALSE;
errString(ghWndMain, errCode, MB_ICONEXCLAMATION | MB_OK );
}
else
{
gfRegistered = TRUE;
}
hAccel = LoadAccelerators(ghInst, gszAppName);
while ( GetMessage( &msg, NULL, 0, 0 ) )
{
if ( ghWndMain == NULL || !IsDialogMessage( ghWndMain, &msg ) )
{
if(!TranslateAccelerator(ghWndMain, hAccel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// If: 1) Dialer is a call manager (if not, ignore requests)
// 2) the currently chosen line is available
// 3) there is a Simple TAPI request
// Then: process the request
if ( gfCurrentLineAvail && gfCallRequest )
{
ManageAssistedTelephony();
}
}
DialerCleanup();
CloseHandle( hImHere );
return (int)msg.wParam;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
LPVOID DialerAlloc(size_t cbToAlloc)
{
return LocalAlloc(LPTR, cbToAlloc);
}
LPVOID DialerFree(LPVOID lpMem)
{
return LocalFree( lpMem );
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
VOID ReadINI( VOID )
{
WORD cSDEntry, cLastDialed;
POINT ptLeftTop;
TCHAR szName[ TAPIMAXCALLEDPARTYSIZE ] = {0};
TCHAR szTemp[ TAPIMAXCALLEDPARTYSIZE ];
TCHAR szNum[TAPIMAXDESTADDRESSSIZE];
TCHAR szFieldName[MAXBUFSIZE];
TCHAR *p;
HKEY hKey = NULL;
DWORD dwSize;
RegOpenKeyEx (DIALER_REGISTRY_ROOT, DIALER_REGISTRY_PATH, 0, KEY_READ, &hKey);
// get speed dial settings from INI file
for(cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry)
{
wsprintf(szFieldName, TEXT("Number%d"), cSDEntry);
*szNum = 0;
dwSize = sizeof (szNum);
RegQueryValueEx (hKey, szFieldName, NULL, NULL, (LPBYTE)szNum, &dwSize);
for (p = szNum; *p == TEXT(' '); p++);
if (0 == *p)
{
continue;
}
lstrcpyn (gszSDNumber[cSDEntry], p, sizeof(gszSDNumber[cSDEntry])/sizeof(TCHAR));
wsprintf(szFieldName, TEXT("Name%d"), cSDEntry);
dwSize = sizeof (szName);
RegQueryValueEx (hKey, szFieldName, NULL, NULL, (LPBYTE)szName, &dwSize);
if (0 == *szName)
{
lstrcpyn( szName, gszSDNumber[ cSDEntry ], sizeof(szName)/sizeof(szName[0]) );
}
FitTextToButton( ghWndMain, IDD_DSPEEDDIAL1 + cSDEntry - 1, szName );
AmpersandCompensate( szName, szTemp );
SetDlgItemText (
ghWndMain,
IDD_DSPEEDDIAL1 + cSDEntry - 1,
(LPCTSTR)szTemp
); // Label the speed dial button
}
// set up last dialed numbers in combo box (read from INI)
for(cLastDialed = 1; cLastDialed <= NLASTDIALED; ++cLastDialed)
{
wsprintf(szFieldName, TEXT("Last dialed %d"), cLastDialed);
dwSize = sizeof (szNum);
szNum[0] = 0;
RegQueryValueEx (hKey, szFieldName, NULL, NULL, (LPBYTE)szNum, &dwSize);
if (0 != szNum[0])
{
SendDlgItemMessage(
ghWndMain,
IDD_DCOMBO,
CB_ADDSTRING,
0,
(LPARAM)(LPCTSTR)szNum
);
}
}
// set defaults
ptLeftTop.x = 100;
ptLeftTop.y = 100;
// set the window position based on the INI data
dwSize = sizeof (ptLeftTop);
RegQueryValueEx (hKey, TEXT("Main Window Left/Top"), NULL, NULL, (LPBYTE)&ptLeftTop, &dwSize);
if ( ptLeftTop.x < 0
|| ptLeftTop.x + 50 >= GetSystemMetrics(SM_CXSCREEN)
|| ptLeftTop.y < 0
|| ptLeftTop.y + 50 >= GetSystemMetrics(SM_CYSCREEN)
)
{
ptLeftTop.x = 100; // set defaults if the box is off of the screen
ptLeftTop.y = 100; // set defaults if the box is off of the screen
}
SetWindowPos (
ghWndMain,
NULL,
ptLeftTop.x,
ptLeftTop.y,
0,
0,
SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOZORDER
);
RegCloseKey (hKey);
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
VOID DisableDialButtons(BOOL fDisable)
{
int IDD;
// Disable/enable Dial button
EnableWindow( GetDlgItem( ghWndMain, IDD_DDIAL ),!fDisable) ;
// Disable/enable Speed dial buttons
for ( IDD = IDD_DSPEEDDIAL1; IDD <= IDD_DSPEEDDIAL8; ++IDD )
{
EnableWindow(GetDlgItem(ghWndMain, IDD),!fDisable);
}
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
VOID DialerCleanup(VOID)
{
RECT rc;
WORD cItem; // count of numbers in combo box
DWORD cLastDialed;
TCHAR szNumber[TAPIMAXDESTADDRESSSIZE];
TCHAR szFieldName[MAXBUFSIZE];
HKEY hKey = NULL;
DWORD dwSize;
RegCreateKeyEx (DIALER_REGISTRY_ROOT, DIALER_REGISTRY_PATH, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
CloseTAPI(); // unregister and line close
if(!IsIconic(ghWndMain)) // if the window is not minimized, record position
{
GetWindowRect(ghWndMain, &rc);
RegSetValueEx (hKey,
TEXT("Main Window Left/Top"),
0,
REG_BINARY,
(LPBYTE)&rc,
sizeof(POINT));
}
cItem = (WORD)SendDlgItemMessage(ghWndMain, IDD_DCOMBO, CB_GETCOUNT, 0, 0);
// write out last dialed numbers from combo box (write to INI)
for(cLastDialed = 1; cLastDialed <= NLASTDIALED; ++cLastDialed)
{
if(cLastDialed <= cItem)
SendDlgItemMessage(
ghWndMain,
IDD_DCOMBO,
CB_GETLBTEXT,
cLastDialed - 1, // it's a zero-based count
(LPARAM)szNumber);
else
szNumber[0] = 0;
wsprintf(szFieldName, TEXT("Last dialed %d"), cLastDialed);
RegSetValueEx (hKey,
szFieldName,
0,
REG_SZ,
(LPBYTE)szNumber,
(lstrlen(szNumber)+1)*sizeof(TCHAR));
}
RegCloseKey (hKey);
WinHelp(ghWndMain, gszHELPfilename, HELP_QUIT, 0); // unload help
DestroyWindow(ghWndMain);
ghWndMain = NULL;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
// unregister and line close
VOID CloseTAPI(VOID)
{
// unregister as call manager
lineRegisterRequestRecipient (
ghLineApp,
0, // registration instance
LINEREQUESTMODE_MAKECALL,
FALSE
);
if ( gCurrentLineInfo.hLine )
{
lineClose ( gCurrentLineInfo.hLine );
gfCurrentLineAvail = FALSE;
gCurrentLineInfo.hLine = 0;
}
lineShutdown(ghLineApp);
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
INT_PTR CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HICON hIcon;
static const DWORD aMenuHelpIDs[] =
{
IDD_DSPEEDDIALGRP, (DWORD)-1,
IDD_DNUMTODIAL, IDH_DIALER_DIAL_NUMBER,
IDD_DCOMBO, IDH_DIALER_DIAL_NUMBER,
IDD_DDIAL, IDH_DIALER_DIAL_BUTTON,
IDD_DSPEEDDIAL1, IDH_DIALER_DIAL_SPEED_CHOOSE,
IDD_DSPEEDDIAL2, IDH_DIALER_DIAL_SPEED_CHOOSE,
IDD_DSPEEDDIAL3, IDH_DIALER_DIAL_SPEED_CHOOSE,
IDD_DSPEEDDIAL4, IDH_DIALER_DIAL_SPEED_CHOOSE,
IDD_DSPEEDDIAL5, IDH_DIALER_DIAL_SPEED_CHOOSE,
IDD_DSPEEDDIAL6, IDH_DIALER_DIAL_SPEED_CHOOSE,
IDD_DSPEEDDIAL7, IDH_DIALER_DIAL_SPEED_CHOOSE,
IDD_DSPEEDDIAL8, IDH_DIALER_DIAL_SPEED_CHOOSE,
IDD_DSPEEDDIALTEXT1, IDH_DIALER_DIAL_SPEED_CHOOSE,
IDD_DSPEEDDIALTEXT2, IDH_DIALER_DIAL_SPEED_CHOOSE,
IDD_DSPEEDDIALTEXT3, IDH_DIALER_DIAL_SPEED_CHOOSE,
IDD_DSPEEDDIALTEXT4, IDH_DIALER_DIAL_SPEED_CHOOSE,
IDD_DSPEEDDIALTEXT5, IDH_DIALER_DIAL_SPEED_CHOOSE,
IDD_DSPEEDDIALTEXT6, IDH_DIALER_DIAL_SPEED_CHOOSE,
IDD_DSPEEDDIALTEXT7, IDH_DIALER_DIAL_SPEED_CHOOSE,
IDD_DSPEEDDIALTEXT8, IDH_DIALER_DIAL_SPEED_CHOOSE,
IDD_DBUTTON1, IDH_DIALER_DIAL_KEYPAD,
IDD_DBUTTON2, IDH_DIALER_DIAL_KEYPAD,
IDD_DBUTTON3, IDH_DIALER_DIAL_KEYPAD,
IDD_DBUTTON4, IDH_DIALER_DIAL_KEYPAD,
IDD_DBUTTON5, IDH_DIALER_DIAL_KEYPAD,
IDD_DBUTTON6, IDH_DIALER_DIAL_KEYPAD,
IDD_DBUTTON7, IDH_DIALER_DIAL_KEYPAD,
IDD_DBUTTON8, IDH_DIALER_DIAL_KEYPAD,
IDD_DBUTTON9, IDH_DIALER_DIAL_KEYPAD,
IDD_DBUTTONSTAR, IDH_DIALER_DIAL_KEYPAD,
IDD_DBUTTON0, IDH_DIALER_DIAL_KEYPAD,
IDD_DBUTTONPOUND, IDH_DIALER_DIAL_KEYPAD,
0, 0
};
switch (msg)
{
case WM_INITDIALOG:
hIcon = LoadIcon( ghInst, MAKEINTRESOURCE( IDI_DIALER ) );
return TRUE;
case WM_SYSCOMMAND:
switch( (DWORD) wParam )
{
case SC_CLOSE:
PostQuitMessage(0);
}
break;
// processes clicks on controls when
// context mode help is selected
case WM_HELP:
WinHelp (
( (LPHELPINFO) lParam)->hItemHandle,
gszHELPfilename,
HELP_WM_HELP,
(ULONG_PTR) aMenuHelpIDs
);
return TRUE;
// processes right-clicks on controls
case WM_CONTEXTMENU:
WinHelp (
(HWND)wParam,
gszHELPfilename,
HELP_CONTEXTMENU,
(ULONG_PTR)aMenuHelpIDs
);
return TRUE;
case WM_INITMENUPOPUP:
// if edit menu
if ( LOWORD(lParam) == 1 )
{
UINT wEnable;
if ( GetParent( GetFocus() ) != GetDlgItem( ghWndMain, IDD_DCOMBO ) )
{
wEnable = MF_GRAYED;
}
else
{
LRESULT lSelect = SendDlgItemMessage (
ghWndMain,
IDD_DCOMBO,
CB_GETEDITSEL,
0,
0
);
if ( HIWORD( lSelect ) != LOWORD( lSelect ) )
wEnable = MF_ENABLED;
else
wEnable = MF_GRAYED;
}
EnableMenuItem((HMENU)wParam, IDM_EDIT_CUT, wEnable);
EnableMenuItem((HMENU)wParam, IDM_EDIT_COPY, wEnable);
EnableMenuItem((HMENU)wParam, IDM_EDIT_DELETE, wEnable);
// enable paste option is there is data
// in the clipboard
if ( IsClipboardFormatAvailable( CF_TEXT ) )
{
if ( GetClipboardData ( CF_TEXT ) )
{
wEnable = MF_ENABLED;
}
else
{
wEnable = MF_GRAYED;
}
}
else
{
wEnable = MF_GRAYED;
}
}
break;
case WM_COMMAND:
{
TCHAR szName[TAPIMAXCALLEDPARTYSIZE] = {0};
TCHAR szNumber[TAPIMAXDESTADDRESSSIZE] = {TEXT('\0')};
switch( LOWORD( (DWORD)wParam ) )
{
// FILE menu
case IDM_EXIT:
PostQuitMessage(0);
return TRUE;
// EDIT menu
case IDM_EDIT_CUT:
SendDlgItemMessage(ghWndMain, IDD_DCOMBO, WM_CUT, 0, 0);
return TRUE;
case IDM_EDIT_COPY:
SendDlgItemMessage(ghWndMain, IDD_DCOMBO, WM_COPY, 0, 0);
return TRUE;
case IDM_EDIT_PASTE:
SendDlgItemMessage(ghWndMain, IDD_DCOMBO, WM_PASTE, 0, 0);
return TRUE;
case IDM_EDIT_DELETE:
SendDlgItemMessage(ghWndMain, IDD_DCOMBO, WM_CLEAR, 0, 0);
return TRUE;
case IDM_EDIT_SPEEDDIAL:
DialogBoxParam (
ghInst,
MAKEINTRESOURCE(IDD_SD1),
ghWndMain,
SpeedDial1Proc,
0
);
SetFocus(GetDlgItem(ghWndMain, IDD_DDIAL));
return TRUE;
// TOOLS menu
case IDM_CONNECTUSING:
DialogBoxParam (
ghInst,
MAKEINTRESOURCE(IDD_CONNECTUSING),
ghWndMain,
ConnectUsingProc,
MENU_CHOICE
);
return TRUE;
case IDM_LOCATION:
{
TCHAR szCanNumber[ TAPIMAXDESTADDRESSSIZE ] = TEXT("");
// fetch the number to be dialed
if ( GetDlgItemText (
ghWndMain,
IDD_DCOMBO,
szNumber,
TAPIMAXDESTADDRESSSIZE
)
)
{
// if a number exists, convert it to
// its canonical form.
if ( !MakeCanonicalNumber ( szNumber, szCanNumber ) )
{
lstrcpy( szCanNumber, szNumber );
}
}
lineTranslateDialog (
ghLineApp,
0,
TAPI_CURRENT_VERSION,
ghWndMain,
szCanNumber
);
return TRUE;
}
// HELP menu
case IDM_HELP_CONTENTS:
WinHelp(ghWndMain, gszHELPfilename, HELP_CONTENTS, 0);
return TRUE;
case IDM_HELP_WHATSTHIS:
PostMessage(ghWndMain, WM_SYSCOMMAND, SC_CONTEXTHELP, 0);
return TRUE;
case IDM_ABOUT:
#ifdef SDKRELEASE
DialogBoxParam(
ghInst,
MAKEINTRESOURCE(IDD_ABOUT),
ghWndMain,
AboutProc,
0
);
#else
ShellAbout(
ghWndMain,
gszAppName,
gszNULL,
LoadIcon(ghInst, MAKEINTRESOURCE(IDI_DIALER))
);
#endif
return TRUE;
// Accelerator processing
case IDM_ACCEL_NUMTODIAL:
if(GetActiveWindow() == ghWndMain)
SetFocus(GetDlgItem(ghWndMain, IDD_DCOMBO));
return TRUE;
// Buttons
case IDD_DDIAL:
{
DWORD cSDEntry;
TCHAR szSDNumber[TAPIMAXDESTADDRESSSIZE];
TCHAR szFieldName[MAXBUFSIZE];
HKEY hKey = NULL;
DWORD dwSize;
// check if number entered is dialable
if ( SendMessage (
GetDlgItem(ghWndMain, IDD_DCOMBO),
WM_GETTEXTLENGTH,
0,
0
) > 0
)
{
// get the number to be dialed
GetDlgItemText (
ghWndMain,
IDD_DCOMBO,
szNumber,
TAPIMAXDESTADDRESSSIZE
);
// check if it is a speed dial number.
// If so choose the name to be displayed.
RegOpenKeyEx (DIALER_REGISTRY_ROOT, DIALER_REGISTRY_PATH, 0, KEY_READ, &hKey);
for( cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry)
{
wsprintf(szFieldName, TEXT("Number%d"), cSDEntry);
dwSize = sizeof (szSDNumber);
if (ERROR_SUCCESS ==
RegQueryValueEx (hKey, szFieldName, NULL, NULL, (LPBYTE)szSDNumber, &dwSize))
{
if ( lstrcmp(szSDNumber, szNumber) == 0 )
{
wsprintf( szFieldName, TEXT("Name%d"), cSDEntry);
dwSize = sizeof (szName);
RegQueryValueEx (hKey, szFieldName, NULL, NULL, (LPBYTE)szName, &dwSize);
break;
}
}
}
RegCloseKey (hKey);
SetFocus( GetDlgItem( ghWndMain, IDD_DDIAL ) );
// once the currentline has been set
// using the connect proc
// the user must hit dial again
if ( giCurrentLine == (DWORD)-1 )
{
DialogBoxParam (
ghInst,
MAKEINTRESOURCE(IDD_CONNECTUSING),
ghWndMain,
ConnectUsingProc,
INVALID_LINE
);
}
else
{
AddToRedialList(szNumber);
InitiateCall(szNumber, szName);
}
}
return TRUE;
}
case IDD_DBUTTON1:
case IDD_DBUTTON2:
case IDD_DBUTTON3:
case IDD_DBUTTON4:
case IDD_DBUTTON5:
case IDD_DBUTTON6:
case IDD_DBUTTON7:
case IDD_DBUTTON8:
case IDD_DBUTTON9:
case IDD_DBUTTON0:
case IDD_DBUTTONSTAR:
case IDD_DBUTTONPOUND:
{
int i;
TCHAR szBuffer[TAPIMAXDESTADDRESSSIZE+1];
static const TCHAR digits[] = {
TEXT('1'),
TEXT('2'),
TEXT('3'),
TEXT('4'),
TEXT('5'),
TEXT('6'),
TEXT('7'),
TEXT('8'),
TEXT('9'),
TEXT('0'),
TEXT('*'),
TEXT('#')
};
i = (int)SendDlgItemMessage(ghWndMain,
IDD_DCOMBO,
WM_GETTEXT,
(WPARAM)TAPIMAXDESTADDRESSSIZE+1,
(LPARAM)szBuffer);
if (i < TAPIMAXDESTADDRESSSIZE)
{
MoveMemory(szBuffer+gdwStartSel+1,
szBuffer+gdwEndSel,
(i - ( gdwEndSel ) + 1)*sizeof(TCHAR) );
szBuffer[gdwStartSel] = digits[LOWORD(wParam) - IDD_DBUTTON1];
SendDlgItemMessage(ghWndMain,
IDD_DCOMBO,
WM_SETTEXT,
0,
(LPARAM)szBuffer);
gdwStartSel++;
gdwEndSel = gdwStartSel;
}
SetFocus(GetDlgItem(ghWndMain, IDD_DDIAL));
EnableWindow(GetDlgItem(ghWndMain, IDD_DDIAL), TRUE);
return TRUE;
}
case IDD_DCOMBO:
if (HIWORD(wParam) == CBN_SELENDOK)
{
EnableWindow( GetDlgItem(ghWndMain, IDD_DDIAL), TRUE );
}
if ((HIWORD(wParam) == CBN_SELENDOK) ||
(HIWORD(wParam) == CBN_SELENDCANCEL))
{
(DWORD)SendDlgItemMessage(ghWndMain,
IDD_DCOMBO,
CB_GETEDITSEL,
(WPARAM)&gdwStartSel,
(LPARAM)&gdwEndSel);
return FALSE;
}
if ( HIWORD( wParam ) == CBN_EDITCHANGE )
{
EnableWindow (
GetDlgItem( ghWndMain, IDD_DDIAL ),
(BOOL) GetWindowTextLength (
GetDlgItem (
ghWndMain,
IDD_DCOMBO
)
)
);
return TRUE;
}
break;
case IDD_DSPEEDDIAL1:
case IDD_DSPEEDDIAL2:
case IDD_DSPEEDDIAL3:
case IDD_DSPEEDDIAL4:
case IDD_DSPEEDDIAL5:
case IDD_DSPEEDDIAL6:
case IDD_DSPEEDDIAL7:
case IDD_DSPEEDDIAL8:
{
DWORD cSDEntry = LOWORD( (DWORD) wParam) - IDD_DSPEEDDIAL1 + 1;
TCHAR szFieldName [MAXBUFSIZE];
TCHAR szNum[TAPIMAXDESTADDRESSSIZE] ={0};
TCHAR *p;
HKEY hKey = NULL;
DWORD dwSize;
// get information for the speed dial button
// from the INI file
RegOpenKeyEx (DIALER_REGISTRY_ROOT, DIALER_REGISTRY_PATH, 0, KEY_READ, &hKey);
wsprintf(szFieldName, TEXT("Name%d"), cSDEntry);
dwSize = sizeof (szName);
RegQueryValueEx (hKey, szFieldName, NULL, NULL, (LPBYTE)szName, &dwSize);
wsprintf(szFieldName, TEXT("%s%d"), TEXT("Number"), cSDEntry);
dwSize = sizeof (szNum);//gszSDNumber[cSDEntry]);
RegQueryValueEx (hKey, szFieldName, NULL, NULL, (LPBYTE)szNum, &dwSize);
RegCloseKey (hKey);
for (p = szNum; *p == TEXT(' '); p++);
lstrcpyn (gszSDNumber[cSDEntry], p, sizeof(gszSDNumber[cSDEntry])/sizeof(TCHAR));
// entry not set yet
if( gszSDNumber[cSDEntry][0] == 0 )
{
DialogBoxParam (
ghInst,
MAKEINTRESOURCE(IDD_SD2),
ghWndMain,
SpeedDial2Proc,
MAKELPARAM(wParam,0)
);
}
// no line open
// once the currentline has been set
// using the connect proc
// the user must hit dial again
else if ( giCurrentLine == (DWORD)-1)
{
DialogBoxParam (
ghInst,
MAKEINTRESOURCE(IDD_CONNECTUSING),
ghWndMain,
ConnectUsingProc,
INVALID_LINE
);
}
// entry is set and valid voice line is open
else
{
// add number to list box combo.
AddToRedialList( gszSDNumber[cSDEntry] );
InitiateCall( gszSDNumber[cSDEntry], szName );
}
break;
}
} // end switch (LOWORD((DWORD)wParam)) { ... }
break; // end case WM_COMMAND
}
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(ghWndMain, &ps);
if(IsIconic(ghWndMain))
DrawIcon(ps.hdc, 0, 0, hIcon);
else
{
HBRUSH hBrush;
hBrush = GetSysColorBrush( COLOR_3DFACE );
// FillRect(ps.hdc, &ps.rcPaint, GetStockObject(LTGRAY_BRUSH));
FillRect(ps.hdc, &ps.rcPaint, hBrush);
}
EndPaint(ghWndMain, &ps);
return TRUE;
}
case WM_CTLCOLORLISTBOX:
case WM_CTLCOLORBTN:
case WM_CTLCOLORSTATIC:
SetBkColor((HDC)wParam, GetSysColor(COLOR_BTNFACE));
return (INT_PTR)GetSysColorBrush( COLOR_3DFACE );
default:
;
// return DefDlgProc( hwnd, msg, wParam, lParam );
// return DefWindowProc( hwnd, msg, wParam, lParam );
} // switch (msg) { ... }
return FALSE;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
VOID AddToRedialList( LPCTSTR szNumber )
{
// NLASTDIALED == 10
WORD cNum;
HWND hWndCombo = GetDlgItem(ghWndMain, IDD_DCOMBO);
DWORD nMatch;
// if valid number
if ( szNumber[0] )
{
// if list box has entries, check if this number
// is already present. If so delete old entry
cNum = (WORD) SendMessage(hWndCombo, CB_GETCOUNT, 0, 0);
if ( cNum != 0 )
{
nMatch = (int)SendMessage ( hWndCombo, CB_FINDSTRING, 0, (LPARAM)szNumber );
if ( nMatch != CB_ERR )
{
SendMessage(hWndCombo, CB_DELETESTRING, nMatch, 0);
}
else
{
// if the list is full, remove oldest
if ( cNum == NLASTDIALED )
{
SendMessage( hWndCombo, CB_DELETESTRING, NLASTDIALED - 1, 0 );
}
}
}
SendMessage(hWndCombo, CB_INSERTSTRING, 0, (LPARAM)szNumber);
SendMessage(hWndCombo, CB_SETCURSEL, 0, 0L);
EnableWindow ( GetDlgItem( ghWndMain, IDD_DDIAL ), TRUE );
}
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
VOID InitiateCall ( LPCTSTR szNumber, LPCTSTR szName )
{
HLINE hLine = 0;
DWORD errCode;
// struct size info
DWORD dwLTPSize = sizeof ( LINETRANSLATEOUTPUT );
DWORD dwNameLen = lstrlen( szName ) + 1;
DWORD dwLCPSize = sizeof( LINECALLPARAMS );
LPLINETRANSLATEOUTPUT lpTransOut = NULL;
LPLINECALLPARAMS lpLineCallParams = NULL;
TCHAR szCanNumber[ TAPIMAXDESTADDRESSSIZE ];
// Open a line
errCode = lineOpen (
ghLineApp,
giCurrentLine,
&hLine,
gCurrentLineInfo.dwAPIVersion,
0,
0,
LINECALLPRIVILEGE_NONE,
0,
NULL
);
if (errCode)
{
errString ( ghWndMain, errCode, MB_ICONEXCLAMATION | MB_OK );
goto error;
}
// call translate address before dialing
do
{
lpTransOut = (LPLINETRANSLATEOUTPUT) DialerAlloc( dwLTPSize );
if ( !lpTransOut )
{
errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK );
goto error;
}
lpTransOut-> dwTotalSize = dwLTPSize;
if ( !MakeCanonicalNumber( szNumber, szCanNumber ) )
{
lstrcpy( szCanNumber, szNumber );
}
errCode = lineTranslateAddress (
ghLineApp,
giCurrentLine,
gCurrentLineInfo.dwAPIVersion,
szCanNumber,
0,
0,
lpTransOut
);
if ( ((LONG)errCode) < 0 )
{
errString( ghWndMain, errCode, MB_ICONEXCLAMATION | MB_OK );
goto error;
}
if ( lpTransOut-> dwNeededSize <= lpTransOut->dwTotalSize )
{
// ok we are done
break;
}
else
{
dwLTPSize = lpTransOut-> dwNeededSize;
DialerFree ( lpTransOut );
lpTransOut = NULL;
}
} while ( TRUE );
// if number dialed is 911, bring up a warning
if ( Is911( lpTransOut) )
{
INT nRes = errString ( ghWndMain, ERR_911WARN, MB_ICONSTOP | MB_YESNO );
if ( nRes == IDNO )
{
goto error;
}
}
// set call parameters
dwLCPSize += dwNameLen + lpTransOut-> dwDisplayableStringSize;
lpLineCallParams = (LPLINECALLPARAMS) DialerAlloc( dwLCPSize );
if ( !lpLineCallParams )
{
errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK );
goto error;
}
lpLineCallParams->dwTotalSize = dwLCPSize;
lpLineCallParams->dwBearerMode = LINEBEARERMODE_VOICE;
lpLineCallParams->dwMediaMode = LINEMEDIAMODE_INTERACTIVEVOICE;
lpLineCallParams->dwCallParamFlags = LINECALLPARAMFLAGS_IDLE;
lpLineCallParams->dwAddressMode = LINEADDRESSMODE_ADDRESSID;
lpLineCallParams->dwAddressID = giCurrentAddress;
if ( szName[ 0 ] )
{
lpLineCallParams->dwCalledPartySize = dwNameLen;
lpLineCallParams->dwCalledPartyOffset = sizeof( LINECALLPARAMS );
lstrcpy ((LPTSTR)((char*)lpLineCallParams + sizeof(LINECALLPARAMS)),
szName);
}
lpLineCallParams-> dwDisplayableAddressSize = lpTransOut-> dwDisplayableStringSize;
lpLineCallParams-> dwDisplayableAddressOffset = sizeof( LINECALLPARAMS ) + dwNameLen;
lstrcpy (
(LPTSTR) ((char*)lpLineCallParams + sizeof(LINECALLPARAMS) + dwNameLen),
(LPTSTR) ((char*)lpTransOut + lpTransOut-> dwDisplayableStringOffset)
);
// save dialing information
// Free old allocs.
if ( gszCurrentName )
{
DialerFree ( gszCurrentName );
}
if ( gszCurrentNumber )
{
DialerFree ( gszCurrentNumber );
}
// save new stuff
gszCurrentName = (LPTSTR) DialerAlloc( dwNameLen*sizeof(TCHAR) );
if ( !gszCurrentName )
{
errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK );
goto error;
}
lstrcpy ( gszCurrentName, szName );
gszCurrentNumber = (LPTSTR) DialerAlloc( lpTransOut->dwDisplayableStringSize);
if ( !gszCurrentNumber )
{
errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK );
goto error;
}
lstrcpy (
gszCurrentNumber,
(LPTSTR) ((char*)lpTransOut + lpTransOut-> dwDisplayableStringOffset)
);
gCurrentLineInfo.hLine = hLine;
ghCall = 0;
// finally make the call.
gMakeCallRequestID = 0;
gMakeCallRequestID = lineMakeCall (
hLine,
&ghCall,
(LPTSTR) ((char*)lpTransOut + lpTransOut-> dwDialableStringOffset),
0,
lpLineCallParams
);
// async request ID
// - the call is going out
if ( (LONG) gMakeCallRequestID > 0 )
{
gfCurrentLineAvail = FALSE;
gfMakeCallReplyPending = TRUE;
DialogBoxParam (
ghInst,
MAKEINTRESOURCE(IDD_DIALING),
ghWndMain,
DialingProc,
0
);
}
else
{
if ( gMakeCallRequestID == LINEERR_CALLUNAVAIL )
{
DialogBoxParam (
ghInst,
MAKEINTRESOURCE(IDD_CALLFAILED),
ghWndMain,
LineInUseProc,
0
);
}
else
{
errString( ghWndMain, gMakeCallRequestID, MB_ICONEXCLAMATION | MB_OK );
}
DialerLineClose();
gfCurrentLineAvail = TRUE;
}
error :
if ( lpLineCallParams )
{
DialerFree( lpLineCallParams );
}
if ( lpTransOut )
{
DialerFree( lpTransOut );
}
// if makecall did not succeed but line
// was opened, close it.
if ( ( gMakeCallRequestID <= 0 ) && ( gCurrentLineInfo.hLine ) )
{
DialerLineClose ();
gfCurrentLineAvail = TRUE;
}
SetFocus( GetDlgItem( ghWndMain, IDD_DCOMBO ) );
return;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
DWORD GetLineInfo ( DWORD iLine, LPLINEINFO lpLineInfo )
{
DWORD errCode = 0;
DWORD dwNeededSize = 0;
LINEEXTENSIONID ExtensionID;
LPTSTR pszLineName = NULL;
LPLINEDEVCAPS lpDevCaps = NULL;
int lineNameLen;
errCode = lineNegotiateAPIVersion (
ghLineApp,
iLine,
TAPI_VERSION_1_0,
TAPI_CURRENT_VERSION,
&( lpLineInfo->dwAPIVersion ),
&ExtensionID
);
if ( errCode )
{
GetLineInfoFailed( iLine, lpDevCaps, lpLineInfo );
goto error;
}
dwNeededSize = sizeof( LINEDEVCAPS );
do
{
lpDevCaps = ( LPLINEDEVCAPS ) DialerAlloc( dwNeededSize );
if ( !lpDevCaps )
{
GetLineInfoFailed( iLine, lpDevCaps, lpLineInfo );
errCode = LINEERR_NOMEM;
goto error;
}
lpDevCaps->dwTotalSize = dwNeededSize;
errCode = lineGetDevCaps (
ghLineApp,
iLine,
lpLineInfo->dwAPIVersion,
0,
lpDevCaps
);
if ( errCode )
{
GetLineInfoFailed( iLine, lpDevCaps, lpLineInfo );
goto error;
}
if ( lpDevCaps-> dwNeededSize <= lpDevCaps-> dwTotalSize )
{
break;
}
dwNeededSize = lpDevCaps->dwNeededSize;
DialerFree( lpDevCaps );
lpDevCaps = NULL;
} while ( TRUE );
lpLineInfo->nAddr = lpDevCaps->dwNumAddresses;
lpLineInfo->fVoiceLine =
( (lpDevCaps->dwMediaModes & LINEMEDIAMODE_INTERACTIVEVOICE) != 0 );
pszLineName = (LPTSTR) DialerAlloc( MAXBUFSIZE*sizeof(TCHAR) );
if ( !pszLineName )
{
errCode = LINEERR_NOMEM;
goto error;
}
if ( lpDevCaps->dwLineNameSize > 0 )
{
lineNameLen = 1 + (lpDevCaps->dwLineNameSize / sizeof (TCHAR));
if (lineNameLen > MAXBUFSIZE)
{
lstrcpyn (
pszLineName,
(LPTSTR) ((char*)lpDevCaps + lpDevCaps->dwLineNameOffset),
MAXBUFSIZE
);
}
else
{
lstrcpyn (
pszLineName,
(LPTSTR) ((char*)lpDevCaps + lpDevCaps->dwLineNameOffset),
lineNameLen);
}
}
else
{
wsprintf ( pszLineName, TEXT("Line %d"), iLine );
}
lstrcpy( lpLineInfo->szLineName, pszLineName );
lpLineInfo->dwPermanentLineID = lpDevCaps->dwPermanentLineID;
error:
if ( lpDevCaps )
DialerFree( lpDevCaps );
if ( pszLineName )
DialerFree( pszLineName );
return errCode;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
VOID GetLineInfoFailed ( DWORD iLine, LPLINEDEVCAPS lpDevCaps, LPLINEINFO lpLineInfo )
{
if ( lpDevCaps )
DialerFree(lpDevCaps);
lpLineInfo->nAddr = 0;
lpLineInfo->fVoiceLine = FALSE;
lpLineInfo->dwAPIVersion = 0;
lpLineInfo->hLine = (HLINE)0;
lpLineInfo->dwPermanentLineID = 0;
lpLineInfo->szLineName[0] = 0;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
LPTSTR GetAddressName(DWORD iLine, DWORD iAddress)
{
DWORD errCode = 0;
DWORD dwNeededSize = 0;
LPTSTR pszAddressName = NULL;
LPLINEADDRESSCAPS lpAddressCaps = NULL;
// allocate space for lineGetAddressCaps data
dwNeededSize = sizeof( LINEADDRESSCAPS );
do
{
lpAddressCaps = ( LPLINEADDRESSCAPS )DialerAlloc( dwNeededSize );
if ( !lpAddressCaps )
{
goto error;
}
lpAddressCaps->dwTotalSize = dwNeededSize;
errCode = lineGetAddressCaps (
ghLineApp,
iLine,
iAddress,
gCurrentLineInfo.dwAPIVersion,
0,
lpAddressCaps
);
if ( errCode )
{
errString (NULL, errCode, MB_ICONSTOP | MB_OK );
goto error;
}
if ( lpAddressCaps-> dwNeededSize <= lpAddressCaps-> dwTotalSize )
{
break;
}
dwNeededSize = lpAddressCaps->dwNeededSize;
DialerFree( lpAddressCaps );
lpAddressCaps = NULL;
} while( TRUE );
// get the address name
pszAddressName = DialerAlloc( MAXBUFSIZE * sizeof(TCHAR));
if ( !pszAddressName )
{
goto error;
}
if ( lpAddressCaps-> dwAddressSize > 0 )
{
// keep string length bounded
if ( lpAddressCaps-> dwAddressSize > (MAXBUFSIZE - 1 ) )
{
lstrcpyn(
pszAddressName,
(LPTSTR) ((char*)lpAddressCaps + lpAddressCaps->dwAddressOffset),
MAXBUFSIZE
);
pszAddressName[ MAXBUFSIZE - 1] = '\0';
}
else
{
lstrcpy (
pszAddressName,
(LPTSTR) ((char*)lpAddressCaps + lpAddressCaps->dwAddressOffset)
);
}
}
else
// use default name
{
wsprintf(pszAddressName, TEXT("Address %d"), iAddress);
}
error:
if ( lpAddressCaps )
{
DialerFree( lpAddressCaps );
}
return pszAddressName;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
INT_PTR CALLBACK DialingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
TCHAR szTemp[ TAPIMAXCALLEDPARTYSIZE ];
case WM_INITDIALOG:
// set global handle to window
ghWndDialing = hwnd;
AmpersandCompensate( gszCurrentName, szTemp );
SetDlgItemText(hwnd, IDD_DGNUMBERTEXT, gszCurrentNumber);
SetDlgItemText(hwnd, IDD_DGNAMETEXT, szTemp );
break;
case WM_COMMAND:
switch ( LOWORD( (DWORD)wParam ) )
{
// hang up
case IDCANCEL:
// if lineMakeCall has completed
// only then drop call.
if (!gfMakeCallReplyPending && ghCall )
{
if ( ( gDropCallRequestID = lineDrop ( ghCall, NULL, 0 ) ) < 0 )
{
errString ( ghWndDialing, gDropCallRequestID, MB_ICONSTOP | MB_OK );
}
}
else
{
DialerLineClose();
gfCurrentLineAvail = TRUE;
gfMakeCallReplyPending = FALSE;
}
ghWndDialing = NULL;
EndDialog(hwnd, FALSE);
return TRUE;
// something else terminated the call
// all we have to do is terminate this dialog box
case IDOK:
ghWndDialing = NULL;
EndDialog(hwnd, TRUE);
return TRUE;
}
break;
default:
;
}
return FALSE;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
INT_PTR CALLBACK AboutProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_INITDIALOG:
{
TCHAR sz[MAXBUFSIZE];
TCHAR szLabel[MAXBUFSIZE];
// sets up the version number for Windows
GetDlgItemText(hwnd, IDD_ATEXTTITLE, sz, MAXBUFSIZE);
wsprintf(
szLabel,
sz,
LOWORD(GetVersion()) & 0xFF,
HIBYTE(LOWORD(GetVersion)) == 10 ? 1 : 0
);
SetDlgItemText(hwnd, IDD_ATEXTTITLE, szLabel);
return TRUE;
}
case WM_COMMAND:
if(LOWORD((DWORD)wParam) == IDOK)
{
EndDialog(hwnd, TRUE);
return TRUE;
}
break;
}
return FALSE;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
INT_PTR CALLBACK ConnectUsingProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
static const DWORD aMenuHelpIDs[] =
{
IDD_CUTEXTLINE, IDH_DIALER_OPTIONS_LINE,
IDD_CULISTLINE, IDH_DIALER_OPTIONS_LINE,
IDD_CUTEXTADDRESS, IDH_DIALER_OPTIONS_ADDRESS,
IDD_CULISTADDRESS, IDH_DIALER_OPTIONS_ADDRESS,
IDD_CUSIMPLETAPICHKBOX, IDH_DIALER_OPTIONS_VOICE,
IDD_CUPROPERTIES, IDH_DIALER_OPTIONS_PROPERTIES,
0, 0
};
switch(msg)
{
case WM_HELP:
// processes clicks on controls when
// context mode help is selected
WinHelp (
((LPHELPINFO)lParam)->hItemHandle,
gszHELPfilename,
HELP_WM_HELP,
(ULONG_PTR)aMenuHelpIDs
);
return TRUE;
case WM_CONTEXTMENU:
// processes right-clicks on controls
WinHelp (
(HWND)wParam,
gszHELPfilename,
HELP_CONTEXTMENU,
(ULONG_PTR)aMenuHelpIDs
);
return TRUE;
case WM_INITDIALOG:
{
BOOL fEnable;
DWORD dwPriority;
//
// Is there any point in even showing this dialog box?
if ( gnAvailDevices == 0 )
{
// Nope. Let's tell the user what we don't like.
errString ( ghWndMain, ERR_NOLINES, MB_ICONEXCLAMATION | MB_OK );
EndDialog(hwnd, FALSE);
return TRUE;
}
// if not brought up by InitializeTAPI()
if ( lParam != INVALID_LINE )
{
// hide error text
EnableWindow( GetDlgItem( hwnd, IDD_CUERRORTEXT ), FALSE );
}
// get list of lines into the line list box.
fEnable = InitializeLineBox( GetDlgItem(hwnd, IDD_CULISTLINE) );
EnableWindow( GetDlgItem( hwnd, IDD_CULISTLINE ), fEnable);
// get list of addresses into the address list box.
fEnable = fEnable &&
InitializeAddressBox (
GetDlgItem(hwnd, IDD_CULISTLINE),
GetDlgItem(hwnd, IDD_CULISTADDRESS)
);
EnableWindow( GetDlgItem( hwnd, IDD_CULISTADDRESS ), fEnable );
EnableWindow( GetDlgItem( hwnd, IDOK ), fEnable );
EnableWindow( GetDlgItem( hwnd, IDD_CUPROPERTIES ), fEnable );
lineGetAppPriority (
TEXT("DIALER.EXE"),
0, // checking app priority for Assisted Telephony requests
NULL,
LINEREQUESTMODE_MAKECALL,
NULL,
&dwPriority
);
CheckDlgButton(hwnd, IDD_CUSIMPLETAPICHKBOX, (dwPriority == 1));
// if dwPriority == 1, we're supporting Assisted Telephony AND
// have the highest priority.
EnableWindow (
GetDlgItem(hwnd, IDD_CUSIMPLETAPICHKBOX),
gfRegistered
);
return FALSE;
}
case WM_COMMAND:
{
switch ( LOWORD( (DWORD)wParam ) )
{
case IDD_CULISTLINE:
if ( HIWORD( wParam ) == CBN_SELENDOK )
// update address box
InitializeAddressBox (
GetDlgItem(hwnd, IDD_CULISTLINE),
GetDlgItem(hwnd, IDD_CULISTADDRESS)
);
break;
case IDD_CUPROPERTIES:
{
HWND hW = GetDlgItem(hwnd, IDD_CULISTLINE);
lineConfigDialog (
// device ID
(DWORD) SendMessage (
hW,
CB_GETITEMDATA,
(WORD) SendMessage(hW, CB_GETCURSEL, 0, 0),
0
),
hwnd,
NULL
);
break;
}
case IDOK:
{
HWND hwndBox;
TCHAR szBuffer[MAXBUFSIZE];
DWORD dwPriority;
HKEY hKey = NULL;
DWORD dwSize;
RegCreateKeyEx (DIALER_REGISTRY_ROOT, DIALER_REGISTRY_PATH, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
// Update line
hwndBox = GetDlgItem( hwnd, IDD_CULISTLINE );
giCurrentLine = (int) SendMessage (
hwndBox,
CB_GETITEMDATA,
SendMessage( hwndBox, CB_GETCURSEL, 0, 0 ),
0
);
// base 10
_itot( gdwPLID[giCurrentLine], szBuffer, 10 );
RegSetValueEx (hKey, TEXT("Preferred Line"), 0, REG_SZ,
(LPBYTE)szBuffer, (lstrlen(szBuffer)+1)*sizeof(TCHAR));
// Update address
hwndBox = GetDlgItem( hwnd, IDD_CULISTADDRESS );
giCurrentAddress = (int) SendMessage (
hwndBox,
CB_GETITEMDATA,
SendMessage(hwndBox, CB_GETCURSEL, 0, 0),
0
);
_itot( giCurrentAddress, szBuffer, 10 );
RegSetValueEx (hKey, TEXT("Preferred Address"), 0, REG_SZ,
(LPBYTE)szBuffer, (lstrlen(szBuffer)+1)*sizeof(TCHAR));
RegCloseKey (hKey);
// Update application priority
if ( SendDlgItemMessage (
hwnd,
IDD_CUSIMPLETAPICHKBOX,
BM_GETCHECK,
0,
0L
)
== 0)
{
dwPriority = 0;
}
else
{
dwPriority = 1;
}
lineSetAppPriority (
TEXT("DIALER.EXE"),
0,
NULL,
LINEREQUESTMODE_MAKECALL,
NULL,
dwPriority
);
EndDialog(hwnd, TRUE);
return TRUE;
}
case IDCANCEL:
EndDialog(hwnd, FALSE);
return TRUE;
}
}
default:
;
}
return FALSE;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
INT_PTR CALLBACK LineInUseProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
int lNewParam = (int)lParam;
PTSTR ptStr;
switch(msg)
{
case WM_INITDIALOG:
{
switch(lParam)
{
case LINEDISCONNECTMODE_REJECT:
lNewParam = ikszDisconnectedReject;
break;
case LINEDISCONNECTMODE_BUSY:
lNewParam = ikszDisconnectedBusy;
break;
case LINEDISCONNECTMODE_NOANSWER:
lNewParam = ikszDisconnectedNoAnswer;
break;
case LINEDISCONNECTMODE_CONGESTION:
lNewParam = ikszDisconnectedNetwork;
break;
case LINEDISCONNECTMODE_INCOMPATIBLE:
lNewParam = ikszDisconnectedIncompatible;
break;
case LINEDISCONNECTMODE_NODIALTONE:
lNewParam = ikszDisconnectedNoDialTone;
break;
default:
lNewParam = ikszDisconnectedCantDo;
break;
}
ptStr = DialerAlloc( MAXBUFSIZE*sizeof(TCHAR) );
LoadString( ghInst, lNewParam, ptStr, MAXBUFSIZE );
SetDlgItemText (hwnd, IDD_CFTEXT, ptStr);
DialerFree( ptStr );
return TRUE;
}
case WM_COMMAND:
if(LOWORD((DWORD)wParam) == IDOK)
{
EndDialog(hwnd, TRUE);
return TRUE;
}
break;
}
return FALSE;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
INT_PTR CALLBACK SpeedDial1Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static DWORD nCurrentSpeedDial;
static const DWORD aMenuHelpIDs[] =
{
IDOK, IDH_DIALER_SPEED_SAVE,
IDD_SD1SPEEDDIAL1, IDH_DIALER_BUTTONS,
IDD_SD1SPEEDDIAL2, IDH_DIALER_BUTTONS,
IDD_SD1SPEEDDIAL3, IDH_DIALER_BUTTONS,
IDD_SD1SPEEDDIAL4, IDH_DIALER_BUTTONS,
IDD_SD1SPEEDDIAL5, IDH_DIALER_BUTTONS,
IDD_SD1SPEEDDIAL6, IDH_DIALER_BUTTONS,
IDD_SD1SPEEDDIAL7, IDH_DIALER_BUTTONS,
IDD_SD1SPEEDDIAL8, IDH_DIALER_BUTTONS,
IDD_SD1SPEEDDIALTEXT1, IDH_DIALER_BUTTONS,
IDD_SD1SPEEDDIALTEXT2, IDH_DIALER_BUTTONS,
IDD_SD1SPEEDDIALTEXT3, IDH_DIALER_BUTTONS,
IDD_SD1SPEEDDIALTEXT4, IDH_DIALER_BUTTONS,
IDD_SD1SPEEDDIALTEXT5, IDH_DIALER_BUTTONS,
IDD_SD1SPEEDDIALTEXT6, IDH_DIALER_BUTTONS,
IDD_SD1SPEEDDIALTEXT7, IDH_DIALER_BUTTONS,
IDD_SD1SPEEDDIALTEXT8, IDH_DIALER_BUTTONS,
IDD_SD1TEXTNAME, IDH_DIALER_SPEED_NAME,
IDD_SD1EDITNAME, IDH_DIALER_SPEED_NAME,
IDD_SD1TEXTNUMBER, IDH_DIALER_SPEED_NUMBER,
IDD_SD1EDITNUMBER, IDH_DIALER_SPEED_NUMBER,
IDD_SD1TEXTCHOOSE, (DWORD)-1,
IDD_SD1TEXTENTER, (DWORD)-1,
0, 0
};
// buffer to store speed dial names till they are saved.
static TCHAR szSDName[NSPEEDDIALS + 1][TAPIMAXCALLEDPARTYSIZE] = {0};
switch(msg)
{
case WM_HELP:
// processes clicks on controls when
// context mode help is selected
WinHelp(
((LPHELPINFO)lParam)->hItemHandle,
gszHELPfilename,
HELP_WM_HELP,
(ULONG_PTR)aMenuHelpIDs
);
return TRUE;
case WM_CONTEXTMENU: // processes right-clicks on controls
WinHelp(
(HWND)wParam,
gszHELPfilename,
HELP_CONTEXTMENU,
(ULONG_PTR)aMenuHelpIDs
);
return TRUE;
case WM_INITDIALOG:
{
DWORD cSDEntry;
DWORD idFirstEmpty = (DWORD) -1;
TCHAR szName[TAPIMAXCALLEDPARTYSIZE] = {0};
TCHAR szTemp[TAPIMAXCALLEDPARTYSIZE];
TCHAR szFieldName[MAXBUFSIZE];
HKEY hKey = NULL;
DWORD dwSize;
// Retrieve speed dial info from INI file
RegOpenKeyEx (DIALER_REGISTRY_ROOT, DIALER_REGISTRY_PATH, 0, KEY_READ, &hKey);
for(cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry)
{
wsprintf(szFieldName, TEXT("Name%d"), cSDEntry);
dwSize = sizeof (szSDName[ cSDEntry ]);
RegQueryValueEx (hKey, szFieldName, NULL, NULL, (LPBYTE)szSDName[cSDEntry], &dwSize);
// set the first empty speed dial button
if ( idFirstEmpty == -1 &&
szSDName[ cSDEntry ][0] == '\0' &&
gszSDNumber[ cSDEntry ][ 0 ] == '\0' )
idFirstEmpty = cSDEntry;
wsprintf(szFieldName, TEXT("Number%d"), cSDEntry);
dwSize = sizeof (gszSDNumber[cSDEntry]);
RegQueryValueEx (hKey, szFieldName, NULL, NULL, (LPBYTE)gszSDNumber[cSDEntry], &dwSize);
// get a copy of the name for editing
// if name is empty, use the number as the
// name.
if (0 != szSDName[ cSDEntry][0])
{
lstrcpyn( szName, szSDName[ cSDEntry], sizeof(szName)/sizeof(szName[0]));
}
else
{
lstrcpyn( szName, gszSDNumber[ cSDEntry ], sizeof(szName)/sizeof(szName[0]) );
}
FitTextToButton( hwnd, IDD_SD1SPEEDDIAL1 + cSDEntry - 1, szName );
AmpersandCompensate( szName, szTemp );
SetDlgItemText (
hwnd,
IDD_SD1SPEEDDIAL1 + cSDEntry - 1,
(LPCTSTR) szTemp
);
}
RegCloseKey (hKey);
// for the edit speed dial dialog
// limit the lengths of text
SendDlgItemMessage (
hwnd,
IDD_SD1EDITNAME,
EM_LIMITTEXT,
(WPARAM)(TAPIMAXCALLEDPARTYSIZE - 1),
0
);
SendDlgItemMessage (
hwnd,
IDD_SD1EDITNUMBER,
EM_LIMITTEXT,
(WPARAM)(TAPIMAXDESTADDRESSSIZE - 1),
0
);
// select the first empty button
// nothing empty, then edit #1
if ( -1 == idFirstEmpty )
{
nCurrentSpeedDial = 1;
SetDlgItemText(
hwnd,
IDD_SD1EDITNAME,
(LPCTSTR) szSDName[ 1 ]
);
SetDlgItemText(
hwnd,
IDD_SD1EDITNUMBER,
(LPCTSTR) gszSDNumber[ 1 ]
);
}
else
{
nCurrentSpeedDial = idFirstEmpty;
}
SetFocus( GetDlgItem( hwnd, IDD_SD1EDITNAME ) );
return FALSE;
}
case WM_COMMAND:
{
TCHAR szName[TAPIMAXCALLEDPARTYSIZE];
TCHAR szTemp[ TAPIMAXCALLEDPARTYSIZE ];
switch( LOWORD( (DWORD) wParam ) )
{
case IDOK:
{
DWORD cSDEntry;
TCHAR szFieldName[MAXBUFSIZE];
HKEY hKey = NULL;
// save new speed dial settings
RegCreateKeyEx (DIALER_REGISTRY_ROOT, DIALER_REGISTRY_PATH, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
for ( cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry )
{
wsprintf(szFieldName, TEXT("Name%d"), cSDEntry);
RegSetValueEx (hKey, szFieldName, 0, REG_SZ,
(LPBYTE)(szSDName[cSDEntry]),
(lstrlen(szSDName[cSDEntry])+1)*sizeof(TCHAR));
wsprintf(szFieldName, TEXT("Number%d"), cSDEntry);
RegSetValueEx (hKey, szFieldName, 0, REG_SZ,
(LPBYTE)(gszSDNumber[cSDEntry]),
(lstrlen(gszSDNumber[cSDEntry])+1)*sizeof(TCHAR));
// set the text for the corresponding
// main window button
if ( szSDName[ cSDEntry ][ 0 ] == TEXT('\0') )
{
lstrcpyn( szName, gszSDNumber[ cSDEntry ], sizeof(szName)/sizeof(szName[0]) );
}
else
{
lstrcpyn( szName, szSDName[ cSDEntry ], sizeof(szName)/sizeof(szName[0]) );
}
FitTextToButton(
ghWndMain,
IDD_DSPEEDDIAL1 + cSDEntry - 1,
szName
);
AmpersandCompensate( szName, szTemp );
SetDlgItemText (
ghWndMain,
IDD_DSPEEDDIAL1 + cSDEntry - 1,
(LPCTSTR) szTemp
);
}
RegCloseKey (hKey);
EndDialog(hwnd, TRUE);
return TRUE;
}
case IDCANCEL:
EndDialog(hwnd, FALSE);
return TRUE;
case IDD_SD1SPEEDDIAL1:
case IDD_SD1SPEEDDIAL2:
case IDD_SD1SPEEDDIAL3:
case IDD_SD1SPEEDDIAL4:
case IDD_SD1SPEEDDIAL5:
case IDD_SD1SPEEDDIAL6:
case IDD_SD1SPEEDDIAL7:
case IDD_SD1SPEEDDIAL8:
nCurrentSpeedDial = LOWORD( (DWORD) wParam ) - IDD_SD1SPEEDDIAL1 + 1;
SetDlgItemText (
hwnd,
IDD_SD1EDITNAME,
szSDName [ nCurrentSpeedDial ]
);
SetDlgItemText (
hwnd,
IDD_SD1EDITNUMBER,
gszSDNumber[nCurrentSpeedDial]
);
SetFocus( GetDlgItem( hwnd, IDD_SD1EDITNAME ) );
SendDlgItemMessage(
hwnd,
IDD_SD1EDITNAME,
EM_SETSEL,
0,
MAKELPARAM(0, -1)
);
break;
case IDD_SD1EDITNAME:
if ( HIWORD( wParam ) == EN_CHANGE )
{
TCHAR *p;
GetDlgItemText (
hwnd,
IDD_SD1EDITNAME,
szName,
TAPIMAXCALLEDPARTYSIZE
);
for (p = szName; *p == TEXT(' '); p++);
// if there is no name, label the button with
// the number
if ( *p == TEXT('\0') )
{
szSDName[ nCurrentSpeedDial ][ 0 ] = TEXT('\0');
lstrcpyn( szName, gszSDNumber[ nCurrentSpeedDial ], sizeof(szName)/sizeof(szName[0]) );
p = szName;
}
else
{
lstrcpy( szSDName[ nCurrentSpeedDial ], p );
}
FitTextToButton (
hwnd,
IDD_SD1SPEEDDIAL1 + nCurrentSpeedDial - 1,
szName
);
AmpersandCompensate( p, szTemp );
SetDlgItemText (
hwnd,
IDD_SD1SPEEDDIAL1 + nCurrentSpeedDial - 1,
szTemp
);
}
break;
case IDD_SD1EDITNUMBER:
if ( HIWORD( wParam ) == EN_CHANGE )
{
GetDlgItemText (
hwnd,
IDD_SD1EDITNUMBER,
gszSDNumber[nCurrentSpeedDial],
TAPIMAXDESTADDRESSSIZE
);
if ( gszSDNumber[ nCurrentSpeedDial ][ 0 ] == '\0' )
{
GetDlgItemText (
hwnd,
IDD_SD1EDITNAME,
szName,
TAPIMAXDESTADDRESSSIZE
);
if ( szName[ 0 ] == TEXT('\0') )
{
SetDlgItemText (
hwnd,
IDD_SD1SPEEDDIAL1 + nCurrentSpeedDial - 1,
szName
);
}
}
}
break;
} // switch(LOWORD((DWORD)wParam))
break;
} // case WM_COMMAND:
default:
;
} // switch(msg)
return FALSE;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
INT_PTR CALLBACK SpeedDial2Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static DWORD nCurrentSpeedDial;
static const DWORD aMenuHelpIDs[] =
{
IDOK, IDH_DIALER_SPEED_SAVE,
IDD_SD2SAVEANDDIAL, IDH_DIALER_SPEED_SAVE_DIAL,
IDD_SD2TEXTNAME, IDH_DIALER_SPEED_NAME,
IDD_SD2EDITNAME, IDH_DIALER_SPEED_NAME,
IDD_SD2TEXTNUMBER, IDH_DIALER_SPEED_NUMBER,
IDD_SD2EDITNUMBER, IDH_DIALER_SPEED_NUMBER,
0, 0
};
switch(msg)
{
case WM_HELP:
// processes clicks on controls when
// context mode help is selected
WinHelp (
((LPHELPINFO)lParam)->hItemHandle,
gszHELPfilename,
HELP_WM_HELP,
(ULONG_PTR)aMenuHelpIDs
);
return TRUE;
case WM_CONTEXTMENU:
// processes right-clicks on controls
WinHelp (
(HWND)wParam,
gszHELPfilename,
HELP_CONTEXTMENU,
(ULONG_PTR)aMenuHelpIDs
);
return TRUE;
case WM_INITDIALOG:
{
TCHAR szFieldName [MAXBUFSIZE];
TCHAR szName [TAPIMAXCALLEDPARTYSIZE] = {0};
HKEY hKey = NULL;
DWORD dwSize;
nCurrentSpeedDial = LOWORD( lParam ) - IDD_DSPEEDDIAL1 + 1;
// retrieve speed dial button info
RegOpenKeyEx (DIALER_REGISTRY_ROOT, DIALER_REGISTRY_PATH, 0, KEY_READ, &hKey);
wsprintf(szFieldName, TEXT("Name%d"), nCurrentSpeedDial);
dwSize = sizeof (szName);
RegQueryValueEx (hKey, szFieldName, NULL, NULL, (LPBYTE)szName, &dwSize);
RegCloseKey (hKey);
SetDlgItemText (
hwnd,
IDD_SD2EDITNAME,
szName
);
SetDlgItemText (
hwnd,
IDD_SD2EDITNUMBER,
gszSDNumber[nCurrentSpeedDial]
);
// limit the lengths of the texts
SendDlgItemMessage (
hwnd,
IDD_SD2EDITNAME,
EM_LIMITTEXT,
(WPARAM)(TAPIMAXCALLEDPARTYSIZE - 1),
0
);
SendDlgItemMessage (
hwnd,
IDD_SD2EDITNUMBER,
EM_LIMITTEXT,
(WPARAM)(TAPIMAXDESTADDRESSSIZE - 1),
0
);
SetFocus( GetDlgItem( hwnd, IDD_SD2EDITNAME ) );
SendDlgItemMessage (
hwnd,
IDD_SD2EDITNAME,
EM_SETSEL,
0,
MAKELPARAM(0, -1)
);
return FALSE;
}
case WM_COMMAND:
{
TCHAR szName[ TAPIMAXDESTADDRESSSIZE ];
TCHAR szTemp[ TAPIMAXCALLEDPARTYSIZE ];
TCHAR szFieldName[MAXBUFSIZE];
TCHAR *p;
switch ( LOWORD( (DWORD) wParam ) )
{
case IDOK:
case IDD_SD2SAVEANDDIAL:
{
HKEY hKey = NULL;
RegCreateKeyEx (DIALER_REGISTRY_ROOT, DIALER_REGISTRY_PATH, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
GetDlgItemText (
hwnd,
IDD_SD2EDITNUMBER,
(LPTSTR) szName,
TAPIMAXDESTADDRESSSIZE
);
for (p = szName; *p == TEXT(' '); p++);
if (0 == *p)
{
wsprintf (szFieldName, TEXT("Name%d"), nCurrentSpeedDial);
RegDeleteValue (hKey, szFieldName);
wsprintf (szFieldName, TEXT("Number%d"), nCurrentSpeedDial);
RegDeleteValue (hKey, szFieldName);
}
else
{
lstrcpyn (gszSDNumber[nCurrentSpeedDial], p,
sizeof(gszSDNumber[nCurrentSpeedDial])/sizeof(TCHAR));
GetDlgItemText (
hwnd,
IDD_SD2EDITNAME,
szName,
TAPIMAXCALLEDPARTYSIZE
);
for (p = szName; *p == TEXT(' '); p++);
wsprintf ( szFieldName, TEXT("Name%d"), nCurrentSpeedDial );
RegSetValueEx (hKey, szFieldName, 0, REG_SZ, (LPBYTE)p, (lstrlen(p)+1)*sizeof(TCHAR));
wsprintf ( szFieldName, TEXT("Number%d"), nCurrentSpeedDial );
RegSetValueEx (hKey, szFieldName, 0, REG_SZ,
(LPBYTE)(gszSDNumber[nCurrentSpeedDial]),
(lstrlen(gszSDNumber[nCurrentSpeedDial])+1)*sizeof(TCHAR));
// update main window buttons
// is only number has been entered, label button with it.
if ( *p == TEXT('\0') )
{
lstrcpyn( szName, gszSDNumber[ nCurrentSpeedDial ], sizeof(szName)/sizeof(szName[0]) );
p = szName;
}
FitTextToButton (
ghWndMain,
IDD_DSPEEDDIAL1 + nCurrentSpeedDial - 1,
p
);
AmpersandCompensate( p, szTemp );
SetDlgItemText (
ghWndMain,
IDD_DSPEEDDIAL1 + nCurrentSpeedDial - 1,
szTemp
);
// if save and dial, then post dial message to main window
if ( LOWORD( (DWORD) wParam ) == IDD_SD2SAVEANDDIAL )
{
PostMessage (
ghWndMain,
WM_COMMAND,
MAKEWPARAM (
nCurrentSpeedDial + IDD_DSPEEDDIAL1 - 1,
BN_CLICKED
),
(LPARAM) GetDlgItem (
ghWndMain,
nCurrentSpeedDial + IDD_DSPEEDDIAL1 - 1
)
);
}
}
RegCloseKey (hKey);
EndDialog(hwnd, TRUE);
return TRUE;
}
case IDCANCEL:
EndDialog(hwnd, FALSE);
return TRUE;
case IDD_SD2EDITNAME:
case IDD_SD2EDITNUMBER:
if ( HIWORD( wParam ) == EN_CHANGE)
{
EnableWindow (
GetDlgItem( hwnd, IDD_SD2SAVEANDDIAL ),
GetWindowTextLength ( GetDlgItem( hwnd, IDD_SD2EDITNUMBER ) ) > 0
);
}
break;
} // switch(LOWORD((DWORD)wParam))
break;
}
default:
;
} // switch(msg)
return FALSE;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
VOID CALLBACK
tapiCallback (
DWORD hDevice,
DWORD dwMsg,
DWORD dwCBInstance,
DWORD dwParam1,
DWORD dwParam2,
DWORD dwParam3
)
{
switch (dwMsg)
{
INT errCode;
case LINE_ADDRESSSTATE:
break;
case LINE_CALLINFO:
break;
case LINE_CALLSTATE:
if ( (HCALL)hDevice != ghCall )
return;
switch ( dwParam1 ) // new state
{
case LINECALLSTATE_IDLE:
// tell "Dialing" window to terminate
if ( ghWndDialing )
{
SendMessage (
ghWndDialing,
WM_COMMAND,
MAKEWPARAM( IDOK, 0 ),
0
);
}
// tapi call cleanup
if ( !gfMakeCallReplyPending && ghCall )
{
if ( ( errCode = lineDeallocateCall( ghCall ) ) < 0 )
{
errString ( ghWndMain, errCode, MB_ICONSTOP | MB_OK );
}
ghCall = 0;
}
DialerLineClose();
gfCurrentLineAvail = TRUE;
// update main window
DisableDialButtons( FALSE );
break;
case LINECALLSTATE_BUSY:
tapiCallback (
hDevice,
dwMsg,
dwCBInstance,
LINECALLSTATE_DISCONNECTED,
LINEDISCONNECTMODE_BUSY,
dwParam3
);
break;
case LINECALLSTATE_SPECIALINFO:
tapiCallback (
hDevice,
dwMsg,
dwCBInstance,
LINECALLSTATE_DISCONNECTED,
LINEDISCONNECTMODE_UNREACHABLE,
dwParam3
);
break;
case LINECALLSTATE_DISCONNECTED:
{
BOOL fCallOK;
DWORD LineDisconnectMode;
if ( dwParam2 == 0 )
LineDisconnectMode = LINEDISCONNECTMODE_NORMAL;
else
LineDisconnectMode = dwParam2;
fCallOK = ( LineDisconnectMode == LINEDISCONNECTMODE_NORMAL ||
LineDisconnectMode == LINEDISCONNECTMODE_UNKNOWN ||
LineDisconnectMode == LINEDISCONNECTMODE_PICKUP ||
LineDisconnectMode == LINEDISCONNECTMODE_FORWARDED ||
LineDisconnectMode == LINEDISCONNECTMODE_UNAVAIL
);
if ( !gfMakeCallReplyPending && ghCall )
{
//gfDropping = TRUE;
if ( ( gDropCallRequestID = lineDrop ( ghCall, NULL, 0 ) ) < 0 )
{
errString ( ghWndMain, gDropCallRequestID, MB_ICONSTOP | MB_OK );
}
}
if ( !fCallOK )
DialogBoxParam (
ghInst,
MAKEINTRESOURCE(IDD_CALLFAILED),
ghWndMain,
LineInUseProc,
LineDisconnectMode
);
break;
}
}
break;
case LINE_CLOSE:
if ( gCurrentLineInfo.hLine == (HLINE)hDevice )
{
errString(ghWndMain, ERR_LINECLOSE, MB_ICONEXCLAMATION | MB_OK );
gCurrentLineInfo.hLine = 0;
gfCurrentLineAvail = FALSE;
DisableDialButtons(FALSE);
}
break;
case LINE_CREATE:
// dwParam1 is the new device's ID
if ( dwParam1 >= gnAvailDevices )
{
DWORD* gnAddrTemp;
DWORD iLine;
LINEINFO LineInfo;
// we record new device's address count.
// we are assuming here that we're just adding a new
// line and it's sequential and it's the last one
gnAvailDevices = dwParam1 + 1;
gnAddrTemp = (DWORD *) DialerAlloc ( sizeof(DWORD) * (int)(gnAvailDevices) );
for ( iLine = 0; iLine < (gnAvailDevices-1); ++iLine )
gnAddrTemp[iLine] = gnAddr[iLine];
DialerFree( gnAddr );
// we have effectively added one more
// space in the gnAddr array
gnAddr = gnAddrTemp;
if ( GetLineInfo( dwParam1, &LineInfo ) != ERR_NONE )
break;
gnAddr[dwParam1] = LineInfo.nAddr;
}
break;
case LINE_DEVSPECIFIC:
break;
case LINE_DEVSPECIFICFEATURE:
break;
case LINE_GATHERDIGITS:
break;
case LINE_GENERATE:
break;
case LINE_LINEDEVSTATE:
if ( dwParam1 & LINEDEVSTATE_REINIT )
{
if(dwParam2 != 0)
{
// this is another msg translated into REINIT
tapiCallback( hDevice, dwParam2, dwCBInstance, dwParam3, 0, 0 );
}
else
{
// Re-initialize TAPI
gfNeedToReinit = TRUE;
}
}
if ( dwParam1 & LINEDEVSTATE_REMOVED )
{
DialerLineClose();
tapiCallback(hDevice, LINE_CLOSE, dwCBInstance, 0, 0, 0); // is this needed?
}
break;
case LINE_MONITORDIGITS:
break;
case LINE_MONITORMEDIA:
break;
case LINE_MONITORTONE:
break;
// async reply from lineMakeCall() or lineDrop()
case LINE_REPLY:
// reply for lineMakeCall
if ( (LONG) dwParam1 == gMakeCallRequestID )
{
// error on make call
if ( dwParam2 != ERR_NONE )
{
// Get rid of the Dialing Dialog box if it's up
if ( ghWndDialing )
{
SendMessage(
ghWndDialing,
WM_COMMAND,
MAKEWPARAM(IDOK,0),
0
);
}
if ( dwParam2 == LINEERR_CALLUNAVAIL )
{
DialogBoxParam (
ghInst,
MAKEINTRESOURCE(IDD_CALLFAILED),
ghWndMain,
LineInUseProc,
0
);
}
else
{
errString ( ghWndMain, dwParam2, MB_ICONEXCLAMATION | MB_OK );
}
ghCall = 0;
DialerLineClose();
gfCurrentLineAvail = TRUE;
}
gfMakeCallReplyPending = FALSE;
}
// reply from lineDrop()
if ( (LONG) dwParam1 == gDropCallRequestID )
{
// tell "Dialing" window to terminate
if ( ghWndDialing )
{
SendMessage (
ghWndDialing,
WM_COMMAND,
MAKEWPARAM( IDOK,0 ),
0
);
}
// tapi call cleanup
if ( dwParam2 == ERR_NONE )
{
if ( !gfMakeCallReplyPending && ghCall )
{
if ( ( errCode = lineDeallocateCall( ghCall ) ) < 0 )
{
errString ( ghWndMain, errCode, MB_ICONSTOP | MB_OK );
}
ghCall = 0;
}
}
DialerLineClose ();
gfCurrentLineAvail = TRUE;
}
break;
case LINE_REQUEST:
// Simple TAPI request
if ( dwParam1 == LINEREQUESTMODE_MAKECALL )
{
gfCallRequest = TRUE;
}
break;
}
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
BOOL InitializeLineBox(HWND hwndLineBox)
{
DWORD iLine, iItem, iItemCurrent = (DWORD)-1;
DWORD errCode;
LPLINEINFO lpLineInfo = NULL;
// allocate buffer for storing LINEINFO for all of
// the available lines. Always allocate space for
// at least one line
if ( gnAvailDevices == 0 )
{
lpLineInfo = (LPLINEINFO) DialerAlloc( sizeof(LINEINFO) );
}
else
{
lpLineInfo = (LPLINEINFO) DialerAlloc ( sizeof(LINEINFO) * (int)gnAvailDevices );
}
// if no space was set aside...
if ( lpLineInfo == NULL )
return LINEERR_NOMEM;
// fill lpLineInfo[] and open each line
for ( iLine = 0; iLine < gnAvailDevices; ++iLine )
{
// skip remaining processing for this line if it didn't open
if ( GetLineInfo( iLine, &lpLineInfo[iLine] ) != ERR_NONE )
{
continue;
}
iItem = (int) SendMessage (
hwndLineBox,
CB_ADDSTRING,
0,
(LPARAM)(lpLineInfo[iLine].szLineName)
);
// error, bail out.
if ( iItem == CB_ERR || iItem == CB_ERRSPACE )
{
if (lpLineInfo)
{
DialerFree(lpLineInfo);
}
return FALSE;
}
errCode = (int) SendMessage (
hwndLineBox,
CB_SETITEMDATA,
(WPARAM)iItem,
(LPARAM)iLine
);
if ( iLine == giCurrentLine )
{
iItemCurrent = iItem;
}
else if ( iItemCurrent != -1 && iItem <= iItemCurrent )
{
// if the item we are putting is before the
// "current" item, we must increment iItemCurrent
// to reflect that something is being placed before
// it, due to sorting
++iItemCurrent;
}
}
if ( iItemCurrent == (DWORD)-1 )
iItemCurrent = 0;
if ( SendMessage( hwndLineBox, CB_GETCOUNT, 0, 0) != 0 )
{
SendMessage( hwndLineBox, CB_SETCURSEL, (WPARAM)iItemCurrent, 0 );
return TRUE;
}
DialerFree(lpLineInfo);
return FALSE;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
BOOL InitializeAddressBox( HWND hwndLineBox, HWND hwndAddressBox )
{
DWORD errCode;
DWORD iAddress, iItem, iItemCurrent = (DWORD)-1;
DWORD iLineBoxCurrent;
LPTSTR pszAddressName;
if ( SendMessage( hwndLineBox, CB_GETCOUNT, 0, 0 ) == 0 )
{
return FALSE;
}
// select current entry in line box
iLineBoxCurrent = (int) SendMessage (
hwndLineBox,
CB_GETITEMDATA,
SendMessage( hwndLineBox, CB_GETCURSEL, 0, 0 ),
0
);
// empty address list box
SendMessage ( hwndAddressBox, CB_RESETCONTENT, 0, 0);
// get all the address for this line
for ( iAddress = 0; iAddress < gnAddr[iLineBoxCurrent]; ++iAddress )
{
pszAddressName = GetAddressName (iLineBoxCurrent, iAddress );
// if this address if fails, try the next one
if ( !pszAddressName )
continue;
iItem = (int) SendMessage (
hwndAddressBox,
CB_ADDSTRING,
0,
(LPARAM)pszAddressName
);
// error, bail out
if ( iItem == CB_ERR || iItem == CB_ERRSPACE )
return FALSE;
errCode = (int)SendMessage (
hwndAddressBox,
CB_SETITEMDATA,
(WPARAM) iItem,
(LPARAM) iAddress
);
if ( iLineBoxCurrent == giCurrentLine )
{
if(iAddress == giCurrentAddress)
{
iItemCurrent = iItem;
}
else
{
// if the item we are putting is before the
// "current" item, we must increment iItemCur
// to reflect that something is being placed
// before it, due to sorting
if ( iItemCurrent != -1 && iItem <= iItemCurrent )
{
++iItemCurrent;
}
}
}
DialerFree( pszAddressName );
}
if ( iLineBoxCurrent != giCurrentLine )
{
// if we're not looking at the current line
// then highlight address 0
iItemCurrent = 0;
}
SendMessage (
hwndAddressBox,
CB_SETCURSEL,
iItemCurrent,
0
);
return TRUE;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
VOID ManageAssistedTelephony(VOID)
{
DWORD errCode;
LINEREQMAKECALL *lpRequestBuffer;
lpRequestBuffer = (LINEREQMAKECALL*) DialerAlloc( sizeof( LINEREQMAKECALL ) );
if ( !lpRequestBuffer )
{
goto error;
}
// bring window to front
SetForegroundWindow(ghWndMain);
// get next queued request.
errCode = lineGetRequest (
ghLineApp,
LINEREQUESTMODE_MAKECALL,
lpRequestBuffer
);
if ( errCode )
{
// if no more call requests pending, reset flag.
if ( errCode == LINEERR_NOREQUEST )
{
gfCallRequest = FALSE;
}
else
{
errString ( ghWndMain, errCode, MB_ICONEXCLAMATION | MB_OK );
}
goto error;
}
// if a line has not been selected
if ( giCurrentLine == (DWORD)-1 )
{
if (!DialogBoxParam (
ghInst,
MAKEINTRESOURCE(IDD_CONNECTUSING),
ghWndMain,
ConnectUsingProc,
INVALID_LINE
))
{
// failed to get a line
goto error;
}
}
// make the reuested call.
InitiateCall (
lpRequestBuffer->szDestAddress,
lpRequestBuffer->szCalledParty
);
error :
if ( lpRequestBuffer )
{
DialerFree( lpRequestBuffer );
}
return;
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
VOID DialerLineClose()
{
DWORD errCode;
if ( gCurrentLineInfo.hLine )
{
if ( errCode = lineClose ( gCurrentLineInfo.hLine ) )
{
errString ( ghWndMain, errCode, MB_ICONSTOP | MB_OK );
}
gCurrentLineInfo.hLine = 0;
}
// re-initialize TAPI if it needs to be re-initialized
if ( gfNeedToReinit )
{
CloseTAPI();
errCode = InitializeTAPI();
if(errCode)
{
errString(ghWndMain, errCode, MB_APPLMODAL | MB_ICONEXCLAMATION );
DialerCleanup(); // terminate program if we can't init
return;
}
errCode = lineRegisterRequestRecipient (
ghLineApp,
0,
LINEREQUESTMODE_MAKECALL,
TRUE
);
if (errCode)
{
errString(ghWndMain, errCode, MB_ICONEXCLAMATION | MB_OK );
}
gfNeedToReinit = FALSE;
}
}
//***************************************************************************
//***************************************************************************
//***************************************************************************
int errString( HWND hWndOwner, UINT errCode, UINT uFlags )
{
PTSTR ptStrTitle;
PTSTR ptStrError;
int nResult;
BOOL bDefault = FALSE;
ptStrTitle = DialerAlloc( MAXBUFSIZE*sizeof(TCHAR) );
if ( NULL == ptStrTitle )
{
// Now, _this_ is a problem.
return 0;
}
ptStrError = DialerAlloc( MAXBUFSIZE*sizeof(TCHAR) );
if ( NULL == ptStrError )
{
// Now, _this_ is a problem.
DialerFree( ptStrTitle);
return 0;
}
switch(errCode)
{
case ERR_NOLINES:
errCode = ikszErrNoVoiceLine;
break;
case ERR_NOVOICELINE:
errCode = ikszErrNoVoiceLine;
break;
case ERR_LINECLOSE:
errCode = ikszErrLineClose;
break;
case ERR_911WARN:
errCode = ikszWarningFor911;
break;
case ERR_NEWDEFAULT:
errCode = ikszWarningNewDefault;
break;
case LINEERR_NODRIVER:
errCode = ikszErrLineInitNoDriver;
break;
case LINEERR_NODEVICE:
errCode = ikszErrLineInitNoDevice;
break;
case LINEERR_INIFILECORRUPT:
errCode = ikszErrLineInitBadIniFile ;
break;
case LINEERR_NOMEM:
errCode = ikszErrOOM;
break;
case LINEERR_INCOMPATIBLEAPIVERSION:
errCode = ikszErrLineInitWrongDrivers ;
break;
case LINEERR_OPERATIONFAILED:
errCode = ikszErrTAPI;
break;
case LINEERR_INVALADDRESS:
errCode = ikszErrInvalAddress;
break;
case LINEERR_ADDRESSBLOCKED:
errCode = ikszErrAddrBlocked;
break;
case LINEERR_BILLINGREJECTED:
errCode = ikszErrBillingRejected;
break;
case LINEERR_RESOURCEUNAVAIL:
case LINEERR_ALLOCATED:
case LINEERR_INUSE:
errCode = ikszErrResUnavail;
break;
case LINEERR_NOMULTIPLEINSTANCE:
errCode = ikszErrNoMultipleInstance;
break;
case LINEERR_INVALCALLSTATE:
errCode = ikszErrInvalCallState;
break;
case LINEERR_INVALCOUNTRYCODE:
errCode = ikszErrInvalidCountryCode;
break;
case LINEERR_INVALCALLPARAMS:
errCode = ikszDisconnectedCantDo;
break;
default:
bDefault = TRUE;
break;
}
if (bDefault)
{
// if using default error, get TAPI's
// error message from FormatError()
if (!FormatMessage(FORMAT_MESSAGE_FROM_HMODULE,
(LPCVOID)GetModuleHandle(TEXT("TAPI32.DLL")),
(DWORD)TAPIERROR_FORMATMESSAGE(errCode),
0,
(LPTSTR)ptStrError,
MAXBUFSIZE,
NULL))
{
// if this fails, fall back on default
LoadString( ghInst, ikszErrDefault, ptStrError, MAXBUFSIZE);
}
}
else // not the default error message
{
if ( 0 == LoadString( ghInst, errCode, ptStrError, MAXBUFSIZE ) )
{
LoadString( ghInst, ikszErrDefault, ptStrError, MAXBUFSIZE );
}
}
LoadString( ghInst, ikszWarningTitle, ptStrTitle, MAXBUFSIZE );
nResult = MessageBox( hWndOwner, ptStrError, ptStrTitle, uFlags );
DialerFree( ptStrTitle );
DialerFree( ptStrError );
return nResult;
}
/*
* Name :
* FitTextToButton
*
* Arguements :
* hDlg handle for the dialog in which this button is embedded
* nButtonID button id of this button
* szName Name to fit on the button. Max size TAPIMAXCALLEDPARTYSIZE
*
* Return :
* None
*
* Comments :
* Function first checks to see if the button text specified fits in the
* button. If it does not it truncates it appropriately and adds trailing
* ellipses.
*/
VOID FitTextToButton ( HWND hDlg, INT nButtonID, LPTSTR szName )
{
HDC hDC;
HFONT hFont, hOldFont;
HWND hWnd;
do
{
// calculate number of chars. that can fit on
// the button
int nLen;
RECT rect;
SIZE size;
POINT pt;
TCHAR buf [TAPIMAXCALLEDPARTYSIZE + 1];
// get button dimensions
hWnd = GetDlgItem( hDlg, nButtonID );
if ( hWnd == NULL )
break;
if ( !GetClientRect( hWnd, &rect ) )
break;
// get character dimensions
hDC = GetDC( hWnd );
if ( hDC == NULL )
break;
hFont = (HFONT) SendMessage( hWnd, WM_GETFONT, 0, 0 );
if ( hFont == NULL )
hOldFont = SelectObject( hDC, GetStockObject( SYSTEM_FONT ) );
else
hOldFont = SelectObject( hDC, hFont );
// add an extra char at the end to compensate for
// leading space,
lstrcpy ( buf, szName );
nLen = lstrlen( buf );
buf [ nLen ] = TEXT('X');
buf [ nLen + 1 ] = TEXT('\0');
if ( !GetTextExtentPoint32( hDC, buf, nLen + 1, &size ) )
break;
pt.x = size.cx;
if ( !LPtoDP( hDC, &pt, 1 ) )
break;
// check if name fits on button
if ( pt.x > rect.right )
{
// find how much of the name fits
int i = 0;
nLen = lstrlen( szName );
for ( i = 0; i < nLen; i++ )
{
buf[ i ] = szName[ i ];
// an extra char is stuffed to compensate for the
// leading space left by the left alignment
buf [ i + 1 ] = TEXT('X');
buf [ i + 2 ] = TEXT('\0');
// break out in cases of error condition
if ( !GetTextExtentPoint32( hDC, buf, i + 2, &size ) )
{
i = nLen;
break;
}
pt.x = size.cx;
if ( !LPtoDP( hDC, &pt, 1 ) )
{
i = nLen;
break;
}
if ( pt.x > rect.right )
break;
}
// error
if ( i >= nLen )
break;
// name is too long. truncate and add ellipses
szName [i - 3] = TEXT('\0');
lstrcat( szName, TEXT("...") );
}
} while( FALSE );
if ( hDC )
{
SelectObject( hDC, hOldFont );
ReleaseDC( hWnd, hDC );
}
return;
}
/*
* Name :
* Is911
*
* Arguements :
* lpTransOut - Translated address contained the dialable string
*
* Returns
* TRUE - If number to be dialed (in the US) is prefixed by 911
* FALSE - Otherwise
*
* Comments
*
*/
BOOL Is911 ( LPLINETRANSLATEOUTPUT lpTransOut )
{
DWORD i = 0, j = 0;
LPTSTR lpDialDigits = (LPTSTR)((char*)lpTransOut + lpTransOut-> dwDialableStringOffset);
TCHAR sz3Pref [ 4 ] = TEXT("");
// if this is not the US
if ( lpTransOut-> dwCurrentCountry != 1 )
return FALSE;
// skip non digit characters and extract
// the first 3 digits in the dialable number
for ( i = 0, j = 0; i < lpTransOut-> dwDialableStringSize ; i++ )
{
if ( ISDIGIT( lpDialDigits[i] ) )
{
sz3Pref[ j++ ] = lpDialDigits [ i ];
sz3Pref[ j ] = TEXT('\0');
if ( j == 3 )
break;
}
}
if ( !lstrcmp( sz3Pref, TEXT("911") ) )
{
return TRUE;
}
return FALSE;
}
/*
* Name :
* MakeCanonicalNumber
*
* Arguements :
* szNumber Number to convert into canonical form. Max size TAPIMAXDESTADDRESSSIZE
* szCanNumber Canonical representation of number specified in szNumber
*
* Return :
* TRUE If the conversion was successful.
* FALSE otherwise
*
* Comments :
* Function first checks if given number is already in canonical form.
* If it is, it returns. If it is not, then it performs the conversion.
*/
BOOL MakeCanonicalNumber ( LPCTSTR szNumber, LPTSTR szCanNumber )
{
TCHAR szDigits [ TAPIMAXDESTADDRESSSIZE ];
TCHAR szPref [ TAPIMAXDESTADDRESSSIZE ];
BOOL bRes = FALSE;
BOOL bTryAgain = TRUE;
INT errCode = -1;
INT nLenPref, nLenDigits, cPos, i;
DWORD dwSize = 0;
DWORD dwInd = 0;
LPLINETRANSLATEOUTPUT lpTransOut = NULL;
LPLINETRANSLATECAPS lpTransCaps = NULL;
dwSize = sizeof ( LINETRANSLATEOUTPUT );
do
{
lpTransOut = ( LPLINETRANSLATEOUTPUT ) DialerAlloc ( dwSize );
if ( !lpTransOut )
{
errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK );
goto error;
}
while (TRUE)
{
lpTransOut-> dwTotalSize = dwSize;
errCode = lineTranslateAddress (
ghLineApp,
giCurrentLine,
gCurrentLineInfo.dwAPIVersion,
szNumber,
0,
0,
lpTransOut
);
if ( (LINEERR_INIFILECORRUPT != errCode) ||
(FALSE == bTryAgain) )
{
break;
}
bTryAgain = FALSE;
errCode = lineTranslateDialog (
ghLineApp,
giCurrentLine,
TAPI_VERSION_1_4,
NULL,
szNumber
);
if (NO_ERROR != errCode)
{
break;
}
}
if (errCode)
{
goto error;
}
if ( lpTransOut-> dwNeededSize <= lpTransOut-> dwTotalSize )
break;
dwSize = lpTransOut-> dwNeededSize;
DialerFree( lpTransOut );
} while (TRUE);
// check if input number is already in
// canonical form.
if ( lpTransOut-> dwTranslateResults & LINETRANSLATERESULT_CANONICAL )
goto error;
// ensure country is the USA.
if ( lpTransOut-> dwCurrentCountry != 1 )
goto error;
// Extract the digits from given string
// allowed formatting characters that are ignored are
// space, (, ), -, .
// presence of other characters will render the string invalid.
// find the prefix of the address upto the | mark.
// the rest of the string can be ignored
nLenPref = _tcscspn ( szNumber, TEXT("|") );
lstrcpyn( szPref, szNumber, nLenPref+1 );
szPref[ nLenPref ] = TEXT('\0');
// if string is not composed entirely of digits
// and allowable formating characters, quit conversion
if ( _tcsspn( szPref, TEXT(" 0123456789()-.") ) != (size_t) nLenPref )
goto error;
// collect digits ignoring formating characters.
szDigits[ 0 ] = TEXT('\0');
for ( i = 0, nLenDigits = 0; i < nLenPref; i++ )
{
if ( ISDIGIT( szNumber[ i ] ) )
{
szDigits[ nLenDigits++ ] = szNumber[ i ];
}
}
szDigits[ nLenDigits ] = TEXT('\0');
// if "internal" number
if ( nLenDigits < LOCAL_NUMBER )
goto error;
switch ( nLenDigits )
{
// Local number ( 7 digits) preceeded by a 0/1
// Strip leading 0/1 and treat as a local number
case EXTENDED_LOCAL_NUMBER:
if ( szDigits[ 0 ] == TEXT('0') || szDigits[ 0 ] == TEXT('1') )
{
nLenDigits--;
memmove( szDigits, &(szDigits[1]), nLenDigits*sizeof(TCHAR) );
szDigits[ nLenDigits ] = TEXT('\0');
cPos = _tcscspn( szPref, TEXT("01") );
nLenPref--;
memmove( &(szPref[ cPos ]), &(szPref[ cPos + 1 ]), (nLenPref - cPos)*sizeof(TCHAR) );
szPref[ nLenPref ] = TEXT('\0');
}
else
{
goto error;
}
case LOCAL_NUMBER :
{
LPLINELOCATIONENTRY lpLocLst;
// if leading digit is 0 or 1, it is
// illegal in the US
if ( szDigits[ 0 ] == TEXT('0') || szDigits[ 0 ] == TEXT('1') )
{
goto error;
}
// get area code nformation for local number
dwSize = sizeof( LINETRANSLATECAPS );
do
{
lpTransCaps = (LPLINETRANSLATECAPS) DialerAlloc( dwSize );
if ( !lpTransCaps )
{
errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK );
goto error;
}
lpTransCaps-> dwTotalSize = dwSize;
errCode = lineGetTranslateCaps (
ghLineApp,
gCurrentLineInfo.dwAPIVersion,
lpTransCaps
);
if ( errCode )
{
errString( ghWndMain, errCode, MB_ICONSTOP | MB_OK );
goto error;
}
if ( lpTransCaps-> dwNeededSize <= lpTransCaps-> dwTotalSize )
{
break;
}
dwSize = lpTransCaps-> dwNeededSize;
DialerFree( lpTransCaps );
} while ( TRUE );
// skip entries till you locate information for current location
dwSize = sizeof( LINELOCATIONENTRY );
lpLocLst = (LPLINELOCATIONENTRY) ( (LPTSTR) ((char*)lpTransCaps +
lpTransCaps-> dwLocationListOffset) );
for ( dwInd = 0; dwInd < lpTransCaps-> dwNumLocations ; dwInd++ )
{
if ( lpLocLst[ dwInd ].dwPermanentLocationID == lpTransCaps-> dwCurrentLocationID )
break;
}
// current location no found ?????
// login error
if ( dwInd == lpTransCaps-> dwNumLocations )
{
goto error;
}
// construct canonical form as
szCanNumber[ 0 ]= TEXT('\0');
lstrcat( szCanNumber, TEXT("+1 (") );
lstrcat( szCanNumber, (LPTSTR) ((char*)lpTransCaps + lpLocLst[ dwInd ].dwCityCodeOffset) );
lstrcat( szCanNumber, TEXT(") ") );
lstrcat( szCanNumber, szDigits );
cPos = _tcscspn( szNumber, TEXT("|") );
if ( cPos != lstrlen( szNumber ) )
{
lstrcat( szCanNumber, &(szNumber[ cPos ]) );
}
bRes = TRUE;
break;
}
case EXTENDED_LONG_DISTANCE_NUMBER:
{
// Long distance number ( 10 digits) preceeded by a 0/1
// Strip leading 0/1 and treat as a long distance number
if ( szDigits[ 0 ] == TEXT('0') || szDigits[ 0 ] == TEXT('1') )
{
nLenDigits--;
memmove( szDigits, &(szDigits[1]), nLenDigits*sizeof(TCHAR) );
szDigits[ nLenDigits ] = TEXT('\0');
cPos = _tcscspn( szPref, TEXT("01") );
nLenPref--;
memmove( &(szPref[ cPos ]), &(szPref[ cPos + 1 ]), (nLenPref - cPos)*sizeof(TCHAR) );
szPref[ nLenPref ] = TEXT('\0');
}
else
{
goto error;
}
}
case LONG_DISTANCE_NUMBER:
{
// if first or fourth digit is 0/1, illegal number
if ( szDigits[ 0 ] == TEXT('0') || szDigits[ 0 ] == TEXT('1') ||
szDigits[ 3 ] == TEXT('0') || szDigits[ 3 ] == TEXT('1') )
{
goto error;
}
szCanNumber[ 0 ] = TEXT('\0');
lstrcat( szCanNumber, TEXT("+1 (") );
_tcsncat( szCanNumber, szDigits, 3 );
lstrcat( szCanNumber, TEXT(") ") );
lstrcat( szCanNumber, &(szDigits[ 3 ]) );
bRes = TRUE;
}
break;
default :
goto error;
}
error:
if ( lpTransOut )
DialerFree( lpTransOut );
if ( lpTransCaps )
DialerFree( lpTransCaps );
return bRes;
}
/*
* Name :
* AmpersandCompensate
*
* Arguements :
* lpszSrc : Src string containing &s
* lpszDst : Dest string
*
* Return :
*
* Comments :
* Copies string pointed to by lpszSrc to lpszDst character by
* character. If an & is encountered in this process in lpszSrc
* it is copied as && into lpszDst.
* Assumes lpszDst and lpszSrc are of size TAPIMAXCALLEDPARTYSIZE
*/
VOID AmpersandCompensate ( LPCTSTR lpszSrc, LPTSTR lpszDst )
{
// check if the name has an & in it. If so replace
// it with &&.
INT cCnt, cInd;
for ( cCnt = 0, cInd = 0;
cInd < TAPIMAXCALLEDPARTYSIZE;
cInd++, cCnt++ )
{
if ( lpszSrc[ cCnt ] == TEXT('&') )
{
lpszDst[ cInd++ ] = TEXT('&');
}
lpszDst[ cInd ] = lpszSrc[ cCnt ];
if ( lpszSrc[ cCnt ] == TEXT('\0') )
break;
}
// make sure string is null terminated.
lpszDst[ TAPIMAXCALLEDPARTYSIZE - 1 ] = TEXT('\0');
return;
}
/*
* Name :
* AmpersandDeCompensate
*
* Arguements :
* lpszSrc : Src string containing &s
* lpszDst : Dest string
*
* Return :
*
* Comments :
* Copies string pointed to by lpszSrc to lpszDst character by
* character. If an && is encountered in this process in lpszSrc
* it is copied as & into lpszDst.
* Assumes lpszDst and lpszSrc are of size TAPIMAXCALLEDPARTYSIZE
*/
VOID AmpersandDeCompensate ( LPCTSTR lpszSrc, LPTSTR lpszDst )
{
// check if the name has an & in it. If so replace
// it with &&.
INT cCnt, cInd;
for ( cCnt = 0, cInd = 0;
cInd < TAPIMAXCALLEDPARTYSIZE;
cInd++, cCnt++ )
{
if ( ( lpszSrc[ cInd ] == TEXT('&') ) &&
( lpszSrc[ cInd + 1 ] == TEXT('&') ) )
{
cInd++;
}
lpszDst[ cCnt ] = lpszSrc[ cInd ] ;
if ( lpszSrc [ cInd ] == TEXT('\0') )
{
break;
}
}
lpszDst[ TAPIMAXCALLEDPARTYSIZE - 1 ] = TEXT('\0');
return;
}