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

📄 voipapp.cpp

📁 一个WinCE6。0下的IP phone的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

    //intialize the speaker volume as the current active volume mode
    PHSetActiveVolume(RingerVolumeMode); 

    hr = EnableCalling(); 
    if (FAILED(hr))
    {
        PHONEAPP_RETAILMSG(ZONE_PHONEAPP_ERROR, (L"Failed to enable calling, hr = 0x%x", hr)); 
        goto exit; 
    }

    //start listening the setting changes
    hr = m_Settings.StartListening();
    if (FAILED(hr))
    {
        PHONEAPP_RETAILMSG(ZONE_PHONEAPP_ERROR, (L"Failed to start listening the setting changes, hr = 0x%x", hr));
        goto exit; 
    }

    PumpMessages(); 

exit:

    //cleanup
    m_AudioManager.Uninitialize();     
    m_Poom.Uninitialize(); 
    
    if (m_PendingAuthAction != ActionInvalid)
    {
        PHCancelAuthenticationRequest(m_NotificationWindow);
    }

    DestroyWindow(m_NotificationWindow);

    return hr;
}

/*------------------------------------------------------------------------------
    VoIPApp_t::CreateNotificationWindow

    Creates the listner window
------------------------------------------------------------------------------*/
HRESULT
VoIPApp_t::CreateNotificationWindow(
    void
    )
{
    if (m_NotificationWindow != NULL)
    {
        //already registered!
        ASSERT(FALSE);
        return S_FALSE;
    }

    //register our notification window class
    WNDCLASS    WindowClass     = {0};
    WindowClass.lpfnWndProc     = s_NotificationWindowProc;
    WindowClass.hInstance       = GlobalData_t::s_ModuleInstance;
    WindowClass.lpszClassName   = WNDCLASS_PHONEAPP;

    //it's ok if our class already exists...
    if (! RegisterClass(&WindowClass) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Could not register the window class - last error = (decimal) %d", GetLastError()));
        ASSERT(FALSE);
        return E_FAIL;
    }

    //create the notification window and pack our 'this' pointer into the CREATESTRUCT
    m_NotificationWindow = CreateWindow(
        WNDCLASS_PHONEAPP,
        NULL,
        0, 0, 0, 0, 0, NULL, NULL,
        GlobalData_t::s_ModuleInstance,
        reinterpret_cast<void*>(this)
        );
    if (m_NotificationWindow == NULL)
    {
        ASSERT(FALSE);
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Could not create the listener window! - error code (decimal) %d", GetLastError()));
        return CommonUtilities_t::GetErrorFromWin32();
    }

    return S_OK;
}

/*------------------------------------------------------------------------------
    VoIPApp_t::s_NotificationWindowProc

    Static WndProc for our notification window class.
    Delegates processing to an instance of the window class
------------------------------------------------------------------------------*/
/* static */ LRESULT WINAPI VoIPApp_t::s_NotificationWindowProc(
    HWND hwnd,
    UINT Message,
    WPARAM wParam,
    LPARAM lParam
    )
{
    VoIPApp_t *pVoIPApp = NULL;

    if (Message == WM_CREATE)
    {
        //On WM_CREATE we packed a VoIPApp_t object into the createstruct.
        //Now we extract that object and store it in the USERDATA section of the window
        CREATESTRUCT *pCreateStruct = reinterpret_cast<CREATESTRUCT*>(lParam);
        if (! pCreateStruct)
        {
            ASSERT(FALSE);
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"CreateStruct is empty - cannot create this window"));
            return -1;
        }

        pVoIPApp = reinterpret_cast<VoIPApp_t*>(pCreateStruct->lpCreateParams);
        if (! pVoIPApp)
        {
            ASSERT(FALSE);
            PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"No canvas object in the create struct - cannot create this window"));
            return -1;
        }

        //Pack the canvas object into the window for future retrieval
        SetWindowLong(hwnd, GWL_USERDATA, reinterpret_cast<LONG>(pVoIPApp));
    }

    //Retrieve the object from the window userdata section
    pVoIPApp = reinterpret_cast<VoIPApp_t*>(GetWindowLong(hwnd, GWL_USERDATA));

    if (! pVoIPApp)
    {
        return DefWindowProc(hwnd, Message, wParam, lParam);
    }

    //stabilize the object for this message processing
    pVoIPApp->AddRef();

    //Let the object handle the message
    LRESULT ReturnValue = pVoIPApp->NotificationWindowProc(hwnd, Message, wParam, lParam);

    //release the reference we added before processing the message
    pVoIPApp->Release();

    if (Message == WM_DESTROY)
    {
        SetWindowLong(hwnd, GWL_USERDATA, 0);
    }

    return ReturnValue;
}

LRESULT VoIPApp_t::NotificationWindowProc(
    HWND    hwnd, 
    UINT    Message, 
    WPARAM  wParam, 
    LPARAM  lParam
    )
{
    LRESULT ReturnValue = 0; 
    PCOPYDATASTRUCT pCopyDataStruct = NULL; 

    switch (Message)
    {
    //on create we need to register the hotkeys
    case WM_CREATE:
        HotKeys_t::RegisterHotKeys(hwnd);
        InitializeHookState();
        break;

    case WM_DESTROY:
        HotKeys_t::UnRegisterHotKeys(hwnd);
        ReturnValue = 1; //implies NOT processed
        break;

    case WM_CLOSE:
        Shutdown();
        ReturnValue = 0;
        break;
        
    //On hotkey, delegate to the handlers
    case WM_HOTKEY:
        ReturnValue = RespondToHotKey(
            (INT)wParam,
            (UINT)HIWORD(lParam),
            ((UINT)LOWORD(lParam) & MOD_KEYUP)
            );
        break;

    case WM_HIBERNATE:         
        OnHibernate(); 
        break; 

    case WM_TIMER: 
        m_Timers.OnTimerEvent(wParam); 
        break; 

    case WM_NEW_COMMAND_LINE:
        // Just set existing app as the foreground window for now
        ForegroundExistingApp();
        break;

    case WM_DIALED_DIGIT: 
        m_UIManager.OnHookDialing(
            static_cast<WCHAR>(wParam)
            ); 
        break; 

    case WM_AUTH_COMPLETE:
        OnAuthRequestComplete(
            static_cast<AuthenticationResult_e>(wParam)
            );
        break;
        
#ifdef DEBUG

    case WM_DEBUG_PHONE_STATE: 
        DebugPhoneState();         
        break; 

#endif

    case WM_COPYDATA: 
        pCopyDataStruct = (PCOPYDATASTRUCT) lParam; 
        if (pCopyDataStruct == NULL)
        {
            break; 
        }
        
        switch (pCopyDataStruct->dwData)
        {
            case MAKE_PHONE_CALL: 

                if (pCopyDataStruct->cbData != sizeof(PH_MAKEPHONECALL_PARAMETERS))
                {
                    return E_INVALIDARG;
                }
                
                return (HRESULT)MakePhoneCall(static_cast<PH_MAKEPHONECALL_PARAMETERS*>(pCopyDataStruct->lpData)); 

                break; 
                
#ifdef ENABLE_VOIP_TEST_HOOKS        
            case GET_FORMATTED_NUMBER: 
                
                if (pCopyDataStruct->lpData == NULL)
                {
                    break; 
                }
                
                TestGetFormattedNumber(
                    ((DIAL_STRING_INFO*)(pCopyDataStruct->lpData))->DialString, 
                    ((DIAL_STRING_INFO*)(pCopyDataStruct->lpData))->DialStringLength, 
                    ((DIAL_STRING_INFO*)(pCopyDataStruct->lpData))->FormatType
                    ); 

                break; 

            case GET_IS_NUMBER_AUTODIALABLE:
                if (pCopyDataStruct->lpData == NULL)
                {
                    ASSERT(FALSE);
                    return FALSE;
                }

                return (LRESULT)TestGetIsNumberAutodialable(
                    (const WCHAR*)pCopyDataStruct->lpData
                    );

#endif
            default: 
                break; 
        }

  
        break; 

    default:
        ReturnValue = DefWindowProc(hwnd, Message, wParam, lParam);
        break;
    }

    return ReturnValue;
}

void 
VoIPApp_t::OnTimerExpires(
    UINT    TimerID
    )
{
    return;     
}

