⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dialer.c

📁 Dialer ---- Windows TAPI sample application created as an illustration of the usage of Windows TAPI
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++ 

Copyright 1996 - 1999 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 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 = (HLINEAPP)((ULONG_PTR)NULL);        // Dialer's usage handle (regist. w/TAPI)
HCALL       ghCall = (HCALL)((ULONG_PTR)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,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -