summaryrefslogtreecommitdiffstats
path: root/private/tapi/dev/apps/dialer
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/tapi/dev/apps/dialer/depend.mk4
-rw-r--r--private/tapi/dev/apps/dialer/dialer.c4345
-rw-r--r--private/tapi/dev/apps/dialer/dialer.def9
-rw-r--r--private/tapi/dev/apps/dialer/dialer.h51
-rw-r--r--private/tapi/dev/apps/dialer/dialer.icobin0 -> 1078 bytes
-rw-r--r--private/tapi/dev/apps/dialer/dialer.mak389
-rw-r--r--private/tapi/dev/apps/dialer/dialer.rc452
-rw-r--r--private/tapi/dev/apps/dialer/dialhelp.h29
-rw-r--r--private/tapi/dev/apps/dialer/linebusy.icobin0 -> 766 bytes
-rw-r--r--private/tapi/dev/apps/dialer/makefile29
-rw-r--r--private/tapi/dev/apps/dialer/makefile.def50
-rw-r--r--private/tapi/dev/apps/dialer/nextver/depend.mk4
-rw-r--r--private/tapi/dev/apps/dialer/nextver/dialer.c4300
-rw-r--r--private/tapi/dev/apps/dialer/nextver/dialer.def9
-rw-r--r--private/tapi/dev/apps/dialer/nextver/dialer.h51
-rw-r--r--private/tapi/dev/apps/dialer/nextver/dialer.icobin0 -> 1078 bytes
-rw-r--r--private/tapi/dev/apps/dialer/nextver/dialer.mak389
-rw-r--r--private/tapi/dev/apps/dialer/nextver/dialer.rc419
-rw-r--r--private/tapi/dev/apps/dialer/nextver/dialhelp.h29
-rw-r--r--private/tapi/dev/apps/dialer/nextver/linebusy.icobin0 -> 766 bytes
-rw-r--r--private/tapi/dev/apps/dialer/nextver/makefile29
-rw-r--r--private/tapi/dev/apps/dialer/nextver/makefile.def50
-rw-r--r--private/tapi/dev/apps/dialer/nextver/nt.mak27
-rw-r--r--private/tapi/dev/apps/dialer/nextver/resource.h155
-rw-r--r--private/tapi/dev/apps/dialer/nextver/sources59
-rw-r--r--private/tapi/dev/apps/dialer/nt.mak27
-rw-r--r--private/tapi/dev/apps/dialer/resource.h155
-rw-r--r--private/tapi/dev/apps/dialer/sources59
-rw-r--r--private/tapi/dev/apps/dialer/version.rc66
-rw-r--r--private/tapi/dev/apps/dialer/win31.mak39
30 files changed, 11225 insertions, 0 deletions
diff --git a/private/tapi/dev/apps/dialer/depend.mk b/private/tapi/dev/apps/dialer/depend.mk
new file mode 100644
index 000000000..506be7029
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/depend.mk
@@ -0,0 +1,4 @@
+.\dialer.obj: ..\dialer.c ..\dialer.h ..\dialhelp.h ..\resource.h
+
+.\dialer.res: ..\dialer.rc ..\version.rc ..\resource.h
+
diff --git a/private/tapi/dev/apps/dialer/dialer.c b/private/tapi/dev/apps/dialer/dialer.c
new file mode 100644
index 000000000..a517a9a89
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/dialer.c
@@ -0,0 +1,4345 @@
+/*++
+
+Copyright (c) 1996 Microsoft Corporation
+
+Module Name:
+
+ dialer.c
+
+--*/
+
+
+#include "dialer.h"
+#include "string.h"
+#include "stdlib.h"
+#include "shellapi.h"
+
+
+#define ISDIGIT(x) (((x) - '0') >= 0) && (((x) - '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
+ char 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 [] = "DIALER.INI";
+static TCHAR gszHELPfilename [] = "DIALER.HLP";
+static TCHAR gszDialerClassName[] = "DialerClass";
+TCHAR const gszNULL[] = "";
+
+// window item variables
+HFONT ghFontBtn; // handle to 1, 2, ..., 0's font
+HFONT ghFontBtnText; // handle to number button's text font
+HFONT ghFontBtnStar; // handle to * and # button's font
+HLINEAPP ghLineApp = NULL; // Dialer's usage handle (regist. w/TAPI)
+HCALL ghCall = NULL; // call handle for Dialer's call
+
+LPSTR gszCurrentNumber = NULL; // number of destination of current call
+LPSTR gszCurrentName = NULL; // name of destination of current call
+
+BOOL gfRegistered; // was lineRegisterRequestRecipient()
+ // successful?
+
+//BOOL gfDropping = FALSE; // is Dialer currently dropping a call?
+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 ];
+
+
+// Function declarations
+
+// button related functions
+VOID ButtonFontSetup(VOID);
+VOID DrawButton(HDC hdc, RECT rcBtn, BOOL fHighlighted);
+VOID DrawButtonText(HDC hdc, RECT rcBtn, BOOL fHighlighted, UINT IDD_Btn);
+VOID DisableDialButtons(BOOL fDisable);
+VOID FitTextToButton( HWND, INT, LPSTR );
+
+// Callback functions
+BOOL CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+BOOL CALLBACK DialingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+BOOL CALLBACK AboutProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+BOOL CALLBACK ConnectUsingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+BOOL CALLBACK LineInUseProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+BOOL CALLBACK SpeedDial1Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+BOOL 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(LPCSTR szNumber, LPCSTR szName);
+
+VOID DialerLineClose(VOID);
+VOID DialerCleanup(VOID);
+VOID CloseTAPI(VOID);
+
+DWORD GetLineInfo(DWORD iLine, LPLINEINFO lpLineInfo);
+VOID GetLineInfoFailed (
+ DWORD iLine, LPLINEDEVCAPS lpDevCaps,
+ LPLINEINFO lpLineInfo
+ );
+LPSTR GetAddressName(DWORD iLine, DWORD iAddress);
+BOOL MakeCanonicalNumber( LPCSTR szName, LPSTR szCanNumber );
+
+// misc. helper functions
+VOID ReadINI(VOID);
+int errString(HWND hWnd, UINT errCode, UINT uFlags);
+VOID AddToRedialList(LPCSTR szNumber);
+BOOL InitializeLineBox(HWND hwndLineBox);
+BOOL InitializeAddressBox(HWND hwndLineBox, HWND hwndAddressBox);
+BOOL Is911 ( LPLINETRANSLATEOUTPUT lpTransOut );
+VOID AmpersandCompensate( LPCSTR lpszSrc, LPSTR lpszDst );
+VOID AmpersandDeCompensate( LPCSTR lpszSrc, LPSTR 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;
+
+ char szBuffer[MAXBUFSIZE]; // to read in dwPreferredPLID as a string first
+
+
+
+ errCode = lineInitialize (
+ &ghLineApp,
+ ghInst,
+ (LINECALLBACK) tapiCallback,
+ gszAppName,
+ &gnAvailDevices
+ );
+ 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 = lineInitialize (
+ &ghLineApp,
+ ghInst,
+ (LINECALLBACK)tapiCallback,
+ gszAppName,
+ &gnAvailDevices
+ ) )
+ == 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;
+ }
+
+ // retrieve preferred line info from INI file
+ GetPrivateProfileString (
+ "Preference",
+ "Preferred Line",
+ gszNULL,
+ szBuffer,
+ MAXBUFSIZE,
+ gszINIfilename
+ );
+
+ // if szBuffer is not empty.
+ if ( lstrcmp ( gszNULL, szBuffer ) )
+ {
+ dwPreferredPLID = (DWORD) atoi( 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,
+ (DLGPROC)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
+ GetPrivateProfileString (
+ "Preference",
+ "Preferred Address",
+ gszNULL,
+ szBuffer,
+ MAXBUFSIZE,
+ gszINIfilename
+ );
+
+ // if preferred address read from INI file
+ if ( lstrcmp( gszNULL, szBuffer ) )
+ {
+ giCurrentAddress = (DWORD) atoi( szBuffer );
+
+ // if the address is invalid, set default
+ if ( giCurrentAddress >= gCurrentLineInfo.nAddr )
+ giCurrentAddress = 0;
+ }
+
+
+tapiinit_exit:
+
+ 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, "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,
+ (LPCSTR)MAKEINTRESOURCE(IDD_DIALER),
+ (HWND)NULL,
+ MainWndProc
+ );
+
+ ReadINI();
+ ButtonFontSetup();
+
+ 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 msg.wParam;
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+LPVOID DialerAlloc(size_t cbToAlloc)
+{
+ return LocalAlloc(LPTR, cbToAlloc);
+}
+
+
+LPVOID DialerFree(LPVOID lpMem)
+{
+ return LocalFree( lpMem );
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+VOID ReadINI( VOID )
+{
+ WORD cSDEntry, cLastDialed;
+ DWORD cComma;
+
+ POINT ptLeftTop;
+
+ char szName[ TAPIMAXCALLEDPARTYSIZE ];
+ char szTemp[ TAPIMAXCALLEDPARTYSIZE ];
+
+ char szNum[MAXBUFSIZE];
+ char szFieldName[MAXBUFSIZE];
+ char szPt[MAXBUFSIZE];
+
+
+ // get speed dial settings from INI file
+ for(cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry)
+ {
+
+ wsprintf(szFieldName, "Name%d", cSDEntry);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ szName,
+ TAPIMAXCALLEDPARTYSIZE - 1,
+ gszINIfilename
+ );
+
+ wsprintf(szFieldName, "Number%d", cSDEntry);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ gszSDNumber[cSDEntry],
+ TAPIMAXDESTADDRESSSIZE - 1,
+ gszINIfilename
+ );
+
+ if ( !lstrcmp( gszNULL, szName ) )
+ {
+ lstrcpy( szName, gszSDNumber[ cSDEntry ] );
+ }
+
+ FitTextToButton( ghWndMain, IDD_DSPEEDDIAL1 + cSDEntry - 1, szName );
+
+ AmpersandCompensate( szName, szTemp );
+ SetDlgItemText (
+ ghWndMain,
+ IDD_DSPEEDDIAL1 + cSDEntry - 1,
+ (LPCSTR)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, "Last dialed %d", cLastDialed);
+ GetPrivateProfileString (
+ "Last dialed numbers",
+ szFieldName,
+ gszNULL,
+ szNum,
+ MAXBUFSIZE - 1,
+ gszINIfilename
+ );
+ if ( szNum[0] ) // i.e. if szNum isn't simply "" - if we read something
+ // from the INI - put it in the combo box
+ SendDlgItemMessage(
+ ghWndMain,
+ IDD_DCOMBO,
+ CB_ADDSTRING,
+ 0,
+ (LPARAM)(LPCSTR)szNum
+ );
+ }
+
+ // set defaults
+ ptLeftTop.x = 100;
+ ptLeftTop.y = 100;
+
+ // set the window position based on the INI data
+ GetPrivateProfileString (
+ "Preference",
+ "Main Window Left/Top",
+ gszNULL,
+ szPt,
+ MAXBUFSIZE - 1,
+ gszINIfilename
+ );
+
+ if ( szPt[0] )
+ {
+ cComma = strcspn(szPt, ",");
+ szPt[cComma] = 0;
+ ptLeftTop.x = atoi(szPt);
+
+ // a possibly absurd check to see that the string
+ // wasn't akin to "320," with no second entry
+ if ( *(szPt + cComma + 1 ) )
+ ptLeftTop.y = atoi( szPt + cComma + 1 );
+
+ // check to see that the box is on the screen - the upper left
+ // must be on the screen, along with a 50x50 box below and to
+ // the right of it
+ 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
+ );
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+VOID ButtonFontSetup(VOID)
+ {
+ HDC hdc;
+ int IDD;
+
+ // define the fonts for the buttons
+ hdc = GetDC(GetDesktopWindow());
+
+ ghFontBtn = CreateFont(
+ (-10)*GetDeviceCaps(hdc, LOGPIXELSY)/72,
+ 0,
+ 0,
+ 0,
+ FW_BOLD,
+ FALSE,
+ FALSE,
+ FALSE,
+ ANSI_CHARSET,
+ OUT_DEFAULT_PRECIS,
+ CLIP_DEFAULT_PRECIS,
+ PROOF_QUALITY,
+ VARIABLE_PITCH | FF_SWISS,
+ (LPSTR)"Arial"
+ );
+
+ ghFontBtnText = CreateFont(
+ (-6)*GetDeviceCaps(hdc, LOGPIXELSY)/72,
+ 0,
+ 0,
+ 0,
+ FW_NORMAL,
+ FALSE,
+ FALSE,
+ FALSE,
+ ANSI_CHARSET,
+ OUT_DEFAULT_PRECIS,
+ CLIP_DEFAULT_PRECIS,
+ PROOF_QUALITY,
+ VARIABLE_PITCH | FF_SWISS,
+ NULL
+ );
+
+ ghFontBtnStar = CreateFont(
+ (-18)*GetDeviceCaps(hdc, LOGPIXELSY)/72,
+ 0,
+ 0,
+ 0,
+ FW_BOLD,
+ FALSE,
+ FALSE,
+ FALSE,
+ SYMBOL_CHARSET,
+ OUT_TT_PRECIS,
+ CLIP_DEFAULT_PRECIS,
+ PROOF_QUALITY,
+ VARIABLE_PITCH | FF_DONTCARE,
+ (LPSTR)"Symbol"
+ );
+
+ ReleaseDC(GetDesktopWindow(), hdc);
+
+
+ // set the fonts for the buttons
+ if(ghFontBtn)
+ {
+ // set fonts on number buttons
+ for(IDD = IDD_DBUTTON1; IDD <= IDD_DBUTTON0; ++IDD)
+ // the order is IDD_DBUTTON1, 2, 3, ..., 0 (thus from 1 to 0)
+ SendMessage(
+ GetDlgItem(ghWndMain, IDD),
+ WM_SETFONT,
+ (WPARAM)ghFontBtn,
+ 0L
+ );
+
+ // set fonts on * and # buttons
+ SendMessage(
+ GetDlgItem(ghWndMain, IDD_DBUTTONSTAR),
+ WM_SETFONT,
+ (WPARAM)ghFontBtnStar,
+ 0L
+ );
+ SendMessage(
+ GetDlgItem(ghWndMain, IDD_DBUTTONPOUND),
+ WM_SETFONT,
+ (WPARAM)ghFontBtnStar,
+ 0L
+ );
+ }
+ }
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+// Draws a 3D button within rcBtn on hDC
+VOID DrawButton(HDC hDC, RECT rcBtn, BOOL fHighlighted)
+ {
+ HPEN hPenPrev, hPenShadow, hPenHighlight, hPenBlack;
+ HBRUSH hBrushPrev, hBrushFace;
+ int RopPrev;
+
+ --rcBtn.right;
+ --rcBtn.bottom;
+
+ // set up pens/brush
+ hPenShadow = CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DSHADOW));
+ hPenHighlight = CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DHILIGHT));
+ hPenBlack = GetStockObject(BLACK_PEN);
+ hBrushFace = GetSysColorBrush(COLOR_3DFACE);
+
+ // get current state so we can put it back at the end of DrawButton
+ hPenPrev = SelectObject(hDC, hPenBlack);
+ RopPrev = SetROP2(hDC, R2_COPYPEN);
+ hBrushPrev = SelectObject(hDC, hBrushFace);
+
+ PatBlt(
+ hDC,
+ rcBtn.left + 1,
+ rcBtn.top + 1,
+ rcBtn.right - rcBtn.left - 1,
+ rcBtn.bottom - rcBtn.top - 1,
+ PATCOPY
+ );
+
+ if(fHighlighted)
+ {
+ SelectObject(hDC, hPenBlack);
+ MoveToEx(hDC, rcBtn.left, rcBtn.bottom - 1, NULL);
+ LineTo(hDC, rcBtn.left, rcBtn.top); // _
+ LineTo(hDC, rcBtn.right, rcBtn.top); // |
+
+ SelectObject(hDC, hPenHighlight);
+ MoveToEx(hDC, rcBtn.right, rcBtn.top, NULL);
+ LineTo(hDC, rcBtn.right, rcBtn.bottom);
+ LineTo(hDC, rcBtn.left - 1, rcBtn.bottom); // _|
+
+ SelectObject(hDC, hPenShadow);
+ MoveToEx(hDC, rcBtn.left + 1, rcBtn.bottom - 2, NULL);
+ LineTo(hDC, rcBtn.left + 1, rcBtn.top + 1);
+ LineTo(hDC, rcBtn.right - 1, rcBtn.top + 1);
+ }
+ else
+ {
+ SelectObject(hDC, hPenHighlight);
+ MoveToEx(hDC, rcBtn.left, rcBtn.bottom - 1, NULL);
+ LineTo(hDC, rcBtn.left, rcBtn.top); // _
+ LineTo(hDC, rcBtn.right, rcBtn.top); // |
+
+ SelectObject(hDC, hPenBlack);
+ MoveToEx(hDC, rcBtn.right, rcBtn.top, NULL);
+ LineTo(hDC, rcBtn.right, rcBtn.bottom);
+ LineTo(hDC, rcBtn.left - 1, rcBtn.bottom); // _|
+
+ SelectObject(hDC, hPenShadow);
+ MoveToEx(hDC, rcBtn.left + 1, rcBtn.bottom - 1, NULL);
+ LineTo(hDC, rcBtn.right - 1, rcBtn.bottom - 1);
+ LineTo(hDC, rcBtn.right - 1, rcBtn.top);
+ }
+
+ // put everything back how it was
+ SetROP2(hDC, RopPrev);
+ SelectObject(hDC, hBrushPrev);
+ SelectObject(hDC, hPenPrev);
+
+ DeleteObject(hPenBlack);
+ DeleteObject(hPenShadow);
+ DeleteObject(hPenHighlight);
+ DeleteObject(hBrushFace);
+ }
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+VOID DrawButtonText(HDC hDC, RECT rcBtn, BOOL fHighlighted, UINT IDD_Btn)
+ {
+ char szLine1[MAXBUFSIZE]; // text in button up to '\n'
+ LPSTR pszLine2; // text in button after '\n'
+ int BkModePrev;
+ HFONT hFontPrev = NULL;
+ TEXTMETRIC tm;
+ RECT rcText = rcBtn;
+
+ BkModePrev = SetBkMode(hDC, TRANSPARENT);
+
+ GetDlgItemText(ghWndMain, IDD_Btn, szLine1, MAXBUFSIZE);
+ pszLine2 = strstr(szLine1, "\n");
+ if(pszLine2)
+ {
+ *pszLine2 = 0; // 1 -> "TEST1 \n TEST2" becomes "TEST 1 \0"
+ ++pszLine2; // now 2 -> " TEST 2"
+ }
+
+ // now szLine1 points to the null terminated first string and
+ // pszLine2 points to either the null terminated second string or NULL
+ // if there was no second string
+
+ if(szLine1[0])
+ {
+ if(ghFontBtnText && pszLine2)
+ hFontPrev = SelectObject(hDC, ghFontBtnText);
+
+ GetTextMetrics(hDC, &tm);
+ rcText.bottom = (rcBtn.bottom + rcBtn.top)/2 - 2;
+ rcText.top = rcText.bottom - (tm.tmHeight - 1);
+
+ if(pszLine2 == NULL)
+ OffsetRect(&rcText, 0, (rcText.bottom - rcText.top)/2);
+
+ if(fHighlighted)
+ OffsetRect(&rcText, 1, 1);
+
+ DrawText(hDC, szLine1, -1, &rcText, DT_SINGLELINE | DT_CENTER);
+
+ if(hFontPrev)
+ SelectObject(hDC, hFontPrev);
+ }
+ if(pszLine2) // recall that pszLine2 == NULL to represent no second string
+ {
+ GetTextMetrics(hDC, &tm);
+ if(IDD_Btn == IDD_DBUTTONSTAR || IDD_Btn == IDD_DBUTTONPOUND)
+ rcText.top = (rcBtn.bottom + rcBtn.top)/2 - (tm.tmHeight)/2;
+ else
+ rcText.top = (rcBtn.bottom + rcBtn.top)/2 - 2;
+ rcText.bottom = rcText.top + tm.tmHeight;
+
+ if(fHighlighted)
+ OffsetRect(&rcText, 1, 1);
+
+ DrawText(hDC, pszLine2, -1, &rcText, DT_SINGLELINE | DT_CENTER);
+ }
+
+ SetBkMode(hDC, BkModePrev);
+ }
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+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;
+ char szPt[MAXBUFSIZE];
+ char szNumber[TAPIMAXDESTADDRESSSIZE];
+ char szFieldName[MAXBUFSIZE];
+
+ CloseTAPI(); // unregister and line close
+
+ if(!IsIconic(ghWndMain)) // if the window is not minimized, record position
+ {
+ GetWindowRect(ghWndMain, &rc);
+ wsprintf(szPt, "%ld, %ld", rc.left, rc.top);
+ WritePrivateProfileString(
+ "Preference",
+ "Main Window Left/Top",
+ szPt,
+ gszINIfilename
+ );
+ }
+
+ 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)(LPCSTR)szNumber);
+
+ else
+ szNumber[0] = 0;
+
+ wsprintf(szFieldName, "Last dialed %d", cLastDialed);
+ WritePrivateProfileString(
+ "Last dialed numbers",
+ szFieldName,
+ szNumber,
+ gszINIfilename
+ );
+
+ }
+
+ WinHelp(ghWndMain, gszHELPfilename, HELP_QUIT, 0); // unload help
+
+ DestroyWindow(ghWndMain);
+ ghWndMain = NULL;
+
+ DeleteObject(ghFontBtn);
+ DeleteObject(ghFontBtnText);
+ DeleteObject(ghFontBtnStar);
+ }
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+// 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 = NULL;
+ }
+
+ lineShutdown(ghLineApp);
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+BOOL 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, (LPCSTR) 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,
+ (DWORD)(LPVOID) aMenuHelpIDs
+ );
+ return TRUE;
+
+ // processes right-clicks on controls
+ case WM_CONTEXTMENU:
+ WinHelp (
+ (HWND)wParam,
+ gszHELPfilename,
+ HELP_CONTEXTMENU,
+ (DWORD)(LPVOID)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
+ {
+ LONG 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:
+ {
+ char szName[TAPIMAXCALLEDPARTYSIZE] = {'\0'};
+ char szNumber[TAPIMAXDESTADDRESSSIZE] = {'\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,
+ (DLGPROC)SpeedDial1Proc,
+ 0
+ );
+ SetFocus(GetDlgItem(ghWndMain, IDD_DDIAL));
+ return TRUE;
+
+ // TOOLS menu
+ case IDM_CONNECTUSING:
+ DialogBoxParam (
+ ghInst,
+ MAKEINTRESOURCE(IDD_CONNECTUSING),
+ ghWndMain,
+ (DLGPROC)ConnectUsingProc,
+ MENU_CHOICE
+ );
+ return TRUE;
+
+ case IDM_LOCATION:
+ {
+ char szCanNumber[ TAPIMAXDESTADDRESSSIZE ] = "";
+
+ // 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,
+ (DLGPROC)AboutProc,
+ 0
+ );
+#else
+ ShellAbout(
+ ghWndMain,
+ gszAppName,
+ gszNULL,
+ LoadIcon(ghInst, (LPCSTR)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;
+ char szSDNumber[TAPIMAXDESTADDRESSSIZE];
+ char szFieldName[MAXBUFSIZE];
+
+ // 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,
+ (LPSTR)szNumber,
+ TAPIMAXDESTADDRESSSIZE
+ );
+
+ // check if it is a speed dial number.
+ // If so choose the name to be displayed.
+ for( cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry)
+ {
+ wsprintf(szFieldName, "Number%d", cSDEntry);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ szSDNumber,
+ TAPIMAXCALLEDPARTYSIZE - 1,
+ gszINIfilename
+ );
+
+ // if the number matches, get the name
+ if ( lstrcmp(szSDNumber, szNumber) == 0 )
+ {
+ wsprintf( szFieldName, "Name%d", cSDEntry);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ szName,
+ TAPIMAXCALLEDPARTYSIZE - 1,
+ gszINIfilename
+ );
+ break;
+ }
+ }
+
+ 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,
+ (DLGPROC)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 char digits[] = { '1', '2', '3', '4',
+ '5', '6', '7', '8',
+ '9', '0', '*', '#' };
+
+ i = SendDlgItemMessage(ghWndMain,
+ IDD_DCOMBO,
+ WM_GETTEXT,
+ (WPARAM)TAPIMAXDESTADDRESSSIZE+1,
+ (LPARAM)szBuffer);
+
+ if (i < TAPIMAXDESTADDRESSSIZE)
+ {
+ MoveMemory(szBuffer+gdwStartSel+1,
+ szBuffer+gdwEndSel,
+ i - ( gdwEndSel ) + 1 );
+
+ 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;
+ char szFieldName [MAXBUFSIZE];
+
+ // get information for the speed dial button
+ // from the INI file
+ wsprintf(szFieldName, "Name%d", cSDEntry);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ szName,
+ TAPIMAXCALLEDPARTYSIZE - 1,
+ gszINIfilename
+ );
+
+ wsprintf(szFieldName, "%s%d", "Number", cSDEntry);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ gszSDNumber[cSDEntry],
+ TAPIMAXDESTADDRESSSIZE - 1,
+ gszINIfilename
+ );
+
+ // entry not set yet
+ if( gszSDNumber[cSDEntry][0] == 0 )
+ {
+ DialogBoxParam (
+ ghInst,
+ MAKEINTRESOURCE(IDD_SD2),
+ ghWndMain,
+ (DLGPROC)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,
+ (DLGPROC)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_DRAWITEM:
+ {
+ LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
+ BOOL fHighlighted = (SendDlgItemMessage(
+ ghWndMain,
+ lpdis->CtlID,
+ BM_GETSTATE,
+ 0,
+ 0
+ ) & 0x0004);
+
+ DrawButton(lpdis->hDC, lpdis->rcItem, fHighlighted);
+ DrawButtonText(
+ lpdis->hDC,
+ lpdis->rcItem,
+ fHighlighted,
+ lpdis->CtlID
+ );
+ return TRUE;
+ }
+
+
+ case WM_CTLCOLORLISTBOX:
+ case WM_CTLCOLORBTN:
+ case WM_CTLCOLORSTATIC:
+ SetBkColor((HDC)wParam, GetSysColor(COLOR_BTNFACE));
+ return (BOOL)GetSysColorBrush( COLOR_3DFACE );
+
+
+ default:
+ ;
+ // return DefDlgProc( hwnd, msg, wParam, lParam );
+ // return DefWindowProc( hwnd, msg, wParam, lParam );
+
+
+ } // switch (msg) { ... }
+
+ return FALSE;
+ }
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+VOID AddToRedialList( LPCSTR 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 = 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 ( LPCSTR szNumber, LPCSTR szName )
+{
+ HLINE hLine = NULL;
+
+ DWORD errCode;
+
+ // struct size info
+ DWORD dwLTPSize = sizeof ( LINETRANSLATEOUTPUT );
+ DWORD dwNameLen = lstrlen( szName ) + 1;
+ DWORD dwLCPSize = sizeof( LINECALLPARAMS );
+
+ LPLINETRANSLATEOUTPUT lpTransOut = NULL;
+ LPLINECALLPARAMS lpLineCallParams = NULL;
+
+ char 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 (
+ (LPSTR) lpLineCallParams + sizeof(LINECALLPARAMS),
+ szName
+ );
+ }
+
+ lpLineCallParams-> dwDisplayableAddressSize = lpTransOut-> dwDisplayableStringSize;
+ lpLineCallParams-> dwDisplayableAddressOffset = sizeof( LINECALLPARAMS ) + dwNameLen;
+
+ lstrcpy (
+ (LPSTR) lpLineCallParams + sizeof(LINECALLPARAMS) + dwNameLen,
+ (LPSTR) lpTransOut + lpTransOut-> dwDisplayableStringOffset
+ );
+
+
+ // save dialing information
+ // Free old allocs.
+ if ( gszCurrentName )
+ {
+ DialerFree ( gszCurrentName );
+ }
+
+ if ( gszCurrentNumber )
+ {
+ DialerFree ( gszCurrentNumber );
+ }
+
+ // save new stuff
+ gszCurrentName = (LPSTR) DialerAlloc( dwNameLen );
+ if ( !gszCurrentName )
+ {
+ errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK );
+ goto error;
+ }
+ lstrcpy ( gszCurrentName, szName );
+
+ gszCurrentNumber = (LPSTR) DialerAlloc( lpTransOut-> dwDisplayableStringSize );
+ if ( !gszCurrentNumber )
+ {
+ errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK );
+ goto error;
+ }
+ lstrcpy (
+ gszCurrentNumber,
+ (LPSTR) lpTransOut + lpTransOut-> dwDisplayableStringOffset
+ );
+
+ gCurrentLineInfo.hLine = hLine;
+ ghCall = NULL;
+
+
+ // finally make the call.
+ gMakeCallRequestID = 0;
+
+ gMakeCallRequestID = lineMakeCall (
+ hLine,
+ &ghCall,
+ (LPSTR) 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,
+ (DLGPROC)DialingProc,
+ 0
+ );
+
+ }
+
+ else
+ {
+ if ( gMakeCallRequestID == LINEERR_CALLUNAVAIL )
+ {
+ DialogBoxParam (
+ ghInst,
+ MAKEINTRESOURCE(IDD_CALLFAILED),
+ ghWndMain,
+ (DLGPROC)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;
+
+ LPSTR pszLineName = NULL;
+ LPLINEDEVCAPS lpDevCaps = NULL;
+
+
+ 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 = (LPSTR) DialerAlloc( MAXBUFSIZE );
+ if ( !pszLineName )
+ {
+ errCode = LINEERR_NOMEM;
+ goto error;
+ }
+
+ if ( lpDevCaps->dwLineNameSize > 0 )
+ {
+ if ( lpDevCaps-> dwLineNameSize > (MAXBUFSIZE - 1) )
+ {
+ strncpy (
+ pszLineName,
+ (LPSTR) lpDevCaps + lpDevCaps->dwLineNameOffset,
+ MAXBUFSIZE - 1
+ );
+ pszLineName[ MAXBUFSIZE - 1 ] = '\0';
+ }
+ else
+ {
+ lstrcpy( pszLineName, (LPSTR) lpDevCaps + lpDevCaps-> dwLineNameOffset );
+ }
+ }
+ else
+ {
+ wsprintf ( pszLineName, "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;
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+LPSTR GetAddressName(DWORD iLine, DWORD iAddress)
+{
+ DWORD errCode = 0;
+ DWORD dwNeededSize = 0;
+ LPSTR 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( ghWndMain, 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 );
+ if ( !pszAddressName )
+ {
+ goto error;
+ }
+
+ if ( lpAddressCaps-> dwAddressSize > 0 )
+ {
+ // keep string length bounded
+ if ( lpAddressCaps-> dwAddressSize > (MAXBUFSIZE - 1 ) )
+ {
+ strncpy(
+ pszAddressName,
+ (LPSTR) lpAddressCaps + lpAddressCaps->dwAddressOffset,
+ MAXBUFSIZE - 1
+ );
+ pszAddressName[ MAXBUFSIZE - 1] = '\0';
+ }
+ else
+ {
+ lstrcpy (
+ pszAddressName,
+ (LPSTR) lpAddressCaps + lpAddressCaps->dwAddressOffset
+ );
+ }
+ }
+ else
+ // use default name
+ {
+ wsprintf(pszAddressName, "Address %d", iAddress);
+ }
+
+error:
+ if ( lpAddressCaps )
+ {
+ DialerFree( lpAddressCaps );
+ }
+
+ return pszAddressName;
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+BOOL CALLBACK DialingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+
+ switch(msg)
+ {
+ char 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:
+ //gfDropping = TRUE;
+
+ // 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;
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+BOOL CALLBACK AboutProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+ {
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ char sz[MAXBUFSIZE];
+ char 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);
+
+/* // sets up version number for Dialer
+ GetDlgItemText(hwnd, IDD_ATEXTVERSION, sz, MAXBUFSIZE);
+ wsprintf(szLabel, sz, VER_MAJOR, VER_MINOR, VER_BUILD);
+
+
+ { // strip off build number for release copies
+ DWORD i;
+ LPSTR ch = szLabel;
+
+ for (i = 0; i < 2 && *ch; ++ch)
+ {
+ if(*ch == '.')
+ ++i;
+ if(i == 2)
+ *ch = 0;
+ }
+
+ SetDlgItemText(hwnd ,IDD_ATEXTVERSION, szLabel);
+ } */
+
+
+/* // get free memory information
+ GetDlgItemText(hwnd, IDD_ATEXTFREEMEM, sz, MAXBUFSIZE);
+ wsprintf(szLabel, sz, GetFreeSpace(0)>>10);
+ SetDlgItemText(hwnd, IDD_ATEXTFREEMEM, szLabel);
+
+ // get free resources information
+ GetDlgItemText(hwnd, IDD_ATEXTRESOURCE, sz,MAXBUFSIZE);
+ wsprintf(szLabel, sz, GetFreeSystemResources(0));
+ SetDlgItemText(hwnd, IDD_ATEXTRESOURCE, szLabel); */
+
+ return TRUE;
+ }
+
+ case WM_COMMAND:
+ if(LOWORD((DWORD)wParam) == IDOK)
+ {
+ EndDialog(hwnd, TRUE);
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+ }
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+BOOL 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,
+ (DWORD)(LPVOID)aMenuHelpIDs
+ );
+ return TRUE;
+
+ case WM_CONTEXTMENU:
+ // processes right-clicks on controls
+ WinHelp (
+ (HWND)wParam,
+ gszHELPfilename,
+ HELP_CONTEXTMENU,
+ (DWORD)(LPVOID)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 (
+ "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;
+ char szBuffer[MAXBUFSIZE];
+ DWORD dwPriority;
+
+ // Update line
+ hwndBox = GetDlgItem( hwnd, IDD_CULISTLINE );
+ giCurrentLine = SendMessage (
+ hwndBox,
+ CB_GETITEMDATA,
+ SendMessage( hwndBox, CB_GETCURSEL, 0, 0 ),
+ 0
+ );
+
+ // base 10
+ itoa( gdwPLID[giCurrentLine], szBuffer, 10 );
+ WritePrivateProfileString (
+ "Preference",
+ "Preferred Line",
+ szBuffer,
+ gszINIfilename
+ );
+
+
+ // Update address
+ hwndBox = GetDlgItem( hwnd, IDD_CULISTADDRESS );
+ giCurrentAddress = SendMessage (
+ hwndBox,
+ CB_GETITEMDATA,
+ SendMessage(hwndBox, CB_GETCURSEL, 0, 0),
+ 0
+ );
+
+ itoa( giCurrentAddress, szBuffer, 10 );
+ WritePrivateProfileString (
+ "Preference",
+ "Preferred Address",
+ szBuffer,
+ gszINIfilename
+ );
+
+
+ // Update application priority
+ if ( SendDlgItemMessage (
+ hwnd,
+ IDD_CUSIMPLETAPICHKBOX,
+ BM_GETCHECK,
+ 0,
+ 0L
+ )
+ == 0)
+ {
+ dwPriority = 0;
+ }
+ else
+ {
+ dwPriority = 1;
+ }
+
+ lineSetAppPriority (
+ "DIALER.EXE",
+ 0,
+ NULL,
+ LINEREQUESTMODE_MAKECALL,
+ NULL,
+ dwPriority
+ );
+
+ EndDialog(hwnd, TRUE);
+ return TRUE;
+ }
+
+ case IDCANCEL:
+ EndDialog(hwnd, FALSE);
+ return TRUE;
+ }
+ }
+
+ default:
+ ;
+
+ }
+
+ return FALSE;
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+BOOL CALLBACK LineInUseProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+ {
+ LPARAM lNewParam = 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;
+ }
+ return TRUE;
+ }
+
+ case WM_COMMAND:
+ if(LOWORD((DWORD)wParam) == IDOK)
+ {
+ EndDialog(hwnd, TRUE);
+ return TRUE;
+ }
+ break;
+
+ default:
+ ;
+// return DefDlgProc( hwnd, msg, wParam, lParam );
+
+ }
+
+
+ ptStr = DialerAlloc( MAXBUFSIZE );
+
+ LoadString( ghInst, lNewParam, ptStr, MAXBUFSIZE );
+
+ SetDlgItemText(
+ hwnd,
+ IDD_CFTEXT,
+ ptStr
+ );
+
+ DialerFree( ptStr );
+
+
+ return FALSE;
+ }
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+BOOL 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][TAPIMAXDESTADDRESSSIZE];
+
+ switch(msg)
+ {
+ case WM_HELP:
+ // processes clicks on controls when
+ // context mode help is selected
+ WinHelp(
+ ((LPHELPINFO)lParam)->hItemHandle,
+ gszHELPfilename,
+ HELP_WM_HELP,
+ (DWORD)(LPVOID)aMenuHelpIDs
+ );
+ return TRUE;
+
+ case WM_CONTEXTMENU: // processes right-clicks on controls
+ WinHelp(
+ (HWND)wParam,
+ gszHELPfilename,
+ HELP_CONTEXTMENU,
+ (DWORD)(LPVOID)aMenuHelpIDs
+ );
+ return TRUE;
+
+ case WM_INITDIALOG:
+ {
+ DWORD cSDEntry;
+ DWORD idFirstEmpty = (DWORD) -1;
+
+ char szName[TAPIMAXCALLEDPARTYSIZE];
+ char szTemp[TAPIMAXCALLEDPARTYSIZE];
+ char szFieldName[MAXBUFSIZE];
+
+ // Retrieve speed dial info from INI file
+ for(cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry)
+ {
+ wsprintf(szFieldName, "Name%d", cSDEntry);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ szSDName[ cSDEntry ],
+ TAPIMAXCALLEDPARTYSIZE - 1,
+ gszINIfilename
+ );
+
+ // set the first empty speed dial button
+ if ( idFirstEmpty == -1 &&
+ szSDName[ cSDEntry ][0] == '\0' &&
+ gszSDNumber[ cSDEntry ][ 0 ] == '\0' )
+ idFirstEmpty = cSDEntry;
+
+ wsprintf(szFieldName, "Number%d", cSDEntry);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ gszSDNumber[cSDEntry],
+ MAXBUFSIZE - 1,
+ gszINIfilename
+ );
+
+ // get a copy of the name for editing
+ // if name is empty, use the number as the
+ // name.
+ if ( lstrcmp( gszNULL, szSDName[ cSDEntry ] ) )
+ {
+ lstrcpy( szName, szSDName[ cSDEntry] );
+ }
+ else
+ {
+ lstrcpy( szName, gszSDNumber[ cSDEntry ] );
+ }
+
+ FitTextToButton( hwnd, IDD_SD1SPEEDDIAL1 + cSDEntry - 1, szName );
+ AmpersandCompensate( szName, szTemp );
+
+ SetDlgItemText (
+ hwnd,
+ IDD_SD1SPEEDDIAL1 + cSDEntry - 1,
+ (LPCSTR) szTemp
+ );
+
+ }
+
+ // 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,
+ (LPCSTR) szSDName[ 1 ]
+ );
+
+ SetDlgItemText(
+ hwnd,
+ IDD_SD1EDITNUMBER,
+ (LPCSTR) gszSDNumber[ 1 ]
+ );
+ }
+ else
+ {
+ nCurrentSpeedDial = idFirstEmpty;
+ }
+
+ SetFocus( GetDlgItem( hwnd, IDD_SD1EDITNAME ) );
+ return FALSE;
+ }
+
+ case WM_COMMAND:
+ {
+ char szName[TAPIMAXCALLEDPARTYSIZE];
+ char szTemp[ TAPIMAXCALLEDPARTYSIZE ];
+
+ switch( LOWORD( (DWORD) wParam ) )
+ {
+ case IDOK:
+ {
+ DWORD cSDEntry;
+ char szFieldName[MAXBUFSIZE];
+
+ // save new speed dial settings
+ for ( cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry )
+ {
+ wsprintf(szFieldName, "Name%d", cSDEntry);
+ WritePrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ szSDName [cSDEntry],
+ gszINIfilename
+ );
+
+ wsprintf(szFieldName, "Number%d", cSDEntry);
+ WritePrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszSDNumber[cSDEntry],
+ gszINIfilename
+ );
+
+ // set the text for the corresponding
+ // main window button
+ if ( szSDName[ cSDEntry ][ 0 ] == '\0' )
+ {
+ lstrcpy( szName, gszSDNumber[ cSDEntry ] );
+ }
+ else
+ {
+ lstrcpy( szName, szSDName[ cSDEntry ] );
+ }
+
+ FitTextToButton(
+ ghWndMain,
+ IDD_DSPEEDDIAL1 + cSDEntry - 1,
+ szName
+ );
+
+ AmpersandCompensate( szName, szTemp );
+ SetDlgItemText (
+ ghWndMain,
+ IDD_DSPEEDDIAL1 + cSDEntry - 1,
+ (LPCSTR) szTemp
+ );
+ }
+
+ 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 )
+ {
+
+ GetDlgItemText (
+ hwnd,
+ IDD_SD1EDITNAME,
+ szName,
+ TAPIMAXCALLEDPARTYSIZE
+ );
+
+ // if there is no name, label the button with
+ // the number
+ if ( szName[ 0 ] == '\0' )
+ {
+ szSDName[ nCurrentSpeedDial ][ 0 ] = '\0';
+ lstrcpy( szName, gszSDNumber[ nCurrentSpeedDial ] );
+ }
+ else
+ {
+ lstrcpy( szSDName[ nCurrentSpeedDial ], szName );
+ }
+
+ FitTextToButton (
+ hwnd,
+ IDD_SD1SPEEDDIAL1 + nCurrentSpeedDial - 1,
+ szName
+ );
+ AmpersandCompensate( szName, 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 ] == '\0' )
+ {
+ SetDlgItemText (
+ hwnd,
+ IDD_SD1SPEEDDIAL1 + nCurrentSpeedDial - 1,
+ szName
+ );
+
+ }
+ }
+ }
+ break;
+ } // switch(LOWORD((DWORD)wParam))
+ break;
+
+ } // case WM_COMMAND:
+
+ default:
+ ;
+
+ } // switch(msg)
+
+ return FALSE;
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+BOOL 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,
+ (DWORD)(LPVOID)aMenuHelpIDs
+ );
+ return TRUE;
+
+ case WM_CONTEXTMENU:
+ // processes right-clicks on controls
+ WinHelp (
+ (HWND)wParam,
+ gszHELPfilename,
+ HELP_CONTEXTMENU,
+ (DWORD)(LPVOID)aMenuHelpIDs
+ );
+ return TRUE;
+
+ case WM_INITDIALOG:
+ {
+ char szFieldName [MAXBUFSIZE];
+ char szName [TAPIMAXCALLEDPARTYSIZE];
+
+ nCurrentSpeedDial = LOWORD( lParam ) - IDD_DSPEEDDIAL1 + 1;
+
+ // retrieve speed dial button info
+ wsprintf(szFieldName, "Name%d", nCurrentSpeedDial);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ szName,
+ TAPIMAXCALLEDPARTYSIZE - 1,
+ gszINIfilename
+ );
+ 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:
+ {
+ char szName[ TAPIMAXCALLEDPARTYSIZE ];
+ char szTemp[ TAPIMAXCALLEDPARTYSIZE ];
+ char szFieldName[MAXBUFSIZE];
+
+ switch ( LOWORD( (DWORD) wParam ) )
+ {
+ case IDOK:
+ case IDD_SD2SAVEANDDIAL:
+ {
+ GetDlgItemText (
+ hwnd,
+ IDD_SD2EDITNAME,
+ (LPTSTR) szName,
+ TAPIMAXCALLEDPARTYSIZE
+ );
+
+ GetDlgItemText (
+ hwnd,
+ IDD_SD2EDITNUMBER,
+ (LPTSTR) gszSDNumber[nCurrentSpeedDial],
+ TAPIMAXCALLEDPARTYSIZE
+ );
+
+ wsprintf ( szFieldName, "Name%d", nCurrentSpeedDial );
+
+ WritePrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ szName,
+ gszINIfilename
+ );
+
+ wsprintf ( szFieldName, "Number%d", nCurrentSpeedDial );
+ WritePrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszSDNumber[nCurrentSpeedDial],
+ gszINIfilename
+ );
+
+ // update main window buttons
+ // is only number has been entered, label button with it.
+ if ( szName[ 0 ] == '\0' )
+ {
+ lstrcpy( szName, gszSDNumber[ nCurrentSpeedDial ] );
+ }
+
+ FitTextToButton (
+ ghWndMain,
+ IDD_DSPEEDDIAL1 + nCurrentSpeedDial - 1,
+ (LPSTR) szName
+ );
+
+ AmpersandCompensate( szName, szTemp );
+
+ SetDlgItemText (
+ ghWndMain,
+ IDD_DSPEEDDIAL1 + nCurrentSpeedDial - 1,
+ (LPCSTR)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
+ )
+ );
+ }
+ 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 = NULL;
+ }
+ 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,
+ (DLGPROC)LineInUseProc,
+ LineDisconnectMode
+ );
+ break;
+ }
+ }
+ break;
+
+
+ case LINE_CLOSE:
+ if ( gCurrentLineInfo.hLine == (HLINE)hDevice )
+ {
+ errString(ghWndMain, ERR_LINECLOSE, MB_ICONEXCLAMATION | MB_OK );
+ gCurrentLineInfo.hLine = NULL;
+ 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,
+ (DLGPROC)LineInUseProc,
+ 0
+ );
+ }
+ else
+ {
+ errString ( ghWndMain, dwParam2, MB_ICONEXCLAMATION | MB_OK );
+ }
+
+ ghCall = NULL;
+ DialerLineClose();
+ gfCurrentLineAvail = TRUE;
+ }
+
+ gfMakeCallReplyPending = FALSE;
+ }
+
+ // reply from lineDrop()
+ if ( (LONG) dwParam1 == gDropCallRequestID )
+ {
+ //gfDropping = FALSE;
+
+ // 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 = NULL;
+ }
+ }
+ 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 = SendMessage (
+ hwndLineBox,
+ CB_ADDSTRING,
+ 0,
+ (LPARAM)(LPCSTR)(lpLineInfo[iLine].szLineName)
+ );
+
+ // error, bail out.
+ if ( iItem == CB_ERR || iItem == CB_ERRSPACE )
+ {
+ if (lpLineInfo)
+ {
+ DialerFree(lpLineInfo);
+ }
+
+ return FALSE;
+ }
+
+ errCode = 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;
+ LPSTR pszAddressName;
+
+ if ( SendMessage( hwndLineBox, CB_GETCOUNT, 0, 0 ) == 0 )
+ {
+ return FALSE;
+ }
+
+ // select current entry in line box
+ iLineBoxCurrent = 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 = SendMessage (
+ hwndAddressBox,
+ CB_ADDSTRING,
+ 0,
+ (LPARAM) (LPCSTR) (pszAddressName)
+ );
+
+ // error, bail out
+ if ( iItem == CB_ERR || iItem == CB_ERRSPACE )
+ return FALSE;
+
+ errCode = 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;
+ LPLINEREQMAKECALL lpRequestBuffer;
+
+ lpRequestBuffer = (LPLINEREQMAKECALL) 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,
+ (DLGPROC) 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 = NULL;
+ }
+
+
+ // 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 );
+ if ( NULL == ptStrTitle )
+ {
+ // Now, _this_ is a problem.
+ return 0;
+ }
+
+ ptStrError = DialerAlloc( MAXBUFSIZE );
+ 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;
+
+ 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 ) )
+ {
+#if DBG
+ TCHAR buf[200];
+ wsprintf( buf, "Cannot load string: hinst:0x%08lx errcode: %ld", (DWORD)ghInst,(DWORD)errCode);
+ OutputDebugString( buf );
+ MessageBox( NULL, buf, "Dialer", MB_OK);
+#endif
+
+ 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, LPSTR 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;
+ char 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 ] = 'X';
+ buf [ nLen + 1 ] = '\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 ] = 'X';
+ buf [ i + 2 ] = '\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] = '\0';
+ lstrcat( szName, "..." );
+ }
+
+ } 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;
+ LPSTR lpDialDigits = (LPSTR)lpTransOut + lpTransOut-> dwDialableStringOffset;
+ char sz3Pref [ 4 ] = "";
+
+
+ // 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 ] = '\0';
+ if ( j == 3 )
+ break;
+ }
+ }
+
+ if ( !lstrcmp( sz3Pref, "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 ( LPCSTR szNumber, LPSTR szCanNumber )
+{
+ char szDigits [ TAPIMAXDESTADDRESSSIZE ];
+ char szPref [ TAPIMAXDESTADDRESSSIZE ];
+
+ BOOL bRes = FALSE;
+
+ 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;
+ }
+
+ lpTransOut-> dwTotalSize = dwSize;
+ errCode = lineTranslateAddress (
+ ghLineApp,
+ giCurrentLine,
+ gCurrentLineInfo.dwAPIVersion,
+ szNumber,
+ 0,
+ 0,
+ lpTransOut
+ );
+ 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 = strcspn ( szNumber, "|" );
+ strncpy( szPref, szNumber, nLenPref );
+ szPref[ nLenPref ] = '\0';
+
+ // if string is not composed entirely of digits
+ // and allowable formating characters, quit conversion
+ if ( strspn( szPref, " 0123456789()-." ) != (size_t) nLenPref )
+ goto error;
+
+ // collect digits ignoring formating characters.
+ szDigits[ 0 ] = '\0';
+ for ( i = 0, nLenDigits = 0; i < nLenPref; i++ )
+ {
+ if ( ISDIGIT( szNumber[ i ] ) )
+ {
+ szDigits[ nLenDigits++ ] = szNumber[ i ];
+ }
+ }
+ szDigits[ nLenDigits ] = '\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 ] == '0' || szDigits[ 0 ] == '1' )
+ {
+ nLenDigits--;
+ memmove( szDigits, &(szDigits[1]), nLenDigits );
+ szDigits[ nLenDigits ] = '\0';
+
+ cPos = strcspn( szPref, "01" );
+ nLenPref--;
+ memmove( &(szPref[ cPos ]), &(szPref[ cPos + 1 ]), nLenPref - cPos );
+ szPref[ nLenPref ] = '\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 ] == '0' || szDigits[ 0 ] == '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) ( (LPSTR) 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 ]= '\0';
+ lstrcat( szCanNumber, "+1 (" );
+ lstrcat( szCanNumber, (LPSTR) lpTransCaps + lpLocLst[ dwInd ].dwCityCodeOffset );
+ lstrcat( szCanNumber, ") " );
+ lstrcat( szCanNumber, szDigits );
+
+ cPos = strcspn( szNumber, "|" );
+ 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 ] == '0' || szDigits[ 0 ] == '1' )
+ {
+ nLenDigits--;
+ memmove( szDigits, &(szDigits[1]), nLenDigits );
+ szDigits[ nLenDigits ] = '\0';
+
+ cPos = strcspn( szPref, "01" );
+ nLenPref--;
+ memmove( &(szPref[ cPos ]), &(szPref[ cPos + 1 ]), nLenPref - cPos );
+ szPref[ nLenPref ] = '\0';
+ }
+ else
+ {
+ goto error;
+ }
+
+ }
+
+ case LONG_DISTANCE_NUMBER:
+ {
+ // if first or fourth digit is 0/1, illegal number
+ if ( szDigits[ 0 ] == '0' || szDigits[ 0 ] == '1' ||
+ szDigits[ 3 ] == '0' || szDigits[ 3 ] == '1' )
+ {
+ goto error;
+ }
+
+ szCanNumber[ 0 ] = '\0';
+ lstrcat( szCanNumber, "+1 (" );
+ strncat( szCanNumber, szDigits, 3 );
+ lstrcat( szCanNumber, ") " );
+
+ 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 ( LPCSTR lpszSrc, LPSTR 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 ] == '&' )
+ {
+ lpszDst[ cInd++ ] = '&';
+ }
+ lpszDst[ cInd ] = lpszSrc[ cCnt ];
+
+ if ( lpszSrc[ cCnt ] == '\0' )
+ break;
+ }
+
+ // make sure string is null terminated.
+ lpszDst[ TAPIMAXCALLEDPARTYSIZE - 1 ] = '\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 ( LPCSTR lpszSrc, LPSTR 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 ] == '&' ) &&
+ ( lpszSrc[ cInd + 1 ] == '&' ) )
+ {
+ cInd++;
+ }
+ lpszDst[ cCnt ] = lpszSrc[ cInd ] ;
+
+ if ( lpszSrc [ cInd ] == '\0' )
+ {
+ break;
+ }
+ }
+
+ lpszDst[ TAPIMAXCALLEDPARTYSIZE - 1 ] = '\0';
+
+ return;
+ }
diff --git a/private/tapi/dev/apps/dialer/dialer.def b/private/tapi/dev/apps/dialer/dialer.def
new file mode 100644
index 000000000..b40ab0af1
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/dialer.def
@@ -0,0 +1,9 @@
+NAME DIALER
+;STUB 'WINSTUB.EXE'
+CODE PRELOAD MOVEABLE DISCARDABLE
+DATA PRELOAD MOVEABLE MULTIPLE
+HEAPSIZE 2048
+STACKSIZE 8192
+
+EXPORTS
+ MainWndProc
diff --git a/private/tapi/dev/apps/dialer/dialer.h b/private/tapi/dev/apps/dialer/dialer.h
new file mode 100644
index 000000000..6f5832862
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/dialer.h
@@ -0,0 +1,51 @@
+/*++ BUILD Version: 0001 // Increment this if a change has global effects
+
+Copyright (c) 1995 Microsoft Corporation
+
+Module Name:
+
+ dialer.h
+
+Abstract:
+
+ Header file for dialer
+
+Author:
+
+ Dan Knudson (DanKn) 05-Apr-1995
+
+Revision History:
+
+ Jeremy Horwitz (t-jereh) 30-May-1995
+
+--*/
+
+
+#define TAPI_VERSION_1_0 0x00010003
+#define TAPI_VERSION_1_4 0x00010004
+#define TAPI_VERSION_2_0 0x00020000
+#define TAPI_CURRENT_VERSION TAPI_VERSION_2_0
+
+#include <windows.h>
+#include "tapi.h"
+#include "resource.h"
+#include "dialhelp.h"
+
+
+#define MENU_CHOICE 1 // for Connect Using dialog...
+#define INVALID_LINE 2 // if INVALID_LINE, turn off CANCEL
+ // button and add extra text...
+
+#define MAXNUMLENGTH 64
+#define MAXBUFSIZE 256
+#define NSPEEDDIALS 8 // Dialer supports 8 configurable speed dial entries.
+#define NLASTDIALED 20 // Dialer keeps track of the 20 last dialed numbers.
+
+#define ERR_NONE 0
+#define ERR_NOVOICELINE 1
+#define ERR_LINECLOSE 2
+#define ERR_NOLINES 3
+#define ERR_911WARN 4
+#define ERR_NEWDEFAULT 5
+
+#define itoa(x,y,z) _itoa(x,y,z)
diff --git a/private/tapi/dev/apps/dialer/dialer.ico b/private/tapi/dev/apps/dialer/dialer.ico
new file mode 100644
index 000000000..44ccbca29
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/dialer.ico
Binary files differ
diff --git a/private/tapi/dev/apps/dialer/dialer.mak b/private/tapi/dev/apps/dialer/dialer.mak
new file mode 100644
index 000000000..3c4a04bea
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/dialer.mak
@@ -0,0 +1,389 @@
+# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+# TARGTYPE "Win32 (MIPS) Application" 0x0501
+
+!IF "$(CFG)" == ""
+CFG=Win32 (80x86) Debug
+!MESSAGE No configuration specified. Defaulting to Win32 (80x86) Debug.
+!ENDIF
+
+!IF "$(CFG)" != "Win32 (80x86) Release" && "$(CFG)" != "Win32 (80x86) Debug" &&\
+ "$(CFG)" != "Win32 (MIPS) Debug" && "$(CFG)" != "Win32 (MIPS) Release"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE on this makefile
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "dialer.mak" CFG="Win32 (80x86) Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Win32 (80x86) Release" (based on "Win32 (x86) Application")
+!MESSAGE "Win32 (80x86) Debug" (based on "Win32 (x86) Application")
+!MESSAGE "Win32 (MIPS) Debug" (based on "Win32 (MIPS) Application")
+!MESSAGE "Win32 (MIPS) Release" (based on "Win32 (MIPS) Application")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+################################################################################
+# Begin Project
+# PROP Target_Last_Scanned "Win32 (MIPS) Debug"
+
+!IF "$(CFG)" == "Win32 (80x86) Release"
+
+# PROP BASE Use_MFC 2
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "WinRel"
+# PROP BASE Intermediate_Dir "WinRel"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "WinRel"
+# PROP Intermediate_Dir "WinRel"
+OUTDIR=.\WinRel
+INTDIR=.\WinRel
+
+ALL : $(OUTDIR)/dialer.exe $(OUTDIR)/dialer.bsc
+
+$(OUTDIR) :
+ if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
+
+MTL=MkTypLib.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /win32
+MTL_PROJ=/nologo /D "NDEBUG" /win32
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /W3 /GX /YX /O2 /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c
+# ADD CPP /nologo /W3 /GX /YX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /c
+CPP_PROJ=/nologo /W3 /GX /YX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D\
+ "_MBCS" /FR$(INTDIR)/ /Fp$(OUTDIR)/"dialer.pch" /Fo$(INTDIR)/ /c
+CPP_OBJS=.\WinRel/
+
+.c{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+RSC_PROJ=/l 0x409 /fo$(INTDIR)/"DIALER.res" /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# SUBTRACT BASE BSC32 /Iu
+# ADD BSC32 /nologo
+# SUBTRACT BSC32 /Iu
+BSC32_FLAGS=/nologo /o$(OUTDIR)/"dialer.bsc"
+BSC32_SBRS= \
+ $(INTDIR)/DIALER.SBR
+
+$(OUTDIR)/dialer.bsc : $(OUTDIR) $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+# ADD BASE LINK32 user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib mfc30.lib mfco30.lib mfcd30.lib /NOLOGO /SUBSYSTEM:windows /MACHINE:I386
+# ADD LINK32 tapi32.lib version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /MACHINE:I386
+LINK32_FLAGS=tapi32.lib version.lib kernel32.lib user32.lib gdi32.lib\
+ winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\
+ uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /INCREMENTAL:no\
+ /PDB:$(OUTDIR)/"dialer.pdb" /MACHINE:I386 /OUT:$(OUTDIR)/"dialer.exe"
+DEF_FILE=
+LINK32_OBJS= \
+ $(INTDIR)/DIALER.res \
+ $(INTDIR)/DIALER.OBJ
+
+$(OUTDIR)/dialer.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "Win32 (80x86) Debug"
+
+# PROP BASE Use_MFC 2
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "WinDebug"
+# PROP BASE Intermediate_Dir "WinDebug"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "WinDebug"
+# PROP Intermediate_Dir "WinDebug"
+OUTDIR=.\WinDebug
+INTDIR=.\WinDebug
+
+ALL : $(OUTDIR)/dialer.exe $(OUTDIR)/dialer.bsc
+
+$(OUTDIR) :
+ if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
+
+MTL=MkTypLib.exe
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /win32
+MTL_PROJ=/nologo /D "_DEBUG" /win32
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c
+# ADD CPP /nologo /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /c
+CPP_PROJ=/nologo /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D\
+ "_MBCS" /FR$(INTDIR)/ /Fp$(OUTDIR)/"dialer.pch" /Fo$(INTDIR)/\
+ /Fd$(OUTDIR)/"dialer.pdb" /c
+CPP_OBJS=.\WinDebug/
+
+.c{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+RSC_PROJ=/l 0x409 /fo$(INTDIR)/"DIALER.res" /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# SUBTRACT BASE BSC32 /Iu
+# ADD BSC32 /nologo
+# SUBTRACT BSC32 /Iu
+BSC32_FLAGS=/nologo /o$(OUTDIR)/"dialer.bsc"
+BSC32_SBRS= \
+ $(INTDIR)/DIALER.SBR
+
+$(OUTDIR)/dialer.bsc : $(OUTDIR) $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+# ADD BASE LINK32 user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib mfc30d.lib mfco30d.lib mfcd30d.lib /NOLOGO /SUBSYSTEM:windows /DEBUG /MACHINE:I386
+# ADD LINK32 tapi32.lib version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /DEBUG /MACHINE:I386
+LINK32_FLAGS=tapi32.lib version.lib kernel32.lib user32.lib gdi32.lib\
+ winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\
+ uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /INCREMENTAL:yes\
+ /PDB:$(OUTDIR)/"dialer.pdb" /DEBUG /MACHINE:I386 /OUT:$(OUTDIR)/"dialer.exe"
+DEF_FILE=
+LINK32_OBJS= \
+ $(INTDIR)/DIALER.res \
+ $(INTDIR)/DIALER.OBJ
+
+$(OUTDIR)/dialer.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "Win32 (MIPS) Debug"
+
+# PROP BASE Use_MFC 2
+# PROP BASE Use_Debug_Libraries 1
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "WinDebug"
+# PROP Intermediate_Dir "WinDebug"
+OUTDIR=.\WinDebug
+INTDIR=.\WinDebug
+
+ALL : $(OUTDIR)/dialer.exe $(OUTDIR)/dialer.bsc
+
+$(OUTDIR) :
+ if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
+
+MTL=MkTypLib.exe
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /win32
+MTL_PROJ=/nologo /D "_DEBUG" /win32
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /Gt0 /QMOb2000 /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c
+# ADD CPP /nologo /Gt0 /QMOb2000 /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "WIN32" /FR /c
+CPP_PROJ=/nologo /Gt0 /QMOb2000 /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "_WINDOWS"\
+ /D "_MBCS" /D "WIN32" /FR$(INTDIR)/ /Fp$(OUTDIR)/"dialer.pch" /Fo$(INTDIR)/\
+ /Fd$(OUTDIR)/"dialer.pdb" /c
+CPP_OBJS=.\WinDebug/
+
+.c{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+RSC_PROJ=/l 0x409 /fo$(INTDIR)/"dialer.res" /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# SUBTRACT BASE BSC32 /Iu
+# ADD BSC32 /nologo
+# SUBTRACT BSC32 /Iu
+BSC32_FLAGS=/nologo /o$(OUTDIR)/"dialer.bsc"
+BSC32_SBRS= \
+ $(INTDIR)/dialer.sbr
+
+$(OUTDIR)/dialer.bsc : $(OUTDIR) $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+# ADD BASE LINK32 user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib odbc32.lib mfc30d.lib mfco30d.lib mfcd30d.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /DEBUG /MACHINE:MIPS
+# ADD LINK32 version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /DEBUG /MACHINE:MIPS
+LINK32_FLAGS=version.lib kernel32.lib user32.lib gdi32.lib winspool.lib\
+ comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO\
+ /SUBSYSTEM:windows /PDB:$(OUTDIR)/"dialer.pdb" /DEBUG /MACHINE:MIPS\
+ /OUT:$(OUTDIR)/"dialer.exe"
+DEF_FILE=
+LINK32_OBJS= \
+ $(INTDIR)/dialer.res \
+ $(INTDIR)/dialer.obj
+
+$(OUTDIR)/dialer.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "Win32 (MIPS) Release"
+
+# PROP BASE Use_MFC 2
+# PROP BASE Use_Debug_Libraries 0
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "WinRel"
+# PROP Intermediate_Dir "WinRel"
+OUTDIR=.\WinRel
+INTDIR=.\WinRel
+
+ALL : $(OUTDIR)/dialer.exe $(OUTDIR)/dialer.bsc
+
+$(OUTDIR) :
+ if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
+
+MTL=MkTypLib.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /win32
+MTL_PROJ=/nologo /D "NDEBUG" /win32
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /Gt0 /QMOb2000 /W3 /GX /YX /O2 /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c
+# ADD CPP /nologo /Gt0 /QMOb2000 /W3 /GX /YX /O2 /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "WIN32" /FR /c
+CPP_PROJ=/nologo /Gt0 /QMOb2000 /W3 /GX /YX /O2 /D "NDEBUG" /D "_WINDOWS" /D\
+ "_MBCS" /D "WIN32" /FR$(INTDIR)/ /Fp$(OUTDIR)/"dialer.pch" /Fo$(INTDIR)/ /c
+CPP_OBJS=.\WinRel/
+
+.c{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+RSC_PROJ=/l 0x409 /fo$(INTDIR)/"dialer.res" /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# SUBTRACT BASE BSC32 /Iu
+# ADD BSC32 /nologo
+# SUBTRACT BSC32 /Iu
+BSC32_FLAGS=/nologo /o$(OUTDIR)/"dialer.bsc"
+BSC32_SBRS= \
+ $(INTDIR)/dialer.sbr
+
+$(OUTDIR)/dialer.bsc : $(OUTDIR) $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+# ADD BASE LINK32 user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib odbc32.lib mfc30.lib mfco30.lib mfcd30.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /MACHINE:MIPS
+# ADD LINK32 version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /MACHINE:MIPS
+LINK32_FLAGS=version.lib kernel32.lib user32.lib gdi32.lib winspool.lib\
+ comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO\
+ /SUBSYSTEM:windows /PDB:$(OUTDIR)/"dialer.pdb" /MACHINE:MIPS\
+ /OUT:$(OUTDIR)/"dialer.exe"
+DEF_FILE=
+LINK32_OBJS= \
+ $(INTDIR)/dialer.res \
+ $(INTDIR)/dialer.obj
+
+$(OUTDIR)/dialer.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF
+
+################################################################################
+# Begin Group "Source Files"
+
+################################################################################
+# Begin Source File
+
+SOURCE=.\DIALER.RC
+DEP_DIALE=\
+ .\dialer.ico
+
+!IF "$(CFG)" == "Win32 (80x86) Release"
+
+$(INTDIR)/DIALER.res : $(SOURCE) $(DEP_DIALE) $(INTDIR)
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+!ELSEIF "$(CFG)" == "Win32 (80x86) Debug"
+
+$(INTDIR)/DIALER.res : $(SOURCE) $(DEP_DIALE) $(INTDIR)
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+!ELSEIF "$(CFG)" == "Win32 (MIPS) Debug"
+
+$(INTDIR)/dialer.res : $(SOURCE) $(DEP_GENER) $(INTDIR)
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+!ELSEIF "$(CFG)" == "Win32 (MIPS) Release"
+
+$(INTDIR)/dialer.res : $(SOURCE) $(DEP_GENER) $(INTDIR)
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\DIALER.C
+DEP_DIALER=\
+ .\DIALER.H\
+ ..\..\INC\TAPI.H\
+ .\dialhelp.h
+
+!IF "$(CFG)" == "Win32 (80x86) Release"
+
+$(INTDIR)/DIALER.OBJ : $(SOURCE) $(DEP_DIALER) $(INTDIR)
+
+!ELSEIF "$(CFG)" == "Win32 (80x86) Debug"
+
+$(INTDIR)/DIALER.OBJ : $(SOURCE) $(DEP_DIALER) $(INTDIR)
+
+!ELSEIF "$(CFG)" == "Win32 (MIPS) Debug"
+
+$(INTDIR)/dialer.obj : $(SOURCE) $(DEP_GENERI) $(INTDIR)
+
+!ELSEIF "$(CFG)" == "Win32 (MIPS) Release"
+
+$(INTDIR)/dialer.obj : $(SOURCE) $(DEP_GENERI) $(INTDIR)
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Project
+################################################################################
diff --git a/private/tapi/dev/apps/dialer/dialer.rc b/private/tapi/dev/apps/dialer/dialer.rc
new file mode 100644
index 000000000..d1e73947e
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/dialer.rc
@@ -0,0 +1,452 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "windows.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""windows.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALER DIALOG PRELOAD DISCARDABLE 50, 50, 194, 168
+STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU
+CAPTION "Phone Dialer"
+MENU IDM_MENU
+CLASS "DialerClass"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ CONTROL "",IDD_DRECTSEPARATOR,"Static",SS_ETCHEDHORZ |
+ WS_DISABLED,0,0,194,1
+ LTEXT "&Number to dial:",IDD_DNUMTODIAL,7,7,90,10
+ COMBOBOX IDD_DCOMBO,7,21,90,104,CBS_DROPDOWN | CBS_AUTOHSCROLL |
+ WS_VSCROLL | WS_GROUP | WS_TABSTOP | ES_NOHIDESEL
+ DEFPUSHBUTTON "&Dial",IDD_DDIAL,7,38,90,14,WS_DISABLED | WS_GROUP
+ CONTROL "\n1",IDD_DBUTTON1,"Button",BS_OWNERDRAW,14,62,23,20
+ CONTROL "ABC\n2",IDD_DBUTTON2,"Button",BS_OWNERDRAW,40,62,23,20
+ CONTROL "DEF\n3",IDD_DBUTTON3,"Button",BS_OWNERDRAW,66,62,23,20
+ CONTROL "GHI\n4",IDD_DBUTTON4,"Button",BS_OWNERDRAW,14,86,23,20
+ CONTROL "JKL\n5",IDD_DBUTTON5,"Button",BS_OWNERDRAW,40,86,23,20
+ CONTROL "MNO\n6",IDD_DBUTTON6,"Button",BS_OWNERDRAW,66,86,23,20
+ CONTROL "PQRS\n7",IDD_DBUTTON7,"Button",BS_OWNERDRAW,14,110,23,
+ 20
+ CONTROL "TUV\n8",IDD_DBUTTON8,"Button",BS_OWNERDRAW,40,110,23,20
+ CONTROL "WXYZ\n9",IDD_DBUTTON9,"Button",BS_OWNERDRAW,66,110,23,
+ 20
+ CONTROL "\n*",IDD_DBUTTONSTAR,"Button",BS_OWNERDRAW,14,134,23,20
+ CONTROL "\n0",IDD_DBUTTON0,"Button",BS_OWNERDRAW,40,134,23,20
+ CONTROL "\n#",IDD_DBUTTONPOUND,"Button",BS_OWNERDRAW,66,134,23,
+ 20
+ GROUPBOX "Speed dial",IDD_DSPEEDDIALGRP,103,7,84,154
+ LTEXT "&1",IDD_DSPEEDDIALTEXT1,109,24,7,10
+ PUSHBUTTON "",IDD_DSPEEDDIAL1,117,21,63,14,BS_LEFT | WS_GROUP
+ LTEXT "&2",IDD_DSPEEDDIALTEXT2,109,41,7,10
+ PUSHBUTTON "",IDD_DSPEEDDIAL2,117,38,63,14,BS_LEFT | WS_GROUP
+ LTEXT "&3",IDD_DSPEEDDIALTEXT3,109,58,7,10
+ PUSHBUTTON "",IDD_DSPEEDDIAL3,117,55,63,14,BS_LEFT | WS_GROUP
+ LTEXT "&4",IDD_DSPEEDDIALTEXT4,109,75,7,10
+ PUSHBUTTON "",IDD_DSPEEDDIAL4,117,72,63,14,BS_LEFT | WS_GROUP
+ LTEXT "&5",IDD_DSPEEDDIALTEXT5,109,92,7,10
+ PUSHBUTTON "",IDD_DSPEEDDIAL5,117,89,63,14,BS_LEFT | WS_GROUP
+ LTEXT "&6",IDD_DSPEEDDIALTEXT6,109,109,7,10
+ PUSHBUTTON "",IDD_DSPEEDDIAL6,117,106,63,14,BS_LEFT | WS_GROUP
+ LTEXT "&7",IDD_DSPEEDDIALTEXT7,109,126,7,10
+ PUSHBUTTON "",IDD_DSPEEDDIAL7,117,123,63,14,BS_LEFT | WS_GROUP
+ LTEXT "&8",IDD_DSPEEDDIALTEXT8,109,143,7,10
+ PUSHBUTTON "",IDD_DSPEEDDIAL8,117,140,63,14,BS_LEFT | WS_GROUP
+END
+
+IDD_SD1 DIALOG DISCARDABLE 12, 29, 165, 173
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP
+CAPTION "Edit Speed Dial"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Choose a button from the group below.",
+ IDD_SD1TEXTCHOOSE,7,7,140,10
+ LTEXT "1",IDD_SD1SPEEDDIALTEXT1,7,27,8,10
+ PUSHBUTTON "",IDD_SD1SPEEDDIAL1,16,24,63,14,BS_LEFT | WS_GROUP
+ LTEXT "2",IDD_SD1SPEEDDIALTEXT2,7,44,8,10
+ PUSHBUTTON "",IDD_SD1SPEEDDIAL2,16,41,63,14,BS_LEFT | WS_GROUP
+ LTEXT "3",IDD_SD1SPEEDDIALTEXT3,7,61,8,10
+ PUSHBUTTON "",IDD_SD1SPEEDDIAL3,16,58,63,14,BS_LEFT | WS_GROUP
+ LTEXT "4",IDD_SD1SPEEDDIALTEXT4,7,78,8,10
+ PUSHBUTTON "",IDD_SD1SPEEDDIAL4,16,75,63,14,BS_LEFT | WS_GROUP
+ LTEXT "5",IDD_SD1SPEEDDIALTEXT5,86,27,8,10
+ PUSHBUTTON "",IDD_SD1SPEEDDIAL5,95,24,63,14,BS_LEFT | WS_GROUP
+ LTEXT "6",IDD_SD1SPEEDDIALTEXT6,86,44,8,10
+ PUSHBUTTON "",IDD_SD1SPEEDDIAL6,95,41,63,14,BS_LEFT | WS_GROUP
+ LTEXT "7",IDD_SD1SPEEDDIALTEXT7,86,61,8,10
+ PUSHBUTTON "",IDD_SD1SPEEDDIAL7,95,58,63,14,BS_LEFT | WS_GROUP
+ LTEXT "8",IDD_SD1SPEEDDIALTEXT8,86,78,8,10
+ PUSHBUTTON "",IDD_SD1SPEEDDIAL8,95,75,63,14,BS_LEFT | WS_GROUP
+ LTEXT "",IDD_SD1RECTSEPARATOR,7,96,151,8,WS_DISABLED | NOT
+ WS_GROUP
+ LTEXT "Enter a name and number for the selected button.",
+ IDD_SD1TEXTENTER,7,104,160,10
+ LTEXT "&Name:",IDD_SD1TEXTNAME,16,119,29,10
+ EDITTEXT IDD_SD1EDITNAME,16,130,63,14,ES_AUTOHSCROLL
+ LTEXT "N&umber to dial:",IDD_SD1TEXTNUMBER,95,119,53,10
+ EDITTEXT IDD_SD1EDITNUMBER,95,130,63,14,ES_AUTOHSCROLL
+ PUSHBUTTON "&Save",IDOK,55,152,50,14,WS_GROUP
+ PUSHBUTTON "Cancel",IDCANCEL,108,152,50,14
+END
+
+IDD_SD2 DIALOG DISCARDABLE 12, 29, 158, 91
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP
+CAPTION "Program Speed Dial"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Enter a name and number to save on this button.",
+ IDD_SD2TEXTENTER,7,7,85,21
+ DEFPUSHBUTTON "&Save",IDOK,98,7,53,14,WS_GROUP
+ PUSHBUTTON "Save and &Dial",IDD_SD2SAVEANDDIAL,98,24,53,14,
+ WS_DISABLED | WS_GROUP
+ PUSHBUTTON "Cancel",IDCANCEL,98,41,53,14
+ LTEXT "&Name:",IDD_SD2TEXTNAME,7,30,29,10
+ EDITTEXT IDD_SD2EDITNAME,7,41,63,14,ES_AUTOHSCROLL
+ LTEXT "N&umber to dial:",IDD_SD2TEXTNUMBER,7,59,53,10
+ EDITTEXT IDD_SD2EDITNUMBER,7,70,63,14,ES_AUTOHSCROLL
+END
+
+IDD_CONNECTUSING DIALOG PRELOAD DISCARDABLE 50, 50, 260, 105
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP
+CAPTION "Connect Using"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "&Line:",IDD_CUTEXTLINE,7,16,79,10,NOT WS_GROUP
+ COMBOBOX IDD_CULISTLINE,7,27,173,97,CBS_DROPDOWNLIST | CBS_SORT |
+ WS_GROUP | WS_TABSTOP | WS_VSCROLL
+ LTEXT "&Address:",IDD_CUTEXTADDRESS,7,43,79,10,NOT WS_GROUP
+ COMBOBOX IDD_CULISTADDRESS,7,53,173,82,CBS_DROPDOWNLIST |
+ CBS_SORT | WS_GROUP | WS_TABSTOP | WS_VSCROLL
+ CONTROL "Use Phone Dialer to handle &voice call requests from other programs",
+ IDD_CUSIMPLETAPICHKBOX,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,7,72,230,10
+ PUSHBUTTON "Line &Properties...",IDD_CUPROPERTIES,190,26,63,14
+ DEFPUSHBUTTON "OK",IDOK,146,84,50,14,WS_GROUP
+ PUSHBUTTON "Cancel",IDCANCEL,203,84,50,14,WS_GROUP
+END
+
+IDD_ABOUT DIALOG DISCARDABLE 22, 38, 227, 100
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "About Phone Dialer"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ ICON IDI_DIALER,IDD_AICON,10,5,18,20
+ LTEXT "",IDD_ATEXTTITLE,38,5,127,10,SS_NOPREFIX | NOT WS_GROUP
+ LTEXT "Copyright © 1993-1995 Microsoft. All Rights Reserved.",
+ IDD_ATEXTCOPYRIGHT,38,35,179,20,SS_NOPREFIX | NOT
+ WS_GROUP
+ LTEXT "",-1,38,60,172,1,NOT WS_GROUP
+ LTEXT "Memory:",-1,38,75,70,10,SS_NOPREFIX | NOT WS_GROUP
+ LTEXT "%lu KB Free",IDD_ATEXTFREEMEM,120,75,74,10,SS_NOPREFIX |
+ NOT WS_GROUP
+ DEFPUSHBUTTON "OK",IDOK,177,5,40,14
+ LTEXT "System resources:",-1,38,85,70,10,SS_NOPREFIX | NOT
+ WS_GROUP
+ LTEXT "%d%%",IDD_ATEXTRESOURCE,120,85,74,10,SS_NOPREFIX | NOT
+ WS_GROUP
+END
+
+IDD_INUSE DIALOG DISCARDABLE 22, 38, 199, 81
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Line In Use"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,36,58,53,16
+ ICON IDI_LINEBUSY,IDD_IUICON,10,5,18,20
+ LTEXT "The selected line or address is in use by another program or device on the line. Your call can not be placed at this time.",
+ IDD_IUTEXT1,45,5,144,27,SS_NOPREFIX | NOT WS_GROUP
+ LTEXT "Try your call again later.",IDD_IUTEXT2,45,40,114,12,
+ SS_NOPREFIX | NOT WS_GROUP
+END
+
+IDD_CALLFAILED DIALOG DISCARDABLE 22, 38, 199, 73
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Call Failed"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,72,50,53,16
+ ICON IDI_LINEBUSY,IDD_IUICON,10,5,18,20
+ LTEXT "",IDD_CFTEXT,45,5,144,40,SS_NOPREFIX | NOT WS_GROUP
+END
+
+IDD_DIALING DIALOG DISCARDABLE 0, 0, 172, 62
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION
+CAPTION "Dialing"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ PUSHBUTTON "&Hang Up",IDCANCEL,9,37,50,14
+ RTEXT "Currently dialing:",IDD_DGNUMBER,9,9,52,9
+ LTEXT "",IDD_DGNUMBERTEXT,63,9,100,9
+ LTEXT "",IDD_DGNAMETEXT,63,23,100,9
+END
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDM_MENU MENU DISCARDABLE
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "E&xit", IDM_EXIT
+ END
+ POPUP "&Edit"
+ BEGIN
+ MENUITEM "Cu&t\tCtrl+X", IDM_EDIT_CUT
+ MENUITEM "&Copy\tCtrl+C", IDM_EDIT_COPY
+ MENUITEM "&Paste\tCtrl+V", IDM_EDIT_PASTE
+ MENUITEM "&Delete\tDel", IDM_EDIT_DELETE
+ MENUITEM SEPARATOR
+ MENUITEM "&Speed Dial...", IDM_EDIT_SPEEDDIAL
+ END
+ POPUP "&Tools"
+ BEGIN
+ MENUITEM "&Connect Using...", IDM_CONNECTUSING
+ MENUITEM "&Dialing Properties...", IDM_LOCATION
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "&Help Topics", IDM_HELP_CONTENTS
+ MENUITEM "&What's This?", IDM_HELP_WHATSTHIS
+ MENUITEM SEPARATOR
+ MENUITEM "&About Phone Dialer", IDM_ABOUT
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+#if WINNT
+IDI_DIALER ICON DISCARDABLE "DIALER.ICO"
+IDI_LINEBUSY ICON DISCARDABLE "LINEBUSY.ICO"
+#else
+IDI_DIALER ICON DISCARDABLE "..\\DIALER.ICO"
+IDI_LINEBUSY ICON DISCARDABLE "..\\LINEBUSY.ICO"
+#endif
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDA_DIALER ACCELERATORS DISCARDABLE
+BEGIN
+ "1", IDD_DSPEEDDIAL1, VIRTKEY, ALT, NOINVERT
+ "2", IDD_DSPEEDDIAL2, VIRTKEY, ALT, NOINVERT
+ "3", IDD_DSPEEDDIAL3, VIRTKEY, ALT, NOINVERT
+ "4", IDD_DSPEEDDIAL4, VIRTKEY, ALT, NOINVERT
+ "5", IDD_DSPEEDDIAL5, VIRTKEY, ALT, NOINVERT
+ "6", IDD_DSPEEDDIAL6, VIRTKEY, ALT, NOINVERT
+ "7", IDD_DSPEEDDIAL7, VIRTKEY, ALT, NOINVERT
+ "8", IDD_DSPEEDDIAL8, VIRTKEY, ALT, NOINVERT
+ "C", IDM_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
+ "D", IDD_DDIAL, VIRTKEY, ALT, NOINVERT
+ "N", IDM_ACCEL_NUMTODIAL, VIRTKEY, ALT, NOINVERT
+ "V", IDM_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT
+ VK_INSERT, IDM_EDIT_PASTE, VIRTKEY, SHIFT, NOINVERT
+ "X", IDM_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT
+END
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+
+
+#ifdef SDKRELEASE
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,0,1259,1
+ PRODUCTVERSION 4,0,1259,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904B0"
+ BEGIN
+ VALUE "CompanyName", "Microsoft Corporation\0"
+ VALUE "FileDescription", "Microsoft® Windows(TM) Phone Dialer\0"
+ VALUE "FileVersion", "4.00\0"
+ VALUE "InternalName", "Phone Dialer\0"
+ VALUE "LegalCopyright", "Copyright © Microsoft Corporation 1996. All Rights Reserved.\0"
+ VALUE "OriginalFilename", "dialer.exe\0"
+ VALUE "ProductName", "Microsoft(R) Windows NT(TM) Operating System\0"
+ VALUE "ProductVersion", "4.00\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
+#else
+
+#if WINNT
+#include <ntverp.h>
+#else
+#include <version.h>
+#endif
+
+#define VER_FILEDESCRIPTION_STR "Microsoft\256 Windows(TM) Phone Dialer"
+#define VER_INTERNALNAME_STR "Dialer"
+#define VER_ORIGINALFILENAME_STR "DIALER.EXE"
+//#define VER_LEGALCOPYRIGHT_STR "Copyright \251 Microsoft Corporation 1996. All Rights Reserved."
+#define VER_LEGALCOPYRIGHT_YEARS "1996"
+
+#define VER_FILETYPE VFT_DLL
+#define VER_FILESUBTYPE VFT2_UNKNOWN
+
+#include <common.ver>
+
+
+#endif
+
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ikszAppName "Dialer"
+ ikszAppFriendlyName "Phone Dialer"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ikszErrDefault "An internal error occurred in Phone Dialer.\nQuit and restart Phone Dialer."
+ ikszErrOOM "There was not enough memory to continue.\nQuit one or more programs, and then try again."
+ ikszErrTAPI "Windows Telephony was unable to complete an operation requested by Phone Dialer.\nQuit and restart Phone Dialer."
+ ikszErrNoVoiceLine "Phone Dialer was unable to find a telephone device or modem to use to dial voice calls.\nIn Control Panel, double-click the Modems icon to install a modem, or install another telephone device to use for dialing calls."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ikszWarningTapiReInit "Phone Dialer cannot successfully start.\nQuit all other telephony programs, and then try again."
+ ikszErrLineClose "Your call was cancelled because the Telephony device driver closed the line."
+ ikszDisconnectedNoDialTone
+ "A dial tone was not detected. Please check your telephone cable connections, and be sure the line is not in use by someone else."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ikszErrLineInitBadIniFile
+ "Configuration information relating to Telephony services appears to be corrupt.\nPlease check the configuration of telephone devices in the control panel."
+ ikszErrLineInitNoDriver "One of the components of the Telephony device driver is missing.\nUse the Control Panel to set up the driver properly."
+ ikszErrLineInitNoDevice "The selected device has been removed from your computer. Please select a different device for dialing."
+ ikszErrNoMultipleInstance
+ "You have two copies of the same Telephony driver installed.\nUse the Control Panel to remove one of the copies."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ikszErrInvalAddress "The specified phone number either contains invalid characters, or is incorrectly formatted.\nClick on the number box with the right mouse button to see more information."
+ ikszErrLineInitWrongDrivers
+ "One or more telephone device drivers are incompatible with TAPI.DLL.\nInstall an updated version."
+ ikszErrAddrBlocked "The specified phone number cannot be dialed on the selected line device because it is blocked at the telephone switch."
+ ikszErrBillingRejected "The billing information specified as part of the phone number has been rejected.\nCheck to make sure you've entered it correctly, and then try again."
+ ikszErrResUnavail "Another program is using the selected Telephony device.\nTry again after the other program completes."
+ ikszErrInvalidCountryCode "The country code you entered is invalid.\nPlease check the phone number again."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ikszDisconnectedReject "The call was rejected by the called party."
+ ikszDisconnectedBusy "The called number is busy."
+ ikszDisconnectedNoAnswer "There was no answer."
+ ikszDisconnectedCantDo "The call cannot be completed as dialed."
+ ikszDisconnectedNetwork "The call failed due to network congestion."
+ ikszDisconnectedIncompatible
+ "Equipment at the called number is incompatible with your equipment."
+ ikszErrInvalCallState "The Telephony device driver is unable to respond to your request at this time."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ikszWarningTitle "Warning"
+ ikszWarningFor911 "Using your current location and calling card selection, dialing this number could result in a emergency services call to 911. Are you sure you want to dial this call ?"
+ ikszWarningNewDefault "Your preferred device selection is not available. A new device has been selected by default. If you wish to change the selection use the 'Connect Using' option under the 'Tools' menu"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/private/tapi/dev/apps/dialer/dialhelp.h b/private/tapi/dev/apps/dialer/dialhelp.h
new file mode 100644
index 000000000..54084e44c
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/dialhelp.h
@@ -0,0 +1,29 @@
+//
+// (c) 1995 Microsoft Corporation. All Rights Reserved.
+//
+#define IDH_DIALER_CHANGE_DIAL_HELPER 1000
+#define IDH_DIALER_CHANGE_DIGITS 1001
+#define IDH_DIALER_CHANGE_OPTIONS 1002
+#define IDH_DIALER_CHANGE_REDIAL_BUTTON 1003
+#define IDH_DIALER_DIALING_LOGNAME 1004
+#define IDH_DIALER_DIALING_STATUS 1005
+#define IDH_DIALER_HANGUP 1006
+#define IDH_DIALER_LOG_IN 1007
+#define IDH_DIALER_LOG_OUT 1008
+#define IDH_DIALER_OPTIONS_ADDRESS 1009
+#define IDH_DIALER_OPTIONS_LINE 1010
+#define IDH_DIALER_OPTIONS_NONVOICE 1011
+#define IDH_DIALER_OPTIONS_VOICE 1012
+#define IDH_DIALER_PAUSE_CONTINUE 1013
+#define IDH_DIALER_SPEED_CHOOSE 1014
+#define IDH_DIALER_SPEED_NAME 1015
+#define IDH_DIALER_SPEED_NUMBER 1016
+#define IDH_DIALER_SPEED_SAVE 1017
+#define IDH_DIALER_SPEED_SAVE_DIAL 1018
+#define IDH_DIALER_DIAL_NUMBER 1019
+#define IDH_DIALER_DIAL_SPEED_CHOOSE 1020
+#define IDH_DIALER_DIAL_BUTTON 1021
+#define IDH_DIALER_DIAL_KEYPAD 1022
+#define IDH_DIALER_LOG 1023
+#define IDH_DIALER_OPTIONS_PROPERTIES 1024
+#define IDH_DIALER_BUTTONS 1025
diff --git a/private/tapi/dev/apps/dialer/linebusy.ico b/private/tapi/dev/apps/dialer/linebusy.ico
new file mode 100644
index 000000000..589f2671b
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/linebusy.ico
Binary files differ
diff --git a/private/tapi/dev/apps/dialer/makefile b/private/tapi/dev/apps/dialer/makefile
new file mode 100644
index 000000000..f1084966b
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/makefile
@@ -0,0 +1,29 @@
+!if "$(OS)" == "Windows_NT"
+
+!INCLUDE $(NTMAKEENV)\makefile.def
+
+!else
+
+##############################################################################
+#
+# Dialer.exe Make file
+#
+##############################################################################
+
+#Ok, we're doing a Win9x build.
+
+ROOT=..\..\..\..\..
+
+VERSIONLIST=debug retail
+
+DEPENDNAME=depend.mk
+
+COMMONMKFILE=makefile.def
+
+IS_OEM=TRUE
+IS_32 = TRUE
+
+!include $(ROOT)\dev\master.mk
+
+!endif
+
diff --git a/private/tapi/dev/apps/dialer/makefile.def b/private/tapi/dev/apps/dialer/makefile.def
new file mode 100644
index 000000000..1eb194df8
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/makefile.def
@@ -0,0 +1,50 @@
+##############################################################################
+#
+# Dialer Make file
+#
+##############################################################################
+
+#Ok, we're doing a Win9x build.
+
+ROOT=..\..\..\..\..\..
+
+
+IS_OEM=1
+WANT_C932=1
+IS_32 = TRUE
+WIN32=1
+
+DEPENDNAME=..\depend.mk
+
+DRVNAME=dialer
+TARGETS=dialer.exe
+
+DEFENTRY = WinMain
+
+SRCDIR=..
+
+BUILD_COFF=1
+
+L32EXE=dialer.exe # Name of exe.
+L32DEF=..\dialer.def # Our def file.
+L32MAP=dialer.map # Our map file.
+L32SYM=dialer.sym # Our sym file.
+L32LIBS= \
+ $(W32LIBID)\user32.lib \
+ $(W32LIBID)\gdi32.lib \
+ $(W32LIBID)\kernel32.lib \
+ $(DEVROOT)\sdk\lib\tapi32.lib \
+ $(DEVROOT)\tools\c932\lib\oldnames.lib \
+ $(DEVROOT)\tools\c932\lib\msvcrt.lib \
+ $(DEVROOT)\sdk\lib\shell32.lib
+
+L32RES=dialer.res # Resource file.
+L32OBJS = dialer.obj
+
+!include $(ROOT)\dev\master.mk
+
+CFLAGS=$(CFLAGS) -DWIN32=100 -DWIN_32=100 -Og
+
+!IF "$(VERDIR)" == "debug"
+CFLAGS = $(CFLAGS) -DDBG=1
+!endif
diff --git a/private/tapi/dev/apps/dialer/nextver/depend.mk b/private/tapi/dev/apps/dialer/nextver/depend.mk
new file mode 100644
index 000000000..506be7029
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/nextver/depend.mk
@@ -0,0 +1,4 @@
+.\dialer.obj: ..\dialer.c ..\dialer.h ..\dialhelp.h ..\resource.h
+
+.\dialer.res: ..\dialer.rc ..\version.rc ..\resource.h
+
diff --git a/private/tapi/dev/apps/dialer/nextver/dialer.c b/private/tapi/dev/apps/dialer/nextver/dialer.c
new file mode 100644
index 000000000..3a6d8918b
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/nextver/dialer.c
@@ -0,0 +1,4300 @@
+/*++
+
+Copyright (c) 1996 Microsoft Corporation
+
+Module Name:
+
+ dialer.c
+
+--*/
+
+
+#include "dialer.h"
+#include "string.h"
+#include "stdlib.h"
+#include "shellapi.h"
+
+
+#define ISDIGIT(x) (((x) - '0') >= 0) && (((x) - '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
+ char 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 [] = "DIALER.INI";
+static TCHAR gszHELPfilename [] = "DIALER.HLP";
+static TCHAR gszDialerClassName[] = "DialerClass";
+TCHAR const gszNULL[] = "";
+
+// window item variables
+HFONT ghFontBtn; // handle to 1, 2, ..., 0's font
+HFONT ghFontBtnText; // handle to number button's text font
+HFONT ghFontBtnStar; // handle to * and # button's font
+HLINEAPP ghLineApp = NULL; // Dialer's usage handle (regist. w/TAPI)
+HCALL ghCall = NULL; // call handle for Dialer's call
+
+LPSTR gszCurrentNumber = NULL; // number of destination of current call
+LPSTR gszCurrentName = NULL; // name of destination of current call
+
+BOOL gfRegistered; // was lineRegisterRequestRecipient()
+ // successful?
+
+//BOOL gfDropping = FALSE; // is Dialer currently dropping a call?
+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 ];
+
+
+// Function declarations
+
+// button related functions
+VOID ButtonFontSetup(VOID);
+VOID DrawButton(HDC hdc, RECT rcBtn, BOOL fHighlighted);
+VOID DrawButtonText(HDC hdc, RECT rcBtn, BOOL fHighlighted, UINT IDD_Btn);
+VOID DisableDialButtons(BOOL fDisable);
+VOID FitTextToButton( HWND, INT, LPSTR );
+
+// Callback functions
+BOOL CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+BOOL CALLBACK DialingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+BOOL CALLBACK AboutProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+BOOL CALLBACK ConnectUsingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+BOOL CALLBACK LineInUseProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+BOOL CALLBACK SpeedDial1Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+BOOL 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(LPCSTR szNumber, LPCSTR szName);
+
+VOID DialerLineClose(VOID);
+VOID DialerCleanup(VOID);
+VOID CloseTAPI(VOID);
+
+DWORD GetLineInfo(DWORD iLine, LPLINEINFO lpLineInfo);
+VOID GetLineInfoFailed (
+ DWORD iLine, LPLINEDEVCAPS lpDevCaps,
+ LPLINEINFO lpLineInfo
+ );
+LPSTR GetAddressName(DWORD iLine, DWORD iAddress);
+BOOL MakeCanonicalNumber( LPCSTR szName, LPSTR szCanNumber );
+
+// misc. helper functions
+VOID ReadINI(VOID);
+int errString(HWND hWnd, UINT errCode, UINT uFlags);
+VOID AddToRedialList(LPCSTR szNumber);
+BOOL InitializeLineBox(HWND hwndLineBox);
+BOOL InitializeAddressBox(HWND hwndLineBox, HWND hwndAddressBox);
+BOOL Is911 ( LPLINETRANSLATEOUTPUT lpTransOut );
+VOID AmpersandCompensate( LPCSTR lpszSrc, LPSTR lpszDst );
+VOID AmpersandDeCompensate( LPCSTR lpszSrc, LPSTR 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;
+
+ char szBuffer[MAXBUFSIZE]; // to read in dwPreferredPLID as a string first
+
+
+
+ errCode = lineInitialize (
+ &ghLineApp,
+ ghInst,
+ (LINECALLBACK) tapiCallback,
+ gszAppName,
+ &gnAvailDevices
+ );
+ 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 = lineInitialize (
+ &ghLineApp,
+ ghInst,
+ (LINECALLBACK)tapiCallback,
+ gszAppName,
+ &gnAvailDevices
+ ) )
+ == 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;
+ }
+
+ // retrieve preferred line info from INI file
+ GetPrivateProfileString (
+ "Preference",
+ "Preferred Line",
+ gszNULL,
+ szBuffer,
+ MAXBUFSIZE,
+ gszINIfilename
+ );
+
+ // if szBuffer is not empty.
+ if ( lstrcmp ( gszNULL, szBuffer ) )
+ {
+ dwPreferredPLID = (DWORD) atoi( 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,
+ (DLGPROC)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
+ GetPrivateProfileString (
+ "Preference",
+ "Preferred Address",
+ gszNULL,
+ szBuffer,
+ MAXBUFSIZE,
+ gszINIfilename
+ );
+
+ // if preferred address read from INI file
+ if ( lstrcmp( gszNULL, szBuffer ) )
+ {
+ giCurrentAddress = (DWORD) atoi( szBuffer );
+
+ // if the address is invalid, set default
+ if ( giCurrentAddress >= gCurrentLineInfo.nAddr )
+ giCurrentAddress = 0;
+ }
+
+
+tapiinit_exit:
+
+ 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, "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,
+ (LPCSTR)MAKEINTRESOURCE(IDD_DIALER),
+ (HWND)NULL,
+ MainWndProc
+ );
+
+ ReadINI();
+ ButtonFontSetup();
+
+ 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 msg.wParam;
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+LPVOID DialerAlloc(size_t cbToAlloc)
+{
+ return LocalAlloc(LPTR, cbToAlloc);
+}
+
+
+LPVOID DialerFree(LPVOID lpMem)
+{
+ return LocalFree( lpMem );
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+VOID ReadINI( VOID )
+{
+ WORD cSDEntry, cLastDialed;
+ DWORD cComma;
+
+ POINT ptLeftTop;
+
+ char szName[ TAPIMAXCALLEDPARTYSIZE ];
+ char szTemp[ TAPIMAXCALLEDPARTYSIZE ];
+
+ char szNum[MAXBUFSIZE];
+ char szFieldName[MAXBUFSIZE];
+ char szPt[MAXBUFSIZE];
+
+
+ // get speed dial settings from INI file
+ for(cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry)
+ {
+
+ wsprintf(szFieldName, "Name%d", cSDEntry);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ szName,
+ TAPIMAXCALLEDPARTYSIZE - 1,
+ gszINIfilename
+ );
+
+ wsprintf(szFieldName, "Number%d", cSDEntry);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ gszSDNumber[cSDEntry],
+ TAPIMAXDESTADDRESSSIZE - 1,
+ gszINIfilename
+ );
+
+ if ( !lstrcmp( gszNULL, szName ) )
+ {
+ lstrcpy( szName, gszSDNumber[ cSDEntry ] );
+ }
+
+ FitTextToButton( ghWndMain, IDD_DSPEEDDIAL1 + cSDEntry - 1, szName );
+
+ AmpersandCompensate( szName, szTemp );
+ SetDlgItemText (
+ ghWndMain,
+ IDD_DSPEEDDIAL1 + cSDEntry - 1,
+ (LPCSTR)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, "Last dialed %d", cLastDialed);
+ GetPrivateProfileString (
+ "Last dialed numbers",
+ szFieldName,
+ gszNULL,
+ szNum,
+ MAXBUFSIZE - 1,
+ gszINIfilename
+ );
+ if ( szNum[0] ) // i.e. if szNum isn't simply "" - if we read something
+ // from the INI - put it in the combo box
+ SendDlgItemMessage(
+ ghWndMain,
+ IDD_DCOMBO,
+ CB_ADDSTRING,
+ 0,
+ (LPARAM)(LPCSTR)szNum
+ );
+ }
+
+ // set defaults
+ ptLeftTop.x = 100;
+ ptLeftTop.y = 100;
+
+ // set the window position based on the INI data
+ GetPrivateProfileString (
+ "Preference",
+ "Main Window Left/Top",
+ gszNULL,
+ szPt,
+ MAXBUFSIZE - 1,
+ gszINIfilename
+ );
+
+ if ( szPt[0] )
+ {
+ cComma = strcspn(szPt, ",");
+ szPt[cComma] = 0;
+ ptLeftTop.x = atoi(szPt);
+
+ // a possibly absurd check to see that the string
+ // wasn't akin to "320," with no second entry
+ if ( *(szPt + cComma + 1 ) )
+ ptLeftTop.y = atoi( szPt + cComma + 1 );
+
+ // check to see that the box is on the screen - the upper left
+ // must be on the screen, along with a 50x50 box below and to
+ // the right of it
+ 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
+ );
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+VOID ButtonFontSetup(VOID)
+ {
+ HDC hdc;
+ int IDD;
+
+ // define the fonts for the buttons
+ hdc = GetDC(GetDesktopWindow());
+
+ ghFontBtn = CreateFont(
+ (-10)*GetDeviceCaps(hdc, LOGPIXELSY)/72,
+ 0,
+ 0,
+ 0,
+ FW_BOLD,
+ FALSE,
+ FALSE,
+ FALSE,
+ ANSI_CHARSET,
+ OUT_DEFAULT_PRECIS,
+ CLIP_DEFAULT_PRECIS,
+ PROOF_QUALITY,
+ VARIABLE_PITCH | FF_SWISS,
+ (LPSTR)"Arial"
+ );
+
+ ghFontBtnText = CreateFont(
+ (-6)*GetDeviceCaps(hdc, LOGPIXELSY)/72,
+ 0,
+ 0,
+ 0,
+ FW_NORMAL,
+ FALSE,
+ FALSE,
+ FALSE,
+ ANSI_CHARSET,
+ OUT_DEFAULT_PRECIS,
+ CLIP_DEFAULT_PRECIS,
+ PROOF_QUALITY,
+ VARIABLE_PITCH | FF_SWISS,
+ NULL
+ );
+
+ ghFontBtnStar = CreateFont(
+ (-18)*GetDeviceCaps(hdc, LOGPIXELSY)/72,
+ 0,
+ 0,
+ 0,
+ FW_BOLD,
+ FALSE,
+ FALSE,
+ FALSE,
+ SYMBOL_CHARSET,
+ OUT_TT_PRECIS,
+ CLIP_DEFAULT_PRECIS,
+ PROOF_QUALITY,
+ VARIABLE_PITCH | FF_DONTCARE,
+ (LPSTR)"Symbol"
+ );
+
+ ReleaseDC(GetDesktopWindow(), hdc);
+
+
+ // set the fonts for the buttons
+ if(ghFontBtn)
+ {
+ // set fonts on number buttons
+ for(IDD = IDD_DBUTTON1; IDD <= IDD_DBUTTON0; ++IDD)
+ // the order is IDD_DBUTTON1, 2, 3, ..., 0 (thus from 1 to 0)
+ SendMessage(
+ GetDlgItem(ghWndMain, IDD),
+ WM_SETFONT,
+ (WPARAM)ghFontBtn,
+ 0L
+ );
+
+ // set fonts on * and # buttons
+ SendMessage(
+ GetDlgItem(ghWndMain, IDD_DBUTTONSTAR),
+ WM_SETFONT,
+ (WPARAM)ghFontBtnStar,
+ 0L
+ );
+ SendMessage(
+ GetDlgItem(ghWndMain, IDD_DBUTTONPOUND),
+ WM_SETFONT,
+ (WPARAM)ghFontBtnStar,
+ 0L
+ );
+ }
+ }
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+// Draws a 3D button within rcBtn on hDC
+VOID DrawButton(HDC hDC, RECT rcBtn, BOOL fHighlighted)
+ {
+ HPEN hPenPrev, hPenShadow, hPenHighlight, hPenBlack;
+ HBRUSH hBrushPrev, hBrushFace;
+ int RopPrev;
+
+ --rcBtn.right;
+ --rcBtn.bottom;
+
+ // set up pens/brush
+ hPenShadow = CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DSHADOW));
+ hPenHighlight = CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DHILIGHT));
+ hPenBlack = GetStockObject(BLACK_PEN);
+ hBrushFace = GetSysColorBrush(COLOR_3DFACE);
+
+ // get current state so we can put it back at the end of DrawButton
+ hPenPrev = SelectObject(hDC, hPenBlack);
+ RopPrev = SetROP2(hDC, R2_COPYPEN);
+ hBrushPrev = SelectObject(hDC, hBrushFace);
+
+ PatBlt(
+ hDC,
+ rcBtn.left + 1,
+ rcBtn.top + 1,
+ rcBtn.right - rcBtn.left - 1,
+ rcBtn.bottom - rcBtn.top - 1,
+ PATCOPY
+ );
+
+ if(fHighlighted)
+ {
+ SelectObject(hDC, hPenBlack);
+ MoveToEx(hDC, rcBtn.left, rcBtn.bottom - 1, NULL);
+ LineTo(hDC, rcBtn.left, rcBtn.top); // _
+ LineTo(hDC, rcBtn.right, rcBtn.top); // |
+
+ SelectObject(hDC, hPenHighlight);
+ MoveToEx(hDC, rcBtn.right, rcBtn.top, NULL);
+ LineTo(hDC, rcBtn.right, rcBtn.bottom);
+ LineTo(hDC, rcBtn.left - 1, rcBtn.bottom); // _|
+
+ SelectObject(hDC, hPenShadow);
+ MoveToEx(hDC, rcBtn.left + 1, rcBtn.bottom - 2, NULL);
+ LineTo(hDC, rcBtn.left + 1, rcBtn.top + 1);
+ LineTo(hDC, rcBtn.right - 1, rcBtn.top + 1);
+ }
+ else
+ {
+ SelectObject(hDC, hPenHighlight);
+ MoveToEx(hDC, rcBtn.left, rcBtn.bottom - 1, NULL);
+ LineTo(hDC, rcBtn.left, rcBtn.top); // _
+ LineTo(hDC, rcBtn.right, rcBtn.top); // |
+
+ SelectObject(hDC, hPenBlack);
+ MoveToEx(hDC, rcBtn.right, rcBtn.top, NULL);
+ LineTo(hDC, rcBtn.right, rcBtn.bottom);
+ LineTo(hDC, rcBtn.left - 1, rcBtn.bottom); // _|
+
+ SelectObject(hDC, hPenShadow);
+ MoveToEx(hDC, rcBtn.left + 1, rcBtn.bottom - 1, NULL);
+ LineTo(hDC, rcBtn.right - 1, rcBtn.bottom - 1);
+ LineTo(hDC, rcBtn.right - 1, rcBtn.top);
+ }
+
+ // put everything back how it was
+ SetROP2(hDC, RopPrev);
+ SelectObject(hDC, hBrushPrev);
+ SelectObject(hDC, hPenPrev);
+
+ DeleteObject(hPenBlack);
+ DeleteObject(hPenShadow);
+ DeleteObject(hPenHighlight);
+ DeleteObject(hBrushFace);
+ }
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+VOID DrawButtonText(HDC hDC, RECT rcBtn, BOOL fHighlighted, UINT IDD_Btn)
+ {
+ char szLine1[MAXBUFSIZE]; // text in button up to '\n'
+ LPSTR pszLine2; // text in button after '\n'
+ int BkModePrev;
+ HFONT hFontPrev = NULL;
+ TEXTMETRIC tm;
+ RECT rcText = rcBtn;
+
+ BkModePrev = SetBkMode(hDC, TRANSPARENT);
+
+ GetDlgItemText(ghWndMain, IDD_Btn, szLine1, MAXBUFSIZE);
+ pszLine2 = strstr(szLine1, "\n");
+ if(pszLine2)
+ {
+ *pszLine2 = 0; // 1 -> "TEST1 \n TEST2" becomes "TEST 1 \0"
+ ++pszLine2; // now 2 -> " TEST 2"
+ }
+
+ // now szLine1 points to the null terminated first string and
+ // pszLine2 points to either the null terminated second string or NULL
+ // if there was no second string
+
+ if(szLine1[0])
+ {
+ if(ghFontBtnText && pszLine2)
+ hFontPrev = SelectObject(hDC, ghFontBtnText);
+
+ GetTextMetrics(hDC, &tm);
+ rcText.bottom = (rcBtn.bottom + rcBtn.top)/2 - 2;
+ rcText.top = rcText.bottom - (tm.tmHeight - 1);
+
+ if(pszLine2 == NULL)
+ OffsetRect(&rcText, 0, (rcText.bottom - rcText.top)/2);
+
+ if(fHighlighted)
+ OffsetRect(&rcText, 1, 1);
+
+ DrawText(hDC, szLine1, -1, &rcText, DT_SINGLELINE | DT_CENTER);
+
+ if(hFontPrev)
+ SelectObject(hDC, hFontPrev);
+ }
+ if(pszLine2) // recall that pszLine2 == NULL to represent no second string
+ {
+ GetTextMetrics(hDC, &tm);
+ if(IDD_Btn == IDD_DBUTTONSTAR || IDD_Btn == IDD_DBUTTONPOUND)
+ rcText.top = (rcBtn.bottom + rcBtn.top)/2 - (tm.tmHeight)/2;
+ else
+ rcText.top = (rcBtn.bottom + rcBtn.top)/2 - 2;
+ rcText.bottom = rcText.top + tm.tmHeight;
+
+ if(fHighlighted)
+ OffsetRect(&rcText, 1, 1);
+
+ DrawText(hDC, pszLine2, -1, &rcText, DT_SINGLELINE | DT_CENTER);
+ }
+
+ SetBkMode(hDC, BkModePrev);
+ }
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+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;
+ char szPt[MAXBUFSIZE];
+ char szNumber[TAPIMAXDESTADDRESSSIZE];
+ char szFieldName[MAXBUFSIZE];
+
+ CloseTAPI(); // unregister and line close
+
+ if(!IsIconic(ghWndMain)) // if the window is not minimized, record position
+ {
+ GetWindowRect(ghWndMain, &rc);
+ wsprintf(szPt, "%ld, %ld", rc.left, rc.top);
+ WritePrivateProfileString(
+ "Preference",
+ "Main Window Left/Top",
+ szPt,
+ gszINIfilename
+ );
+ }
+
+ 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)(LPCSTR)szNumber);
+
+ else
+ szNumber[0] = 0;
+
+ wsprintf(szFieldName, "Last dialed %d", cLastDialed);
+ WritePrivateProfileString(
+ "Last dialed numbers",
+ szFieldName,
+ szNumber,
+ gszINIfilename
+ );
+
+ }
+
+ WinHelp(ghWndMain, gszHELPfilename, HELP_QUIT, 0); // unload help
+
+ DestroyWindow(ghWndMain);
+ ghWndMain = NULL;
+
+ DeleteObject(ghFontBtn);
+ DeleteObject(ghFontBtnText);
+ DeleteObject(ghFontBtnStar);
+ }
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+// 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 = NULL;
+ }
+
+ lineShutdown(ghLineApp);
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+BOOL 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, (LPCSTR) 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,
+ (DWORD)(LPVOID) aMenuHelpIDs
+ );
+ return TRUE;
+
+ // processes right-clicks on controls
+ case WM_CONTEXTMENU:
+ WinHelp (
+ (HWND)wParam,
+ gszHELPfilename,
+ HELP_CONTEXTMENU,
+ (DWORD)(LPVOID)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
+ {
+ LONG 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:
+ {
+ char szName[TAPIMAXCALLEDPARTYSIZE] = {'\0'};
+ char szNumber[TAPIMAXDESTADDRESSSIZE] = {'\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,
+ (DLGPROC)SpeedDial1Proc,
+ 0
+ );
+ SetFocus(GetDlgItem(ghWndMain, IDD_DDIAL));
+ return TRUE;
+
+ // TOOLS menu
+ case IDM_CONNECTUSING:
+ DialogBoxParam (
+ ghInst,
+ MAKEINTRESOURCE(IDD_CONNECTUSING),
+ ghWndMain,
+ (DLGPROC)ConnectUsingProc,
+ MENU_CHOICE
+ );
+ return TRUE;
+
+ case IDM_LOCATION:
+ {
+ char szCanNumber[ TAPIMAXDESTADDRESSSIZE ] = "";
+
+ // 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:
+ DialogBoxParam(
+ ghInst,
+ MAKEINTRESOURCE(IDD_ABOUT),
+ ghWndMain,
+ (DLGPROC)AboutProc,
+ 0
+ );
+
+ return TRUE;
+
+
+ // Accelerator processing
+ case IDM_ACCEL_NUMTODIAL:
+ if(GetActiveWindow() == ghWndMain)
+ SetFocus(GetDlgItem(ghWndMain, IDD_DCOMBO));
+ return TRUE;
+
+
+ // Buttons
+ case IDD_DDIAL:
+
+ {
+ DWORD cSDEntry;
+ char szSDNumber[TAPIMAXDESTADDRESSSIZE];
+ char szFieldName[MAXBUFSIZE];
+
+ // 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,
+ (LPSTR)szNumber,
+ TAPIMAXDESTADDRESSSIZE
+ );
+
+ // check if it is a speed dial number.
+ // If so choose the name to be displayed.
+ for( cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry)
+ {
+ wsprintf(szFieldName, "Number%d", cSDEntry);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ szSDNumber,
+ TAPIMAXCALLEDPARTYSIZE - 1,
+ gszINIfilename
+ );
+
+ // if the number matches, get the name
+ if ( lstrcmp(szSDNumber, szNumber) == 0 )
+ {
+ wsprintf( szFieldName, "Name%d", cSDEntry);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ szName,
+ TAPIMAXCALLEDPARTYSIZE - 1,
+ gszINIfilename
+ );
+ break;
+ }
+ }
+
+ 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,
+ (DLGPROC)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 char digits[] = { '1', '2', '3', '4',
+ '5', '6', '7', '8',
+ '9', '0', '*', '#' };
+
+ i = SendDlgItemMessage(ghWndMain,
+ IDD_DCOMBO,
+ WM_GETTEXT,
+ (WPARAM)TAPIMAXDESTADDRESSSIZE+1,
+ (LPARAM)szBuffer);
+
+ if (i < TAPIMAXDESTADDRESSSIZE)
+ {
+ MoveMemory(szBuffer+gdwStartSel+1,
+ szBuffer+gdwEndSel,
+ i - ( gdwEndSel ) + 1 );
+
+ 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;
+ char szFieldName [MAXBUFSIZE];
+
+ // get information for the speed dial button
+ // from the INI file
+ wsprintf(szFieldName, "Name%d", cSDEntry);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ szName,
+ TAPIMAXCALLEDPARTYSIZE - 1,
+ gszINIfilename
+ );
+
+ wsprintf(szFieldName, "%s%d", "Number", cSDEntry);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ gszSDNumber[cSDEntry],
+ TAPIMAXDESTADDRESSSIZE - 1,
+ gszINIfilename
+ );
+
+ // entry not set yet
+ if( gszSDNumber[cSDEntry][0] == 0 )
+ {
+ DialogBoxParam (
+ ghInst,
+ MAKEINTRESOURCE(IDD_SD2),
+ ghWndMain,
+ (DLGPROC)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,
+ (DLGPROC)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_DRAWITEM:
+ {
+ LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
+ BOOL fHighlighted = (SendDlgItemMessage(
+ ghWndMain,
+ lpdis->CtlID,
+ BM_GETSTATE,
+ 0,
+ 0
+ ) & 0x0004);
+
+ DrawButton(lpdis->hDC, lpdis->rcItem, fHighlighted);
+ DrawButtonText(
+ lpdis->hDC,
+ lpdis->rcItem,
+ fHighlighted,
+ lpdis->CtlID
+ );
+ return TRUE;
+ }
+
+
+ case WM_CTLCOLORLISTBOX:
+ case WM_CTLCOLORBTN:
+ case WM_CTLCOLORSTATIC:
+ SetBkColor((HDC)wParam, GetSysColor(COLOR_BTNFACE));
+ return (BOOL)GetSysColorBrush( COLOR_3DFACE );
+
+
+ default:
+ ;
+ // return DefDlgProc( hwnd, msg, wParam, lParam );
+ // return DefWindowProc( hwnd, msg, wParam, lParam );
+
+
+ } // switch (msg) { ... }
+
+ return FALSE;
+ }
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+VOID AddToRedialList( LPCSTR 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 = 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 ( LPCSTR szNumber, LPCSTR szName )
+{
+ HLINE hLine = NULL;
+
+ DWORD errCode;
+
+ // struct size info
+ DWORD dwLTPSize = sizeof ( LINETRANSLATEOUTPUT );
+ DWORD dwNameLen = lstrlen( szName ) + 1;
+ DWORD dwLCPSize = sizeof( LINECALLPARAMS );
+
+ LPLINETRANSLATEOUTPUT lpTransOut = NULL;
+ LPLINECALLPARAMS lpLineCallParams = NULL;
+
+ char 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 (
+ (LPSTR) lpLineCallParams + sizeof(LINECALLPARAMS),
+ szName
+ );
+ }
+
+ lpLineCallParams-> dwDisplayableAddressSize = lpTransOut-> dwDisplayableStringSize;
+ lpLineCallParams-> dwDisplayableAddressOffset = sizeof( LINECALLPARAMS ) + dwNameLen;
+
+ lstrcpy (
+ (LPSTR) lpLineCallParams + sizeof(LINECALLPARAMS) + dwNameLen,
+ (LPSTR) lpTransOut + lpTransOut-> dwDisplayableStringOffset
+ );
+
+
+ // save dialing information
+ // Free old allocs.
+ if ( gszCurrentName )
+ {
+ DialerFree ( gszCurrentName );
+ }
+
+ if ( gszCurrentNumber )
+ {
+ DialerFree ( gszCurrentNumber );
+ }
+
+ // save new stuff
+ gszCurrentName = (LPSTR) DialerAlloc( dwNameLen );
+ if ( !gszCurrentName )
+ {
+ errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK );
+ goto error;
+ }
+ lstrcpy ( gszCurrentName, szName );
+
+ gszCurrentNumber = (LPSTR) DialerAlloc( lpTransOut-> dwDisplayableStringSize );
+ if ( !gszCurrentNumber )
+ {
+ errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK );
+ goto error;
+ }
+ lstrcpy (
+ gszCurrentNumber,
+ (LPSTR) lpTransOut + lpTransOut-> dwDisplayableStringOffset
+ );
+
+ gCurrentLineInfo.hLine = hLine;
+ ghCall = NULL;
+
+
+ // finally make the call.
+ gMakeCallRequestID = 0;
+
+ gMakeCallRequestID = lineMakeCall (
+ hLine,
+ &ghCall,
+ (LPSTR) 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,
+ (DLGPROC)DialingProc,
+ 0
+ );
+
+ }
+
+ else
+ {
+ if ( gMakeCallRequestID == LINEERR_CALLUNAVAIL )
+ {
+ DialogBoxParam (
+ ghInst,
+ MAKEINTRESOURCE(IDD_CALLFAILED),
+ ghWndMain,
+ (DLGPROC)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;
+
+ LPSTR pszLineName = NULL;
+ LPLINEDEVCAPS lpDevCaps = NULL;
+
+
+ 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 = (LPSTR) DialerAlloc( MAXBUFSIZE );
+ if ( !pszLineName )
+ {
+ errCode = LINEERR_NOMEM;
+ goto error;
+ }
+
+ if ( lpDevCaps->dwLineNameSize > 0 )
+ {
+ if ( lpDevCaps-> dwLineNameSize > (MAXBUFSIZE - 1) )
+ {
+ strncpy (
+ pszLineName,
+ (LPSTR) lpDevCaps + lpDevCaps->dwLineNameOffset,
+ MAXBUFSIZE - 1
+ );
+ pszLineName[ MAXBUFSIZE - 1 ] = '\0';
+ }
+ else
+ {
+ lstrcpy( pszLineName, (LPSTR) lpDevCaps + lpDevCaps-> dwLineNameOffset );
+ }
+ }
+ else
+ {
+ wsprintf ( pszLineName, "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;
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+LPSTR GetAddressName(DWORD iLine, DWORD iAddress)
+{
+ DWORD errCode = 0;
+ DWORD dwNeededSize = 0;
+ LPSTR 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( ghWndMain, 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 );
+ if ( !pszAddressName )
+ {
+ goto error;
+ }
+
+ if ( lpAddressCaps-> dwAddressSize > 0 )
+ {
+ // keep string length bounded
+ if ( lpAddressCaps-> dwAddressSize > (MAXBUFSIZE - 1 ) )
+ {
+ strncpy(
+ pszAddressName,
+ (LPSTR) lpAddressCaps + lpAddressCaps->dwAddressOffset,
+ MAXBUFSIZE - 1
+ );
+ pszAddressName[ MAXBUFSIZE - 1] = '\0';
+ }
+ else
+ {
+ lstrcpy (
+ pszAddressName,
+ (LPSTR) lpAddressCaps + lpAddressCaps->dwAddressOffset
+ );
+ }
+ }
+ else
+ // use default name
+ {
+ wsprintf(pszAddressName, "Address %d", iAddress);
+ }
+
+error:
+ if ( lpAddressCaps )
+ {
+ DialerFree( lpAddressCaps );
+ }
+
+ return pszAddressName;
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+BOOL CALLBACK DialingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+
+ switch(msg)
+ {
+ char 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:
+ //gfDropping = TRUE;
+
+ // 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;
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+BOOL CALLBACK AboutProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ return TRUE;
+ }
+
+ case WM_CLOSE:
+ EndDialog(hwnd, TRUE);
+ return TRUE;
+
+ case WM_COMMAND:
+ if(LOWORD((DWORD)wParam) == IDOK)
+ {
+ EndDialog(hwnd, TRUE);
+ return TRUE;
+ }
+
+ break;
+ }
+
+ return FALSE;
+
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+BOOL 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,
+ (DWORD)(LPVOID)aMenuHelpIDs
+ );
+ return TRUE;
+
+ case WM_CONTEXTMENU:
+ // processes right-clicks on controls
+ WinHelp (
+ (HWND)wParam,
+ gszHELPfilename,
+ HELP_CONTEXTMENU,
+ (DWORD)(LPVOID)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 (
+ "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;
+ char szBuffer[MAXBUFSIZE];
+ DWORD dwPriority;
+
+ // Update line
+ hwndBox = GetDlgItem( hwnd, IDD_CULISTLINE );
+ giCurrentLine = SendMessage (
+ hwndBox,
+ CB_GETITEMDATA,
+ SendMessage( hwndBox, CB_GETCURSEL, 0, 0 ),
+ 0
+ );
+
+ // base 10
+ itoa( gdwPLID[giCurrentLine], szBuffer, 10 );
+ WritePrivateProfileString (
+ "Preference",
+ "Preferred Line",
+ szBuffer,
+ gszINIfilename
+ );
+
+
+ // Update address
+ hwndBox = GetDlgItem( hwnd, IDD_CULISTADDRESS );
+ giCurrentAddress = SendMessage (
+ hwndBox,
+ CB_GETITEMDATA,
+ SendMessage(hwndBox, CB_GETCURSEL, 0, 0),
+ 0
+ );
+
+ itoa( giCurrentAddress, szBuffer, 10 );
+ WritePrivateProfileString (
+ "Preference",
+ "Preferred Address",
+ szBuffer,
+ gszINIfilename
+ );
+
+
+ // Update application priority
+ if ( SendDlgItemMessage (
+ hwnd,
+ IDD_CUSIMPLETAPICHKBOX,
+ BM_GETCHECK,
+ 0,
+ 0L
+ )
+ == 0)
+ {
+ dwPriority = 0;
+ }
+ else
+ {
+ dwPriority = 1;
+ }
+
+ lineSetAppPriority (
+ "DIALER.EXE",
+ 0,
+ NULL,
+ LINEREQUESTMODE_MAKECALL,
+ NULL,
+ dwPriority
+ );
+
+ EndDialog(hwnd, TRUE);
+ return TRUE;
+ }
+
+ case IDCANCEL:
+ EndDialog(hwnd, FALSE);
+ return TRUE;
+ }
+ }
+
+ default:
+ ;
+
+ }
+
+ return FALSE;
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+BOOL CALLBACK LineInUseProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+ {
+ LPARAM lNewParam = 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;
+ }
+ return TRUE;
+ }
+
+ case WM_COMMAND:
+ if(LOWORD((DWORD)wParam) == IDOK)
+ {
+ EndDialog(hwnd, TRUE);
+ return TRUE;
+ }
+ break;
+
+ default:
+ ;
+// return DefDlgProc( hwnd, msg, wParam, lParam );
+
+ }
+
+
+ ptStr = DialerAlloc( MAXBUFSIZE );
+
+ LoadString( ghInst, lNewParam, ptStr, MAXBUFSIZE );
+
+ SetDlgItemText(
+ hwnd,
+ IDD_CFTEXT,
+ ptStr
+ );
+
+ DialerFree( ptStr );
+
+
+ return FALSE;
+ }
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+BOOL 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][TAPIMAXDESTADDRESSSIZE];
+
+ switch(msg)
+ {
+ case WM_HELP:
+ // processes clicks on controls when
+ // context mode help is selected
+ WinHelp(
+ ((LPHELPINFO)lParam)->hItemHandle,
+ gszHELPfilename,
+ HELP_WM_HELP,
+ (DWORD)(LPVOID)aMenuHelpIDs
+ );
+ return TRUE;
+
+ case WM_CONTEXTMENU: // processes right-clicks on controls
+ WinHelp(
+ (HWND)wParam,
+ gszHELPfilename,
+ HELP_CONTEXTMENU,
+ (DWORD)(LPVOID)aMenuHelpIDs
+ );
+ return TRUE;
+
+ case WM_INITDIALOG:
+ {
+ DWORD cSDEntry;
+ DWORD idFirstEmpty = (DWORD) -1;
+
+ char szName[TAPIMAXCALLEDPARTYSIZE];
+ char szTemp[TAPIMAXCALLEDPARTYSIZE];
+ char szFieldName[MAXBUFSIZE];
+
+ // Retrieve speed dial info from INI file
+ for(cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry)
+ {
+ wsprintf(szFieldName, "Name%d", cSDEntry);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ szSDName[ cSDEntry ],
+ TAPIMAXCALLEDPARTYSIZE - 1,
+ gszINIfilename
+ );
+
+ // set the first empty speed dial button
+ if ( idFirstEmpty == -1 &&
+ szSDName[ cSDEntry ][0] == '\0' &&
+ gszSDNumber[ cSDEntry ][ 0 ] == '\0' )
+ idFirstEmpty = cSDEntry;
+
+ wsprintf(szFieldName, "Number%d", cSDEntry);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ gszSDNumber[cSDEntry],
+ MAXBUFSIZE - 1,
+ gszINIfilename
+ );
+
+ // get a copy of the name for editing
+ // if name is empty, use the number as the
+ // name.
+ if ( lstrcmp( gszNULL, szSDName[ cSDEntry ] ) )
+ {
+ lstrcpy( szName, szSDName[ cSDEntry] );
+ }
+ else
+ {
+ lstrcpy( szName, gszSDNumber[ cSDEntry ] );
+ }
+
+ FitTextToButton( hwnd, IDD_SD1SPEEDDIAL1 + cSDEntry - 1, szName );
+ AmpersandCompensate( szName, szTemp );
+
+ SetDlgItemText (
+ hwnd,
+ IDD_SD1SPEEDDIAL1 + cSDEntry - 1,
+ (LPCSTR) szTemp
+ );
+
+ }
+
+ // 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,
+ (LPCSTR) szSDName[ 1 ]
+ );
+
+ SetDlgItemText(
+ hwnd,
+ IDD_SD1EDITNUMBER,
+ (LPCSTR) gszSDNumber[ 1 ]
+ );
+ }
+ else
+ {
+ nCurrentSpeedDial = idFirstEmpty;
+ }
+
+ SetFocus( GetDlgItem( hwnd, IDD_SD1EDITNAME ) );
+ return FALSE;
+ }
+
+ case WM_COMMAND:
+ {
+ char szName[TAPIMAXCALLEDPARTYSIZE];
+ char szTemp[ TAPIMAXCALLEDPARTYSIZE ];
+
+ switch( LOWORD( (DWORD) wParam ) )
+ {
+ case IDOK:
+ {
+ DWORD cSDEntry;
+ char szFieldName[MAXBUFSIZE];
+
+ // save new speed dial settings
+ for ( cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry )
+ {
+ wsprintf(szFieldName, "Name%d", cSDEntry);
+ WritePrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ szSDName [cSDEntry],
+ gszINIfilename
+ );
+
+ wsprintf(szFieldName, "Number%d", cSDEntry);
+ WritePrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszSDNumber[cSDEntry],
+ gszINIfilename
+ );
+
+ // set the text for the corresponding
+ // main window button
+ if ( szSDName[ cSDEntry ][ 0 ] == '\0' )
+ {
+ lstrcpy( szName, gszSDNumber[ cSDEntry ] );
+ }
+ else
+ {
+ lstrcpy( szName, szSDName[ cSDEntry ] );
+ }
+
+ FitTextToButton(
+ ghWndMain,
+ IDD_DSPEEDDIAL1 + cSDEntry - 1,
+ szName
+ );
+
+ AmpersandCompensate( szName, szTemp );
+ SetDlgItemText (
+ ghWndMain,
+ IDD_DSPEEDDIAL1 + cSDEntry - 1,
+ (LPCSTR) szTemp
+ );
+ }
+
+ 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 )
+ {
+
+ GetDlgItemText (
+ hwnd,
+ IDD_SD1EDITNAME,
+ szName,
+ TAPIMAXCALLEDPARTYSIZE
+ );
+
+ // if there is no name, label the button with
+ // the number
+ if ( szName[ 0 ] == '\0' )
+ {
+ szSDName[ nCurrentSpeedDial ][ 0 ] = '\0';
+ lstrcpy( szName, gszSDNumber[ nCurrentSpeedDial ] );
+ }
+ else
+ {
+ lstrcpy( szSDName[ nCurrentSpeedDial ], szName );
+ }
+
+ FitTextToButton (
+ hwnd,
+ IDD_SD1SPEEDDIAL1 + nCurrentSpeedDial - 1,
+ szName
+ );
+ AmpersandCompensate( szName, 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 ] == '\0' )
+ {
+ SetDlgItemText (
+ hwnd,
+ IDD_SD1SPEEDDIAL1 + nCurrentSpeedDial - 1,
+ szName
+ );
+
+ }
+ }
+ }
+ break;
+ } // switch(LOWORD((DWORD)wParam))
+ break;
+
+ } // case WM_COMMAND:
+
+ default:
+ ;
+
+ } // switch(msg)
+
+ return FALSE;
+}
+
+
+
+//***************************************************************************
+//***************************************************************************
+//***************************************************************************
+BOOL 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,
+ (DWORD)(LPVOID)aMenuHelpIDs
+ );
+ return TRUE;
+
+ case WM_CONTEXTMENU:
+ // processes right-clicks on controls
+ WinHelp (
+ (HWND)wParam,
+ gszHELPfilename,
+ HELP_CONTEXTMENU,
+ (DWORD)(LPVOID)aMenuHelpIDs
+ );
+ return TRUE;
+
+ case WM_INITDIALOG:
+ {
+ char szFieldName [MAXBUFSIZE];
+ char szName [TAPIMAXCALLEDPARTYSIZE];
+
+ nCurrentSpeedDial = LOWORD( lParam ) - IDD_DSPEEDDIAL1 + 1;
+
+ // retrieve speed dial button info
+ wsprintf(szFieldName, "Name%d", nCurrentSpeedDial);
+ GetPrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszNULL,
+ szName,
+ TAPIMAXCALLEDPARTYSIZE - 1,
+ gszINIfilename
+ );
+ 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:
+ {
+ char szName[ TAPIMAXCALLEDPARTYSIZE ];
+ char szTemp[ TAPIMAXCALLEDPARTYSIZE ];
+ char szFieldName[MAXBUFSIZE];
+
+ switch ( LOWORD( (DWORD) wParam ) )
+ {
+ case IDOK:
+ case IDD_SD2SAVEANDDIAL:
+ {
+ GetDlgItemText (
+ hwnd,
+ IDD_SD2EDITNAME,
+ (LPTSTR) szName,
+ TAPIMAXCALLEDPARTYSIZE
+ );
+
+ GetDlgItemText (
+ hwnd,
+ IDD_SD2EDITNUMBER,
+ (LPTSTR) gszSDNumber[nCurrentSpeedDial],
+ TAPIMAXCALLEDPARTYSIZE
+ );
+
+ wsprintf ( szFieldName, "Name%d", nCurrentSpeedDial );
+
+ WritePrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ szName,
+ gszINIfilename
+ );
+
+ wsprintf ( szFieldName, "Number%d", nCurrentSpeedDial );
+ WritePrivateProfileString (
+ "Speed Dial Settings",
+ szFieldName,
+ gszSDNumber[nCurrentSpeedDial],
+ gszINIfilename
+ );
+
+ // update main window buttons
+ // is only number has been entered, label button with it.
+ if ( szName[ 0 ] == '\0' )
+ {
+ lstrcpy( szName, gszSDNumber[ nCurrentSpeedDial ] );
+ }
+
+ FitTextToButton (
+ ghWndMain,
+ IDD_DSPEEDDIAL1 + nCurrentSpeedDial - 1,
+ (LPSTR) szName
+ );
+
+ AmpersandCompensate( szName, szTemp );
+
+ SetDlgItemText (
+ ghWndMain,
+ IDD_DSPEEDDIAL1 + nCurrentSpeedDial - 1,
+ (LPCSTR)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
+ )
+ );
+ }
+ 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 = NULL;
+ }
+ 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,
+ (DLGPROC)LineInUseProc,
+ LineDisconnectMode
+ );
+ break;
+ }
+ }
+ break;
+
+
+ case LINE_CLOSE:
+ if ( gCurrentLineInfo.hLine == (HLINE)hDevice )
+ {
+ errString(ghWndMain, ERR_LINECLOSE, MB_ICONEXCLAMATION | MB_OK );
+ gCurrentLineInfo.hLine = NULL;
+ 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,
+ (DLGPROC)LineInUseProc,
+ 0
+ );
+ }
+ else
+ {
+ errString ( ghWndMain, dwParam2, MB_ICONEXCLAMATION | MB_OK );
+ }
+
+ ghCall = NULL;
+ DialerLineClose();
+ gfCurrentLineAvail = TRUE;
+ }
+
+ gfMakeCallReplyPending = FALSE;
+ }
+
+ // reply from lineDrop()
+ if ( (LONG) dwParam1 == gDropCallRequestID )
+ {
+ //gfDropping = FALSE;
+
+ // 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 = NULL;
+ }
+ }
+ 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 = SendMessage (
+ hwndLineBox,
+ CB_ADDSTRING,
+ 0,
+ (LPARAM)(LPCSTR)(lpLineInfo[iLine].szLineName)
+ );
+
+ // error, bail out.
+ if ( iItem == CB_ERR || iItem == CB_ERRSPACE )
+ {
+ if (lpLineInfo)
+ {
+ DialerFree(lpLineInfo);
+ }
+
+ return FALSE;
+ }
+
+ errCode = 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;
+ LPSTR pszAddressName;
+
+ if ( SendMessage( hwndLineBox, CB_GETCOUNT, 0, 0 ) == 0 )
+ {
+ return FALSE;
+ }
+
+ // select current entry in line box
+ iLineBoxCurrent = 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 = SendMessage (
+ hwndAddressBox,
+ CB_ADDSTRING,
+ 0,
+ (LPARAM) (LPCSTR) (pszAddressName)
+ );
+
+ // error, bail out
+ if ( iItem == CB_ERR || iItem == CB_ERRSPACE )
+ return FALSE;
+
+ errCode = 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;
+ LPLINEREQMAKECALL lpRequestBuffer;
+
+ lpRequestBuffer = (LPLINEREQMAKECALL) 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,
+ (DLGPROC) 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 = NULL;
+ }
+
+
+ // 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 );
+ if ( NULL == ptStrTitle )
+ {
+ // Now, _this_ is a problem.
+ return 0;
+ }
+
+ ptStrError = DialerAlloc( MAXBUFSIZE );
+ 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;
+
+ 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 ) )
+ {
+#if DBG
+ TCHAR buf[200];
+ wsprintf( buf, "Cannot load string: hinst:0x%08lx errcode: %ld", (DWORD)ghInst,(DWORD)errCode);
+ OutputDebugString( buf );
+ MessageBox( NULL, buf, "Dialer", MB_OK);
+#endif
+
+ 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, LPSTR 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;
+ char 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 ] = 'X';
+ buf [ nLen + 1 ] = '\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 ] = 'X';
+ buf [ i + 2 ] = '\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] = '\0';
+ lstrcat( szName, "..." );
+ }
+
+ } 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;
+ LPSTR lpDialDigits = (LPSTR)lpTransOut + lpTransOut-> dwDialableStringOffset;
+ char sz3Pref [ 4 ] = "";
+
+
+ // 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 ] = '\0';
+ if ( j == 3 )
+ break;
+ }
+ }
+
+ if ( !lstrcmp( sz3Pref, "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 ( LPCSTR szNumber, LPSTR szCanNumber )
+{
+ char szDigits [ TAPIMAXDESTADDRESSSIZE ];
+ char szPref [ TAPIMAXDESTADDRESSSIZE ];
+
+ BOOL bRes = FALSE;
+
+ 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;
+ }
+
+ lpTransOut-> dwTotalSize = dwSize;
+ errCode = lineTranslateAddress (
+ ghLineApp,
+ giCurrentLine,
+ gCurrentLineInfo.dwAPIVersion,
+ szNumber,
+ 0,
+ 0,
+ lpTransOut
+ );
+ 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 = strcspn ( szNumber, "|" );
+ strncpy( szPref, szNumber, nLenPref );
+ szPref[ nLenPref ] = '\0';
+
+ // if string is not composed entirely of digits
+ // and allowable formating characters, quit conversion
+ if ( strspn( szPref, " 0123456789()-." ) != (size_t) nLenPref )
+ goto error;
+
+ // collect digits ignoring formating characters.
+ szDigits[ 0 ] = '\0';
+ for ( i = 0, nLenDigits = 0; i < nLenPref; i++ )
+ {
+ if ( ISDIGIT( szNumber[ i ] ) )
+ {
+ szDigits[ nLenDigits++ ] = szNumber[ i ];
+ }
+ }
+ szDigits[ nLenDigits ] = '\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 ] == '0' || szDigits[ 0 ] == '1' )
+ {
+ nLenDigits--;
+ memmove( szDigits, &(szDigits[1]), nLenDigits );
+ szDigits[ nLenDigits ] = '\0';
+
+ cPos = strcspn( szPref, "01" );
+ nLenPref--;
+ memmove( &(szPref[ cPos ]), &(szPref[ cPos + 1 ]), nLenPref - cPos );
+ szPref[ nLenPref ] = '\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 ] == '0' || szDigits[ 0 ] == '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) ( (LPSTR) 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 ]= '\0';
+ lstrcat( szCanNumber, "+1 (" );
+ lstrcat( szCanNumber, (LPSTR) lpTransCaps + lpLocLst[ dwInd ].dwCityCodeOffset );
+ lstrcat( szCanNumber, ") " );
+ lstrcat( szCanNumber, szDigits );
+
+ cPos = strcspn( szNumber, "|" );
+ 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 ] == '0' || szDigits[ 0 ] == '1' )
+ {
+ nLenDigits--;
+ memmove( szDigits, &(szDigits[1]), nLenDigits );
+ szDigits[ nLenDigits ] = '\0';
+
+ cPos = strcspn( szPref, "01" );
+ nLenPref--;
+ memmove( &(szPref[ cPos ]), &(szPref[ cPos + 1 ]), nLenPref - cPos );
+ szPref[ nLenPref ] = '\0';
+ }
+ else
+ {
+ goto error;
+ }
+
+ }
+
+ case LONG_DISTANCE_NUMBER:
+ {
+ // if first or fourth digit is 0/1, illegal number
+ if ( szDigits[ 0 ] == '0' || szDigits[ 0 ] == '1' ||
+ szDigits[ 3 ] == '0' || szDigits[ 3 ] == '1' )
+ {
+ goto error;
+ }
+
+ szCanNumber[ 0 ] = '\0';
+ lstrcat( szCanNumber, "+1 (" );
+ strncat( szCanNumber, szDigits, 3 );
+ lstrcat( szCanNumber, ") " );
+
+ 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 ( LPCSTR lpszSrc, LPSTR 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 ] == '&' )
+ {
+ lpszDst[ cInd++ ] = '&';
+ }
+ lpszDst[ cInd ] = lpszSrc[ cCnt ];
+
+ if ( lpszSrc[ cCnt ] == '\0' )
+ break;
+ }
+
+ // make sure string is null terminated.
+ lpszDst[ TAPIMAXCALLEDPARTYSIZE - 1 ] = '\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 ( LPCSTR lpszSrc, LPSTR 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 ] == '&' ) &&
+ ( lpszSrc[ cInd + 1 ] == '&' ) )
+ {
+ cInd++;
+ }
+ lpszDst[ cCnt ] = lpszSrc[ cInd ] ;
+
+ if ( lpszSrc [ cInd ] == '\0' )
+ {
+ break;
+ }
+ }
+
+ lpszDst[ TAPIMAXCALLEDPARTYSIZE - 1 ] = '\0';
+
+ return;
+ }
diff --git a/private/tapi/dev/apps/dialer/nextver/dialer.def b/private/tapi/dev/apps/dialer/nextver/dialer.def
new file mode 100644
index 000000000..b40ab0af1
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/nextver/dialer.def
@@ -0,0 +1,9 @@
+NAME DIALER
+;STUB 'WINSTUB.EXE'
+CODE PRELOAD MOVEABLE DISCARDABLE
+DATA PRELOAD MOVEABLE MULTIPLE
+HEAPSIZE 2048
+STACKSIZE 8192
+
+EXPORTS
+ MainWndProc
diff --git a/private/tapi/dev/apps/dialer/nextver/dialer.h b/private/tapi/dev/apps/dialer/nextver/dialer.h
new file mode 100644
index 000000000..6f5832862
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/nextver/dialer.h
@@ -0,0 +1,51 @@
+/*++ BUILD Version: 0001 // Increment this if a change has global effects
+
+Copyright (c) 1995 Microsoft Corporation
+
+Module Name:
+
+ dialer.h
+
+Abstract:
+
+ Header file for dialer
+
+Author:
+
+ Dan Knudson (DanKn) 05-Apr-1995
+
+Revision History:
+
+ Jeremy Horwitz (t-jereh) 30-May-1995
+
+--*/
+
+
+#define TAPI_VERSION_1_0 0x00010003
+#define TAPI_VERSION_1_4 0x00010004
+#define TAPI_VERSION_2_0 0x00020000
+#define TAPI_CURRENT_VERSION TAPI_VERSION_2_0
+
+#include <windows.h>
+#include "tapi.h"
+#include "resource.h"
+#include "dialhelp.h"
+
+
+#define MENU_CHOICE 1 // for Connect Using dialog...
+#define INVALID_LINE 2 // if INVALID_LINE, turn off CANCEL
+ // button and add extra text...
+
+#define MAXNUMLENGTH 64
+#define MAXBUFSIZE 256
+#define NSPEEDDIALS 8 // Dialer supports 8 configurable speed dial entries.
+#define NLASTDIALED 20 // Dialer keeps track of the 20 last dialed numbers.
+
+#define ERR_NONE 0
+#define ERR_NOVOICELINE 1
+#define ERR_LINECLOSE 2
+#define ERR_NOLINES 3
+#define ERR_911WARN 4
+#define ERR_NEWDEFAULT 5
+
+#define itoa(x,y,z) _itoa(x,y,z)
diff --git a/private/tapi/dev/apps/dialer/nextver/dialer.ico b/private/tapi/dev/apps/dialer/nextver/dialer.ico
new file mode 100644
index 000000000..44ccbca29
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/nextver/dialer.ico
Binary files differ
diff --git a/private/tapi/dev/apps/dialer/nextver/dialer.mak b/private/tapi/dev/apps/dialer/nextver/dialer.mak
new file mode 100644
index 000000000..3c4a04bea
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/nextver/dialer.mak
@@ -0,0 +1,389 @@
+# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+# TARGTYPE "Win32 (MIPS) Application" 0x0501
+
+!IF "$(CFG)" == ""
+CFG=Win32 (80x86) Debug
+!MESSAGE No configuration specified. Defaulting to Win32 (80x86) Debug.
+!ENDIF
+
+!IF "$(CFG)" != "Win32 (80x86) Release" && "$(CFG)" != "Win32 (80x86) Debug" &&\
+ "$(CFG)" != "Win32 (MIPS) Debug" && "$(CFG)" != "Win32 (MIPS) Release"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE on this makefile
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "dialer.mak" CFG="Win32 (80x86) Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Win32 (80x86) Release" (based on "Win32 (x86) Application")
+!MESSAGE "Win32 (80x86) Debug" (based on "Win32 (x86) Application")
+!MESSAGE "Win32 (MIPS) Debug" (based on "Win32 (MIPS) Application")
+!MESSAGE "Win32 (MIPS) Release" (based on "Win32 (MIPS) Application")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+################################################################################
+# Begin Project
+# PROP Target_Last_Scanned "Win32 (MIPS) Debug"
+
+!IF "$(CFG)" == "Win32 (80x86) Release"
+
+# PROP BASE Use_MFC 2
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "WinRel"
+# PROP BASE Intermediate_Dir "WinRel"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "WinRel"
+# PROP Intermediate_Dir "WinRel"
+OUTDIR=.\WinRel
+INTDIR=.\WinRel
+
+ALL : $(OUTDIR)/dialer.exe $(OUTDIR)/dialer.bsc
+
+$(OUTDIR) :
+ if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
+
+MTL=MkTypLib.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /win32
+MTL_PROJ=/nologo /D "NDEBUG" /win32
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /W3 /GX /YX /O2 /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c
+# ADD CPP /nologo /W3 /GX /YX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /c
+CPP_PROJ=/nologo /W3 /GX /YX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D\
+ "_MBCS" /FR$(INTDIR)/ /Fp$(OUTDIR)/"dialer.pch" /Fo$(INTDIR)/ /c
+CPP_OBJS=.\WinRel/
+
+.c{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+RSC_PROJ=/l 0x409 /fo$(INTDIR)/"DIALER.res" /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# SUBTRACT BASE BSC32 /Iu
+# ADD BSC32 /nologo
+# SUBTRACT BSC32 /Iu
+BSC32_FLAGS=/nologo /o$(OUTDIR)/"dialer.bsc"
+BSC32_SBRS= \
+ $(INTDIR)/DIALER.SBR
+
+$(OUTDIR)/dialer.bsc : $(OUTDIR) $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+# ADD BASE LINK32 user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib mfc30.lib mfco30.lib mfcd30.lib /NOLOGO /SUBSYSTEM:windows /MACHINE:I386
+# ADD LINK32 tapi32.lib version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /MACHINE:I386
+LINK32_FLAGS=tapi32.lib version.lib kernel32.lib user32.lib gdi32.lib\
+ winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\
+ uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /INCREMENTAL:no\
+ /PDB:$(OUTDIR)/"dialer.pdb" /MACHINE:I386 /OUT:$(OUTDIR)/"dialer.exe"
+DEF_FILE=
+LINK32_OBJS= \
+ $(INTDIR)/DIALER.res \
+ $(INTDIR)/DIALER.OBJ
+
+$(OUTDIR)/dialer.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "Win32 (80x86) Debug"
+
+# PROP BASE Use_MFC 2
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "WinDebug"
+# PROP BASE Intermediate_Dir "WinDebug"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "WinDebug"
+# PROP Intermediate_Dir "WinDebug"
+OUTDIR=.\WinDebug
+INTDIR=.\WinDebug
+
+ALL : $(OUTDIR)/dialer.exe $(OUTDIR)/dialer.bsc
+
+$(OUTDIR) :
+ if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
+
+MTL=MkTypLib.exe
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /win32
+MTL_PROJ=/nologo /D "_DEBUG" /win32
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c
+# ADD CPP /nologo /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /c
+CPP_PROJ=/nologo /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D\
+ "_MBCS" /FR$(INTDIR)/ /Fp$(OUTDIR)/"dialer.pch" /Fo$(INTDIR)/\
+ /Fd$(OUTDIR)/"dialer.pdb" /c
+CPP_OBJS=.\WinDebug/
+
+.c{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+RSC_PROJ=/l 0x409 /fo$(INTDIR)/"DIALER.res" /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# SUBTRACT BASE BSC32 /Iu
+# ADD BSC32 /nologo
+# SUBTRACT BSC32 /Iu
+BSC32_FLAGS=/nologo /o$(OUTDIR)/"dialer.bsc"
+BSC32_SBRS= \
+ $(INTDIR)/DIALER.SBR
+
+$(OUTDIR)/dialer.bsc : $(OUTDIR) $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+# ADD BASE LINK32 user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib mfc30d.lib mfco30d.lib mfcd30d.lib /NOLOGO /SUBSYSTEM:windows /DEBUG /MACHINE:I386
+# ADD LINK32 tapi32.lib version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /DEBUG /MACHINE:I386
+LINK32_FLAGS=tapi32.lib version.lib kernel32.lib user32.lib gdi32.lib\
+ winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\
+ uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /INCREMENTAL:yes\
+ /PDB:$(OUTDIR)/"dialer.pdb" /DEBUG /MACHINE:I386 /OUT:$(OUTDIR)/"dialer.exe"
+DEF_FILE=
+LINK32_OBJS= \
+ $(INTDIR)/DIALER.res \
+ $(INTDIR)/DIALER.OBJ
+
+$(OUTDIR)/dialer.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "Win32 (MIPS) Debug"
+
+# PROP BASE Use_MFC 2
+# PROP BASE Use_Debug_Libraries 1
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "WinDebug"
+# PROP Intermediate_Dir "WinDebug"
+OUTDIR=.\WinDebug
+INTDIR=.\WinDebug
+
+ALL : $(OUTDIR)/dialer.exe $(OUTDIR)/dialer.bsc
+
+$(OUTDIR) :
+ if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
+
+MTL=MkTypLib.exe
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /win32
+MTL_PROJ=/nologo /D "_DEBUG" /win32
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /Gt0 /QMOb2000 /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c
+# ADD CPP /nologo /Gt0 /QMOb2000 /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "WIN32" /FR /c
+CPP_PROJ=/nologo /Gt0 /QMOb2000 /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "_WINDOWS"\
+ /D "_MBCS" /D "WIN32" /FR$(INTDIR)/ /Fp$(OUTDIR)/"dialer.pch" /Fo$(INTDIR)/\
+ /Fd$(OUTDIR)/"dialer.pdb" /c
+CPP_OBJS=.\WinDebug/
+
+.c{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+RSC_PROJ=/l 0x409 /fo$(INTDIR)/"dialer.res" /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# SUBTRACT BASE BSC32 /Iu
+# ADD BSC32 /nologo
+# SUBTRACT BSC32 /Iu
+BSC32_FLAGS=/nologo /o$(OUTDIR)/"dialer.bsc"
+BSC32_SBRS= \
+ $(INTDIR)/dialer.sbr
+
+$(OUTDIR)/dialer.bsc : $(OUTDIR) $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+# ADD BASE LINK32 user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib odbc32.lib mfc30d.lib mfco30d.lib mfcd30d.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /DEBUG /MACHINE:MIPS
+# ADD LINK32 version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /DEBUG /MACHINE:MIPS
+LINK32_FLAGS=version.lib kernel32.lib user32.lib gdi32.lib winspool.lib\
+ comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO\
+ /SUBSYSTEM:windows /PDB:$(OUTDIR)/"dialer.pdb" /DEBUG /MACHINE:MIPS\
+ /OUT:$(OUTDIR)/"dialer.exe"
+DEF_FILE=
+LINK32_OBJS= \
+ $(INTDIR)/dialer.res \
+ $(INTDIR)/dialer.obj
+
+$(OUTDIR)/dialer.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "Win32 (MIPS) Release"
+
+# PROP BASE Use_MFC 2
+# PROP BASE Use_Debug_Libraries 0
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "WinRel"
+# PROP Intermediate_Dir "WinRel"
+OUTDIR=.\WinRel
+INTDIR=.\WinRel
+
+ALL : $(OUTDIR)/dialer.exe $(OUTDIR)/dialer.bsc
+
+$(OUTDIR) :
+ if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
+
+MTL=MkTypLib.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /win32
+MTL_PROJ=/nologo /D "NDEBUG" /win32
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /Gt0 /QMOb2000 /W3 /GX /YX /O2 /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c
+# ADD CPP /nologo /Gt0 /QMOb2000 /W3 /GX /YX /O2 /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "WIN32" /FR /c
+CPP_PROJ=/nologo /Gt0 /QMOb2000 /W3 /GX /YX /O2 /D "NDEBUG" /D "_WINDOWS" /D\
+ "_MBCS" /D "WIN32" /FR$(INTDIR)/ /Fp$(OUTDIR)/"dialer.pch" /Fo$(INTDIR)/ /c
+CPP_OBJS=.\WinRel/
+
+.c{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+RSC_PROJ=/l 0x409 /fo$(INTDIR)/"dialer.res" /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# SUBTRACT BASE BSC32 /Iu
+# ADD BSC32 /nologo
+# SUBTRACT BSC32 /Iu
+BSC32_FLAGS=/nologo /o$(OUTDIR)/"dialer.bsc"
+BSC32_SBRS= \
+ $(INTDIR)/dialer.sbr
+
+$(OUTDIR)/dialer.bsc : $(OUTDIR) $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+# ADD BASE LINK32 user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib odbc32.lib mfc30.lib mfco30.lib mfcd30.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /MACHINE:MIPS
+# ADD LINK32 version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /MACHINE:MIPS
+LINK32_FLAGS=version.lib kernel32.lib user32.lib gdi32.lib winspool.lib\
+ comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO\
+ /SUBSYSTEM:windows /PDB:$(OUTDIR)/"dialer.pdb" /MACHINE:MIPS\
+ /OUT:$(OUTDIR)/"dialer.exe"
+DEF_FILE=
+LINK32_OBJS= \
+ $(INTDIR)/dialer.res \
+ $(INTDIR)/dialer.obj
+
+$(OUTDIR)/dialer.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF
+
+################################################################################
+# Begin Group "Source Files"
+
+################################################################################
+# Begin Source File
+
+SOURCE=.\DIALER.RC
+DEP_DIALE=\
+ .\dialer.ico
+
+!IF "$(CFG)" == "Win32 (80x86) Release"
+
+$(INTDIR)/DIALER.res : $(SOURCE) $(DEP_DIALE) $(INTDIR)
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+!ELSEIF "$(CFG)" == "Win32 (80x86) Debug"
+
+$(INTDIR)/DIALER.res : $(SOURCE) $(DEP_DIALE) $(INTDIR)
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+!ELSEIF "$(CFG)" == "Win32 (MIPS) Debug"
+
+$(INTDIR)/dialer.res : $(SOURCE) $(DEP_GENER) $(INTDIR)
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+!ELSEIF "$(CFG)" == "Win32 (MIPS) Release"
+
+$(INTDIR)/dialer.res : $(SOURCE) $(DEP_GENER) $(INTDIR)
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\DIALER.C
+DEP_DIALER=\
+ .\DIALER.H\
+ ..\..\INC\TAPI.H\
+ .\dialhelp.h
+
+!IF "$(CFG)" == "Win32 (80x86) Release"
+
+$(INTDIR)/DIALER.OBJ : $(SOURCE) $(DEP_DIALER) $(INTDIR)
+
+!ELSEIF "$(CFG)" == "Win32 (80x86) Debug"
+
+$(INTDIR)/DIALER.OBJ : $(SOURCE) $(DEP_DIALER) $(INTDIR)
+
+!ELSEIF "$(CFG)" == "Win32 (MIPS) Debug"
+
+$(INTDIR)/dialer.obj : $(SOURCE) $(DEP_GENERI) $(INTDIR)
+
+!ELSEIF "$(CFG)" == "Win32 (MIPS) Release"
+
+$(INTDIR)/dialer.obj : $(SOURCE) $(DEP_GENERI) $(INTDIR)
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Project
+################################################################################
diff --git a/private/tapi/dev/apps/dialer/nextver/dialer.rc b/private/tapi/dev/apps/dialer/nextver/dialer.rc
new file mode 100644
index 000000000..157bf41dd
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/nextver/dialer.rc
@@ -0,0 +1,419 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "windows.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""windows.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALER DIALOG PRELOAD DISCARDABLE 50, 50, 194, 168
+STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU
+CAPTION "Phone Dialer"
+MENU IDM_MENU
+CLASS "DialerClass"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ CONTROL "",IDD_DRECTSEPARATOR,"Static",SS_ETCHEDHORZ |
+ WS_DISABLED,0,0,194,1
+ LTEXT "&Number to dial:",IDD_DNUMTODIAL,7,7,90,10
+ COMBOBOX IDD_DCOMBO,7,21,90,104,CBS_DROPDOWN | CBS_AUTOHSCROLL |
+ WS_VSCROLL | WS_GROUP | WS_TABSTOP | ES_NOHIDESEL
+ DEFPUSHBUTTON "&Dial",IDD_DDIAL,7,38,90,14,WS_DISABLED | WS_GROUP
+ CONTROL "\n1",IDD_DBUTTON1,"Button",BS_OWNERDRAW,14,62,23,20
+ CONTROL "ABC\n2",IDD_DBUTTON2,"Button",BS_OWNERDRAW,40,62,23,20
+ CONTROL "DEF\n3",IDD_DBUTTON3,"Button",BS_OWNERDRAW,66,62,23,20
+ CONTROL "GHI\n4",IDD_DBUTTON4,"Button",BS_OWNERDRAW,14,86,23,20
+ CONTROL "JKL\n5",IDD_DBUTTON5,"Button",BS_OWNERDRAW,40,86,23,20
+ CONTROL "MNO\n6",IDD_DBUTTON6,"Button",BS_OWNERDRAW,66,86,23,20
+ CONTROL "PQRS\n7",IDD_DBUTTON7,"Button",BS_OWNERDRAW,14,110,23,
+ 20
+ CONTROL "TUV\n8",IDD_DBUTTON8,"Button",BS_OWNERDRAW,40,110,23,20
+ CONTROL "WXYZ\n9",IDD_DBUTTON9,"Button",BS_OWNERDRAW,66,110,23,
+ 20
+ CONTROL "\n*",IDD_DBUTTONSTAR,"Button",BS_OWNERDRAW,14,134,23,20
+ CONTROL "\n0",IDD_DBUTTON0,"Button",BS_OWNERDRAW,40,134,23,20
+ CONTROL "\n#",IDD_DBUTTONPOUND,"Button",BS_OWNERDRAW,66,134,23,
+ 20
+ GROUPBOX "Speed dial",IDD_DSPEEDDIALGRP,103,7,84,154
+ LTEXT "&1",IDD_DSPEEDDIALTEXT1,109,24,7,10
+ PUSHBUTTON "",IDD_DSPEEDDIAL1,117,21,63,14,BS_LEFT | WS_GROUP
+ LTEXT "&2",IDD_DSPEEDDIALTEXT2,109,41,7,10
+ PUSHBUTTON "",IDD_DSPEEDDIAL2,117,38,63,14,BS_LEFT | WS_GROUP
+ LTEXT "&3",IDD_DSPEEDDIALTEXT3,109,58,7,10
+ PUSHBUTTON "",IDD_DSPEEDDIAL3,117,55,63,14,BS_LEFT | WS_GROUP
+ LTEXT "&4",IDD_DSPEEDDIALTEXT4,109,75,7,10
+ PUSHBUTTON "",IDD_DSPEEDDIAL4,117,72,63,14,BS_LEFT | WS_GROUP
+ LTEXT "&5",IDD_DSPEEDDIALTEXT5,109,92,7,10
+ PUSHBUTTON "",IDD_DSPEEDDIAL5,117,89,63,14,BS_LEFT | WS_GROUP
+ LTEXT "&6",IDD_DSPEEDDIALTEXT6,109,109,7,10
+ PUSHBUTTON "",IDD_DSPEEDDIAL6,117,106,63,14,BS_LEFT | WS_GROUP
+ LTEXT "&7",IDD_DSPEEDDIALTEXT7,109,126,7,10
+ PUSHBUTTON "",IDD_DSPEEDDIAL7,117,123,63,14,BS_LEFT | WS_GROUP
+ LTEXT "&8",IDD_DSPEEDDIALTEXT8,109,143,7,10
+ PUSHBUTTON "",IDD_DSPEEDDIAL8,117,140,63,14,BS_LEFT | WS_GROUP
+END
+
+IDD_SD1 DIALOG DISCARDABLE 12, 29, 165, 173
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP
+CAPTION "Edit Speed Dial"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Choose a button from the group below.",
+ IDD_SD1TEXTCHOOSE,7,7,140,10
+ LTEXT "1",IDD_SD1SPEEDDIALTEXT1,7,27,8,10
+ PUSHBUTTON "",IDD_SD1SPEEDDIAL1,16,24,63,14,BS_LEFT | WS_GROUP
+ LTEXT "2",IDD_SD1SPEEDDIALTEXT2,7,44,8,10
+ PUSHBUTTON "",IDD_SD1SPEEDDIAL2,16,41,63,14,BS_LEFT | WS_GROUP
+ LTEXT "3",IDD_SD1SPEEDDIALTEXT3,7,61,8,10
+ PUSHBUTTON "",IDD_SD1SPEEDDIAL3,16,58,63,14,BS_LEFT | WS_GROUP
+ LTEXT "4",IDD_SD1SPEEDDIALTEXT4,7,78,8,10
+ PUSHBUTTON "",IDD_SD1SPEEDDIAL4,16,75,63,14,BS_LEFT | WS_GROUP
+ LTEXT "5",IDD_SD1SPEEDDIALTEXT5,86,27,8,10
+ PUSHBUTTON "",IDD_SD1SPEEDDIAL5,95,24,63,14,BS_LEFT | WS_GROUP
+ LTEXT "6",IDD_SD1SPEEDDIALTEXT6,86,44,8,10
+ PUSHBUTTON "",IDD_SD1SPEEDDIAL6,95,41,63,14,BS_LEFT | WS_GROUP
+ LTEXT "7",IDD_SD1SPEEDDIALTEXT7,86,61,8,10
+ PUSHBUTTON "",IDD_SD1SPEEDDIAL7,95,58,63,14,BS_LEFT | WS_GROUP
+ LTEXT "8",IDD_SD1SPEEDDIALTEXT8,86,78,8,10
+ PUSHBUTTON "",IDD_SD1SPEEDDIAL8,95,75,63,14,BS_LEFT | WS_GROUP
+ LTEXT "",IDD_SD1RECTSEPARATOR,7,96,151,8,WS_DISABLED | NOT
+ WS_GROUP
+ LTEXT "Enter a name and number for the selected button.",
+ IDD_SD1TEXTENTER,7,104,160,10
+ LTEXT "&Name:",IDD_SD1TEXTNAME,16,119,29,10
+ EDITTEXT IDD_SD1EDITNAME,16,130,63,14,ES_AUTOHSCROLL
+ LTEXT "N&umber to dial:",IDD_SD1TEXTNUMBER,95,119,53,10
+ EDITTEXT IDD_SD1EDITNUMBER,95,130,63,14,ES_AUTOHSCROLL
+ PUSHBUTTON "&Save",IDOK,55,152,50,14,WS_GROUP
+ PUSHBUTTON "Cancel",IDCANCEL,108,152,50,14
+END
+
+IDD_SD2 DIALOG DISCARDABLE 12, 29, 158, 91
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP
+CAPTION "Program Speed Dial"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Enter a name and number to save on this button.",
+ IDD_SD2TEXTENTER,7,7,85,21
+ DEFPUSHBUTTON "&Save",IDOK,98,7,53,14,WS_GROUP
+ PUSHBUTTON "Save and &Dial",IDD_SD2SAVEANDDIAL,98,24,53,14,
+ WS_DISABLED | WS_GROUP
+ PUSHBUTTON "Cancel",IDCANCEL,98,41,53,14
+ LTEXT "&Name:",IDD_SD2TEXTNAME,7,30,29,10
+ EDITTEXT IDD_SD2EDITNAME,7,41,63,14,ES_AUTOHSCROLL
+ LTEXT "N&umber to dial:",IDD_SD2TEXTNUMBER,7,59,53,10
+ EDITTEXT IDD_SD2EDITNUMBER,7,70,63,14,ES_AUTOHSCROLL
+END
+
+IDD_CONNECTUSING DIALOG PRELOAD DISCARDABLE 50, 50, 260, 105
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP
+CAPTION "Connect Using"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "&Line:",IDD_CUTEXTLINE,7,16,79,10,NOT WS_GROUP
+ COMBOBOX IDD_CULISTLINE,7,27,173,97,CBS_DROPDOWNLIST | CBS_SORT |
+ WS_GROUP | WS_TABSTOP | WS_VSCROLL
+ LTEXT "&Address:",IDD_CUTEXTADDRESS,7,43,79,10,NOT WS_GROUP
+ COMBOBOX IDD_CULISTADDRESS,7,53,173,82,CBS_DROPDOWNLIST |
+ CBS_SORT | WS_GROUP | WS_TABSTOP | WS_VSCROLL
+ CONTROL "Use Phone Dialer to handle &voice call requests from other programs",
+ IDD_CUSIMPLETAPICHKBOX,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,7,72,230,10
+ PUSHBUTTON "Line &Properties...",IDD_CUPROPERTIES,190,26,63,14
+ DEFPUSHBUTTON "OK",IDOK,146,84,50,14,WS_GROUP
+ PUSHBUTTON "Cancel",IDCANCEL,203,84,50,14,WS_GROUP
+END
+
+IDD_ABOUT DIALOG DISCARDABLE 22, 38, 227, 100
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "About Phone Dialer"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ ICON IDI_DIALER,IDD_AICON,10,5,18,20
+ LTEXT "",IDD_ATEXTTITLE,38,5,127,10,SS_NOPREFIX | NOT WS_GROUP
+ LTEXT "Copyright © 1993-1996 Microsoft. All Rights Reserved.",
+ IDD_ATEXTCOPYRIGHT,38,35,179,20,SS_NOPREFIX | NOT
+ WS_GROUP
+ DEFPUSHBUTTON "OK",IDOK,177,5,40,14
+END
+
+IDD_INUSE DIALOG DISCARDABLE 22, 38, 199, 81
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Line In Use"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,36,58,53,16
+ ICON IDI_LINEBUSY,IDD_IUICON,10,5,18,20
+ LTEXT "The selected line or address is in use by another program or device on the line. Your call can not be placed at this time.",
+ IDD_IUTEXT1,45,5,144,27,SS_NOPREFIX | NOT WS_GROUP
+ LTEXT "Try your call again later.",IDD_IUTEXT2,45,40,114,12,
+ SS_NOPREFIX | NOT WS_GROUP
+END
+
+IDD_CALLFAILED DIALOG DISCARDABLE 22, 38, 199, 73
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Call Failed"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,72,50,53,16
+ ICON IDI_LINEBUSY,IDD_IUICON,10,5,18,20
+ LTEXT "",IDD_CFTEXT,45,5,144,40,SS_NOPREFIX | NOT WS_GROUP
+END
+
+IDD_DIALING DIALOG DISCARDABLE 0, 0, 172, 62
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION
+CAPTION "Dialing"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ PUSHBUTTON "&Hang Up",IDCANCEL,9,37,50,14
+ RTEXT "Currently dialing:",IDD_DGNUMBER,9,9,52,9
+ LTEXT "",IDD_DGNUMBERTEXT,63,9,100,9
+ LTEXT "",IDD_DGNAMETEXT,63,23,100,9
+END
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDM_MENU MENU DISCARDABLE
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "E&xit", IDM_EXIT
+ END
+ POPUP "&Edit"
+ BEGIN
+ MENUITEM "Cu&t\tCtrl+X", IDM_EDIT_CUT
+ MENUITEM "&Copy\tCtrl+C", IDM_EDIT_COPY
+ MENUITEM "&Paste\tCtrl+V", IDM_EDIT_PASTE
+ MENUITEM "&Delete\tDel", IDM_EDIT_DELETE
+ MENUITEM SEPARATOR
+ MENUITEM "&Speed Dial...", IDM_EDIT_SPEEDDIAL
+ END
+ POPUP "&Tools"
+ BEGIN
+ MENUITEM "&Connect Using...", IDM_CONNECTUSING
+ MENUITEM "&Dialing Properties...", IDM_LOCATION
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "&Help Topics", IDM_HELP_CONTENTS
+ MENUITEM "&What's This?", IDM_HELP_WHATSTHIS
+ MENUITEM SEPARATOR
+ MENUITEM "&About Phone Dialer", IDM_ABOUT
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+#if WINNT
+IDI_DIALER ICON DISCARDABLE "DIALER.ICO"
+IDI_LINEBUSY ICON DISCARDABLE "LINEBUSY.ICO"
+#else
+IDI_DIALER ICON DISCARDABLE "..\\DIALER.ICO"
+IDI_LINEBUSY ICON DISCARDABLE "..\\LINEBUSY.ICO"
+#endif
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDA_DIALER ACCELERATORS DISCARDABLE
+BEGIN
+ "1", IDD_DSPEEDDIAL1, VIRTKEY, ALT, NOINVERT
+ "2", IDD_DSPEEDDIAL2, VIRTKEY, ALT, NOINVERT
+ "3", IDD_DSPEEDDIAL3, VIRTKEY, ALT, NOINVERT
+ "4", IDD_DSPEEDDIAL4, VIRTKEY, ALT, NOINVERT
+ "5", IDD_DSPEEDDIAL5, VIRTKEY, ALT, NOINVERT
+ "6", IDD_DSPEEDDIAL6, VIRTKEY, ALT, NOINVERT
+ "7", IDD_DSPEEDDIAL7, VIRTKEY, ALT, NOINVERT
+ "8", IDD_DSPEEDDIAL8, VIRTKEY, ALT, NOINVERT
+ "C", IDM_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
+ "D", IDD_DDIAL, VIRTKEY, ALT, NOINVERT
+ "N", IDM_ACCEL_NUMTODIAL, VIRTKEY, ALT, NOINVERT
+ "V", IDM_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT
+ VK_INSERT, IDM_EDIT_PASTE, VIRTKEY, SHIFT, NOINVERT
+ "X", IDM_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT
+END
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,0,1259,1
+ PRODUCTVERSION 4,0,1259,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904B0"
+ BEGIN
+ VALUE "CompanyName", "Microsoft Corporation\0"
+ VALUE "FileDescription", "Microsoft® Windows(TM) Phone Dialer\0"
+ VALUE "FileVersion", "4.00\0"
+ VALUE "InternalName", "Phone Dialer\0"
+ VALUE "LegalCopyright", "Copyright © Microsoft Corporation 1996. All Rights Reserved.\0"
+ VALUE "OriginalFilename", "dialer.exe\0"
+ VALUE "ProductName", "Microsoft(R) Windows NT(TM) Operating System\0"
+ VALUE "ProductVersion", "4.00\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ikszAppName "Dialer"
+ ikszAppFriendlyName "Phone Dialer"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ikszErrDefault "An internal error occurred in Phone Dialer.\nQuit and restart Phone Dialer."
+ ikszErrOOM "There was not enough memory to continue.\nQuit one or more programs, and then try again."
+ ikszErrTAPI "Windows Telephony was unable to complete an operation requested by Phone Dialer.\nQuit and restart Phone Dialer."
+ ikszErrNoVoiceLine "Phone Dialer was unable to find a telephone device or modem to use to dial voice calls.\nIn Control Panel, double-click the Modems icon to install a modem, or install another telephone device to use for dialing calls."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ikszWarningTapiReInit "Phone Dialer cannot successfully start.\nQuit all other telephony programs, and then try again."
+ ikszErrLineClose "Your call was cancelled because the Telephony device driver closed the line."
+ ikszDisconnectedNoDialTone
+ "A dial tone was not detected. Please check your telephone cable connections, and be sure the line is not in use by someone else."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ikszErrLineInitBadIniFile
+ "Configuration information relating to Telephony services appears to be corrupt.\nPlease check the configuration of telephone devices in the control panel."
+ ikszErrLineInitNoDriver "One of the components of the Telephony device driver is missing.\nUse the Control Panel to set up the driver properly."
+ ikszErrLineInitNoDevice "The selected device has been removed from your computer. Please select a different device for dialing."
+ ikszErrNoMultipleInstance
+ "You have two copies of the same Telephony driver installed.\nUse the Control Panel to remove one of the copies."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ikszErrInvalAddress "The specified phone number either contains invalid characters, or is incorrectly formatted.\nClick on the number box with the right mouse button to see more information."
+ ikszErrLineInitWrongDrivers
+ "One or more telephone device drivers are incompatible with TAPI.DLL.\nInstall an updated version."
+ ikszErrAddrBlocked "The specified phone number cannot be dialed on the selected line device because it is blocked at the telephone switch."
+ ikszErrBillingRejected "The billing information specified as part of the phone number has been rejected.\nCheck to make sure you've entered it correctly, and then try again."
+ ikszErrResUnavail "Another program is using the selected Telephony device.\nTry again after the other program completes."
+ ikszErrInvalidCountryCode "The country code you entered is invalid.\nPlease check the phone number again."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ikszDisconnectedReject "The call was rejected by the called party."
+ ikszDisconnectedBusy "The called number is busy."
+ ikszDisconnectedNoAnswer "There was no answer."
+ ikszDisconnectedCantDo "The call cannot be completed as dialed."
+ ikszDisconnectedNetwork "The call failed due to network congestion."
+ ikszDisconnectedIncompatible
+ "Equipment at the called number is incompatible with your equipment."
+ ikszErrInvalCallState "The Telephony device driver is unable to respond to your request at this time."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ikszWarningTitle "Warning"
+ ikszWarningFor911 "Using your current location and calling card selection, dialing this number could result in a emergency services call to 911. Are you sure you want to dial this call ?"
+ ikszWarningNewDefault "Your preferred device selection is not available. A new device has been selected by default. If you wish to change the selection use the 'Connect Using' option under the 'Tools' menu"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/private/tapi/dev/apps/dialer/nextver/dialhelp.h b/private/tapi/dev/apps/dialer/nextver/dialhelp.h
new file mode 100644
index 000000000..54084e44c
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/nextver/dialhelp.h
@@ -0,0 +1,29 @@
+//
+// (c) 1995 Microsoft Corporation. All Rights Reserved.
+//
+#define IDH_DIALER_CHANGE_DIAL_HELPER 1000
+#define IDH_DIALER_CHANGE_DIGITS 1001
+#define IDH_DIALER_CHANGE_OPTIONS 1002
+#define IDH_DIALER_CHANGE_REDIAL_BUTTON 1003
+#define IDH_DIALER_DIALING_LOGNAME 1004
+#define IDH_DIALER_DIALING_STATUS 1005
+#define IDH_DIALER_HANGUP 1006
+#define IDH_DIALER_LOG_IN 1007
+#define IDH_DIALER_LOG_OUT 1008
+#define IDH_DIALER_OPTIONS_ADDRESS 1009
+#define IDH_DIALER_OPTIONS_LINE 1010
+#define IDH_DIALER_OPTIONS_NONVOICE 1011
+#define IDH_DIALER_OPTIONS_VOICE 1012
+#define IDH_DIALER_PAUSE_CONTINUE 1013
+#define IDH_DIALER_SPEED_CHOOSE 1014
+#define IDH_DIALER_SPEED_NAME 1015
+#define IDH_DIALER_SPEED_NUMBER 1016
+#define IDH_DIALER_SPEED_SAVE 1017
+#define IDH_DIALER_SPEED_SAVE_DIAL 1018
+#define IDH_DIALER_DIAL_NUMBER 1019
+#define IDH_DIALER_DIAL_SPEED_CHOOSE 1020
+#define IDH_DIALER_DIAL_BUTTON 1021
+#define IDH_DIALER_DIAL_KEYPAD 1022
+#define IDH_DIALER_LOG 1023
+#define IDH_DIALER_OPTIONS_PROPERTIES 1024
+#define IDH_DIALER_BUTTONS 1025
diff --git a/private/tapi/dev/apps/dialer/nextver/linebusy.ico b/private/tapi/dev/apps/dialer/nextver/linebusy.ico
new file mode 100644
index 000000000..589f2671b
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/nextver/linebusy.ico
Binary files differ
diff --git a/private/tapi/dev/apps/dialer/nextver/makefile b/private/tapi/dev/apps/dialer/nextver/makefile
new file mode 100644
index 000000000..f1084966b
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/nextver/makefile
@@ -0,0 +1,29 @@
+!if "$(OS)" == "Windows_NT"
+
+!INCLUDE $(NTMAKEENV)\makefile.def
+
+!else
+
+##############################################################################
+#
+# Dialer.exe Make file
+#
+##############################################################################
+
+#Ok, we're doing a Win9x build.
+
+ROOT=..\..\..\..\..
+
+VERSIONLIST=debug retail
+
+DEPENDNAME=depend.mk
+
+COMMONMKFILE=makefile.def
+
+IS_OEM=TRUE
+IS_32 = TRUE
+
+!include $(ROOT)\dev\master.mk
+
+!endif
+
diff --git a/private/tapi/dev/apps/dialer/nextver/makefile.def b/private/tapi/dev/apps/dialer/nextver/makefile.def
new file mode 100644
index 000000000..1eb194df8
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/nextver/makefile.def
@@ -0,0 +1,50 @@
+##############################################################################
+#
+# Dialer Make file
+#
+##############################################################################
+
+#Ok, we're doing a Win9x build.
+
+ROOT=..\..\..\..\..\..
+
+
+IS_OEM=1
+WANT_C932=1
+IS_32 = TRUE
+WIN32=1
+
+DEPENDNAME=..\depend.mk
+
+DRVNAME=dialer
+TARGETS=dialer.exe
+
+DEFENTRY = WinMain
+
+SRCDIR=..
+
+BUILD_COFF=1
+
+L32EXE=dialer.exe # Name of exe.
+L32DEF=..\dialer.def # Our def file.
+L32MAP=dialer.map # Our map file.
+L32SYM=dialer.sym # Our sym file.
+L32LIBS= \
+ $(W32LIBID)\user32.lib \
+ $(W32LIBID)\gdi32.lib \
+ $(W32LIBID)\kernel32.lib \
+ $(DEVROOT)\sdk\lib\tapi32.lib \
+ $(DEVROOT)\tools\c932\lib\oldnames.lib \
+ $(DEVROOT)\tools\c932\lib\msvcrt.lib \
+ $(DEVROOT)\sdk\lib\shell32.lib
+
+L32RES=dialer.res # Resource file.
+L32OBJS = dialer.obj
+
+!include $(ROOT)\dev\master.mk
+
+CFLAGS=$(CFLAGS) -DWIN32=100 -DWIN_32=100 -Og
+
+!IF "$(VERDIR)" == "debug"
+CFLAGS = $(CFLAGS) -DDBG=1
+!endif
diff --git a/private/tapi/dev/apps/dialer/nextver/nt.mak b/private/tapi/dev/apps/dialer/nextver/nt.mak
new file mode 100644
index 000000000..a93df1f2d
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/nextver/nt.mak
@@ -0,0 +1,27 @@
+!include <ntwin32.mak>
+
+!ifndef MYDEBUG
+MYDEBUG = 0
+!endif
+
+!if $(MYDEBUG)
+L_FLAGS = $(linkdebug)
+!else
+L_FLAGS =
+!endif
+
+APPLIBS=\telephon\tapi\lib\tapi32.lib
+
+OBJS=ui.obj vars.obj tb.obj widget.obj
+
+all: tb.exe
+
+.c.obj:
+ $(cc) -DTAPI_1_1 $(cdebug) $(cflags) $(cvars) $*.c
+
+tb.rbj: tb.rc
+ $(rc) -DTAPI_1_1 $(rcvars) -r -fo tb.res tb.rc
+ cvtres -$(CPU) tb.res -o tb.rbj
+
+tb.exe: $(OBJS) tb.rbj tb.def
+ $(link) $(L_FLAGS) $(guiflags) -out:tb14.exe $(OBJS) tb.rbj $(APPLIBS) $(guilibsdll)
diff --git a/private/tapi/dev/apps/dialer/nextver/resource.h b/private/tapi/dev/apps/dialer/nextver/resource.h
new file mode 100644
index 000000000..0296f8654
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/nextver/resource.h
@@ -0,0 +1,155 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by dialer.RC
+//
+#define IDI_DIALER 1
+#define IDD_DDIAL 1
+#define IDI_LINEBUSY 116
+#define IDA_DIALER 117
+#define IDM_MENU 118
+#define IDD_DIALER 200
+#define IDD_DCOMBO 201
+#define IDD_DBUTTON1 202
+#define IDD_DBUTTON2 203
+#define IDD_DBUTTON3 204
+#define IDD_DBUTTON4 205
+#define IDD_DBUTTON5 206
+#define IDD_DBUTTON6 207
+#define IDD_DBUTTON7 208
+#define IDD_DBUTTON8 209
+#define IDD_DBUTTON9 210
+#define IDD_DBUTTON0 211
+#define IDD_DBUTTONSTAR 212
+#define IDD_DBUTTONPOUND 213
+#define IDD_DSPEEDDIAL1 214
+#define IDD_DSPEEDDIAL2 215
+#define IDD_DSPEEDDIAL3 216
+#define IDD_DSPEEDDIAL4 217
+#define IDD_DSPEEDDIAL5 218
+#define IDD_DSPEEDDIAL6 219
+#define IDD_DSPEEDDIAL7 220
+#define IDD_DSPEEDDIAL8 221
+#define IDD_DSPEEDDIALGRP 222
+#define IDD_DNUMTODIAL 223
+#define IDD_DRECTSEPARATOR 224
+#define IDD_DSPEEDDIALTEXT1 225
+#define IDD_DSPEEDDIALTEXT2 226
+#define IDD_DSPEEDDIALTEXT3 227
+#define IDD_DSPEEDDIALTEXT4 228
+#define IDD_DSPEEDDIALTEXT5 229
+#define IDD_DSPEEDDIALTEXT6 230
+#define IDD_DSPEEDDIALTEXT7 231
+#define IDD_DSPEEDDIALTEXT8 232
+#define IDD_SD1 300
+#define IDD_SD1SPEEDDIAL1 301
+#define IDD_SD1SPEEDDIAL2 302
+#define IDD_SD1SPEEDDIAL3 303
+#define IDD_SD1SPEEDDIAL4 304
+#define IDD_SD1SPEEDDIAL5 305
+#define IDD_SD1SPEEDDIAL6 306
+#define IDD_SD1SPEEDDIAL7 307
+#define IDD_SD1SPEEDDIAL8 308
+#define IDD_SD1EDITNAME 317
+#define IDD_SD1EDITNUMBER 318
+#define IDD_SD1TEXTCHOOSE 319
+#define IDD_SD1TEXTENTER 320
+#define IDD_SD1TEXTNAME 321
+#define IDD_SD1TEXTNUMBER 322
+#define IDD_SD1RECTSEPARATOR 323
+#define IDD_SD1SPEEDDIALTEXT1 324
+#define IDD_SD1SPEEDDIALTEXT2 325
+#define IDD_SD1SPEEDDIALTEXT3 326
+#define IDD_SD1SPEEDDIALTEXT4 327
+#define IDD_SD1SPEEDDIALTEXT5 328
+#define IDD_SD1SPEEDDIALTEXT6 329
+#define IDD_SD1SPEEDDIALTEXT7 330
+#define IDD_SD1SPEEDDIALTEXT8 331
+#define IDD_SD2 400
+#define IDD_SD2SAVEANDDIAL 401
+#define IDD_SD2EDITNAME 402
+#define IDD_SD2EDITNUMBER 403
+#define IDD_SD2TEXTENTER 404
+#define IDD_SD2TEXTNAME 405
+#define IDD_SD2TEXTNUMBER 406
+#define IDD_CONNECTUSING 500
+#define IDD_CULISTLINE 501
+#define IDD_CULISTADDRESS 502
+#define IDD_CUSIMPLETAPICHKBOX 503
+#define IDD_CUTEXTLINE 504
+#define IDD_CUTEXTADDRESS 505
+#define IDD_CUPROPERTIES 506
+#define IDD_ABOUT 700
+#define IDD_AICON 701
+#define IDD_ATEXTTITLE 702
+#define IDD_ATEXTVERSION 703
+#define IDD_ATEXTWINMODE 704
+#define IDD_ATEXTFREEMEM 705
+#define IDD_ATEXTRESOURCE 706
+#define IDD_ATEXTCOPYRIGHT 707
+#define IDD_INUSE 900
+#define IDD_IUICON 901
+#define ikszAppName 901
+#define IDD_IUTEXT1 902
+#define ikszAppFriendlyName 902
+#define IDD_IUTEXT2 903
+#define ikszErrDefault 940
+#define ikszErrOOM 941
+#define ikszErrTAPI 942
+#define ikszErrNoVoiceLine 943
+#define ikszErrInvalAddress 945
+#define ikszErrLineInitWrongDrivers 949
+#define ikszErrAddrBlocked 950
+#define ikszErrBillingRejected 952
+#define ikszErrResUnavail 956
+#define ikszWarningTitle 977
+#define ikszWarningRegisterSTapi 978
+#define ikszWarningFor911 978
+#define ikszWarningNewDefault 979
+#define IDM_EXIT 1000
+#define IDM_EDIT_CUT 1001
+#define IDM_EDIT_COPY 1002
+#define IDD_DGNUMBERTEXT 1002
+#define IDM_EDIT_PASTE 1003
+#define IDM_EDIT_DELETE 1004
+#define IDD_DGNAMETEXT 1004
+#define IDM_EDIT_SPEEDDIAL 1005
+#define IDM_CONNECTUSING 1006
+#define IDM_LOCATION 1008
+#define IDM_HELP_CONTENTS 1010
+#define IDM_ABOUT 1011
+#define IDM_ACCEL_NUMTODIAL 1012
+#define ikszErrLineInitBadIniFile 1013
+#define IDM_ACCEL_HELP 1013
+#define ikszErrLineInitNoDriver 1014
+#define ikszErrBadTAPIAddr 1015
+#define IDM_HELP_WHATSTHIS 1015
+#define ikszErrLineInitNoDevice 1016
+#define ikszErrNoMultipleInstance 1020
+#define IDD_CALLFAILED 1300
+#define IDD_CFTEXT 1301
+#define ikszWarning911 1544
+#define ikszDisconnectedReject 1545
+#define ikszDisconnectedBusy 1546
+#define ikszDisconnectedNoAnswer 1547
+#define ikszDisconnectedCantDo 1548
+#define ikszDisconnectedNetwork 1549
+#define ikszDisconnectedIncompatible 1550
+#define ikszErrInvalCallState 1551
+#define ikszWarningTapiReInit 1552
+#define ikszErrLineClose 1553
+#define ikszDisconnectedNoDialTone 1554
+#define ikszErrInvalidCountryCode 1555
+#define IDD_DIALING 9115
+#define IDD_CUERRORTEXT -1
+#define IDD_DGNUMBER -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 9116
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1005
+#define _APS_NEXT_SYMED_VALUE 9101
+#endif
+#endif
diff --git a/private/tapi/dev/apps/dialer/nextver/sources b/private/tapi/dev/apps/dialer/nextver/sources
new file mode 100644
index 000000000..0e80d7fe8
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/nextver/sources
@@ -0,0 +1,59 @@
+!IF 0
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+Author:
+
+ John Rogers (JohnRo) 25-Oct-1991
+
+Notes:
+
+ Commented description of this file is in \nt\public\oak\bin\sources.tpl
+
+Revision History:
+
+!ENDIF
+
+
+MAJORCOMP=net
+MINORCOMP=tapi
+
+TARGETNAME=dialer
+TARGETPATH=$(BASEDIR)\public\sdk\lib
+TARGETTYPE=PROGRAM
+
+TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\kernel32.lib \
+ $(BASEDIR)\public\sdk\lib\*\comdlg32.lib \
+ $(BASEDIR)\public\sdk\lib\*\shell32.lib \
+ $(BASEDIR)\public\sdk\lib\*\tapi32.lib
+!if 0
+# $(BASEDIR)\public\sdk\lib\*\oldnames.lib
+!endif
+
+INCLUDES=.;$(BASEDIR)\public\sdk\inc
+
+USE_CRTDLL=1
+
+SOURCES=dialer.c \
+ dialer.rc
+
+C_DEFINES=-DWINVER=0x0400
+
+UMTYPE=windows
+
+UMENTRY=winmain
+
+!IFNDEF 386_WARNING_LEVEL
+386_WARNING_LEVEL=/W3
+!ENDIF
diff --git a/private/tapi/dev/apps/dialer/nt.mak b/private/tapi/dev/apps/dialer/nt.mak
new file mode 100644
index 000000000..a93df1f2d
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/nt.mak
@@ -0,0 +1,27 @@
+!include <ntwin32.mak>
+
+!ifndef MYDEBUG
+MYDEBUG = 0
+!endif
+
+!if $(MYDEBUG)
+L_FLAGS = $(linkdebug)
+!else
+L_FLAGS =
+!endif
+
+APPLIBS=\telephon\tapi\lib\tapi32.lib
+
+OBJS=ui.obj vars.obj tb.obj widget.obj
+
+all: tb.exe
+
+.c.obj:
+ $(cc) -DTAPI_1_1 $(cdebug) $(cflags) $(cvars) $*.c
+
+tb.rbj: tb.rc
+ $(rc) -DTAPI_1_1 $(rcvars) -r -fo tb.res tb.rc
+ cvtres -$(CPU) tb.res -o tb.rbj
+
+tb.exe: $(OBJS) tb.rbj tb.def
+ $(link) $(L_FLAGS) $(guiflags) -out:tb14.exe $(OBJS) tb.rbj $(APPLIBS) $(guilibsdll)
diff --git a/private/tapi/dev/apps/dialer/resource.h b/private/tapi/dev/apps/dialer/resource.h
new file mode 100644
index 000000000..0296f8654
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/resource.h
@@ -0,0 +1,155 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by dialer.RC
+//
+#define IDI_DIALER 1
+#define IDD_DDIAL 1
+#define IDI_LINEBUSY 116
+#define IDA_DIALER 117
+#define IDM_MENU 118
+#define IDD_DIALER 200
+#define IDD_DCOMBO 201
+#define IDD_DBUTTON1 202
+#define IDD_DBUTTON2 203
+#define IDD_DBUTTON3 204
+#define IDD_DBUTTON4 205
+#define IDD_DBUTTON5 206
+#define IDD_DBUTTON6 207
+#define IDD_DBUTTON7 208
+#define IDD_DBUTTON8 209
+#define IDD_DBUTTON9 210
+#define IDD_DBUTTON0 211
+#define IDD_DBUTTONSTAR 212
+#define IDD_DBUTTONPOUND 213
+#define IDD_DSPEEDDIAL1 214
+#define IDD_DSPEEDDIAL2 215
+#define IDD_DSPEEDDIAL3 216
+#define IDD_DSPEEDDIAL4 217
+#define IDD_DSPEEDDIAL5 218
+#define IDD_DSPEEDDIAL6 219
+#define IDD_DSPEEDDIAL7 220
+#define IDD_DSPEEDDIAL8 221
+#define IDD_DSPEEDDIALGRP 222
+#define IDD_DNUMTODIAL 223
+#define IDD_DRECTSEPARATOR 224
+#define IDD_DSPEEDDIALTEXT1 225
+#define IDD_DSPEEDDIALTEXT2 226
+#define IDD_DSPEEDDIALTEXT3 227
+#define IDD_DSPEEDDIALTEXT4 228
+#define IDD_DSPEEDDIALTEXT5 229
+#define IDD_DSPEEDDIALTEXT6 230
+#define IDD_DSPEEDDIALTEXT7 231
+#define IDD_DSPEEDDIALTEXT8 232
+#define IDD_SD1 300
+#define IDD_SD1SPEEDDIAL1 301
+#define IDD_SD1SPEEDDIAL2 302
+#define IDD_SD1SPEEDDIAL3 303
+#define IDD_SD1SPEEDDIAL4 304
+#define IDD_SD1SPEEDDIAL5 305
+#define IDD_SD1SPEEDDIAL6 306
+#define IDD_SD1SPEEDDIAL7 307
+#define IDD_SD1SPEEDDIAL8 308
+#define IDD_SD1EDITNAME 317
+#define IDD_SD1EDITNUMBER 318
+#define IDD_SD1TEXTCHOOSE 319
+#define IDD_SD1TEXTENTER 320
+#define IDD_SD1TEXTNAME 321
+#define IDD_SD1TEXTNUMBER 322
+#define IDD_SD1RECTSEPARATOR 323
+#define IDD_SD1SPEEDDIALTEXT1 324
+#define IDD_SD1SPEEDDIALTEXT2 325
+#define IDD_SD1SPEEDDIALTEXT3 326
+#define IDD_SD1SPEEDDIALTEXT4 327
+#define IDD_SD1SPEEDDIALTEXT5 328
+#define IDD_SD1SPEEDDIALTEXT6 329
+#define IDD_SD1SPEEDDIALTEXT7 330
+#define IDD_SD1SPEEDDIALTEXT8 331
+#define IDD_SD2 400
+#define IDD_SD2SAVEANDDIAL 401
+#define IDD_SD2EDITNAME 402
+#define IDD_SD2EDITNUMBER 403
+#define IDD_SD2TEXTENTER 404
+#define IDD_SD2TEXTNAME 405
+#define IDD_SD2TEXTNUMBER 406
+#define IDD_CONNECTUSING 500
+#define IDD_CULISTLINE 501
+#define IDD_CULISTADDRESS 502
+#define IDD_CUSIMPLETAPICHKBOX 503
+#define IDD_CUTEXTLINE 504
+#define IDD_CUTEXTADDRESS 505
+#define IDD_CUPROPERTIES 506
+#define IDD_ABOUT 700
+#define IDD_AICON 701
+#define IDD_ATEXTTITLE 702
+#define IDD_ATEXTVERSION 703
+#define IDD_ATEXTWINMODE 704
+#define IDD_ATEXTFREEMEM 705
+#define IDD_ATEXTRESOURCE 706
+#define IDD_ATEXTCOPYRIGHT 707
+#define IDD_INUSE 900
+#define IDD_IUICON 901
+#define ikszAppName 901
+#define IDD_IUTEXT1 902
+#define ikszAppFriendlyName 902
+#define IDD_IUTEXT2 903
+#define ikszErrDefault 940
+#define ikszErrOOM 941
+#define ikszErrTAPI 942
+#define ikszErrNoVoiceLine 943
+#define ikszErrInvalAddress 945
+#define ikszErrLineInitWrongDrivers 949
+#define ikszErrAddrBlocked 950
+#define ikszErrBillingRejected 952
+#define ikszErrResUnavail 956
+#define ikszWarningTitle 977
+#define ikszWarningRegisterSTapi 978
+#define ikszWarningFor911 978
+#define ikszWarningNewDefault 979
+#define IDM_EXIT 1000
+#define IDM_EDIT_CUT 1001
+#define IDM_EDIT_COPY 1002
+#define IDD_DGNUMBERTEXT 1002
+#define IDM_EDIT_PASTE 1003
+#define IDM_EDIT_DELETE 1004
+#define IDD_DGNAMETEXT 1004
+#define IDM_EDIT_SPEEDDIAL 1005
+#define IDM_CONNECTUSING 1006
+#define IDM_LOCATION 1008
+#define IDM_HELP_CONTENTS 1010
+#define IDM_ABOUT 1011
+#define IDM_ACCEL_NUMTODIAL 1012
+#define ikszErrLineInitBadIniFile 1013
+#define IDM_ACCEL_HELP 1013
+#define ikszErrLineInitNoDriver 1014
+#define ikszErrBadTAPIAddr 1015
+#define IDM_HELP_WHATSTHIS 1015
+#define ikszErrLineInitNoDevice 1016
+#define ikszErrNoMultipleInstance 1020
+#define IDD_CALLFAILED 1300
+#define IDD_CFTEXT 1301
+#define ikszWarning911 1544
+#define ikszDisconnectedReject 1545
+#define ikszDisconnectedBusy 1546
+#define ikszDisconnectedNoAnswer 1547
+#define ikszDisconnectedCantDo 1548
+#define ikszDisconnectedNetwork 1549
+#define ikszDisconnectedIncompatible 1550
+#define ikszErrInvalCallState 1551
+#define ikszWarningTapiReInit 1552
+#define ikszErrLineClose 1553
+#define ikszDisconnectedNoDialTone 1554
+#define ikszErrInvalidCountryCode 1555
+#define IDD_DIALING 9115
+#define IDD_CUERRORTEXT -1
+#define IDD_DGNUMBER -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 9116
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1005
+#define _APS_NEXT_SYMED_VALUE 9101
+#endif
+#endif
diff --git a/private/tapi/dev/apps/dialer/sources b/private/tapi/dev/apps/dialer/sources
new file mode 100644
index 000000000..0e80d7fe8
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/sources
@@ -0,0 +1,59 @@
+!IF 0
+
+Copyright (c) 1989-1993 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+Author:
+
+ John Rogers (JohnRo) 25-Oct-1991
+
+Notes:
+
+ Commented description of this file is in \nt\public\oak\bin\sources.tpl
+
+Revision History:
+
+!ENDIF
+
+
+MAJORCOMP=net
+MINORCOMP=tapi
+
+TARGETNAME=dialer
+TARGETPATH=$(BASEDIR)\public\sdk\lib
+TARGETTYPE=PROGRAM
+
+TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\kernel32.lib \
+ $(BASEDIR)\public\sdk\lib\*\comdlg32.lib \
+ $(BASEDIR)\public\sdk\lib\*\shell32.lib \
+ $(BASEDIR)\public\sdk\lib\*\tapi32.lib
+!if 0
+# $(BASEDIR)\public\sdk\lib\*\oldnames.lib
+!endif
+
+INCLUDES=.;$(BASEDIR)\public\sdk\inc
+
+USE_CRTDLL=1
+
+SOURCES=dialer.c \
+ dialer.rc
+
+C_DEFINES=-DWINVER=0x0400
+
+UMTYPE=windows
+
+UMENTRY=winmain
+
+!IFNDEF 386_WARNING_LEVEL
+386_WARNING_LEVEL=/W3
+!ENDIF
diff --git a/private/tapi/dev/apps/dialer/version.rc b/private/tapi/dev/apps/dialer/version.rc
new file mode 100644
index 000000000..7d824cc20
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/version.rc
@@ -0,0 +1,66 @@
+//
+// (c) 1995 Microsoft Corporation. All Rights Reserved.
+//
+/* Version Numbering stuff */
+
+#define VER_FILEDESCRIPTION_STR "Microsoft\256 Windows(TM) Phone Dialer"
+#define VER_INTERNALNAME_STR "Phone Dialer"
+#define VER_ORIGINALFILENAME_STR "dialer.exe"
+
+#ifdef SDKRELEASE
+#include <ver.h>
+
+#define VER_PRODUCTVERSION_STR "1.00.150"
+#define VER_PRODUCTVERSION 1,0,0,150
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION VER_PRODUCTVERSION
+PRODUCTVERSION VER_PRODUCTVERSION
+FILEFLAGSMASK VS_FF_DEBUG | VS_FF_PRERELEASE
+FILEFLAGS VS_FF_DEBUG | VS_FF_PRERELEASE
+FILEOS VOS__WINDOWS16
+FILETYPE VFT_APP
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4"
+ BEGIN
+ VALUE "CompanyName", "Microsoft Corporation", "\0"
+ VALUE "FileDescription", VER_FILEDESCRIPTION_STR, "\0"
+ VALUE "FileVersion", VER_PRODUCTVERSION_STR, "\0"
+ VALUE "InternalName", VER_INTERNALNAME_STR, "\0"
+ VALUE "LegalCopyright", "Copyright 1995 Microsoft Corp", "\0"
+ VALUE "OriginalFilename",VER_ORIGINALFILENAME_STR, "\0"
+ VALUE "ProductName", "Windows Telephony", "\0"
+ VALUE "ProductVersion", VER_PRODUCTVERSION_STR, "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ /* the following line should be extended for localized versions */
+ VALUE "Translation", 0x0409, 0x04E4
+ END
+END
+#else
+
+
+// Is the following FLAG good to use for this?
+#ifdef NT_INST
+#include <ntverp.h>
+#else
+#include <version.h>
+#endif
+
+#define VER_LEGALCOPYRIGHT_STR "Copyright \251 Microsoft Corporation 1995. All Rights Reserved."
+
+#define VER_FILETYPE VFT_APP
+#define VER_FILESUBTYPE VFT2_UNKNOWN
+
+#include <common.ver>
+
+// /////////////////////////////////////////////////////////////////////////
+// /////////////////////////////////////////////////////////////////////////
+
+// #include <tapiver.h>
+// #include <common.ver>
+#endif
diff --git a/private/tapi/dev/apps/dialer/win31.mak b/private/tapi/dev/apps/dialer/win31.mak
new file mode 100644
index 000000000..0481e0d68
--- /dev/null
+++ b/private/tapi/dev/apps/dialer/win31.mak
@@ -0,0 +1,39 @@
+!ifndef TAPI_1_1
+TAPI_1_1 = 0
+!endif
+
+!ifndef MYDEBUG
+MYDEBUG = 0
+!endif
+
+!if $(TAPI_1_1)
+TAPI_VER_FLAGS = -DTAPI_1_1
+TAPILIB = ..\..\lib\i386\tapi.lib
+TAPIINC = -I..\..\inc
+TARGET = ..\..\lib\i386\tb1416.exe
+!else
+TAPI_VER_FLAGS =
+TAPILIB = ..\..\lib\tapi10\tapi.lib
+TAPIINC = -I..\..\inc\tapi10
+TARGET = ..\..\lib\i386\tb13.exe
+!endif
+
+!if $(MYDEBUG)
+C_FLAGS = -AL -G2s -W3 -GA -GEf -Zp /Od /Oi /Zi
+!else
+C_FLAGS = -AL -G2s -W3 -GA -GEf -Zp /Od /Oi
+!endif
+
+
+OBJS=ui.obj vars.obj tb.obj widget.obj
+
+all : $(TARGET)
+
+.c.obj:
+ cl -c $(TAPI_VER_FLAGS) $(TAPIINC) $(C_FLAGS) $*.c
+
+$(TARGET) : $(OBJS) tb.def tb.rc
+ rc -r $(TAPI_VER_FLAGS) tb.rc
+ link $(OBJS),$(TARGET),tb.map,libw.lib /MAP:FULL /COD /NOD:llibce llibcew commdlg $(TAPILIB),tb.def
+ rc -k tb.res $(TARGET)
+ mapsym tb