📄 speeddialeditdialog.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 "SpeedDialEditDialog.hpp"
#include "InfoApp.hpp"
#include "Common.hpp"
#include "Controls.hpp"
#include "RingtoneIterator.h"
#include "Resource.h"
#include "DisplayItem.hpp"
#include <winuserm.h>
#include "Layout.hpp"
const UINT c_idxSpeedDialMin = 1;
const UINT c_idxSpeedDialMax = 99;
#define DEFAULT_RINGTONE -1
/*------------------------------------------------------------------------------
GenerateNextSpeedDialIndex
Helper function to determine the next available speed dial index
------------------------------------------------------------------------------*/
int GenerateNextSpeedDialIndex(
IVoIPCallerInfoDB* pCallerInfoDB
)
{
CComPtr<IVoIPCallerInfoRecord> cpRecord;
CComPtr<IVoIPCallerInfoDBEnum> cpEnum;
HRESULT hr = S_OK;
BOOL MoreItems = TRUE;
int NextFree = c_idxSpeedDialMin;
if (! pCallerInfoDB)
{
return VOIP_INVALID_SPEED_DIAL_ENTRY;
}
hr = pCallerInfoDB->get_SpeedDialEnumerator(&cpEnum);
if (FAILED(hr))
{
return VOIP_INVALID_SPEED_DIAL_ENTRY;
}
//The speed dial enumerator returns its results as sorted
//by speed dial index. Therefore we can perform a linear search
//and find a free index (or until we have exhausted all possibilities)
while (NextFree <= c_idxSpeedDialMax)
{
//get the next item
hr = cpEnum->Next(1, &cpRecord, NULL);
if (hr != S_OK)
{
break;
}
int CurrentSpeedDialIndex = VOIP_INVALID_SPEED_DIAL_ENTRY;
cpRecord->get_SpeedDialEntry(&CurrentSpeedDialIndex);
if (CurrentSpeedDialIndex != NextFree)
{
return NextFree;
}
NextFree++;
cpRecord = NULL;
}
//if we are out of speed dial records, but still have entries left,
//then we can return the valid index
if (NextFree < c_idxSpeedDialMax)
{
return NextFree;
}
//otherwise we are out of entries
return VOIP_INVALID_SPEED_DIAL_ENTRY;
}
/*------------------------------------------------------------------------------
CallerInfoSetting
Structure containing the settings the user can view/change and the corresponding
label/id strings
------------------------------------------------------------------------------*/
enum ItemId
{
ItemName = 0,
ItemUri,
ItemRingtone,
ItemSpeedDialIndex
};
struct CallerInfoSetting_t
{
ItemId id;
UINT Label;
UINT HelpString;
UINT ImeType;
UINT ExtraEditSetting;
INT EditLimit;
};
//cookie for the notification area
const UINT NotificationCookie = 400;
//Table of the settings
const CallerInfoSetting_t SettingsArray[] =
{
{ ItemName , IDS_LABEL_NAME, IDS_STATUS_HELP_SD_NAMENUM, EIM_SPELL, 0, -1 },
{ ItemUri , IDS_LABEL_PHONENUM, IDS_STATUS_HELP_SD_NAMENUM, EIM_NUMBERS, 0, -1 },
{ ItemRingtone , IDS_LABEL_RINGTONE, IDS_STATUS_HELP_SD_RINGTONE, EIM_NUMBERS, ES_READONLY, -1 },
{ ItemSpeedDialIndex, IDS_LABEL_SPEEDDIAL, IDS_STATUS_HELP_SD_SD, EIM_NUMBERS, ES_NUMBER, 2 },
};
/*------------------------------------------------------------------------------
SpeedDialEditDialog_t::SpeedDialEditDialog_t
Ctor
------------------------------------------------------------------------------*/
SpeedDialEditDialog_t::SpeedDialEditDialog_t()
{
m_RingtoneIndex = DEFAULT_RINGTONE;
m_SpeedDialIndex = VOIP_INVALID_SPEED_DIAL_ENTRY;
}
SpeedDialEditDialog_t::~SpeedDialEditDialog_t()
{
}
/*------------------------------------------------------------------------------
SpeedDialEditDialog_t::CreateDialogScreen
Create the dialog screen...
------------------------------------------------------------------------------*/
HRESULT
SpeedDialEditDialog_t::CreateDialogScreen(
IUnknown* pUnknown,
InfoApp_t* pApp
)
{
//verify we have the database...
HRESULT hr = pApp->GetCallerInfoDB(&m_cpCallerInfoDB);
if (FAILED(hr))
{
ASSERT(FALSE);
return hr;
}
m_cpUnknown = pUnknown;
//create the screen
return DialogScreen_t::CreateDialogScreen(
PHINFO_SPEEDDIAL_EDIT_SCREEN_ID,
0,
CommonUtilities_t::LoadString(GlobalData_t::s_ModuleInstance, IDS_TITLE_SPEEDDIAL),
L""
);
}
/*------------------------------------------------------------------------------
SpeedDialEditDialog_t::HookProc
WndProc for this dialog
------------------------------------------------------------------------------*/
BOOL
SpeedDialEditDialog_t::HookProc(
HWND hwnd,
UINT Message,
WPARAM wParam,
LPARAM lParam
)
{
HRESULT hr;
switch (Message)
{
case WM_INITDIALOG:
hr = OnInitDialog();
if (FAILED(hr))
{
DestroyWindow(hwnd);
}
return FALSE;
case WM_COMMAND:
switch (HIWORD(wParam))
{
case EN_UPDATE:
ShowHideBackspaceButton();
break;
case LBN_SELCHANGE:
UpdateStatusRegion();
UpdateMenuBar();
break;
case 0:
switch (LOWORD(wParam))
{
case IDOK:
if (SaveProperties() == S_OK)
{
PhInfoGlobalData_t::pPhInfoApp->GoBackToPreviousScreen();
}
break;
case IDCANCEL:
hr = DialogScreen_t::Exit();
break;
case IDC_BACKSPACE:
hr = DialogScreen_t::OnBackspace();
break;
case IDC_CHANGERINGTONE:
hr = OnChangeRingtone();
break;
default:
return FALSE;
}
break;
}
break;
default:
return FALSE;
}
return SUCCEEDED(hr);
}
/*------------------------------------------------------------------------------
SpeedDialEditDialog_t::Enter
Enters the state and verifies construction went correctly
Returns (HRESULT): indicating success or failure
------------------------------------------------------------------------------*/
HRESULT SpeedDialEditDialog_t::OnInitDialog()
{
HRESULT hr = S_OK;
CComPtr<IVoIPCallerInfoDB> cpDB;
ASSERT(m_cpCallerInfoDB);
//This state was entered with either a
//call log record, caller info record , or call object
//containing information to start the speed dial entry
hr = CreateAppropriateRecord();
if (FAILED(hr))
{
ASSERT(FALSE);
return hr;
}
if (m_cpRecord == NULL)
{
ASSERT(FALSE);
return E_INVALIDARG;
}
//Cache the speed dial entry for quick lookup/verification later
m_cpRecord->get_SpeedDialEntry(&m_SpeedDialIndex);
//if there is no speed dial entry, create a new one
if (m_SpeedDialIndex == VOIP_INVALID_SPEED_DIAL_ENTRY)
{
m_SpeedDialIndex = GenerateNextSpeedDialIndex(m_cpCallerInfoDB);
}
//if we are out of entries, notify the user and exit the state
if (m_SpeedDialIndex == VOIP_INVALID_SPEED_DIAL_ENTRY)
{
ShowError(
IDS_ERROR_SPEEDDIAL_FULL,
IDMB_MSGBOX_ERROR,
true
);
}
//now we can add the display items!
for (int i = 0; i < _countof(SettingsArray); i++)
{
const CallerInfoSetting_t* pSetting = &SettingsArray[i];
IVoIPDisplayItem* pItem = NULL;
hr = PHCreateLabeledEditDisplayItem(
CommonUtilities_t::LoadString(GlobalData_t::s_ModuleInstance, pSetting->Label),
WS_BORDER | pSetting->ExtraEditSetting,
pSetting->EditLimit,
&pItem,
Layout_t::SpeedDialListLabelWidth(),
pSetting->ImeType
);
if (FAILED(hr))
{
return hr;
}
hr = SetDefaultItemText(pSetting->id, pItem);
if (FAILED(hr))
{
return hr;
}
hr = m_Listbox.AddItem(
pSetting->id, //add by ID as the index
pItem
);
if (FAILED(hr))
{
delete pItem;
return hr;
}
}
//update the context buttons
UpdateStatusRegion();
UpdateMenuBar();
return S_OK;
}
/*------------------------------------------------------------------------------
SpeedDialEditDialog_t::CreateAppropriateRecord
Create a record based on the type of record passed into the state
------------------------------------------------------------------------------*/
HRESULT SpeedDialEditDialog_t::CreateAppropriateRecord()
{
/*
There are a variety of choices for entering the state.
To create a new record, pass in NULL
To edit an existing record, pass in the record,
To create/edit a record based on a call, pass in a Call pointer
To create/edit a record based on call log record, pass in a record pointer
*/
HRESULT hr = S_OK;
//case 1 : create a new record
if (m_cpUnknown == NULL)
{
return m_cpCallerInfoDB->CreateRecord(&m_cpRecord);
}
//case 2 : the record is an existing caller info record
hr = m_cpUnknown->QueryInterface(IID_IVoIPCallerInfoRecord, (void**)&m_cpRecord);
if (SUCCEEDED(hr))
{
return hr;
}
///TODO: Get from other parameters...
//not a valid in-param
return E_INVALIDARG;
}
/*------------------------------------------------------------------------------
SpeedDialEditDialog_t::SetDefaultItemText
Set the default text for specific items
------------------------------------------------------------------------------*/
HRESULT
SpeedDialEditDialog_t::SetDefaultItemText(
int id,
IVoIPDisplayItem* pItem
)
{
if (! pItem)
{
ASSERT(FALSE);
return E_UNEXPECTED;
}
WCHAR Value[MAX_PATH] = L"";
ce::auto_bstr bstr;
switch (id)
{
case ItemName:
m_cpRecord->get_FriendlyName(&bstr);
if (bstr == NULL || bstr[0] == 0)
{
bstr = NULL;
m_cpRecord->get_VoIPName(&bstr);
}
if (bstr != NULL)
{
StringCchCopy(
Value,
_countof(Value),
bstr
);
}
break;
case ItemUri:
m_cpRecord->get_URI(&bstr);
if (bstr != NULL)
{
StringCchCopy(
Value,
_countof(Value),
bstr
);
}
break;
case ItemRingtone:
m_cpRecord->get_RingTone(&bstr);
if (bstr && bstr[0])
{
GetRingtoneIndex(
bstr
);
}
GetRingtoneText(
Value,
_countof(Value)
);
break;
case ItemSpeedDialIndex:
if (m_SpeedDialIndex != VOIP_INVALID_SPEED_DIAL_ENTRY)
{
StringCchPrintf(
Value,
_countof(Value),
L"%02d",
m_SpeedDialIndex
);
}
break;
}
Value[_countof(Value)-1] = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -