richardli79

导航

WindowsMobile2003拨号回拨

以前写的一手机个来电回拨的例子,贴上来,写得还不完善,好多需要改进的地方。

// 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, 
00 );
        
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, 
0sizeof(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, 
00 );
        
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, 
00 );
        
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, 00 );
            memset(szTmpInfo, 
0sizeof(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) 
            
{
                
// Set the previous instance as the foreground window

                
// The "| 0x01" in the code below activates
                
// the correct owned window of the
                
// previous instance's main window.
                SetForegroundWindow((HWND) (((ULONG) hwnd) | 0x01));

                
// We are done.
                *pfActivated = TRUE;
                
break;
            }


            
// It's possible that the instance we found isn't coming up,
            
// but rather is going down.  Try again.
            cTries--;
        }

        
else
        
{
            
// We were the first one to create the EXITx
            
// so that makes us the main instance.  'leak'
            
// the EXITx in this function so it gets cleaned
            
// up by the OS when this instance exits.
            break;
        }

    }


    
if(cTries <= 0)
    
{
        
// Someone else owns the EXITx but we cannot find
        
// their main window to activate.
        hr = E_FAIL;
        
goto Exit;
    }


Exit:
    
return(hr);
}



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

  WinMain

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


int WINAPI WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPWSTR lpCmdLine,
    
int nCmdShow
    )
{
    MSG msg;
    HWND hwnd 
= NULL;
    BOOL fActivated;
    WNDCLASS wc;
    HWND hwndMain;
    TCHAR szAppTitle[
20];
    memset( szAppTitle, 
0sizeof(szAppTitle) );

    _tcscpy( szAppTitle, _T(
"回拨伴侣V1.0") );
    g_hDialCallBackInst 
= hInstance;


    
if(FAILED(ActivatePreviousInstance(g_szAppWndClass, szAppTitle, &fActivated)) ||
        fActivated)
    
{
        
return(0);
    }


    
// Register our main window's class.
    ZeroMemory(&wc, sizeof(wc));
    wc.style 
= CS_HREDRAW | CS_VREDRAW ;
    wc.lpfnWndProc 
= (WNDPROC)WndProc;
    wc.cbClsExtra 
= 0;
    wc.cbWndExtra 
= 0;
    wc.hIcon 
= (HICON)LoadImage(g_hDialCallBackInst, MAKEINTRESOURCE(IDI_DIAL_ICON), IMAGE_ICON, 32320);
    wc.hInstance 
= g_hDialCallBackInst;
    wc.hCursor 
= NULL;
    wc.hbrBackground 
= (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszMenuName 
= NULL;
    wc.lpszClassName 
= g_szAppWndClass;
    
    UnregisterClass( g_szAppWndClass, g_hDialCallBackInst );
    
if(!RegisterClass(&wc))
    
{
        
return(0);
    }


    
// Create the main window.    
    hwndMain = CreateWindow(g_szAppWndClass, szAppTitle,
            WS_VISIBLE, 
// Setting this to 0 gives a default style we don't want.  Use a benign style bit instead.
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
            NULL, NULL, g_hDialCallBackInst, NULL );
    
if(!hwndMain)
    
{
        
return(0);
    }

    hDialCallBackMainWnd 
= hwndMain;

    CreateWindowItem( hDialCallBackMainWnd );

    SetFocus( hFirstNumTxt );
    GetServerNum();
    GetIMEICode();
    
if( GetCheckInfo() == FALSE )
    
{
//        ShowWindow(hDialCallBackMainWnd, SW_HIDE );
//        UpdateWindow(hDialCallBackMainWnd);
        CallCheckerWnd();
    }

    
else
    
{
        ShowWindow(hwndMain, nCmdShow);
        UpdateWindow(hwndMain);
    }

    
// Pump messages until a PostQuitMessage.
    while(GetMessage(&msg, NULL, 00))
    
{
        TranslateMessage (
&msg);
        DispatchMessage(
&msg);
    }

    
return msg.wParam;
}


static void GetPrePhoneNum()
{
    DWORD dwTextLength;
    TCHAR szDialablePhoneNum[TAPIMAXDESTADDRESSSIZE 
+ 1= {'\0'};
    memset( szDialablePhoneNum, 
0sizeof(szDialablePhoneNum) );
    dwTextLength 
= GetWindowTextLength(hFirstNumTxt) + 1;
    
if( dwTextLength < 3 )
    
{
        
// 如果号码小与3位,拨打默认号码
        _tcscpy( szDialablePhoneNum, _T("1860") );
        SetWindowText( hFirstNumTxt, szDialablePhoneNum );
    }

}


BOOL MakePhoneCall(LPCTSTR lpszPhoneNum, HCALL
* hCall, DWORD pnSize)
{
    DWORD dwSizeOfTransOut 
= sizeof (LINETRANSLATEOUTPUT),
    dwSizeOfCallParams 
= sizeof (LINECALLPARAMS);
    LPLINECALLPARAMS lpCallParams 
= NULL;
    LPLINETRANSLATEOUTPUT lpTransOutput 
= NULL;
    TCHAR szDialablePhoneNum[TAPIMAXDESTADDRESSSIZE 
+ 1= {'\0'};
    memcpy( szDialablePhoneNum, lpszPhoneNum, pnSize );
//_tcslen( lpszPhoneNum ) );
    g_MakeCallRequestID = 0;

    
//拨号:
//    MessageBox( 0, szDialablePhoneNum, _T("DIAL"), 1 );
    g_MakeCallRequestID = lineMakeCall(g_CurrentLineInfo.hLine, 
        
&(*hCall), szDialablePhoneNum, 0, lpCallParams);
    g_CurrentLineInfo.hCurrentCall 
= *hCall;
    g_hCheckedCall 
= *hCall;
    
if!WaitForTAPILine( *hCall, LINECALLSTATE_CONNECTED, 1, LINE_CALL_WAIT_TIMEOUT *2 ) )
    
{
        ShowErrorMsg( _T(
"等待拨号超时"),_T("DIALING") );
        
goto exit;
    }

    
if (g_MakeCallRequestID >= 0
    
{
        g_bCurrentLineAvail 
= FALSE;
    }

    
else 
    
{//关闭线路
        goto exit;
    }

    
return TRUE;
exit:
    
{
        CloseLine();
        
return FALSE;
    }

}


// 拨打指定电话等待指定的返回消息
BOOL MakeDisconnectPhoneCall(HCALL* hCall, DWORD dwLineCallState, LPCTSTR lpszPhoneNum, DWORD pnSize)
{
    DWORD dwSizeOfTransOut 
= sizeof (LINETRANSLATEOUTPUT),
    dwSizeOfCallParams 
= sizeof (LINECALLPARAMS);
    LPLINECALLPARAMS lpCallParams 
= NULL;
    LPLINETRANSLATEOUTPUT lpTransOutput 
= NULL;
    TCHAR szDialablePhoneNum[TAPIMAXDESTADDRESSSIZE 
+ 1= {'\0'};
    memcpy( szDialablePhoneNum, lpszPhoneNum, pnSize );
//_tcslen( lpszPhoneNum ) );
    g_MakeCallRequestID = 0;
    
//拨号:
//    MessageBox( 0, szDialablePhoneNum, _T("DIAL"), 1 );
    g_MakeCallRequestID = lineMakeCall(g_CurrentLineInfo.hLine, 
        
&(*hCall), szDialablePhoneNum, 0, lpCallParams);
    ShowLineErrorMsg( g_MakeCallRequestID, _T(
"lineMakeCall") );
    g_hCheckedCall 
= *hCall;
    g_CurrentLineInfo.hCurrentCall 
= *hCall;
    
if (g_MakeCallRequestID >= 0
    
{
        g_bCurrentLineAvail 
= FALSE;
    }

    
else 
    
{//关闭线路
        ShowLineErrorMsg( g_MakeCallRequestID, _T("lineMakeCall") );
        
goto exit;
    }

    
if!WaitForTAPILine( *hCall, dwLineCallState, 1, LINE_CALL_WAIT_TIMEOUT ) )
    
{
        ShowErrorMsg( _T(
"等待拨号超时"),_T("DIALING") );
        
goto exit;
    }

#ifdef DEBUG
    
if( WaitForTAPILine( *hCall, LINECALLSTATE_DISCONNECTED, 11000 ) )
#else
    
if( WaitForTAPILine( *hCall, LINECALLSTATE_DISCONNECTED, 19000 ) )
#endif
    
{
        ShowErrorMsg( _T(
"对方挂断"),_T("DIALING") );
        
goto exit;
    }

    
return TRUE;
exit:
    
{
        CloseLine();
        
return FALSE;
    }

}


void CreateWindowItem(HWND hWnd)
{
    
int iTop,iLeft,iHeight,iItemHeight,iCount,iWidth;
    HDC hdc 
= GetDC( hWnd );
    DWORD dwBtnStyle 
= WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_OWNERDRAW ;
    TEXTMETRIC tm;
    GetTextMetrics( hdc, 
&tm );
    cxAveChar 
= tm.tmAveCharWidth;
    cyAveChar 
= tm.tmHeight + tm.tmExternalLeading;
    ReleaseDC( hWnd, hdc );
    iCount 
= 0;                // 表示为第几块,从0开始
    iLeft = 5;
    iHeight 
= 30;            // 每块的高度
    iItemHeight = 20;        // TextBox的高度    
    iWidth = 170;
    iTop 
= 5;                // 距离顶端的高度

    LoadString(g_hDialCallBackInst, IDS_STRING_INPUTNUMBER, g_szMessage, ARRAYSIZE(g_szMessage));
    hFirstNumLable 
= CreateWindow(_T("STATIC"),g_szMessage,WS_CHILD | WS_VISIBLE|ES_AUTOHSCROLL,
        iLeft , iCount 
* iHeight + iTop, iWidth ,iItemHeight,hWnd,(HMENU)IDC_LBL_FIRST,g_hDialCallBackInst,NULL);
    
    iCount
++;
    
    hFirstNumTxt 
= CreateWindow(_T("EDIT"),_T(""),WS_CHILD | WS_VISIBLE ,
        iLeft , iTop 
+ iCount * iHeight, iWidth  ,iItemHeight,hWnd,(HMENU)IDC_TXT_FIRST,g_hDialCallBackInst,NULL);
    SendMessage( hFirstNumTxt, EM_SETINPUTMODE, (WPARAM)
0, (LPARAM)EIM_NUMBERS );
}

DWORD InitializeTAPI ()
{
    DWORD dwReturn 
= lineInitialize(&g_hLineApp,g_hDialCallBackInst,(LINECALLBACK) lineCallbackFunc,
        g_szAppWndClass,
&g_dwNumDevs);
    ShowLineErrorMsg( dwReturn, _T(
"lineInitialize") );
    hCurrentRelpyEvent 
= CreateEvent( NULL, TRUE, FALSE, _T("LineReplyEvent") );
    g_LineCallEvent.hLineCallDialingEvent 
= CreateEvent( NULL, TRUE, FALSE, _T("LineCallDialing") );
    g_LineCallEvent.hLineCallProceedingEvent 
= CreateEvent( NULL, TRUE, FALSE, _T("LineCallProceeding") );
    g_LineCallEvent.hLineCallBusyEvent 
= CreateEvent( NULL, TRUE, FALSE, _T("LineCallBusy") );
    g_LineCallEvent.hLineCallConnectedEvent 
= CreateEvent( NULL, TRUE, FALSE, _T("LineCallConnected") );
    g_LineCallEvent.hLineCallDisConnectedEvent 
= CreateEvent( NULL, TRUE, FALSE, _T("LineCallDisConnected") );
    g_LineCallEvent.hLineCallOnHoldEvent 
= CreateEvent( NULL, TRUE, FALSE, _T("LineCallOnHold") );
    g_LineCallEvent.hLineCallRingBackEvent 
= CreateEvent( NULL, TRUE, FALSE, _T("LineCallRingBack") );
    g_LineCallEvent.hLineCallConferencedEvent 
= CreateEvent( NULL, TRUE, FALSE, _T("LineCallConferenced") );
    g_LineCallEvent.hLineCallOfferingEvent 
= CreateEvent( NULL, TRUE, FALSE, _T("LineCallOffering") );
    g_LineCallEvent.hLineCallIdleEvent 
= CreateEvent( NULL, TRUE, FALSE, _T("LineCallIDLE") );
    
return dwReturn;
}


DWORD SelectLine(
const HLINEAPP hLineApp,
                 
const DWORD dwNumberDevices,
                 
const DWORD dwAPIVersionLow,
                 
const DWORD dwAPIVersionHigh,
                 
const TCHAR* const psTSPLineName
                 )
{

    DWORD dwReturn 
= 0xffffffff;
    
for(DWORD dwCurrentDevID = 0 ; dwCurrentDevID < dwNumberDevices ;
        dwCurrentDevID
++)
    
{
        DWORD dwAPIVersion;
        LINEEXTENSIONID LineExtensionID ;
        
if(0 == lineNegotiateAPIVersion(hLineApp, dwCurrentDevID,
            dwAPIVersionLow, dwAPIVersionHigh,
            
&dwAPIVersion, &LineExtensionID)) {
                LINEDEVCAPS LineDevCaps;
                LineDevCaps.dwTotalSize 
= sizeof(LineDevCaps);
                
if(0 == lineGetDevCaps(hLineApp, dwCurrentDevID,
                    dwAPIVersion, 
0&LineDevCaps)) {
                        BYTE
* pLineDevCapsBytes = new BYTE[LineDevCaps.dwNeededSize];
                        
if(0 != pLineDevCapsBytes) {
                            LINEDEVCAPS
* pLineDevCaps = (LINEDEVCAPS*)pLineDevCapsBytes;
                            pLineDevCaps
->dwTotalSize = LineDevCaps.dwNeededSize;
                            
if(0 == lineGetDevCaps(hLineApp, dwCurrentDevID,
                                dwAPIVersion, 
0, pLineDevCaps)) 
                            
{
                                
if(!(_tcscmp((_TCHAR*)((BYTE*)pLineDevCaps+pLineDevCaps->dwLineNameOffset), psTSPLineName)))
                                
{
                                    g_CurrentLineInfo.dwAPIVersion 
= dwAPIVersion;
                                    dwReturn 
= dwCurrentDevID;
                                }


                            }

                            delete[]  pLineDevCapsBytes;
                        }

                    }

            }

    }

    
return dwReturn;
}




VOID CALLBACK lineCallbackFunc (DWORD hDevice,
                                DWORD dwMsg,
                                DWORD dwCallbackInstance,
                                DWORD dwParam1,
                                DWORD dwParam2,
                                DWORD dwParam3)
{
    LINECALLINFO    
*lpCallInfo = NULL;

    
switch (dwMsg)
    
{
    
case LINE_APPNEWCALL:
        
{
            
break;
        }

    
case LINE_REPLY:
        
{
            HCALL hCall 
= (HCALL)hDevice;
            
switch (dwParam2)
            
{
            
case 0:
                
if( g_hCheckedCall == hCall )
                    SetEvent(hCurrentRelpyEvent);
                
break;
            }

        }

    
case LINE_CALLSTATE:
        
{
            DWORD lRes;
            HCALL hCall 
= (HCALL)hDevice;
            
switch (dwParam1)
            
{
            
case LINECALLSTATE_ACCEPTED:
                
//MessageBox( hDialCallBackMainWnd, _T("LINECALLSTATE_ACCEPTED"), _T("LINE_CALLSTATE"), 1 );
                break;
            
case LINECALLSTATE_BUSY:
                
{
                    
//MessageBox( hDialCallBackMainWnd, _T("LINECALLSTATE_BUSY"), _T("LINE_CALLSTATE"), 1 );
                    if( g_hCheckedCall == hCall )
                        SetEvent(g_LineCallEvent.hLineCallBusyEvent);
                    
break;
                }

            
case LINECALLSTATE_CONFERENCED:
                
{
                    
//MessageBox( hDialCallBackMainWnd, _T("LINECALLSTATE_CONFERENCED"), _T("LINE_CALLSTATE"), 1 );
                    if( g_hCheckedCall == hCall )
                        SetEvent(g_LineCallEvent.hLineCallConferencedEvent);
                    
break;
                }

            
case LINECALLSTATE_CONNECTED:
                
{
                    
//MessageBox( hDialCallBackMainWnd, _T("LINECALLSTATE_CONNECTED"), _T("LINE_CALLSTATE"), 1 );
                    if( g_hCheckedCall == hCall )
                        SetEvent(g_LineCallEvent.hLineCallConnectedEvent);
                    
break;
                }

            
case LINECALLSTATE_DIALING:
                
{
                    
//MessageBox( hDialCallBackMainWnd, _T("LINECALLSTATE_DIALING"), _T("LINE_CALLSTATE"), 1 );
                    if( g_hCheckedCall == hCall )
                        SetEvent(g_LineCallEvent.hLineCallDialingEvent);
//                    MessageBox( hDialCallBackMainWnd,_T("DIALING"),_T("DIALING"),1);
                    break;
                }

            
case LINECALLSTATE_DIALTONE:
                ShowErrorMsg( _T(
"LINECALLSTATE_DIALTONE"), _T("LINE_CALLSTATE") );
                
break;
            
case LINECALLSTATE_DISCONNECTED:
                
{
                    g_bComunication 
= FALSE;
                    
if( g_hCheckedCall == hCall )
                    
{
                        SetEvent(g_LineCallEvent.hLineCallDisConnectedEvent);
                    }

                    
if( lpCallInfo != NULL )
                    
{
                        free( lpCallInfo );
                    }

                    lpCallInfo 
= NULL;
                    
break;
                }

            
case LINECALLSTATE_IDLE:
                
//MessageBox( hDialCallBackMainWnd, _T("LINECALLSTATE_IDLE"), _T("LINE_CALLSTATE"), 1 );
                if( g_hCheckedCall == hCall )
                    SetEvent(g_LineCallEvent.hLineCallIdleEvent);
                
break;
            
case LINECALLSTATE_OFFERING:
                
{
                    lRes 
= lineSetCallPrivilege( hCall, LINECALLPRIVILEGE_OWNER );
                    ShowLineErrorMsg( lRes, _T(
"lineSetCallPrivilege") );
                    
if( g_bWaitSecondCall == TRUE )
                    
{
                        lRes 
= lineDrop( hCall, NULL, 0 );
                        ShowLineErrorMsg( lRes, _T(
"lineDrop") );
                        
break;
                    }

                    g_CurrentLineInfo.hCurrentCall 
= hCall;
                    SetEvent(g_LineCallEvent.hLineCallOfferingEvent);
                }

                
break;
            
case LINECALLSTATE_ONHOLD:
                
{
                    
//MessageBox( hDialCallBackMainWnd, _T("LINECALLSTATE_ONHOLD"), _T("LINE_CALLSTATE"), 1 );
                    if( g_hCheckedCall == hCall )
                        SetEvent(g_LineCallEvent.hLineCallOnHoldEvent);
                    
break;
                }

            
case LINECALLSTATE_ONHOLDPENDCONF:
                
//MessageBox( hDialCallBackMainWnd, _T("LINECALLSTATE_ONHOLDPENDCONF"), _T("LINE_CALLSTATE"), 1 );
                break;
            
case LINECALLSTATE_ONHOLDPENDTRANSFER:
                
//MessageBox( hDialCallBackMainWnd, _T("LINECALLSTATE_ONHOLDPENDTRANSFER"), _T("LINE_CALLSTATE"), 1 );
                break;
            
case LINECALLSTATE_PROCEEDING:
                
{
                    
//MessageBox( hDialCallBackMainWnd, _T("LINECALLSTATE_PROCEEDING"), _T("LINE_CALLSTATE"), 1 );
                    if( g_hCheckedCall == hCall )
                        SetEvent(g_LineCallEvent.hLineCallProceedingEvent);
//                    //MessageBox( hDialCallBackMainWnd,_T("拨号完毕,正在呼叫"),_T("拨号完毕,正在呼叫"),1);
                    break;
                }

            
case LINECALLSTATE_RINGBACK:
                
{
                    
//MessageBox( hDialCallBackMainWnd, _T("LINECALLSTATE_RINGBACK"), _T("LINE_CALLSTATE"), 1 );
                    if( g_hCheckedCall == hCall )
                        SetEvent(g_LineCallEvent.hLineCallRingBackEvent);
                    
break;
                }

            
case LINECALLSTATE_SPECIALINFO:
                
//MessageBox( hDialCallBackMainWnd, _T("LINECALLSTATE_SPECIALINFO"), _T("LINE_CALLSTATE"), 1 );
                break;
            
case LINECALLSTATE_UNKNOWN:
                
//MessageBox( hDialCallBackMainWnd, _T("LINECALLSTATE_UNKNOWN"), _T("LINE_CALLSTATE"), 1 );
                break;
//            default:
//                ShowLineErrorMsg( dwParam1, _T("LINE_CALLSTATE") );
//                _tsprintf( g_szMessage, _T("%d"), dwParam1 );
//                MessageBox( hDialCallBackMainWnd, g_szMessage, _T("LINE_CALLSTATE"), 1 );
//                break;
            }

            
break;
        }

    
case LINE_CALLINFO:
        
{
            
//LINECALLINFO    *lpCallInfo;
            if(dwParam1 == LINECALLINFOSTATE_CALLERID)
            
{
                lpCallInfo 
= (LINECALLINFO *)malloc(sizeof(LINECALLINFO)+1000);
                memset(lpCallInfo, 
0sizeof(LINECALLINFO)+1000);
                lpCallInfo
->dwTotalSize = sizeof(LINECALLINFO)+1000;
                
while (1)
                
{
                    lineGetCallInfo(g_CurrentLineInfo.hCurrentCall, lpCallInfo);
                    
if (lpCallInfo->dwTotalSize < lpCallInfo->dwNeededSize)
                        lpCallInfo 
= (LINECALLINFO *)realloc(lpCallInfo,
                        lpCallInfo
->dwNeededSize);
                    
else break;
                }

                lstrcpy(szPhoneNumber,(LPTSTR)((LPSTR)((
                    DWORD)lpCallInfo
+(DWORD)lpCallInfo->
                    dwCallerIDOffset)));
                counterIn 
= true;
                check 
= true;
                
//MessageBox(0,szPhoneNumber,szPhoneNumber,0);
                break;
            }

            
if(dwParam1 == 16 )
            
{
                
if(check == true)
                    
break;

                
if(counterOut == true && counterIn == true)
                
{
                    counterOut 
= false;
                    
//counterOut = true;
                    lpCallInfo = (LINECALLINFO *)malloc(sizeof(LINECALLINFO)+1000);
                    memset(lpCallInfo, 
0sizeof(LINECALLINFO)+1000);
                    lpCallInfo
->dwTotalSize = sizeof(LINECALLINFO)+1000;
                    
while (1)
                    
{
                        lineGetCallInfo(g_CurrentLineInfo.hCurrentCall, lpCallInfo);
                        
if (lpCallInfo->dwTotalSize < lpCallInfo->dwNeededSize)
                            lpCallInfo 
= (LINECALLINFO *)realloc(lpCallInfo,
                            lpCallInfo
->dwNeededSize);
                        
else break;
                    }

                    _tcscpy(szPhoneNumber,(LPTSTR)((LPSTR)((
                        DWORD)lpCallInfo
+(DWORD)lpCallInfo->
                        dwCalledIDOffset)));
                
//    MessageBox( hDialCallBackMainWnd,szPhoneNumber,_T("calledID"),1);
                    break;
                }

                counterOut 
= true;
                lpCallInfo 
= (LINECALLINFO *)malloc(sizeof(LINECALLINFO)+1000);
                memset(lpCallInfo, 
0sizeof(LINECALLINFO)+1000);
                lpCallInfo
->dwTotalSize = sizeof(LINECALLINFO)+1000;
                
while (1)
                
{
                    lineGetCallInfo(g_CurrentLineInfo.hCurrentCall, lpCallInfo);
                    
if (lpCallInfo->dwTotalSize < lpCallInfo->dwNeededSize)
                        lpCallInfo 
= (LINECALLINFO *)realloc(lpCallInfo,
                        lpCallInfo
->dwNeededSize);
                    
else break;
                }

                _tcscpy(szPhoneNumber,(LPTSTR)((LPSTR)((
                    DWORD)lpCallInfo
+(DWORD)lpCallInfo->
                    dwCalledIDOffset)));
        
//        MessageBox( hDialCallBackMainWnd,szPhoneNumber,_T("calledID"),1);
                break;
            }

            
break;
        }

    
default:
        
break;
    }

}


void CloseLine()
{
    LONG    lRes;
    
if( g_CurrentLineInfo.hCurrentCall != NULL )
    
{
        lRes 
= lineDrop( g_CurrentLineInfo.hCurrentCall, NULL, 0 );
        ShowLineErrorMsg( lRes, _T(
"lineDrop") );
        lineDeallocateCall( g_CurrentLineInfo.hCurrentCall );
        ShowLineErrorMsg( lRes, _T(
"lineDeallocateCall") );
        g_CurrentLineInfo.hCurrentCall 
= NULL;
    }

    
if( g_CurrentLineInfo.hLine != NULL )
    
{
        lRes 
= lineClose(g_CurrentLineInfo.hLine);
        ShowLineErrorMsg( lRes, _T(
"LineClose") );
        lRes 
= lineShutdown(g_hLineApp);
        ShowLineErrorMsg( lRes, _T(
"LineShutDown") );
        g_CurrentLineInfo.hLine 
= NULL;
    }

    
if(g_bComunication == TRUE )
    
{
        LoadString(g_hDialCallBackInst, IDS_STRING_INPUTNUMBER, g_szMessage, ARRAYSIZE(g_szMessage));
        ShowOperMsg( g_szMessage );
        g_bComunication 
= FALSE;
    }

    memset( (VOID
*)&g_CurrentLineInfo, 0sizeof(LINEINFO) );
}

// end DialCallBack.cpp
BOOL InitCallLine()
{
    DWORD lRes;
    CloseLine();
    lRes 
= InitializeTAPI ();

    ShowLineErrorMsg( lRes, _T(
"InitializeTAPI") );
    g_dwMediaMode 
= LINEMEDIAMODE_INTERACTIVEVOICE |
        LINEMEDIAMODE_DATAMODEM ;
    g_dwTAPIVer 
= 0x00020000;
    g_dwDevId 
= SelectLine(g_hLineApp,g_dwNumDevs,
        TAPI_API_LOW_VERSION,
        TAPI_API_HIGH_VERSION,
        CELLTSP_LINENAME_STRING);

    
if(g_dwDevId == 0xffffffff)
    
{
        lineShutdown(g_hLineApp);
        
return (FALSE);
    }


    lRes 
= lineOpen(g_hLineApp, g_dwDevId, &g_CurrentLineInfo.hLine, g_CurrentLineInfo.dwAPIVersion,
        
0x000000001, LINECALLPRIVILEGE_MONITOR, g_dwMediaMode, NULL);
    g_lResforcall 
= lRes;
    
if(lRes != 0)
    
{
        ShowLineErrorMsg( lRes, _T(
"lineOpen") );
        lineShutdown(g_hLineApp);
        
return FALSE;
    }

    lineGetMuteState(g_CurrentLineInfo.hLine, 
&g_CurrentLineInfo.dwMuteState );
    lRes 
= lineSetMuteState(g_CurrentLineInfo.hLine, LINEMUTESTATE_MUTEENABLED );
    ShowLineErrorMsg( lRes, _T(
"lineSetMuteState") );
    lRes 
= lineSetAppPriority( g_szAppWndClass, LINEMEDIAMODE_INTERACTIVEVOICE, NULL, 0, NULL, 1 );
    ShowLineErrorMsg( lRes, _T(
"lineSetAppPriority") );
    
return TRUE;
}

static DWORD CallingThreadProc(LPVOID pData)
{
    DWORD lRes;
    TCHAR szDialablePhoneNum[TAPIMAXDESTADDRESSSIZE 
+ 1= {'\0'};
    DWORD dwTextLength 
= 0;
    
if!InitCallLine() )
        
goto EXIT;
    
    
// 拨第一个号码
    _tcscpy( szDialablePhoneNum, g_szServerNum );
    dwTextLength 
= _tcslen( g_szServerNum );

    SetPhoneVolumnMute();

    
if!MakeDisconnectPhoneCall(&g_CurrentLineInfo.hCurrentCall,
        LINECALLSTATE_PROCEEDING, szDialablePhoneNum, dwTextLength 
* 2) )
    
{
        ShowErrorMsg( _T(
"拨打服务器失败"), _T("MakeDisconnectPhoneCall") );
        
goto EXIT;
    }

    
// 挂断该电话,等待他拨回来
    if( g_CurrentLineInfo.hCurrentCall == NULL )
        
goto EXIT;
    g_hCheckedCall 
= g_CurrentLineInfo.hCurrentCall;
    lRes 
= lineDrop( g_CurrentLineInfo.hCurrentCall, NULL, 0 );
    ShowLineErrorMsg( lRes, _T(
"lineDrop") );
    
    
if!WaitForTAPILine( g_CurrentLineInfo.hCurrentCall, LINECALLSTATE_DISCONNECTED, 1, LINE_CALL_WAIT_TIMEOUT ) )
    
{
        
if( g_CurrentLineInfo.hCurrentCall == NULL )
            
goto EXIT;
        ShowErrorMsg( _T(
"电话挂断超时"),_T("lineDrop") );
        
goto EXIT;
    }

    
    ShowErrorMsg( _T(
"等待他拨回来"), _T("等待他拨回来") );
    
if!WaitForTAPILine( g_CurrentLineInfo.hCurrentCall, LINECALLSTATE_OFFERING, 1, LINE_CALL_WAIT_TIMEOUT * 4 ) )
    
{    
        
if( g_CurrentLineInfo.hCurrentCall == NULL )
            
goto EXIT;
        ShowErrorMsg( _T(
"等待来电超时"),_T("DIALING") );
        
goto EXIT;
    }

    
else
    
{
        
if( g_CurrentLineInfo.hCurrentCall == NULL )
            
goto EXIT;
        g_bWaitSecondCall 
= TRUE;
        lRes 
= lineAnswer( g_CurrentLineInfo.hCurrentCall, NULL, 0 );
        ShowLineErrorMsg( lRes, _T(
"lineAnswer") );
    }

    
if( g_CurrentLineInfo.hCurrentCall == NULL )
        
goto EXIT;
    
// 发送特定信息
    memset( szDialablePhoneNum, 0sizeof(szDialablePhoneNum) );
    dwTextLength 
= GetWindowTextLength(hFirstNumTxt) + 1;
    GetWindowText( hFirstNumTxt,(LPTSTR)
&szDialablePhoneNum, dwTextLength );
    AddPhoneNumByTele(szDialablePhoneNum);
    _tcscat( szDialablePhoneNum, _T(
"#") );
    WaitForTAPILine( g_CurrentLineInfo.hCurrentCall, LINECALLSTATE_CONNECTED, 
12000 );
    SendDTMF( szDialablePhoneNum, g_CurrentLineInfo.hCurrentCall, 
0 );
    lRes 
= lineSetMuteState(g_CurrentLineInfo.hLine, LINEMUTESTATE_MUTEDISABLED );
    ShowLineErrorMsg( lRes, _T(
"lineAnswer") );
    ShowOperMsg( _T(
"拨号成功") );
    g_bComunication 
= TRUE;
    ResetPhoneVolumn();
    LoadString(g_hDialCallBackInst, IDS_STRING_COMUNICATION, g_szMessage, ARRAYSIZE(g_szMessage));
    ShowOperMsg( g_szMessage );
    CloseHandle(m_hCallThread);
    m_hCallThread 
= NULL;
    
return TRUE;
EXIT:
    ResetPhoneVolumn();
    CloseLine();
    CloseHandle(m_hCallThread);
    m_hCallThread 
= NULL;
    LoadString(g_hDialCallBackInst, IDS_STRING_INPUTNUMBER, g_szMessage, ARRAYSIZE(g_szMessage));
    ShowOperMsg( g_szMessage );
    
return 0;
}

// 等待指定的电话拨入,如果是默认电话就接起来
BOOL WaitIncomingCall( )
{
    DWORD lRes;
    
if( m_hCallThread != NULL )
    
{
        
if( MessageBox( hDialCallBackMainWnd, _T("电话使用中,确认挂断?"), IDS_DIAL_DIALNUMBER, MB_OKCANCEL ) == IDOK )
        
{
            CloseLine();
            ResetPhoneVolumn();
            
return TRUE;
        }

        
return FALSE;
    }

    
else if(g_bComunication == TRUE )
    
{
        
if( MessageBox( hDialCallBackMainWnd, _T("电话通话中,是否挂断"), IDS_DIAL_DIALNUMBER, MB_OKCANCEL ) == IDOK )
        
{
            CloseLine();
            ResetPhoneVolumn();
            
return TRUE;
        }

        
return FALSE;
    }

    g_bWaitSecondCall 
= FALSE;
    ShowOperMsg( _T(
"拨号中.") );
    m_hCallThread 
= CreateThread(NULL, 0, CallingThreadProc, (LPVOID)NULL, 0&lRes);
    
if ( m_hCallThread == NULL )
        
return FALSE;
    
return TRUE;
}


void ShowLineErrorMsg(DWORD dwErrorID, LPCTSTR lpszWho )
{
    memset( szTmpInfo, 
0sizeof(szTmpInfo) );
    
switch( dwErrorID )
    
{
    
case 0:
        
return;
    
case LINEERR_ADDRESSBLOCKED: _tcscpy( szTmpInfo, _T("The specified address is blocked from being dialed on the specified call."));break;
    
case LINEERR_ALLOCATED: _tcscpy( szTmpInfo, _T("The line cannot be opened due to a persistent condition, such as that of a serial port being exclusively opened by another process."));break;
    
case LINEERR_BADDEVICEID: _tcscpy( szTmpInfo, _T("The specified device identifier or line device identifier (such as in a dwDeviceID parameter) is invalid or out of range."));break;
    
case LINEERR_BEARERMODEUNAVAIL: _tcscpy( szTmpInfo, _T("The bearer mode member in LINECALLPARAMS is invalid, the bearer mode specified in LINECALLPARAMS is not available, or the call's bearer mode cannot be changed to the specified bearer mode."));break;
    
case LINEERR_BILLINGREJECTED: _tcscpy( szTmpInfo, _T("The billing mode of the call was rejected."));break;
    
case LINEERR_CALLUNAVAIL: _tcscpy( szTmpInfo, _T("All call appearances on the specified address are currently in use."));break;
    
case LINEERR_COMPLETIONOVERRUN: _tcscpy( szTmpInfo, _T("The maximum number of outstanding call completions has been exceeded."));break;
    
case LINEERR_CONFERENCEFULL: _tcscpy( szTmpInfo, _T("The maximum number of parties for a conference has been reached, or the requested number of parties cannot be satisfied."));break;
    
case LINEERR_DIALBILLING: _tcscpy( szTmpInfo, _T("The dialable address parameter contains dialing control characters that are not processed by the service provider."));break;
    
case LINEERR_DIALDIALTONE: _tcscpy( szTmpInfo, _T("The dialable address parameter contains dialing control characters that are not processed by the service provider."));break;
    
case LINEERR_DIALPROMPT: _tcscpy( szTmpInfo, _T("The dialable address parameter contains dialing control characters that are not processed by the service provider."));break;
    
case LINEERR_DIALQUIET: _tcscpy( szTmpInfo, _T("The dialable address parameter contains dialing control characters that are not processed by the service provider."));break;
    
case LINEERR_DIALVOICEDETECT: _tcscpy( szTmpInfo, _T("Use of the \":\" dial modifier is not supported. This value is exposed only to applications that negotiate a TAPI version of 2.0 or higher."));break;
    
case LINEERR_INCOMPATIBLEAPIVERSION: _tcscpy( szTmpInfo, _T("The application requested a TAPI version or version range that is either incompatible with, or cannot be supported by, the Telephony API implementation and the corresponding service provider."));break;
    
case LINEERR_INCOMPATIBLEEXTVERSION: _tcscpy( szTmpInfo, _T("The application requested an extension version range that is either invalid or cannot be supported by the corresponding service provider."));break;
    
case LINEERR_INIFILECORRUPT: _tcscpy( szTmpInfo, _T("The telephon.ini file cannot be read or understood properly by TAPI because of internal inconsistencies or formatting problems. For example, the [Locations], [Cards], or [Countries] section of the telephon.ini file may be corrupted or inconsistent."));break;
    
case LINEERR_INUSE: _tcscpy( szTmpInfo, _T("The line device is in use and cannot currently be configured, allow a party to be added, allow a call to be answered, allow a call to be placed, or allow a call to be transferred."));break;
    
case LINEERR_INVALADDRESS: _tcscpy( szTmpInfo, _T("A specified address is either invalid or not allowed. If invalid, the address contains invalid characters or digits, or the destination address contains dialing control characters (W, @, $, or ?) that are not supported by the service provider. If not allowed, the specified address is either not assigned to the specified line or is not valid for address redirection."));break;
    
case LINEERR_INVALADDRESSID: _tcscpy( szTmpInfo, _T("The specified address identifier is either invalid or out of range."));break;
    
case LINEERR_INVALADDRESSMODE: _tcscpy( szTmpInfo, _T("The specified address mode is invalid."));break;
    
case LINEERR_INVALADDRESSSTATE: _tcscpy( szTmpInfo, _T("The specified address state contains one or more bits that are not LINEADDRESSSTATE_ constants."));break;
    
case LINEERR_INVALAGENTACTIVITY: _tcscpy( szTmpInfo, _T("The specified agent activity is not valid."));break;
    
case LINEERR_INVALAGENTGROUP: _tcscpy( szTmpInfo, _T("The specified agent group information is not valid or contains errors. The requested action has not been carried out."));break;
    
case LINEERR_INVALAGENTID: _tcscpy( szTmpInfo, _T("The specified agent identifier is invalid."));break;
    
case LINEERR_INVALAGENTSTATE: _tcscpy( szTmpInfo, _T("The specified agent state is not valid or contains errors. No changes have been made to the agent state of the specified address."));break;
    
case LINEERR_INVALAPPHANDLE: _tcscpy( szTmpInfo, _T("The application handle (such as specified by a hLineApp parameter) or the appliction registration handle is invalid."));break;
    
case LINEERR_INVALAPPNAME: _tcscpy( szTmpInfo, _T("The specified application name is invalid. If an application name is specified by the application, it is assumed that the string does not contain any non-displayable characters, and is zero-terminated."));break;
    
case LINEERR_INVALBEARERMODE: _tcscpy( szTmpInfo, _T("The specified bearer mode is invalid."));break;
    
case LINEERR_INVALCALLCOMPLMODE: _tcscpy( szTmpInfo, _T("The specified completion is invalid."));break;
    
case LINEERR_INVALCALLHANDLE: _tcscpy( szTmpInfo, _T("The specified call handle is not valid. For example, the handle is not NULL but does not belong to the given line. In some cases, the specified call device handle is invalid."));break;
    
case LINEERR_INVALCALLPARAMS: _tcscpy( szTmpInfo, _T("The specified call parameters are invalid."));break;
    
case LINEERR_INVALCALLPRIVILEGE: _tcscpy( szTmpInfo, _T("The specified call privilege parameter is invalid."));break;
    
case LINEERR_INVALCALLSELECT: _tcscpy( szTmpInfo, _T("The specified select parameter is invalid."));break;
    
case LINEERR_INVALCALLSTATE: _tcscpy( szTmpInfo, _T("The current state of a call is not in a valid state for the requested operation."));break;
    
case LINEERR_INVALCALLSTATELIST: _tcscpy( szTmpInfo, _T("The specified call state list is invalid."));break;
    
case LINEERR_INVALCARD: _tcscpy( szTmpInfo, _T("The permanent card identifier specified in dwCard could not be found in any entry in the [Cards] section in the registry."));break;
    
case LINEERR_INVALCOMPLETIONID: _tcscpy( szTmpInfo, _T("The completion identifier is invalid."));break;
    
case LINEERR_INVALCONFCALLHANDLE: _tcscpy( szTmpInfo, _T("The specified call handle for the conference call is invalid or is not a handle for a conference call."));break;
    
case LINEERR_INVALCONSULTCALLHANDLE: _tcscpy( szTmpInfo, _T("The specified consultation call handle is invalid."));break;
    
case LINEERR_INVALCOUNTRYCODE: _tcscpy( szTmpInfo, _T("The specified country code is invalid."));break;
    
case LINEERR_INVALDEVICECLASS: _tcscpy( szTmpInfo, _T("The line device has no associated device for the given device class, or the specified line does not support the indicated device class."));break;
    
case LINEERR_INVALDEVICEHANDLE: _tcscpy( szTmpInfo, _T("The line device handle is invalid."));break;
    
case LINEERR_INVALDIALPARAMS: _tcscpy( szTmpInfo, _T("The dialing parameters are invalid."));break;
    
case LINEERR_INVALDIGITLIST: _tcscpy( szTmpInfo, _T("The specified digit list is invalid."));break;
    
case LINEERR_INVALDIGITMODE: _tcscpy( szTmpInfo, _T("The specified digit mode is invalid."));break;
    
case LINEERR_INVALDIGITS: _tcscpy( szTmpInfo, _T("The specified termination digits are not valid."));break;
    
case LINEERR_INVALEXTVERSION: _tcscpy( szTmpInfo, _T("The service provider extension version number is invalid."));break;
    
case LINEERR_INVALFEATURE: _tcscpy( szTmpInfo, _T("The dwFeature parameter is invalid."));break;
    
case LINEERR_INVALGROUPID: _tcscpy( szTmpInfo, _T("The specified group identifier is invalid."));break;
    
case LINEERR_INVALLINEHANDLE: _tcscpy( szTmpInfo, _T("The specified call, device, line device, or line handle is invalid."));break;
    
case LINEERR_INVALLINESTATE: _tcscpy( szTmpInfo, _T("The device configuration may not be changed in the current line state. The line may be in use by another application or a dwLineStates parameter contains one or more bits that are not LINEDEVSTATE_ constants. The LINEERR_INVALLINESTATE value can also indicate that the device is DISCONNECTED or OUTOFSERVICE. These states are indicated by setting the bits corresponding to the LINEDEVSTATUSFLAGS_CONNECTED and LINEDEVSTATUSFLAGS_INSERVICE values to 0 in the dwDevStatusFlags member of the LINEDEVSTATUS structure returned by the lineGetLineDevStatus function."));break;
    
case LINEERR_INVALLOCATION: _tcscpy( szTmpInfo, _T("The permanent location identifier specified in dwLocation could not be found in any entry in the [Locations] section in the registry."));break;
    
case LINEERR_INVALMEDIALIST: _tcscpy( szTmpInfo, _T("The specified media list is invalid."));break;
    
case LINEERR_INVALMEDIAMODE: _tcscpy( szTmpInfo, _T("The list of media types (modes) to be monitored contains invalid information, the specified media type parameter is invalid, or the service provider does not support the specified media type. The media types supported on the line are listed in the dwMediaModes member in the LINEDEVCAPS structure."));break;
    
case LINEERR_INVALMESSAGEID: _tcscpy( szTmpInfo, _T("The number given in dwMessageID is outside the range specified by the dwNumCompletionMessages member in the LINEADDRESSCAPS structure."));break;
    
case LINEERR_INVALPARAM: _tcscpy( szTmpInfo, _T("A parameter or structure that a parameter points to contains invalid information, a country code is invalid, a window handle is invalid, or the specified forward list parameter contains invalid information."));break;
    
case LINEERR_INVALPARKID: _tcscpy( szTmpInfo, _T("The park identifier is invalid."));break;
    
case LINEERR_INVALPARKMODE: _tcscpy( szTmpInfo, _T("The specified park mode is invalid."));break;
    
case LINEERR_INVALPASSWORD: _tcscpy( szTmpInfo, _T("The specified password is not correct and the requested action has not been carried out."));break;
    
case LINEERR_INVALPOINTER: _tcscpy( szTmpInfo, _T("One or more of the specified pointer parameters (such as lpCallList, lpdwAPIVersion, lpExtensionID, lpdwExtVersion, lphIcon, lpLineDevCaps, and lpToneList) are invalid, or a required pointer to an output parameter is NULL."));break;
    
case LINEERR_INVALPRIVSELECT: _tcscpy( szTmpInfo, _T("An invalid flag or combination of flags was set for the dwPrivileges parameter."));break;
    
case LINEERR_INVALRATE: _tcscpy( szTmpInfo, _T("The specified rate is invalid."));break;
    
case LINEERR_INVALREQUESTMODE: _tcscpy( szTmpInfo, _T("The LINEREQUESTMODE indicator is invalid."));break;
    
case LINEERR_INVALTERMINALID: _tcscpy( szTmpInfo, _T("The specified terminal identifier is invalid."));break;
    
case LINEERR_INVALTERMINALMODE: _tcscpy( szTmpInfo, _T("The specified terminal modes parameter is invalid."));break;
    
case LINEERR_INVALTIMEOUT: _tcscpy( szTmpInfo, _T("Timeouts are not supported or a value falls outside the valid range specified in LINEDEVCAPS."));break;
    
case LINEERR_INVALTONE: _tcscpy( szTmpInfo, _T("The specified custom tone does not represent a valid tone or is made up of too many frequencies or the specified tone structure does not describe a valid tone."));break;
    
case LINEERR_INVALTONELIST: _tcscpy( szTmpInfo, _T("The specified tone list is invalid."));break;
    
case LINEERR_INVALTONEMODE: _tcscpy( szTmpInfo, _T("The specified tone mode parameter is invalid."));break;
    
case LINEERR_INVALTRANSFERMODE: _tcscpy( szTmpInfo, _T("The specified transfer mode parameter is invalid."));break;
    
case LINEERR_LINEMAPPERFAILED: _tcscpy( szTmpInfo, _T("LINEMAPPER was the value passed in the dwDeviceID parameter, but no lines were found that match the requirements specified in the CallParams parameter."));break;
    
case LINEERR_NOCONFERENCE: _tcscpy( szTmpInfo, _T("The specified call is not a conference call handle or a participant call."));break;
    
case LINEERR_NODEVICE: _tcscpy( szTmpInfo, _T("The specified device identifier, which was previously valid, is no longer accepted because the associated device has been removed from the system since TAPI was last initialized. Alternately, the line device has no associated device for the given device class."));break;
    
case LINEERR_NODRIVER: _tcscpy( szTmpInfo, _T("Either tapiaddr.dll could not be located or the telephone service provider for the specified device found that one of its components is missing or corrupt in a way that was not detected at initialization time. The user should be advised to use the Telephony Control Panel to correct the problem."));break;
    
case LINEERR_NOMEM: _tcscpy( szTmpInfo, _T("Insufficient memory to perform the operation, or unable to lock memory."));break;
    
case LINEERR_NOMULTIPLEINSTANCE: _tcscpy( szTmpInfo, _T("A telephony service provider that does not support multiple instances is listed more than once in the [Providers] section in the registry. The application should advise the user to use the Telephony Control Panel to remove the duplicated driver."));break;
    
case LINEERR_NOREQUEST: _tcscpy( szTmpInfo, _T("There currently is no request pending of the indicated mode, or the application is no longer the highest-priority application for the specified request mode."));break;
    
case LINEERR_NOTOWNER: _tcscpy( szTmpInfo, _T("The application does not have owner privilege to the specified call."));break;
    
case LINEERR_NOTREGISTERED: _tcscpy( szTmpInfo, _T("The application is not registered as a request recipient for the indicated request mode."));break;
    
case LINEERR_OPERATIONFAILED: _tcscpy( szTmpInfo, _T("The operation failed for an unspecified or unknown reason."));break;
    
case LINEERR_OPERATIONUNAVAIL: _tcscpy( szTmpInfo, _T("The operation is not available, such as for the given device or specified line."));break;
    
case LINEERR_RATEUNAVAIL: _tcscpy( szTmpInfo, _T("The service provider currently does not have enough bandwidth available for the specified rate."));break;
    
case LINEERR_REINIT: _tcscpy( szTmpInfo, _T("If TAPI reinitialization has been requested, for example as a result of adding or removing a telephony service provider, then lineInitialize, lineInitializeEx, or lineOpen requests are rejected with this error until the last application shuts down its usage of the API (using lineShutdown), at which time the new configuration becomes effective and applications are once again permitted to call lineInitialize or lineInitializeEx."));break;
    
case LINEERR_REQUESTOVERRUN: _tcscpy( szTmpInfo, _T("More requests are pending than the device can handle."));break;
    
case LINEERR_RESOURCEUNAVAIL: _tcscpy( szTmpInfo, _T("Insufficient resources to complete the operation. For example, a line cannot be opened due to a dynamic resource overcommitment."));break;
    
case LINEERR_STRUCTURETOOSMALL: _tcscpy( szTmpInfo, _T("The dwTotalSize member of a structure does not specify enough memory to contain the fixed portion of the specified structure."));break;
    
case LINEERR_TARGETNOTFOUND: _tcscpy( szTmpInfo, _T("A target for the call handoff was not found. This can occur if the named application did not open the same line with the LINECALLPRIVILEGE_OWNER bit in the dwPrivileges parameter of lineOpen. Or, in the case of media-mode handoff, no application has opened the same line with the LINECALLPRIVILEGE_OWNER bit in the dwPrivileges parameter of lineOpen and with the media type specified in the dwMediaMode parameter having been specified in the dwMediaModes parameter of lineOpen."));break;
    
case LINEERR_TARGETSELF: _tcscpy( szTmpInfo, _T("The application invoking this operation is the target of the indirect handoff. That is, TAPI has determined that the calling application is also the highest priority application for the given media type."));break;
    
case LINEERR_UNINITIALIZED: _tcscpy( szTmpInfo, _T("The operation was invoked before any application called lineInitialize or lineInitializeEx."));break;
    
case LINEERR_USERUSERINFOTOOBIG: _tcscpy( szTmpInfo, _T("The string containing user-user information exceeds the maximum number of bytes specified in the dwUUIAcceptSize, dwUUIAnswerSize, dwUUIDropSize, dwUUIMakeCallSize, or dwUUISendUserUserInfoSize member of LINEDEVCAPS, or the string containing user-user information is too long."));break;
    }

#ifdef DEBUG
    
if( _tcslen(szTmpInfo) > 0 )
    
{
        MessageBox( hDialCallBackMainWnd, szTmpInfo, lpszWho, 
1 );
    }

#endif
    
/*
#else
    if( _tcslen(szTmpInfo) > 0 )
    {
        SetWindowText( GetDlgItem( hDialCallBackMainWnd, IDC_LBL_FIRST ), szTmpInfo );
    }
#endif
    
*/

}

static void ShowOperMsg(LPCTSTR lpszInfo )
{
    
if( _tcslen(lpszInfo) > 0 )
    
{
        SendMessage( GetDlgItem( hDialCallBackMainWnd, IDC_LBL_FIRST ), WM_SETTEXT, 
0, (LPARAM)lpszInfo );
//        SetWindowText( GetDlgItem( hDialCallBackMainWnd, IDC_LBL_FIRST ), lpszInfo );
    }

}

static void ShowErrorMsg(LPCTSTR lpszInfo, LPCTSTR lpszWho )
{
#ifdef DEBUG
    
if( _tcslen(lpszInfo) > 0 )
    
{
        MessageBox( hDialCallBackMainWnd, lpszInfo, lpszWho, 
1 );
    }

#else
    
if( _tcslen(lpszInfo) > 0 )
    
{
        SetWindowText( GetDlgItem( hDialCallBackMainWnd, IDC_LBL_FIRST ), lpszInfo );
    }

#endif
}

// 是否超时等待,返回值TRUE表示没有超时,FALSE表示超时
BOOL WaitForTAPILine(HCALL hCall, DWORD lineCallState, DWORD interval, DWORD timeout)
{
    HANDLE hCurrentWaitEvent 
= NULL;
    
switch( lineCallState )
    
{
    
case LINECALLSTATE_OFFERING:
        hCurrentWaitEvent 
= g_LineCallEvent.hLineCallOfferingEvent;
        
break;
    
case LINECALLSTATE_IDLE:
        hCurrentWaitEvent 
= g_LineCallEvent.hLineCallIdleEvent;
        
break;
    
case LINECALLSTATE_DIALING:
        hCurrentWaitEvent 
= g_LineCallEvent.hLineCallDialingEvent;
        
break;
    
case LINECALLSTATE_PROCEEDING:
        hCurrentWaitEvent 
= g_LineCallEvent.hLineCallProceedingEvent;
        
break;
    
case LINECALLSTATE_BUSY:
        hCurrentWaitEvent 
= g_LineCallEvent.hLineCallBusyEvent;
        
break;
    
case LINECALLSTATE_CONNECTED:
        hCurrentWaitEvent 
= g_LineCallEvent.hLineCallConnectedEvent;
        
break;
    
case LINECALLSTATE_DISCONNECTED:
        hCurrentWaitEvent 
= g_LineCallEvent.hLineCallDisConnectedEvent;
        
break;
    
case LINECALLSTATE_RINGBACK:
        hCurrentWaitEvent 
= g_LineCallEvent.hLineCallRingBackEvent;
        
break;
    
case LINECALLSTATE_ONHOLD:
        hCurrentWaitEvent 
= g_LineCallEvent.hLineCallOnHoldEvent;
        
break;
    
case LINECALLSTATE_CONFERENCED:
        hCurrentWaitEvent 
= g_LineCallEvent.hLineCallConferencedEvent;
        
break;
    }

    
if( WaitForSingleObject(hCurrentWaitEvent,timeout) == WAIT_OBJECT_0 )
    
{
        ResetEvent( hCurrentWaitEvent );
        
// 等到需要的消息
        return TRUE;
    }
else
    
{
        ResetEvent( hCurrentWaitEvent );
        
// 取消或者超时
        return FALSE;
    }

}


// 是否超时等待,返回值TRUE表示没有超时,FALSE表示超时
BOOL WaitForLineReply(HCALL hCall, DWORD timeout)
{
    
if( WaitForSingleObject(hCurrentRelpyEvent,timeout) == WAIT_OBJECT_0 )
    
{
        ResetEvent( hCurrentRelpyEvent );
        
// 等到需要的消息
        return TRUE;
    }
else
    
{
        ResetEvent( hCurrentRelpyEvent );
        
// 取消或者超时
        return FALSE;
    }

}


BOOL SendDTMF( LPCTSTR lpszDigits, HCALL hCall, DWORD dwDuration )
{
    DWORD dwReturn;
    TCHAR pBuffer[
256= {0};
    dwReturn 
= lineGenerateDigits( hCall, LINEDIGITMODE_DTMF, lpszDigits, dwDuration );
    ShowLineErrorMsg( dwReturn, _T(
"lineGenerateDigits") );
    
return TRUE;
}

static void OnKeyDown(HWND hwnd, WPARAM wp, LPARAM lp)
{
    
if( g_bComunication == TRUE )
    
{
        
switch( wp )
        
{
        
case VK_NUMPAD0:
            lineGenerateDigits( g_CurrentLineInfo.hCurrentCall, LINEDIGITMODE_DTMF, _T(
"0"), 0 );
            
break;
        
case VK_NUMPAD1:
            lineGenerateDigits( g_CurrentLineInfo.hCurrentCall, LINEDIGITMODE_DTMF, _T(
"1"), 0 );
            
break;
        
case VK_NUMPAD2:
            lineGenerateDigits( g_CurrentLineInfo.hCurrentCall, LINEDIGITMODE_DTMF, _T(
"2"), 0 );
            
break;
        
case VK_NUMPAD3:
            lineGenerateDigits( g_CurrentLineInfo.hCurrentCall, LINEDIGITMODE_DTMF, _T(
"3"), 0 );
            
break;
        
case VK_NUMPAD4:
            lineGenerateDigits( g_CurrentLineInfo.hCurrentCall, LINEDIGITMODE_DTMF, _T(
"4"), 0 );
            
break;
        
case VK_NUMPAD5:
            lineGenerateDigits( g_CurrentLineInfo.hCurrentCall, LINEDIGITMODE_DTMF, _T(
"5"), 0 );
            
break;
        
case VK_NUMPAD6:
            lineGenerateDigits( g_CurrentLineInfo.hCurrentCall, LINEDIGITMODE_DTMF, _T(
"6"), 0 );
            
break;
        
case VK_NUMPAD7:
            lineGenerateDigits( g_CurrentLineInfo.hCurrentCall, LINEDIGITMODE_DTMF, _T(
"7"), 0 );
            
break;
        
case VK_NUMPAD8:
            lineGenerateDigits( g_CurrentLineInfo.hCurrentCall, LINEDIGITMODE_DTMF, _T(
"8"), 0 );
            
break;
        
case VK_NUMPAD9:
            lineGenerateDigits( g_CurrentLineInfo.hCurrentCall, LINEDIGITMODE_DTMF, _T(
"9"), 0 );
            
break;
        
case VK_MULTIPLY:
            lineGenerateDigits( g_CurrentLineInfo.hCurrentCall, LINEDIGITMODE_DTMF, _T(
"*"), 0 );
            
break;
        }

    }

    DefWindowProc(hwnd, WM_KEYDOWN, wp, lp);
}

static BOOL GetIMEICode()
{
    TCHAR nTmp[
10];
    DWORD dwIMEIHi 
= 0, dwIMEILo = 0;
    DWORD dwRes 
= 0;
    g_dwCheckNumber 
= 0;
    memset( g_szIMECode, 
0sizeof(g_szIMECode) );
    
if!InitCallLine() )
        
return FALSE;
    LINEGENERALINFO
* lpLineGeneralInfo = (LINEGENERALINFO*)malloc(sizeof(LINEGENERALINFO)+1000);
    lpLineGeneralInfo
->dwTotalSize = sizeof(LINEGENERALINFO)+1000;
    dwRes 
= lineGetGeneralInfo( g_CurrentLineInfo.hLine, lpLineGeneralInfo );
    ShowLineErrorMsg( dwRes, _T(
"lineGetGeneralInfo") );
    memset( szTmpInfo, 
0sizeof(szTmpInfo) );
    memset( nTmp, 
0sizeof( nTmp ) );
    _tcscpy( szTmpInfo, (LPCTSTR)((LPSTR)(
        (DWORD)lpLineGeneralInfo 
+ (DWORD)lpLineGeneralInfo->dwSerialNumberOffset)));
    
if( _tcslen( szTmpInfo ) >= 15 )
    
{
        
int i = 0, j = 0;
        
if( _tcslen( szTmpInfo ) < NEEDEDIMEICODELENGTH )
        
{
            _tcscat( szTmpInfo , _T(
"00") );
        }

        _tcsncpy( g_szIMECode, szTmpInfo, NEEDEDIMEICODELENGTH );
        memset(nTmp, 
0sizeof(nTmp));
        
for(i = 0; i < 9; i++ )
        
{
            
if( isdigit(g_szIMECode[i]) )
            
{
                nTmp[j] 
= g_szIMECode[i];
                j
++;
            }

        }

        dwIMEIHi 
= (DWORD)_ttol( nTmp );

        memset( nTmp, 
0sizeof( nTmp ) );
        j 
= 0;
        
for(i = 9; i < NEEDEDIMEICODELENGTH; i++ )
        
{
            
if( isdigit(g_szIMECode[i]) )
            
{
                nTmp[j] 
= g_szIMECode[i];
                j
++;
            }

        }

        dwIMEILo 
= (DWORD)_ttol( nTmp );
        g_dwCheckNumber 
= dwIMEIHi + dwIMEILo;
        
return TRUE;
    }

    
else
        
return FALSE;
}


BOOL SetPhoneVolumnMute()
{
    HKEY Key;
    DWORD res,dwReadVolumn,dwBufferSize,dwType,dwVolumnSize, i;
    
//dwVolumn between 0 and 0xFFFFFFFF 
/*
    res = RegOpenKeyEx(HKEY_CURRENT_USER,_T("\\ControlPanel\\Volume"),0,0,&Key); 
    if (res == ERROR_SUCCESS) 
    {
        i = 0;
        while( res != ERROR_NO_MORE_ITEMS )
        {
            memset( g_szMessage, 0, sizeof(g_szMessage) );
            dwBufferSize = ARRAYSIZE(g_szMessage);
            res = RegEnumValue( Key, i++, g_szMessage, &dwBufferSize, NULL, &dwType, (LPBYTE)&dwReadVolumn, &dwVolumnSize );
            if( res == ERROR_SUCCESS )
            {
                if( (dwType == REG_DWORD) && (_tcscmp( g_szMessage, _T("Ringer") ) == 0) )
                {
                    g_dwVolumnRinger = dwReadVolumn;
                    break;
                }
            }
        }
        dwReadVolumn = 0;
        res = RegSetValueEx(Key,_T("Ringer"),0,REG_DWORD,(LPBYTE)&dwReadVolumn,sizeof(DWORD)); 
        if (res != ERROR_SUCCESS) 
        {    
            RegCloseKey(Key); 
            return FALSE;
        } 
    }
    RegCloseKey(Key);

*/

    
//dwInitVol between 1 and 5 
    res = RegOpenKeyEx(HKEY_CURRENT_USER,_T("\\ControlPanel\\SoundCategories\\Ring"),0,0,&Key); 
    
if (res == ERROR_SUCCESS) 
    
{    
        i 
= 0;
        
while( res != ERROR_NO_MORE_ITEMS )
        
{
            memset( g_szMessage, 
0sizeof(g_szMessage) );
            dwBufferSize 
= ARRAYSIZE(g_szMessage);
            res 
= RegEnumValue( Key, i, g_szMessage, &dwBufferSize, NULL, &dwType, (LPBYTE)&dwReadVolumn, &dwVolumnSize );
            
if( res == ERROR_SUCCESS )
            
{
                
if( (dwType == REG_DWORD) && (_tcscmp( g_szMessage, _T("InitVol") ) == 0) )
                
{
                    g_RingInitVol 
= dwReadVolumn;
                    
break;
                }

            }

            i
++;
        }

        dwReadVolumn 
= 0;
        res 
= RegSetValueEx(Key,_T("InitVol"),0,REG_DWORD,(LPBYTE)&dwReadVolumn,sizeof(DWORD)); 
        
if (res != ERROR_SUCCESS) 
        
{    
            RegCloseKey(Key); 
            
return FALSE; 
        }

    }

    RegCloseKey(Key); 
    
return TRUE;
}


BOOL ResetPhoneVolumn()
{
    DWORD res;
    HKEY Key;
/*
    res = RegOpenKeyEx(HKEY_CURRENT_USER,_T("\\ControlPanel\\Volume"),0,0,&Key); 
    if (res == ERROR_SUCCESS) 
    {    
        res = RegSetValueEx(Key,_T("Ringer"),0,REG_DWORD,(LPBYTE)&g_dwVolumnRinger,sizeof(DWORD)); 
        if (res != ERROR_SUCCESS) 
        {    
            RegCloseKey(Key); 
            return FALSE; 
        } 
    } 
    RegCloseKey(Key); 
*/

    
//dwInitVol between 1 and 5 
    res = RegOpenKeyEx(HKEY_CURRENT_USER,_T("\\ControlPanel\\SoundCategories\\Ring"),0,0,&Key); 
    
if (res == ERROR_SUCCESS) 
    
{    
        res 
= RegSetValueEx(Key,_T("InitVol"),0,REG_DWORD,(LPBYTE)&g_RingInitVol,sizeof(DWORD)); 
        
if (res != ERROR_SUCCESS) 
        
{    
            RegCloseKey(Key); 
            
return FALSE; 
        }
 
    }
 
    RegCloseKey(Key); 
    
return TRUE;
}

posted on 2007-01-08 12:53  Richard  阅读(1803)  评论(3编辑  收藏  举报