/*------------------------------------------------------------------------------
    VoIPApp_t::EnableCalling

    Enable the VoIP calling by creating and initializing the
    RTC Client and registering our event sink

    Returns (HRESULT): indicating success or failure
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::EnableCalling()
{
    TRACE(ZONE_PHONEAPP_FUNCTION);

    if (m_cpRTCClient != NULL)
    {
        return S_FALSE;
    }

    //Ctor starts the marker, Dtor stops the marker
    CComPtr<IRTCClient2>    cpClient2;
    
    if (m_cpRTCClient != NULL)
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"This object has already been initialized..."));
        return E_FAIL;
    }

    HRESULT hr = m_cpRTCClient.CoCreateInstance(CLSID_RTCClient);
    if (FAILED(hr))
    {
        //Need to log the error...
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Cannot co create the RTC Client. Error 0x%x -- Is the client properly installed though COM reg settings? Is the dll signed? Are all the dependent dll's also in the image? ", hr));
        goto exit;
    }

    //need the client2 interface to call InitializeEx
    hr = m_cpRTCClient->QueryInterface(
        IID_IRTCClient2,
        reinterpret_cast<void**>(&cpClient2)
        );
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to QI the RTC client for IRTCClient2. Error 0x%x.", hr));
        goto exit;
    }
    
    //initialize the rtc client
    hr = cpClient2->InitializeEx(
        GetRTCInitializationFlags()
        );
    if (FAILED(hr))
    {
        //Need to log the error...
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Cannot initialize the RTC Client with flags 0x%x. Error code: 0x%x", GetRTCInitializationFlags()));
        goto exit;;
    }

    //register our event sink as a callback for the rtc client
    hr = RegisterCallbackInterface();
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Cannot register the callback interface - error 0x%x", hr));
        goto exit;
    }

    //register for specific events
    hr = m_cpRTCClient->put_EventFilter(
                            RTCEF_CLIENT |
                            RTCEF_PARTICIPANT_STATE_CHANGE |
                            RTCEF_SESSION_STATE_CHANGE |
                            RTCEF_REGISTRATION_STATE_CHANGE |
                            RTCEF_SESSION_REFER_STATUS |
                            RTCEF_SESSION_REFERRED |
                            RTCEF_SESSION_OPERATION_COMPLETE |
                            RTCEF_SUBSCRIPTION_STATE_CHANGE  |
                            RTCEF_SUBSCRIPTION_NOTIFY
                            );
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to set an event filter with the RTC Client"));
        goto exit;
    }

    //listen for new incoming sessions
    hr = m_cpRTCClient->put_ListenForIncomingSessions(GetRTCListenMode());
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failure when asking the RTC Client to listen for all incoming sessions"));
        goto exit;
    }

    //get the maximum number of calls that are allowed simutanously
    m_MaxNumberOfCalls = GetMaxNumberOfCalls(); 
    
    //start proxy services
    m_ProxyServices.StartServices();

exit:

    if (FAILED(hr))
    {
        DisableCalling();
    }

    return hr;
}


/*------------------------------------------------------------------------------
    VoIPApp_t::RegisterCallbackInterface

    Registers 'this' object as an event sink for RTC's IRTCEventNotification
    connection point callback

    Returns (HRESULT): indicating whether the connection was made
                       (or E_UNEXPECTED if we are already registered)
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::RegisterCallbackInterface()
{
    if (m_cpRTCClient == NULL || m_ConnectionPtCookie != 0)
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Already (at least partially) registered - returning E_FAIL"));
        return E_FAIL;
    }

    CComPtr<IConnectionPointContainer> cpContainer;

    //Recast the RTC Client as a connection point container
    HRESULT  hr = m_cpRTCClient->QueryInterface(IID_IConnectionPointContainer, reinterpret_cast<void**>(&cpContainer));
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Couldn't get the connection point container from the RTC Client - error 0x%x", hr));
        return hr;
    }

    //Find the event notification connection point - we will advise the connection point of our
    //event sink in the next step.
    hr = cpContainer->FindConnectionPoint(IID_IRTCEventNotification, &m_cpConnectionPt);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to find an IRTCEventNotification connection point - error code 0x%x", hr));
        return hr;
    }

    //now advise the connection point that this object is the event sink for the given connection
    hr = m_cpConnectionPt->Advise(static_cast<IUnknown*>(static_cast<IRTCEventNotification*>(this)), &m_ConnectionPtCookie);
    if (FAILED(hr))
    {
        PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to advise the connection point - error 0x%x", hr));
        return hr;
    }

    ASSERT(m_ConnectionPtCookie != 0);
    return S_OK;
}


/*------------------------------------------------------------------------------
    VoIPApp_t::DisableCalling

⌨️ 快捷键说明

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