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)&nb