📄 calllistdialog.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include <windows.h>
#include "CReg.hxx"
#include "InfoApp.hpp"
#include "CallListDialog.hpp"
#include "Controls.hpp"
#include "CallRecordDisplayItem.h"
#include "CallDetailsDialog.hpp"
#include "Common.hpp"
#include "PhoneAPI.hpp"
#include "SettingsApi.hpp"
#include "VoIPNotify.hpp"
HRESULT
CopyInfoFromCallRecordToCallerInfoRecord(
IVoIPCallRecord* pCallRecord,
IVoIPCallerInfoRecord* pCallerInfoRecord
)
{
if (pCallRecord == NULL ||
pCallerInfoRecord == NULL)
{
return E_INVALIDARG;
}
ce::auto_bstr bstrFriendlyName;
HRESULT hr = pCallRecord->get_FriendlyName(&bstrFriendlyName);
if (FAILED(hr))
{
return hr;
}
hr = pCallerInfoRecord->put_FriendlyName(bstrFriendlyName);
if (FAILED(hr))
{
return hr;
}
ce::auto_bstr bstrFriendlyNumber;
hr = pCallRecord->get_URI(&bstrFriendlyNumber);
if (FAILED(hr))
{
return hr;
}
hr = pCallerInfoRecord->put_URI(bstrFriendlyNumber);
if (FAILED(hr))
{
return hr;
}
ce::auto_bstr bstrVoIPName;
hr = pCallRecord->get_VoIPName(&bstrVoIPName);
if (FAILED(hr))
{
return hr;
}
hr = pCallerInfoRecord->put_VoIPName(bstrVoIPName);
if (FAILED(hr))
{
return hr;
}
return hr;
}
CallListDialog_t::CallListDialog_t (
InfoApp_t::ScreenId Id
)
{
m_ScreenId = Id;
m_Dialog = NULL;
m_pCallDetails = NULL;
m_MessageBox = NULL;
m_NotifyHandle = NULL;
m_PendingQuestion = QuestionInvalid;
}
CallListDialog_t::~CallListDialog_t()
{
if (m_pCallDetails != NULL)
{
delete m_pCallDetails;
}
if (m_NotifyHandle)
{
RegistryCloseNotification(m_NotifyHandle);
m_NotifyHandle = NULL;
}
CloseCurrentMessageBox();
}
/*------------------------------------------------------------------------------
CallListDialog_t::CloseCurrentMessageBox
Close the current question message box (if any)
------------------------------------------------------------------------------*/
void
CallListDialog_t::CloseCurrentMessageBox(
void
)
{
if (IsWindow(m_MessageBox))
{
DestroyWindow(m_MessageBox);
m_MessageBox = NULL;
}
m_PendingQuestion = QuestionInvalid;
return;
}
/*------------------------------------------------------------------------------
CreateDialogScreen
Creates Call List dialog screen.
------------------------------------------------------------------------------*/
HRESULT
CallListDialog_t::CreateDialogScreen(
void
)
{
// Get access to the Call Log DB.
CComPtr<IVoIPCallLogDB> cpCallLogDB;
HRESULT hr = PhInfoGlobalData_t::pPhInfoApp->GetCallLogDB(&cpCallLogDB);
if (FAILED(hr) || cpCallLogDB == NULL)
{
COMMON_DEBUGMSG(ZONE_PHINFO_ERROR, (L"Unable to access call log DB. hr = 0x%x", hr));
return hr;
}
// Set Status Header and Title.
UINT TitleResourceId;
UINT ScreenId;
const WCHAR* pTitle = NULL;
HKEY RegistryRoot;
const WCHAR* pRegistryPath = NULL;
const WCHAR* pRegistryValue = NULL;
switch (m_ScreenId)
{
case InfoApp_t::IdOutgoingCallsListDialog:
RegistryRoot = SN_VOIP_NEWOUTGOINGCALLS_ROOT;
pRegistryPath = SN_VOIP_NEWOUTGOINGCALLS_PATH;
pRegistryValue = SN_VOIP_NEWOUTGOINGCALLS_VALUE;
TitleResourceId = IDS_TITLE_OUTGOING;
ScreenId = PHINFO_OUTGOING_CALL_LIST_SCREEN_ID;
hr = cpCallLogDB->get_OutgoingEnumerator(&m_cpEnum);
break;
case InfoApp_t::IdIncomingCallsListDialog:
RegistryRoot = SN_VOIP_NEWINCOMINGCALLS_ROOT;
pRegistryPath = SN_VOIP_NEWINCOMINGCALLS_PATH;
pRegistryValue = SN_VOIP_NEWINCOMINGCALLS_VALUE;
TitleResourceId = IDS_TITLE_INCOMING;
ScreenId = PHINFO_INCOMING_CALL_LIST_SCREEN_ID;
hr = cpCallLogDB->get_IncomingEnumerator(&m_cpEnum);
break;
case InfoApp_t::IdMissedCallsListDialog:
RegistryRoot = SN_VOIP_NEWMISSEDCALLS_ROOT;
pRegistryPath = SN_VOIP_NEWMISSEDCALLS_PATH;
pRegistryValue = SN_VOIP_NEWMISSEDCALLS_VALUE;
TitleResourceId = IDS_TITLE_MISSED;
ScreenId = PHINFO_MISSED_CALL_LIST_SCREEN_ID;
hr = cpCallLogDB->get_MissedEnumerator(&m_cpEnum);
break;
default:
ASSERT(FALSE);
return E_FAIL;
}
if (FAILED(hr))
{
COMMON_DEBUGMSG(ZONE_PHINFO_ERROR, (L"Failed to get the call log enumerator. hr = 0x%x", hr));
ASSERT (FALSE);
return hr;
}
m_CurrentMenuId = IDMB_CALLLOGLIST_BUTTONS;
hr = DialogScreen_t::CreateDialogScreen(
ScreenId,
IDMB_CALLLOGLIST_BUTTONS,
CommonUtilities_t::LoadString(GlobalData_t::s_ModuleInstance, TitleResourceId),
NULL
);
if (FAILED(hr))
{
return hr;
}
//
// Register for reg key notification if a call count changes when viewing this screen.
//
NOTIFICATIONCONDITION CountGreaterThanZero = {REG_CT_NOT_EQUAL, -1, 0};
hr = RegistryNotifyWindow(
RegistryRoot,
pRegistryPath,
pRegistryValue,
m_Dialog,
WM_SCREEN_REFRESH,
100,
&CountGreaterThanZero,
&m_NotifyHandle
);
if (FAILED(hr))
{
COMMON_DEBUGMSG(ZONE_PHINFO_WARNING, (L"Unable to create registry change notification request. hr = 0x%x", hr));
}
return S_OK;
}
HRESULT
CallListDialog_t::Refresh()
{
//
// Reset the call count (if it exists)
//
HRESULT hr = S_OK;
switch (m_ScreenId)
{
case InfoApp_t::IdOutgoingCallsListDialog:
hr = PHSetValue(phsOutgoingCalls, 0);
if (FAILED(hr))
{
COMMON_DEBUGMSG(ZONE_PHINFO_WARNING, (L"Unable to reset Outgoing call count. hr = 0x%x", hr));
}
break;
case InfoApp_t::IdIncomingCallsListDialog:
hr = PHSetValue(phsIncomingCalls, 0);
if (FAILED(hr))
{
COMMON_DEBUGMSG(ZONE_PHINFO_WARNING, (L"Unable to reset Incoming call count. hr = 0x%x", hr));
}
break;
case InfoApp_t::IdMissedCallsListDialog:
hr = PHSetValue(phsMissedCalls, 0);
if (FAILED(hr))
{
COMMON_DEBUGMSG(ZONE_PHINFO_WARNING, (L"Unable to reset Missed call count. hr = 0x%x", hr));
}
break;
}
if (!m_cpEnum)
{
ASSERT(FALSE);
return E_UNEXPECTED;
}
CComPtr<IVoIPCallRecord> cpCallRecord;
//clear the display
SendMessage(m_Listbox, LB_RESETCONTENT, 0, 0);
hr = m_cpEnum->Reset();
if (FAILED(hr))
{
COMMON_DEBUGMSG(ZONE_PHINFO_WARNING, (L"Call log DB enumerator reset failed. hr = 0x%x", hr));
}
while (m_cpEnum->Next(1, &cpCallRecord, NULL) == S_OK)
{
if (cpCallRecord != NULL)
{
CVoIPCallRecordDisplayItem* pCallRecordDisplay = new CVoIPCallRecordDisplayItem (cpCallRecord);
if (!pCallRecordDisplay)
{
return E_OUTOFMEMORY;
}
hr = m_Listbox.AddItem (-1, pCallRecordDisplay);
if (FAILED(hr))
{
delete pCallRecordDisplay;
return E_FAIL;
}
}
}
// Select the first item.
SendMessage(m_Listbox, LB_SETCURSEL, 0, 0);
UpdateStatus();
UpdateMenuBar();
return hr;
}
BOOL
CallListDialog_t::HookProc(
HWND hwnd,
UINT Message,
WPARAM wParam,
LPARAM lParam
)
{
switch (Message)
{
case WM_INITDIALOG:
if (FAILED(Refresh()))
{
DestroyWindow(hwnd);
}
return FALSE;
case WM_COMMAND:
return OnCommand(wParam);
case WM_NOTIFY:
//
// Always return FALSE, so that the dialog screen does the default processing.
//
OnNotify(wParam, lParam);
return FALSE;
case WM_SCREEN_REFRESH:
Refresh();
return TRUE;
default:
break;
}
return FALSE;
}
/*------------------------------------------------------------------------------
GetSelectedCallRecord
Get the call record from the item that is currently selected.
------------------------------------------------------------------------------*/
HRESULT
CallListDialog_t::GetSelectedCallRecord(
IVoIPCallRecord** ppCallRecord
)
{
if(ppCallRecord == NULL)
{
ASSERT(FALSE);
return E_POINTER;
}
*ppCallRecord = NULL;
int SelectedIndex = m_Listbox.GetCurSel();
CVoIPCallRecordDisplayItem* pCallRecordDisplay = reinterpret_cast<CVoIPCallRecordDisplayItem*> (m_Listbox.GetItem(SelectedIndex));
if (pCallRecordDisplay == NULL)
{
return E_POINTER;
}
return pCallRecordDisplay->GetCallRecord(ppCallRecord);
}
/*------------------------------------------------------------------------------
UpdateMenuBar
Update the menu bar. If there are no logs, only show "Done" button.
------------------------------------------------------------------------------*/
HRESULT
CallListDialog_t::UpdateMenuBar(
void
)
{
//
// Decide the proper buttons that are needed for this selection.
//
UINT MenuId = 0;
if (m_Listbox.GetCount() == 0)
{
MenuId = IDMB_DONE;
}
else
{
MenuId = IDMB_CALLLOGLIST_BUTTONS;
}
//
// Display the correct set of buttons if needed.
//
if (MenuId == m_CurrentMenuId)
{
return S_OK;
}
HRESULT hr = m_MenuBar.SetMenu(
GlobalData_t::s_ModuleInstance,
MenuId
);
if (SUCCEEDED(hr))
{
m_CurrentMenuId = MenuId;
}
return hr;
}
/*------------------------------------------------------------------------------
UpdateStatus
Update the status bar with the latest call log count.
------------------------------------------------------------------------------*/
HRESULT
CallListDialog_t::UpdateStatus(
void
)
{
UINT TitleId;
switch (m_ScreenId)
{
case InfoApp_t::IdOutgoingCallsListDialog:
TitleId = IDS_TITLE_OUTGOING;
break;
case InfoApp_t::IdIncomingCallsListDialog:
TitleId = IDS_TITLE_INCOMING;
break;
case InfoApp_t::IdMissedCallsListDialog:
TitleId = IDS_TITLE_MISSED;
break;
default:
ASSERT(FALSE);
return E_FAIL;
}
const WCHAR* pTitle = CommonUtilities_t::LoadString(GlobalData_t::s_ModuleInstance, TitleId);
if (!pTitle)
{
return E_POINTER;
}
WCHAR StatusHeader[MAX_PATH];
int CallLogCount = m_Listbox.GetCount();
StringCchPrintf(
StatusHeader,
_countof(StatusHeader)-1,
L"%i %s",
CallLogCount,
pTitle
);
STATUS_HEADER_PARAMETERS_EX StatusHeaderParameter;
ZeroMemory(&StatusHeaderParameter, sizeof(STATUS_HEADER_PARAMETERS_EX));
StatusHeaderParameter.Instance = GlobalData_t::s_ModuleInstance;
StatusHeaderParameter.Priority = shpDefault;
StatusHeaderParameter.secTimeout = INFINITE;
StatusHeaderParameter.pwszDisplayString = StatusHeader;
SendMessage(
m_StatusRegion,
WM_STATUSHEADER_ADDSTATUSNOTIFICATION,
sizeof(StatusHeaderParameter),
(LPARAM)&StatusHeaderParameter
);
return S_OK;
}
/*------------------------------------------------------------------------------
OnDelete
Delete the selected Call Log Entry from the database.
------------------------------------------------------------------------------*/
HRESULT
CallListDialog_t::OnDelete(
void
)
{
//
// Read the Call Record Item that is selected and delete it from the db.
//
HRESULT hr;
CComPtr<IVoIPCallRecord> cpCallRecord;
hr = GetSelectedCallRecord(&cpCallRecord);
if (FAILED(hr))
{
return hr;
}
hr = cpCallRecord->DeleteFromDB();
if (FAILED(hr))
{
COMMON_DEBUGMSG(ZONE_PHINFO_ERROR, (L"Unable to delete call record from DB. hr = 0x%x", hr));
return hr;
}
//
// Delete the item from the UI.
//
int SelectedIndex = m_Listbox.GetCurSel();
SendMessage(
m_Listbox,
LB_DELETESTRING,
(WPARAM)SelectedIndex,
0
);
//asynchronously refresh the UI
UpdateMenuBar();
UpdateStatus();
return S_OK;
}
/*------------------------------------------------------------------------------
OnDial
Place a call in the phone app with the number specified in the
call log record that is selected.
------------------------------------------------------------------------------*/
HRESULT
CallListDialog_t::OnDial(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -