以前写的一手机个来电回拨的例子,贴上来,写得还不完善,好多需要改进的地方。
// DialCallBack.cpp : Defines the entry point for the application.
//

#include <windows.h>
#include <windowsx.h>
#include <aygshell.h>
#include <tpcshell.h>
#include "resource.h"
#include "tapi.h"
#include "extapi.h"
#include "DialCallBack.h"
#define IDS_DIAL_DIALNUMBER _T("拨号")
#define TAPI_API_LOW_VERSION 0x00020000
#define TAPI_API_HIGH_VERSION 0x00020000
#define EXT_API_LOW_VERSION 0x00010000
#define EXT_API_HIGH_VERSION 0x00010000
#define CELLTSP_LINENAME_STRING _T("Cellular Line")
#define MAX_LOADSTRING 100
#define LINE_CALL_WAIT_TIMEOUT 5000
HINSTANCE g_hDialCallBackInst = NULL; // Local copy of hInstance
static void OnKeyDown(HWND hwnd,WPARAM wp, LPARAM lp);
static void OnNumTxtCommand( HWND hwnd, WPARAM wp, LPARAM lp );
static DWORD CallingThreadProc(LPVOID pData);
BOOL SetPhoneVolumnMute();
BOOL ResetPhoneVolumn();
#define ARRAYSIZE(a) (sizeof(a)/sizeof(*a))
static HANDLE m_hCallThread = NULL;
const static TCHAR* g_szAppWndClass = _T("DialCallBack");
extern int CallCheckerWnd();
extern BOOL GetCheckInfo();
extern int CallParamConfigWnd();
extern int CallPhoneBookViewWnd();
extern void GetServerNum();
extern BOOL GetAppPath(LPCTSTR _appPath);
extern AddPhoneNumByTele( LPCTSTR lpszTel );
TCHAR g_szServerNum[20];
TCHAR g_szMessage[30];
TCHAR g_szIMECode[18];
DWORD g_dwCheckNumber = 0;
//DWORD g_dwVolumnRinger = 0;
DWORD g_RingInitVol = 1;
// 每次开机是否都需要输入密码
BOOL g_bCheckEveryLogin = FALSE;
BOOL g_bComunication = FALSE;
static HLINEAPP g_hLineApp;
static HCALL g_hCheckedCall;
HWND hDialCallBackMainWnd;
static BOOL g_bCurrentLineAvail;
static BOOL g_bWaitSecondCall = FALSE;
static DWORD g_MakeCallRequestID;
static DWORD g_dwNumDevs;
static DWORD g_dwDevId ;
static DWORD g_dwMediaMode;
static DWORD g_dwTAPIVer = 0x00020000;
static DWORD g_lResforcall;
static TCHAR szPhoneNumber[20];
static TCHAR szIncomingPhoneNum[20];
static TCHAR szTmpInfo[255];
static HWND hFirstNumTxt = NULL;
static HWND hFirstNumLable = NULL;
static HANDLE hCurrentRelpyEvent;

static bool counterIn = false;
static bool counterOut = false;
static bool check = false;

typedef struct


{
HANDLE hLineCallDialingEvent;
HANDLE hLineCallProceedingEvent;
HANDLE hLineCallBusyEvent;
HANDLE hLineCallConnectedEvent;
HANDLE hLineCallDisConnectedEvent;
HANDLE hLineCallOnHoldEvent;
HANDLE hLineCallRingBackEvent;
HANDLE hLineCallConferencedEvent;
HANDLE hLineCallOfferingEvent;
HANDLE hLineCallIdleEvent;
}LINECALL_EVENT;

static LINECALL_EVENT g_LineCallEvent;
static DWORD InitializeTAPI();
static BOOL InitCallLine();
static BOOL GetIMEICode();
static DWORD SelectLine(const HLINEAPP hLineApp, const DWORD dwNumberDevices,
const DWORD dwAPIVersionLow, const DWORD dwAPIVersionHigh,
const TCHAR* const psTSPLineName);
static VOID CALLBACK lineCallbackFunc(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD);
static BOOL MakePhoneCall(LPCTSTR lpszPhoneNum, HCALL* hCall, DWORD pnSize);
static BOOL MakeDisconnectPhoneCall(HCALL* hCall, DWORD dwLineCallState, LPCTSTR lpszPhoneNum, DWORD pnSize);
static void CreateWindowItem(HWND hWnd);
static void GetPrePhoneNum();
static void OnCommand( HWND hwnd,UINT msg, WPARAM wp, LPARAM lp );
static void CloseLine();
static BOOL SendDTMF( LPCTSTR lpszDigits, HCALL hCall, DWORD dwDuration );
static BOOL WaitForTAPILine(HCALL hCall, DWORD lineCallState, DWORD interval, DWORD timeout);
static BOOL WaitForLineReply(HCALL hCall, DWORD timeout);
static BOOL WaitIncomingCall();
static void ShowErrorMsg(LPCTSTR lpszInfo, LPCTSTR lpszWho );
static void ShowOperMsg(LPCTSTR lpszInfo );
static void ShowLineErrorMsg(DWORD dwErrorID, LPCTSTR lpszWho);
typedef struct tagLINEINFO


{
HLINE hLine;// 由lineOpen()返回的线路句柄
HCALL hCurrentCall;
BOOL bVoiceLine;
DWORD dwAPIVersion, dwNumOfAddress, dwPermanentLineID;
TCHAR szLineName[256];
// 静音模式
DWORD dwMuteState;
} LINEINFO, *LPLINEINFO;

static LINEINFO g_CurrentLineInfo;

#define BUTTONCLASS _T("button")

#define BUTTONWIDTH 11 * cxAveChar
#define BUTTONHEIGHT 8 * cyAveChar / 4
// 按键间隔
#define BUTTONSPACE 2
#define BUTTONOFFSETLEFT 1
#define BUTTONOFFSETTOP 2 * cyAveChar

int cxAveChar, cyAveChar;


/**//**************************************************************************************

OnCreate

**************************************************************************************/
static LRESULT OnCreate(
HWND hwnd,
CREATESTRUCT* lParam
)


{
// create the menu bar
SHMENUBARINFO mbi;
ZeroMemory(&mbi, sizeof(SHMENUBARINFO));
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = hwnd;
mbi.nToolBarId = IDR_HELLO_MENUBAR;
mbi.hInstRes = g_hDialCallBackInst;
if(!SHCreateMenuBar(&mbi))

{
// Couldn't create the menu bar. Fail creation of the window.
return(-1);
}
HMENU hwndMenuBar = (HMENU)mbi.hwndMB;
// 屏蔽左软件键
// SendMessage((HWND)hwndMenuBar, SHCMBM_OVERRIDEKEY, VK_TSOFT1,
// MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, SHMBOF_NODEFAULT | SHMBOF_NOTIFY));
// 屏蔽右软件键
// SendMessage((HWND)hwndMenuBar, SHCMBM_OVERRIDEKEY, VK_TSOFT2,
// MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, SHMBOF_NODEFAULT | SHMBOF_NOTIFY));

// 屏蔽录音键
SendMessage((HWND)hwndMenuBar, SHCMBM_OVERRIDEKEY, VK_TRECORD,
MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, SHMBOF_NODEFAULT | SHMBOF_NOTIFY));

// 屏蔽BACK键
SendMessage((HWND)hwndMenuBar, SHCMBM_OVERRIDEKEY, VK_TBACK,
MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, SHMBOF_NODEFAULT | SHMBOF_NOTIFY));

// 屏蔽VK_TTALK键
SendMessage((HWND)hwndMenuBar, SHCMBM_OVERRIDEKEY, VK_TTALK,
MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, SHMBOF_NODEFAULT | SHMBOF_NOTIFY));

// 屏蔽VK_TEND键
SendMessage((HWND)hwndMenuBar, SHCMBM_OVERRIDEKEY, VK_TEND,
MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, SHMBOF_NODEFAULT | SHMBOF_NOTIFY));

// 屏蔽app1键
SendMessage((HWND)hwndMenuBar, SHCMBM_OVERRIDEKEY, 0xC1,
MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, SHMBOF_NODEFAULT | SHMBOF_NOTIFY));

// 屏蔽app2键
SendMessage((HWND)hwndMenuBar, SHCMBM_OVERRIDEKEY, 0xC2,
MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, SHMBOF_NODEFAULT | SHMBOF_NOTIFY));
// 屏蔽app3键
SendMessage((HWND)hwndMenuBar, SHCMBM_OVERRIDEKEY, 0xC3,
MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, SHMBOF_NODEFAULT | SHMBOF_NOTIFY));

// 屏蔽VK_THOME键
SendMessage((HWND)hwndMenuBar, SHCMBM_OVERRIDEKEY, VK_THOME,
MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, SHMBOF_NODEFAULT | SHMBOF_NOTIFY));

// // 左键
// LoadString(g_hDialCallBackInst, IDS_MENU_DIAL, g_szMessage, ARRAYSIZE(g_szMessage));
// AppendMenu( hwndMenuBar, MF_STRING, IDM_MENU_DIAL, g_szMessage );
//
// // 右键弹出菜单
// HMENU hPopMenu = CreatePopupMenu();
// LoadString(g_hDialCallBackInst, IDS_MENU_FUN, g_szMessage, ARRAYSIZE(g_szMessage));
// AppendMenu( hPopMenu, MF_STRING, IDM_MENU_FUN, g_szMessage );
// AppendMenu( hwndMenuBar, MF_POPUP, IDM_MENU_FUN, NULL );
//
// LoadString(g_hDialCallBackInst, IDS_MENU_HANGUP, g_szMessage, ARRAYSIZE(g_szMessage));
// AppendMenu( hPopMenu, MF_STRING, IDM_MENU_HANGUP, g_szMessage );
// LoadString(g_hDialCallBackInst, IDS_MENU_CONFIG, g_szMessage, ARRAYSIZE(g_szMessage));
// AppendMenu( hPopMenu, MF_STRING, IDM_MENU_CONFIG, g_szMessage );
// LoadString(g_hDialCallBackInst, IDS_MENU_EXIT, g_szMessage, ARRAYSIZE(g_szMessage));
// AppendMenu( hPopMenu, MF_STRING, IDM_MENU_EXIT, g_szMessage );

// Do other window creation related things here.

return(0); // continue creation of the window
}


/**//**************************************************************************************

WndProc

**************************************************************************************/
LRESULT CALLBACK WndProc(
HWND hwnd,
UINT msg,
WPARAM wp,
LPARAM lp
)


{
LRESULT lResult = TRUE;

switch(msg)

{
case MAKE_INCOMING_CALL:
WaitIncomingCall();
break;
case MAKE_PHONE_BOOK_CALL:
SetWindowText( hFirstNumTxt, (LPCTSTR)lp );
PostMessage( hwnd, MAKE_INCOMING_CALL, 0, 0 );
break;
case WM_CREATE:
lResult = OnCreate(hwnd, (CREATESTRUCT*)lp);
break;
case WM_KEYDOWN:
OnKeyDown(hwnd,wp,lp);
break;
case WM_HOTKEY:

{
// SHSendBackToFocusWindow (msg, wp, lp);
// return TRUE;
DWORD key = HIWORD(lp);
switch( HIWORD(lp) )

{
case VK_TBACK:

{
LoadString(g_hDialCallBackInst, IDS_STRING_INPUTNUMBER, g_szMessage, ARRAYSIZE(g_szMessage));
ShowOperMsg( g_szMessage );
SetWindowText( hFirstNumTxt, _T(""));
}
break;
case VK_THOME:
break;
case VK_TTALK:
break;
case VK_END:
break;
default:
// SHSendBackToFocusWindow (msg, wp, lp);
DefWindowProc(hwnd, msg, wp, lp);
break;
}
break;
}
case WM_COMMAND:
OnCommand( hwnd, msg, wp, lp );
break;
case WM_ACTIVATE:
if( LOWORD( wp ) )

{
if( hFirstNumTxt != NULL )
SetFocus( hFirstNumTxt );
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default: // Pass the message on if unproccessed.
return (DefWindowProc(hwnd, msg, wp, lp));
}

return(lResult);
}
static void OnCommand( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )


{

TCHAR szDialablePhoneNum[TAPIMAXDESTADDRESSSIZE + 1] =
{'\0'};
switch(LOWORD(wp))

{
case IDC_TXT_FIRST:
OnNumTxtCommand( hwnd, wp, lp );
DefWindowProc(hwnd, msg, wp, lp);
break;
case IDM_MENU_EXIT:
CloseLine();
DestroyWindow( hwnd );
break;
case IDM_MENU_TITLE:

{
memset( g_szMessage, 0, sizeof(g_szMessage) );
_tsprintf( g_szMessage, _T("您的手机IMEI是:%s"), g_szIMECode );
MessageBox( hwnd, g_szMessage, _T(""), MB_OK );
break;
}
case IDM_MENU_DIAL:
PostMessage( hDialCallBackMainWnd, MAKE_INCOMING_CALL, 0, 0 );
break;
case IDM_MENU_CONFIG:
CallParamConfigWnd();
break;
case IDM_MENU_HANGUP:
CloseLine();
break;
case IDM_DIAL_LOG:
CallPhoneBookViewWnd();
break;
// 快速拨号,拨号使用上次默认号码
case IDM_QUICK_DIAL:
ShowOperMsg( _T("获取上次拨号
.") );
GetPrePhoneNum();
PostMessage( hDialCallBackMainWnd, MAKE_INCOMING_CALL, 0, 0 );
break;
default:
DefWindowProc(hwnd, msg, wp, lp);
break;
}
}

static void OnNumTxtCommand( HWND hwnd, WPARAM wp, LPARAM lp )


{
DWORD key = 0;
DWORD dwTextLength = 0;
if( g_bComunication == TRUE )

{
key = HIWORD(wp);
switch( key )

{
case EN_CHANGE:
dwTextLength = SendMessage( hFirstNumTxt, WM_GETTEXTLENGTH, 0, 0 );
memset(szTmpInfo, 0, sizeof(szTmpInfo) );
SendMessage( hFirstNumTxt, WM_GETTEXT, (WPARAM)(dwTextLength + 1), (LPARAM)(LPCTSTR)szTmpInfo );
lineGenerateDigits( g_CurrentLineInfo.hCurrentCall, LINEDIGITMODE_DTMF, (LPCTSTR)(szTmpInfo+dwTextLength-1), 0 );
break;
}
}
}


/**//****************************************************************************

ActivatePreviousInstance

****************************************************************************/
HRESULT ActivatePreviousInstance(
const TCHAR* pszClass,
const TCHAR* pszTitle,
BOOL* pfActivated
)


{
HRESULT hr = S_OK;
int cTries;
HANDLE hMutex = NULL;

*pfActivated = FALSE;
cTries = 5;
while(cTries > 0)

{
hMutex = CreateMutex(NULL, FALSE, pszClass); // NOTE: We don't want to own the object.
if(NULL == hMutex)

{
// Something bad happened, fail.
hr = E_FAIL;
goto Exit;
}

if(GetLastError() == ERROR_ALREADY_EXISTS)

{
HWND hwnd;

CloseHandle(hMutex);
hMutex = NULL;

// There is already an instance of this app
// running. Try to bring it to the foreground.

hwnd = FindWindow(pszClass, pszTitle);
if(NULL == hwnd)

{
// It's possible that the other window is in the process of being created
Sleep(500);
hwnd = FindWindow(pszClass, pszTitle);
}

if(NULL != hwnd)&nb