📄 voipapp.cpp
字号:
hr = OnUserAuthenticated(m_PendingAuthAction);
}
m_PendingAuthAction = ActionInvalid;
return hr;
}
/*------------------------------------------------------------------------------
VoIPApp_t::OnRedialPress
Handles the hotkey HK_REDIAL. Redials the last number the user dialed
------------------------------------------------------------------------------*/
HRESULT
VoIPApp_t::OnRedialPress(
BOOL fKeyup
)
{
if (fKeyup)
{
//don't care about keyup events
return S_FALSE;
}
return AuthenticateAction(
ActionRedial
);
}
/*------------------------------------------------------------------------------
VoIPApp_t::Redial
Redial the last number.
------------------------------------------------------------------------------*/
HRESULT
VoIPApp_t::Redial()
{
if (AreThereAnyCurrentCalls())
{
// If there is any current calls, disable the redial button
return S_FALSE;
}
//retrieve last outgoing number from regsitry
WCHAR LastOutgoingNumber[MAX_PATH] = L"";
HRESULT hr = RegistryGetString(
SN_VOIP_LASTOUTGOINGNUMBER_ROOT,
SN_VOIP_LASTOUTGOINGNUMBER_PATH,
SN_VOIP_LASTOUTGOINGNUMBER_VALUE,
LastOutgoingNumber,
ARRAYSIZE(LastOutgoingNumber)
);
if (FAILED(hr))
{
return hr;
}
//call last outgoing number
if (LastOutgoingNumber[0] != L'\0')
{
return Call(
LastOutgoingNumber,
NULL
);
}
return S_FALSE;
}
/*------------------------------------------------------------------------------
VoIPApp_t::OnMutePress
Handles the hotkey mute press
Returns (HRESULT): indicating success or failure
------------------------------------------------------------------------------*/
HRESULT
VoIPApp_t::OnMutePress(
BOOL fKeyup
)
{
if (fKeyup || !IsOffHook() || !AreThereAnyCurrentCalls())
{
return S_FALSE;
}
return m_cpRTCClient->put_AudioMuted(
RTCAD_MICROPHONE,
IsMuted(m_cpRTCClient) ? VARIANT_FALSE : VARIANT_TRUE
);
}
/*------------------------------------------------------------------------------
VoIPApp_t::OnVoicemailPress
Handles the voicemail button being pressed
Returns (HRESULT): (currently not impl)
------------------------------------------------------------------------------*/
HRESULT
VoIPApp_t::OnVoicemailPress(
BOOL fKeyup
)
{
if (fKeyup)
{
//don't care about keyup events
return S_FALSE;
}
return AuthenticateAction(
ActionVoicemail
);
}
/*------------------------------------------------------------------------------
VoIPApp_t::DialVoicemail
Dial the voicemail number
Returns (HRESULT):
------------------------------------------------------------------------------*/
HRESULT
VoIPApp_t::DialVoicemail()
{
if (m_cpActiveVoicemailCall != NULL)
{
//only 1 call to voicemail at a time (via the vm button)
return S_FALSE;
}
//retrieve current voicemail from regsitry
WCHAR VoicemailNumber[MAX_PATH] = L"";
HRESULT hr = RegistryGetString(
SN_VOIP_VOICEMAILNUMBER_ROOT,
SN_VOIP_VOICEMAILNUMBER_PATH,
SN_VOIP_VOICEMAILNUMBER_VALUE,
VoicemailNumber,
ARRAYSIZE(VoicemailNumber)
);
if (FAILED(hr))
{
return hr;
}
//call voicemail number
if (VoicemailNumber[0] != L'\0')
{
return Call(
VoicemailNumber,
CommonUtilities_t::LoadString(GlobalData_t::s_ModuleInstance, IDS_CALLERID_VOICEMAIL),
&m_cpActiveVoicemailCall
);
}
return S_FALSE;
}
/*------------------------------------------------------------------------------
VoIPApp_t::PlayDTMF
Starts playing a DTMF tone
Returns (HRESULT):
------------------------------------------------------------------------------*/
HRESULT
VoIPApp_t::PlayDTMF(
UINT vkKeyCode
)
{
RTC_DTMF DTMFCode;
HRESULT hr = PhoneAppUtilities_t::TranslateVKeyToDTMFCode(
vkKeyCode,
&DTMFCode
);
if (FAILED(hr))
{
return E_NOTIMPL;
}
return m_UIManager.SendDTMF(DTMFCode);
}
/*------------------------------------------------------------------------------
VoIPApp_t::UpdateKeyupDownState
Updates the internal keyup/down state
Parameters:
: BOOL fKeyup - TRUE if the keypressed is UP
: UINT vk - the virtual keycode of the key being presses
Returns (HRESULT): indicating success or failure
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::UpdateKeyupDownState(
BOOL fKeyUp,
UINT virtKey
)
{
if (fKeyUp)
{
m_fWaitingForPressAndHold = FALSE;
m_vkLastKeyPressed = -1;
return S_FALSE;
}
else
{
m_fWaitingForPressAndHold = TRUE;
m_tickLastKeydown = GetTickCount() + 250;
m_vkLastKeyPressed = virtKey;
return S_OK;
}
}
/*------------------------------------------------------------------------------
VoIPApp_t::PossibleGenerateKeydown
If the current keypress state is correct, generate a fake keydown message
for the in-focus control
Parameters:
: BOOL fKeydown - TRUE if the keypressed is DOWN
: WCHAR wc - the character code of the key being presses
Returns (HRESULT):
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::PossiblyGenerateKeydown()
{
if (m_vkLastKeyPressed == -1)
{
return S_FALSE;
}
if (m_vkLastKeyPressed != VK_DOWN && m_vkLastKeyPressed != VK_UP)
{
return S_FALSE;
}
if ((signed int)(GetTickCount() - m_tickLastKeydown) > (signed int)Settings_t::s_dwGenerateKeydown)
{
m_tickLastKeydown = GetTickCount();
SendMessage(
GetFocus(),
WM_KEYDOWN,
(WPARAM)m_vkLastKeyPressed,
2 //make sure the repeat count it set in the lparam (see documentation for WM_KEYDOWN for details)
);
return S_OK;
}
return S_FALSE;
}
//Helper for dispatching events in our IRTCEventNotification sink
#define DispatchEvent(ptr_type, Handler) \
{ \
CComPtr<ptr_type> _ptr; \
hr = pDispatch->QueryInterface(__uuidof(ptr_type), reinterpret_cast<void**>(&_ptr)); \
if (FAILED(hr)) \
{ \
ASSERT(FALSE); \
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed to queryinterface for the desired type - hr = 0x%x", hr)); \
return hr; \
} \
hr = (Handler)(_ptr); \
}
/*------------------------------------------------------------------------------
VoIPApp_t::PumpMessages
Begins a new message pump, and returns the value from
the wParam in a WM_QUIT message
Returns (DWORD): The value sent to PostQuitMessage
------------------------------------------------------------------------------*/
DWORD VoIPApp_t::PumpMessages()
{
MSG msg = {0};
while (GetMessage(&msg, NULL, 0, 0))
{
BOOL fRefresh = FALSE,
fPressAndHold = FALSE,
fEat = FALSE,
fUpdateUserActivity = FALSE;
DWORD dwTickCount = 0;
UINT vk = 0;
switch (msg.message)
{
case WM_CLOSE:
Uninitialize();
fEat = TRUE;
break;
case WM_KEYDOWN:
vk = msg.wParam;
if (vk == m_vkLastKeyPressed)
{
fEat = TRUE;
break;
}
fUpdateUserActivity = TRUE;
UpdateKeyupDownState(FALSE, vk);
break;
case WM_HOTKEY:
{
BOOL fKeyup = (LOWORD(msg.lParam) & MOD_KEYUP);
vk = (HIWORD(msg.lParam));
if (!fKeyup && (vk == m_vkLastKeyPressed))
{
fEat = TRUE;
break;
}
UpdateKeyupDownState(fKeyup, vk);
fUpdateUserActivity = TRUE;
}
break;
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
fUpdateUserActivity = TRUE;
break;
case WM_KEYUP:
vk = msg.wParam;
if (iswdigit((WCHAR)vk))
{
PlayDTMF(vk);
}
UpdateKeyupDownState(TRUE, vk);
break;
case WM_TIMER:
dwTickCount = GetTickCount();
PossiblyGenerateKeydown();
fPressAndHold = (m_fWaitingForPressAndHold && (m_tickLastKeydown < dwTickCount) && ((dwTickCount - m_tickLastKeydown) > Settings_t::s_msPressAndHold));
fRefresh = ((! m_fAlreadyRefreshed && ((dwTickCount - m_tickLastUserAction) > Settings_t::s_msInactivityTimeout)));
break;
default:
break;
}
if (! fEat)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (fUpdateUserActivity)
{
m_fAlreadyRefreshed = FALSE;
m_tickLastUserAction = GetTickCount();
}
if (fPressAndHold)
{
m_fWaitingForPressAndHold = FALSE;
m_UIManager.OnPressAndHold(m_vkLastKeyPressed);
}
if (fRefresh)
{
m_fAlreadyRefreshed = TRUE;
if (m_AudioMode == e_vamSpeakerPhone && !AreThereAnyCurrentCalls())
{
//simulate a speaker press
OnHookModeChange(HotKeys_t::vkSpeaker, FALSE); //false means keydown
}
}
}
return (DWORD)msg.wParam;
}
HRESULT VoIPApp_t::Run(
const WCHAR* c_pCommandLine
)
{
ASSERT(m_cpRTCClient == NULL);
HRESULT hr = CreateNotificationWindow();
if (FAILED(hr))
{
PHONEAPP_RETAILMSG(ZONE_PHONEAPP_ERROR, (L"Failed at creating a notification window, hr = 0x%x", hr));
goto exit;
}
//initialize the timer
hr = m_Timers.Initialize(m_NotificationWindow);
if (FAILED(hr))
{
PHONEAPP_RETAILMSG(ZONE_PHONEAPP_ERROR, (L"Failed at initializing a timer object - hr = 0x%x", hr));
goto exit;
}
//initialize the Settings_t object
hr = m_Settings.Initialize();
if (FAILED(hr))
{
PHONEAPP_RETAILMSG(ZONE_PHONEAPP_ERROR, (L"Failed at initializing Settings object - hr = 0x%x", hr));
goto exit;
}
//initialize the ProxyServices object (updates registration status)
m_ProxyServices.Initialize();
//load custom/default dialing rules - if this fails we do not format dial strings
hr = m_DialEngine.InitializeDialPlan();
if (FAILED(hr))
{
//if this fails we still try to use voip app
PHONEAPP_RETAILMSG(ZONE_PHONEAPP_ERROR, (L"Failed to initialize the dial plan, hr = 0x%x", hr));
}
hr = m_UIManager.Initialize(
ShouldBeVisible(c_pCommandLine)
);
if (FAILED(hr))
{
PHONEAPP_RETAILMSG(ZONE_PHONEAPP_ERROR, (L"Failed to initiazlie the UI Manager, hr = 0x%x", hr));
goto exit;
}
hr = m_AudioManager.Initialize();
if (FAILED(hr))
{
PHONEAPP_RETAILMSG(ZONE_PHONEAPP_ERROR, (L"Failed to initiazlie the Audio Manager, hr = 0x%x", hr));
goto exit;
}
m_Database.Initialize();
hr = m_Poom.Initialize();
if (FAILED(hr))
{
//if this fails, we still try to use voip app
PHONEAPP_RETAILMSG(ZONE_PHONEAPP_ERROR, (L"Failed to initialize the POOM, hr = 0x%x", hr));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -