450 lines
9.9 KiB
C++
450 lines
9.9 KiB
C++
|
// File: calv.cpp
|
||
|
|
||
|
#include "precomp.h"
|
||
|
#include "resource.h"
|
||
|
|
||
|
#include "calv.h"
|
||
|
#include "upropdlg.h"
|
||
|
#include "speedial.h"
|
||
|
#include "dirutil.h"
|
||
|
#include "confroom.h"
|
||
|
|
||
|
///////////////////////////////
|
||
|
// Globals for FEnabledNmAddr
|
||
|
BOOL g_fGkEnabled = FALSE;
|
||
|
BOOL g_fGatewayEnabled = FALSE;
|
||
|
BOOL g_bGkPhoneNumberAddressing = FALSE;
|
||
|
|
||
|
|
||
|
CALV::CALV(int ids, int iIcon, const int * pIdMenu /*=NULL*/, bool fOwnerData /*=false*/ ) :
|
||
|
m_idsName(ids),
|
||
|
m_hwnd(NULL),
|
||
|
m_iIcon(iIcon),
|
||
|
m_pIdMenu(pIdMenu),
|
||
|
m_fAvailable(FALSE),
|
||
|
m_fOwnerDataList( fOwnerData )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
CALV::~CALV()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
VOID CALV::ClearItems(void)
|
||
|
{
|
||
|
if (NULL != m_hwnd)
|
||
|
{
|
||
|
ListView_DeleteAllItems(m_hwnd);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
VOID CALV::DeleteItem(int iItem)
|
||
|
{
|
||
|
if (ListView_DeleteItem(GetHwnd(), iItem))
|
||
|
{
|
||
|
// Auto-select the next item
|
||
|
ListView_SetItemState(GetHwnd(), iItem,
|
||
|
LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
int CALV::GetSelection(void)
|
||
|
{
|
||
|
return ListView_GetNextItem(m_hwnd, -1, LVNI_ALL | LVNI_SELECTED);
|
||
|
}
|
||
|
|
||
|
VOID CALV::SetHeader(HWND hwnd, int ids)
|
||
|
{
|
||
|
m_hwnd = hwnd;
|
||
|
DlgCallSetHeader(hwnd, ids);
|
||
|
}
|
||
|
|
||
|
|
||
|
// Return the name (from the first column)
|
||
|
BOOL CALV::GetSzName(LPTSTR psz, int cchMax)
|
||
|
{
|
||
|
int iItem = GetSelection();
|
||
|
if (-1 == iItem)
|
||
|
return FALSE;
|
||
|
|
||
|
return GetSzName(psz, cchMax, iItem);
|
||
|
}
|
||
|
BOOL CALV::GetSzName(LPTSTR psz, int cchMax, int iItem)
|
||
|
{
|
||
|
return GetSzData(psz, cchMax, iItem, IDI_DLGCALL_NAME);
|
||
|
}
|
||
|
|
||
|
// Return the "callTo" address (from the second column)
|
||
|
BOOL CALV::GetSzAddress(LPTSTR psz, int cchMax)
|
||
|
{
|
||
|
int iItem = GetSelection();
|
||
|
if (-1 == iItem)
|
||
|
return FALSE;
|
||
|
|
||
|
return GetSzAddress(psz, cchMax, iItem);
|
||
|
}
|
||
|
BOOL CALV::GetSzAddress(LPTSTR psz, int cchMax, int iItem)
|
||
|
{
|
||
|
return GetSzData(psz, cchMax, iItem, IDI_DLGCALL_ADDRESS);
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CALV::GetSzData(LPTSTR psz, int cchMax, int iItem, int iCol)
|
||
|
{
|
||
|
LV_ITEM lvi;
|
||
|
ClearStruct(&lvi);
|
||
|
lvi.iItem = iItem;
|
||
|
lvi.iSubItem = iCol;
|
||
|
lvi.mask = LVIF_TEXT;
|
||
|
lvi.pszText = psz;
|
||
|
lvi.cchTextMax = cchMax;
|
||
|
|
||
|
return ListView_GetItem(m_hwnd, &lvi);
|
||
|
}
|
||
|
|
||
|
|
||
|
LPARAM CALV::LParamFromItem(int iItem)
|
||
|
{
|
||
|
LV_ITEM lvi;
|
||
|
ClearStruct(&lvi);
|
||
|
lvi.iItem = iItem;
|
||
|
lvi.mask = LVIF_PARAM;
|
||
|
return ListView_GetItem(GetHwnd(), &lvi) ? lvi.lParam : 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* G E T A D D R I N F O */
|
||
|
/*-------------------------------------------------------------------------
|
||
|
%%Function: GetAddrInfo
|
||
|
|
||
|
General interface to get the rich address info.
|
||
|
-------------------------------------------------------------------------*/
|
||
|
RAI * CALV::GetAddrInfo(void)
|
||
|
{
|
||
|
return GetAddrInfo(NM_ADDR_ULS);
|
||
|
}
|
||
|
|
||
|
/* G E T A D D R I N F O */
|
||
|
/*-------------------------------------------------------------------------
|
||
|
%%Function: GetAddrInfo
|
||
|
|
||
|
Utility routine, usually called by GetAddrInfo()
|
||
|
-------------------------------------------------------------------------*/
|
||
|
RAI * CALV::GetAddrInfo(NM_ADDR_TYPE addrType)
|
||
|
{
|
||
|
TCHAR szName[CCHMAXSZ_NAME];
|
||
|
if (!GetSzName(szName, CCHMAX(szName)))
|
||
|
return NULL;
|
||
|
|
||
|
TCHAR szAddress[CCHMAXSZ_ADDRESS];
|
||
|
if (!GetSzAddress(szAddress, CCHMAX(szAddress)))
|
||
|
return NULL;
|
||
|
|
||
|
return CreateRai(szName, addrType, szAddress);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* S E T B U S Y C U R S O R */
|
||
|
/*-------------------------------------------------------------------------
|
||
|
%%Function: SetBusyCursor
|
||
|
|
||
|
-------------------------------------------------------------------------*/
|
||
|
VOID CALV::SetBusyCursor(BOOL fBusy)
|
||
|
{
|
||
|
extern int g_cBusy; // in dlgcall.cpp
|
||
|
g_cBusy += fBusy ? 1 : -1;
|
||
|
ASSERT(g_cBusy >= 0);
|
||
|
|
||
|
// Wiggle the mouse - force user to send a WM_SETCURSOR
|
||
|
POINT pt;
|
||
|
if (::GetCursorPos(&pt))
|
||
|
{
|
||
|
::SetCursorPos(pt.x, pt.y);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* D O M E N U */
|
||
|
/*-------------------------------------------------------------------------
|
||
|
%%Function: DoMenu
|
||
|
|
||
|
-------------------------------------------------------------------------*/
|
||
|
VOID CALV::DoMenu(POINT pt, const int * pIdMenu)
|
||
|
{
|
||
|
HMENU hMenu = ::LoadMenu(::GetInstanceHandle(), MAKEINTRESOURCE(IDM_DLGCALL));
|
||
|
if (NULL == hMenu)
|
||
|
return;
|
||
|
|
||
|
HMENU hMenuTrack = ::GetSubMenu(hMenu, 0);
|
||
|
ASSERT(NULL != hMenu);
|
||
|
|
||
|
{
|
||
|
// Bold the "Call" menuitem:
|
||
|
MENUITEMINFO iInfo;
|
||
|
iInfo.cbSize = sizeof(iInfo);
|
||
|
iInfo.fMask = MIIM_STATE;
|
||
|
if(::GetMenuItemInfo(hMenuTrack, IDM_DLGCALL_CALL, FALSE, &iInfo))
|
||
|
{
|
||
|
iInfo.fState |= MFS_DEFAULT;
|
||
|
::SetMenuItemInfo(hMenuTrack, IDM_DLGCALL_CALL, FALSE, &iInfo);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Is anything selected?
|
||
|
int iSelItem = GetSelection();
|
||
|
UINT uFlags = (-1 == iSelItem) ? MF_GRAYED : MF_ENABLED;
|
||
|
|
||
|
::EnableMenuItem(hMenuTrack, IDM_DLGCALL_CALL,
|
||
|
((uFlags == MF_GRAYED) || !GetConfRoom()->IsNewCallAllowed()) ?
|
||
|
MF_GRAYED : MF_ENABLED);
|
||
|
::EnableMenuItem(hMenuTrack, IDM_DLGCALL_PROPERTIES, uFlags);
|
||
|
|
||
|
if (NULL != pIdMenu)
|
||
|
{
|
||
|
// Additional menu items
|
||
|
while (0 != *pIdMenu)
|
||
|
{
|
||
|
int id = *pIdMenu++;
|
||
|
if (-1 == id)
|
||
|
{
|
||
|
InsertMenu(hMenuTrack, (DWORD) -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TCHAR sz[CCHMAXSZ];
|
||
|
if (FLoadString(id, sz, CCHMAX(sz)))
|
||
|
{
|
||
|
UINT uf = MF_BYPOSITION | MF_STRING | uFlags;
|
||
|
if (id >= IDM_DLGCALL_ALWAYS_ENABLED)
|
||
|
{
|
||
|
uf = (uf & ~MF_GRAYED) | MF_ENABLED;
|
||
|
}
|
||
|
InsertMenu(hMenuTrack, (DWORD) -1, uf, id, sz);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Check to see if we have "special" coordinates that signify
|
||
|
// that we entered here as a result of a keyboard click
|
||
|
// instead of a mouse click - and if so, get some default coords
|
||
|
if ((0xFFFF == pt.x) && (0xFFFF == pt.y))
|
||
|
{
|
||
|
RECT rc;
|
||
|
if ((-1 == iSelItem) ||
|
||
|
(FALSE == ListView_GetItemRect(m_hwnd, iSelItem, &rc, LVIR_ICON)))
|
||
|
{
|
||
|
::GetWindowRect(m_hwnd, &rc);
|
||
|
pt.x = rc.left;
|
||
|
pt.y = rc.top;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Convert from client coords to screen coords
|
||
|
::MapWindowPoints(m_hwnd, NULL, (LPPOINT)&rc, 2);
|
||
|
pt.x = rc.left + (RectWidth(rc) / 2);
|
||
|
pt.y = rc.top + (RectHeight(rc) / 2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Draw and track the "floating" popup
|
||
|
::TrackPopupMenu(hMenuTrack, TPM_LEFTALIGN | TPM_RIGHTBUTTON,
|
||
|
pt.x, pt.y, 0, ::GetParent(m_hwnd), NULL);
|
||
|
|
||
|
::DestroyMenu(hMenu);
|
||
|
}
|
||
|
|
||
|
VOID CALV::OnRClick(POINT pt)
|
||
|
{
|
||
|
DoMenu(pt, m_pIdMenu);
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID CALV::OnCommand(WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
WORD wCmd = LOWORD(wParam);
|
||
|
|
||
|
switch (wCmd)
|
||
|
{
|
||
|
case IDM_DLGCALL_PROPERTIES:
|
||
|
CmdProperties();
|
||
|
break;
|
||
|
case IDM_DLGCALL_SPEEDDIAL:
|
||
|
CmdSpeedDial();
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* C M D P R O P E R T I E S */
|
||
|
/*-------------------------------------------------------------------------
|
||
|
%%Function: CmdProperties
|
||
|
|
||
|
-------------------------------------------------------------------------*/
|
||
|
VOID CALV::CmdProperties(void)
|
||
|
{
|
||
|
TCHAR szName[CCHMAXSZ_NAME];
|
||
|
TCHAR szAddr[CCHMAXSZ_ADDRESS];
|
||
|
if (!GetSzName(szName, CCHMAX(szName)) ||
|
||
|
!GetSzAddress(szAddr, CCHMAX(szAddr)))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
UPROPDLGENTRY rgProp[1] = {
|
||
|
{IDS_UPROP_ADDRESS, szAddr},
|
||
|
};
|
||
|
|
||
|
CUserPropertiesDlg dlgUserProp(m_hwnd, IDI_LARGE);
|
||
|
dlgUserProp.DoModal(rgProp, ARRAY_ELEMENTS(rgProp), szName, NULL);
|
||
|
}
|
||
|
|
||
|
|
||
|
/* C M D S P E E D D I A L */
|
||
|
/*-------------------------------------------------------------------------
|
||
|
%%Function: CmdSpeedDial
|
||
|
|
||
|
-------------------------------------------------------------------------*/
|
||
|
VOID CALV::CmdSpeedDial(void)
|
||
|
{
|
||
|
TCHAR szName[CCHMAXSZ_NAME];
|
||
|
TCHAR szAddr[CCHMAXSZ_ADDRESS];
|
||
|
if (!GetSzName(szName, CCHMAX(szName)) ||
|
||
|
!GetSzAddress(szAddr, CCHMAX(szAddr)))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
FCreateSpeedDial(szName, szAddr);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* C M D R E F R E S H */
|
||
|
/*-------------------------------------------------------------------------
|
||
|
%%Function: CmdRefresh
|
||
|
|
||
|
-------------------------------------------------------------------------*/
|
||
|
VOID CALV::CmdRefresh(void)
|
||
|
{
|
||
|
ClearItems();
|
||
|
ShowItems(m_hwnd);
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////
|
||
|
// RAI routines
|
||
|
|
||
|
|
||
|
/* C R E A T E R A I */
|
||
|
/*-------------------------------------------------------------------------
|
||
|
%%Function: CreateRai
|
||
|
|
||
|
-------------------------------------------------------------------------*/
|
||
|
RAI * CreateRai(LPCTSTR pszName, NM_ADDR_TYPE addrType, LPCTSTR pszAddr)
|
||
|
{
|
||
|
RAI * pRai = new RAI;
|
||
|
LPTSTR psz = PszAlloc(pszAddr);
|
||
|
if ((NULL == pRai) || (NULL == psz))
|
||
|
{
|
||
|
delete pRai;
|
||
|
delete psz;
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
lstrcpyn(pRai->szName, pszName, CCHMAX(pRai->szName));
|
||
|
pRai->cItems = 1;
|
||
|
pRai->rgDwStr[0].psz = psz;
|
||
|
pRai->rgDwStr[0].dw = addrType;
|
||
|
return pRai;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* C L E A R R A I */
|
||
|
/*-------------------------------------------------------------------------
|
||
|
%%Function: ClearRai
|
||
|
|
||
|
-------------------------------------------------------------------------*/
|
||
|
VOID ClearRai(RAI ** ppRai)
|
||
|
{
|
||
|
if (NULL == *ppRai)
|
||
|
return;
|
||
|
|
||
|
for (int i = 0; i < (*ppRai)->cItems; i++)
|
||
|
{
|
||
|
delete (*ppRai)->rgDwStr[i].psz;
|
||
|
}
|
||
|
delete *ppRai;
|
||
|
*ppRai = NULL;
|
||
|
}
|
||
|
|
||
|
/* D U P R A I */
|
||
|
/*-------------------------------------------------------------------------
|
||
|
%%Function: DupRai
|
||
|
|
||
|
-------------------------------------------------------------------------*/
|
||
|
RAI * DupRai(RAI * pRai)
|
||
|
{
|
||
|
if (NULL == pRai)
|
||
|
return NULL;
|
||
|
|
||
|
RAI * pRaiRet = (RAI *) new BYTE[sizeof(RAI) + (pRai->cItems-1)*sizeof(DWSTR)];
|
||
|
if (NULL != pRaiRet)
|
||
|
{
|
||
|
lstrcpy(pRaiRet->szName, pRai->szName);
|
||
|
pRaiRet->cItems = pRai->cItems;
|
||
|
|
||
|
for (int i = 0; i < pRai->cItems; i++)
|
||
|
{
|
||
|
pRaiRet->rgDwStr[i].dw = pRai->rgDwStr[i].dw;
|
||
|
pRaiRet->rgDwStr[i].psz = PszAlloc(pRai->rgDwStr[i].psz);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return pRaiRet;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* F E N A B L E D N M A D D R */
|
||
|
/*-------------------------------------------------------------------------
|
||
|
%%Function: FEnabledNmAddr
|
||
|
-------------------------------------------------------------------------*/
|
||
|
BOOL FEnabledNmAddr(DWORD dwAddrType)
|
||
|
{
|
||
|
switch (dwAddrType)
|
||
|
{
|
||
|
default:
|
||
|
case NM_ADDR_ULS:
|
||
|
// We only care about ULS addresses if
|
||
|
// we are not in gatekeeper mode...
|
||
|
return !g_fGkEnabled;
|
||
|
|
||
|
case NM_ADDR_UNKNOWN:
|
||
|
case NM_ADDR_IP:
|
||
|
// We always care aobut these addresses
|
||
|
return TRUE;
|
||
|
|
||
|
case NM_ADDR_H323_GATEWAY:
|
||
|
{
|
||
|
return !g_fGkEnabled && g_fGatewayEnabled;
|
||
|
}
|
||
|
|
||
|
case NM_ADDR_ALIAS_ID:
|
||
|
return g_fGkEnabled && !g_bGkPhoneNumberAddressing;
|
||
|
|
||
|
case NM_ADDR_ALIAS_E164:
|
||
|
return g_fGkEnabled && g_bGkPhoneNumberAddressing;
|
||
|
|
||
|
case NM_ADDR_PSTN: // old, never enabled
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|