windows-nt/Source/XPSP1/NT/enduser/netmeeting/ui/conf/dlgcall2.cpp
2020-09-26 16:20:57 +08:00

3051 lines
72 KiB
C++

// File: dlgcall.cpp
#include "precomp.h"
#include "resource.h"
#include "help_ids.h"
#include "dlgcall2.h"
#include "dirutil.h"
#include "mrulist2.h"
#include "ldap.h"
#include "wab.h"
#include "calv.h"
#include "speedial.h"
#include "history.h"
#include "dlgacd.h"
#include "conf.h"
#include "confroom.h"
#include "confutil.h"
#include "confpolicies.h"
#include "cmd.h"
// GUI constants for this dialog
const UINT DX_BORDER = 6; // Standard spacing for Office dialogs
const UINT DY_BORDER = 6; // Standard spacing for Office dialogs
const UINT DY_COMBOBOX = 200; // Height of the dropped list
const UINT DX_DLGCALL_MIN = 460;
const UINT DY_DLGCALL_MIN = 400;
const UINT DX_DLGCALL_DEFAULT = 800;
const UINT DY_DLGCALL_DEFAULT = 600;
void GetDefaultRect(const HWND hwndParent, RECT & rcRect, const int iDefaultWidth, const int iDefaultHeight);
int GetPixelsPerChar(const HWND hwnd);
const static struct _ColumnInfo
{
int iColumnLabelIds;
int iMinColumnChars;
} ciColumnInfo[ MAX_DIR_COLUMNS ] =
{
{ IDS_DIR_COLUMN_EMAIL, 28 },
{ IDS_DIR_COLUMN_AUDIO, 0 },
{ IDS_DIR_COLUMN_VIDEO, 0 },
{ IDS_DIR_COLUMN_LAST_NAME, 16 },
{ IDS_DIR_COLUMN_FIRST_NAME, 14 },
{ IDS_DIR_COLUMN_LOCATION, 16 },
{ IDS_DIR_COLUMN_COMMENTS, 22 }
};
///////////////////////////////////////////////////////////////////////////
// Local Data
static const DWORD _mpIdHelpDlgCall[] =
{
IDM_DLGCALL_DELETE_ILS, IDH_FINDSOMEONE_DELETE_ILS,
IDM_DLGCALL_NEWWINDOW, IDH_FINDSOMEONE_BROWSER,
IDM_DLGCALL_REFRESH, IDH_FINDSOMEONE_REFRESH,
ID_TB_HELP, IDH_FINDSOMEONE_HELP,
IDS_DLGCALL_EDIT_HDR, IDH_PLACECALL_NAME,
IDE_DLGCALL_NAME, IDH_PLACECALL_NAME,
IDC_DLGCALL_COMBO, IDH_PLACECALL_INFOSTORE,
IDS_SECURITY_CHECKBOX, IDH_PLACECALL_SECURITY_CHKBX,
IDL_DLGCALL_LIST, IDH_PLACECALL_LIST,
IDL_DLGCALL_LISTOWNERDATA, IDH_PLACECALL_LIST,
IDL_DLGCALL_ILS_LISTVIEW, IDH_PLACECALL_LIST,
IDOK, IDH_PLACECALL_CALL,
0, 0
};
int g_cBusy = 0; // non-zero if busy connecting to server
#ifdef nmDlgCallNormal
const int NM_CALLDLG_DEFAULT = nmDlgCallNormal;
const int NM_CALLDLG_NO_ILS_FILTER = nmDlgCallNoFilter;
const int NM_CALLDLG_NO_ILS = nmDlgCallNoIls;
const int NM_CALLDLG_NO_GAL = nmDlgCallNoGal;
const int NM_CALLDLG_NO_WAB = nmDlgCallNoWab;
const int NM_CALLDLG_NO_SPEEDDIAL = nmDlgCallNoSpeedDial;
const int NM_CALLDLG_NO_HISTORY = nmDlgCallNoHistory;
#endif /* old NM_CALL_DLG constants */
// Dir list types:
const UINT DLT_ULS = 0;
const UINT DLT_IN_CALL_LOG = 1;
const UINT DLT_OUT_CALL_LOG = 2;
const UINT DLT_WAB = 3;
struct DLTCOLUMNINFO
{
int nColumns; // number of columns
int nIconColumns; // number of icon-only columns
UINT uStringID; // string ID of first column
LPTSTR pszRVOrder; // reg val to store column order
LPTSTR pszRVWidths; // reg val to store column widths
LPTSTR pszRVSortAscending; // reg val to store sort direction
LPTSTR pszRVSortColumn; // reg val to store sort column
};
const DLTCOLUMNINFO g_rgDLColumnInfo[] =
{
{ MAX_DIR_COLUMNS, 2, IDS_DIR_COLUMN_FIRST, // DLT_ULS
&REGVAL_DIR_COLUMN_ORDER, &REGVAL_DIR_COLUMN_WIDTHS,
&REGVAL_DIR_SORT_ASCENDING, &REGVAL_DIR_SORT_COLUMN },
};
CFindSomeone* CFindSomeone::s_pDlgCall= NULL;
///////////////////////////////////////////////////////////////////////////
int StringCompare( const TCHAR * const psz1, const TCHAR * const psz2 );
void UpdateSecurityCheck(CConfRoom *pConfRoom, HWND hDlg, UINT idCheck)
{
bool userAlterable, secure;
pConfRoom->get_securitySettings( userAlterable, secure );
EnableWindow( GetDlgItem(hDlg, idCheck), userAlterable );
::CheckDlgButton( hDlg, idCheck, secure? BST_CHECKED: BST_UNCHECKED );
}
/* C D L G C A L L */
/*-------------------------------------------------------------------------
%%Function: CFindSomeone
-------------------------------------------------------------------------*/
CFindSomeone::CFindSomeone(CConfRoom *pConfRoom):
m_pAccel(NULL),
m_dwOptions(0),
m_hwndList(NULL),
m_ilsListView(NULL),
m_hwndCombo(NULL),
m_hwndComboEdit(NULL),
m_hwndEdit(NULL),
m_webView( NULL ),
m_WndOwnerDataListOldWndProc(NULL),
m_fInEdit(FALSE),
m_iSel(0),
m_pMruServer(NULL),
m_pUls(NULL),
m_pSpeedDial(NULL),
#if USE_GAL
m_pGAL(NULL),
#endif //#if USE_GAL
m_pAlv(NULL),
m_pWab(NULL),
m_pHistory(NULL),
m_pszDefault(NULL),
m_pRai(NULL),
m_pConfRoom(pConfRoom),
m_bPlacedCall(false)
{
SetEmptySz(m_szAddress);
SetEmptySz(m_szDirectory);
// BUGBUG georgep: Why are we checking m_dwOptions? It was set to 0 above.
if ((0 == (m_dwOptions & NM_CALLDLG_NO_WAB)) &&
(NULL == CWAB::GetInstance()) )
{
m_pWab = new CWAB();
}
if (0 == (m_dwOptions & NM_CALLDLG_NO_ILS))
{
m_pMruServer = GetMruListServer();
m_pUls = new CLDAP();
}
if (0 == (m_dwOptions & NM_CALLDLG_NO_SPEEDDIAL))
{
m_pSpeedDial = new CSPEEDDIAL();
}
#if USE_GAL
if ((0 == (m_dwOptions & NM_CALLDLG_NO_GAL)) &&
CGAL::FLoadMapiFns() )
{
m_pGAL = new CGAL();
}
#endif // USE_GAL
if (0 == (m_dwOptions & NM_CALLDLG_NO_HISTORY))
{
m_pHistory = new CHISTORY();
}
// Load the small icon list
m_himlIcon = ImageList_Create(DXP_ICON_SMALL, DYP_ICON_SMALL, ILC_MASK, 1, 0);
if (NULL != m_himlIcon)
{
HBITMAP hBmp = ::LoadBitmap(::GetInstanceHandle(), MAKEINTRESOURCE(IDB_ICON_IMAGES));
if (NULL != hBmp)
{
ImageList_AddMasked(m_himlIcon, hBmp, TOOLBAR_MASK_COLOR);
::DeleteObject(hBmp);
}
}
m_pConfRoom->AddConferenceChangeHandler(this);
}
CFindSomeone::~CFindSomeone(void)
{
// Clear any existing data
if (NULL != m_pAlv)
{
m_pAlv->ClearItems();
}
delete m_pMruServer;
if (NULL != m_pWab)
{
m_pWab->Release();
}
if (NULL != m_pUls)
{
m_pUls->Release();
}
if (NULL != m_pSpeedDial)
{
m_pSpeedDial->Release();
}
if (NULL != m_himlIcon)
{
ImageList_Destroy(m_himlIcon);
}
#if USE_GAL
if (NULL != m_pGAL)
{
m_pGAL->Release();
}
#endif // USE_GAL
if (NULL != m_pHistory)
{
m_pHistory->Release();
}
ClearRai(&m_pRai);
m_pConfRoom->RemoveConferenceChangeHandler(this);
}
//--------------------------------------------------------------------------//
// CFindSomeone::findSomeone. //
//--------------------------------------------------------------------------//
void
CFindSomeone::findSomeone(CConfRoom *pConfRoom)
{
if (NULL == s_pDlgCall)
{
s_pDlgCall = new CFindSomeone(pConfRoom);
s_pDlgCall->doModeless();
}
if (NULL != s_pDlgCall)
{
HWND hwnd = s_pDlgCall->GetWindow();
::ShowWindow( hwnd, SW_RESTORE );
::SetForegroundWindow( hwnd );
}
} // End of CFindSomeone::findSomeone.
//--------------------------------------------------------------------------//
// CDlgCall::Destroy. //
//--------------------------------------------------------------------------//
void
CFindSomeone::Destroy()
{
WARNING_OUT(("Entering CFindSomeone::Destroy( )..."));
CFindSomeone * pDlgCall = s_pDlgCall;
s_pDlgCall = NULL;
if( pDlgCall != NULL )
{
if( pDlgCall->m_pUls != NULL )
{
// Stop the CLDAP thread from trying to interact with the FindSomeone
// windows after we've already destroyed them...
pDlgCall->m_pUls->CloseServer();
}
HWND hwnd = pDlgCall->GetWindow();
if (NULL != hwnd)
{
WARNING_OUT(("CFindSomeone::Destroy( ): destroying windows..."));
DestroyWindow(hwnd);
}
pDlgCall->Release();
}
WARNING_OUT(("Exiting CFindSomeone::Destroy( )..."));
} // End of CDlgCall::Destroy.
HWND CFindSomeone::GetHwndList()
{
return ( m_pAlv && m_pAlv->FOwnerData() ) ?
m_hwndOwnerDataList : (m_pAlv == (CALV *) m_pUls)? m_ilsListView: m_hwndList;
}
RAI * CFindSomeone::GetAddrInfo()
{
return DupRai(m_pRai);
}
/* F M S G S P E C I A L */
/*-------------------------------------------------------------------------
%%Function: FMsgSpecial
Return TRUE if this is a special message, not to be passed to IsDialogMessage
-------------------------------------------------------------------------*/
BOOL CFindSomeone::FMsgSpecial(MSG * pMsg)
{
switch (pMsg->message)
{
case WM_KEYDOWN:
case WM_KEYUP:
case WM_CHAR:
if (VK_F5 == pMsg->wParam)
return TRUE;
if (VK_RETURN == pMsg->wParam)
{
if (m_hwndComboEdit == GetFocus())
{
return TRUE;
}
}
break;
default:
break;
}
return FALSE;
}
/* D O M O D A L */
/*-------------------------------------------------------------------------
%%Function: DoModal
-------------------------------------------------------------------------*/
HRESULT
CFindSomeone::doModeless(void)
{
#if 0
HACCEL hAccel = LoadAccelerators(::GetInstanceHandle(), MAKEINTRESOURCE(IDA_DLGCALL));
#endif
HRESULT hr = CreateDlgCall(NULL);
#if 0
if (SUCCEEDED(hr) && (NULL != m_hwnd))
{
while (IsWindow(m_hwnd))
{
MSG msg;
if (!::GetMessage(&msg, NULL, 0, 0))
{
// Don't eat the WM_QUIT
PostQuitMessage(msg.wParam);
break; // out of loop
}
if (FMsgSpecial(&msg) || !IsDialogMessage(m_hwnd, &msg))
{
if (FALSE == ::TranslateAccelerator(m_hwnd, hAccel, &msg))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
}
}
#endif
return hr;
}
// Determine the standard font size
VOID CFindSomeone::CalcDyText(void)
{
m_dyText = 14; // default to something reasonable
HWND hwnd = GetWindow();
ASSERT(NULL != hwnd);
HDC hdc = GetDC(hwnd);
if (NULL == hdc)
return;
TEXTMETRIC tm;
if (GetTextMetrics(hdc, &tm))
{
m_dyText = tm.tmHeight;
}
// Leave space for 4 n's (two on each side)
TCHAR sz[MAX_PATH];
const int cSpaceN = 4;
for (int ich = 0; ich < cSpaceN; ich++)
{
sz[ich] = _T('n');
}
if (FLoadString( IDS_DLGCALL_CLOSE, &sz[cSpaceN], CCHMAX(sz)-cSpaceN))
{
HFONT hfont = SelectFont(hdc, ::GetDefaultFont());
RECT rc;
SetRect(&rc, 0, 0, 0, 0);
m_dyButton = 2*DY_BORDER + DrawText(hdc, sz, -1, &rc, DT_CALCRECT);
m_dxButton = rc.right;
hfont = SelectFont(hdc, hfont);
}
ReleaseDC(hwnd, hdc);
}
HWND CreatIconButton(HWND hwndParent, int idTooltip, int idCmd, int idIcon)
{
HWND hwndButton = CreateButton( hwndParent, idTooltip, idCmd );
if (NULL != hwndButton)
{
AddToolTip(hwndParent, hwndButton, idTooltip);
SetWindowLong(hwndButton, GWL_STYLE, BS_PUSHBUTTON|BS_ICON|WS_VISIBLE|WS_CHILD|WS_TABSTOP);
HANDLE hIcon = LoadImage(GetInstanceHandle(), MAKEINTRESOURCE(idIcon),
IMAGE_ICON, 0, 0, 0);
SendMessage(hwndButton, BM_SETIMAGE, IMAGE_ICON, reinterpret_cast<LPARAM>(hIcon));
}
return(hwndButton);
}
/* C R E A T E D L G C A L L */
/*-------------------------------------------------------------------------
%%Function: CreateDlgCall
The order in which these windows is created is very important.
See the Layout function and pay attention to the tab order
-------------------------------------------------------------------------*/
HRESULT CFindSomeone::CreateDlgCall(HWND hwndParent)
{
TCHAR sz[CCHMAXSZ];
HRESULT hr = S_OK;
if (NULL == m_himlIcon)
return E_FAIL; // no pretty icons, don't bother trying to continue
if (!FLoadString(IDS_DLGCALL_TITLE, sz, CCHMAX(sz)))
return E_FAIL;
// Get the window position
PVOID pv;
RECT rcDest; // left, right, width, height
RegEntry re(DLGCALL_MRU_KEY, HKEY_CURRENT_USER);
if (sizeof(rcDest) == re.GetBinary(REGVAL_DLGCALL_POSITION, &pv))
{
CopyMemory(&rcDest, pv, sizeof(rcDest));
}
else
{
GetDefaultRect( hwndParent, rcDest, DX_DLGCALL_DEFAULT, DY_DLGCALL_DEFAULT );
rcDest.right -= rcDest.left;
rcDest.bottom -= rcDest.top;
}
if (!CFrame::Create(
hwndParent,
sz,
WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME,
0,
rcDest.left, rcDest.top, rcDest.right, rcDest.bottom,
GetInstanceHandle(),
LoadIcon(GetInstanceHandle(), MAKEINTRESOURCE(IDI_WEBVIEW))
))
{
return E_OUTOFMEMORY;
}
HWND hwndThis = GetWindow();
CalcDyText();
//////////////////////////////////
// Static text at the top
HWND hwnd = CreateStaticText(hwndThis, IDS_DLGCALL_HDR);
DWORD dwStyle = WS_CHILD | WS_BORDER | WS_VSCROLL | WS_VISIBLE | WS_TABSTOP |
WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CBS_AUTOHSCROLL;
// Either a complicated combo edit/listbox or a simple drop list
if ((NULL != m_pUls) && m_pUls->FAvailable())
{
dwStyle |= (0 != (nmDlgCallNoServerEdit & m_dwOptions)) ?
CBS_DROPDOWNLIST : CBS_DROPDOWN;
}
else
{
dwStyle |= CBS_DROPDOWNLIST;
}
m_hwndCombo = ::CreateWindowEx(0L, g_cszComboBoxEx, g_cszEmpty, dwStyle,
0, 0, DX_BORDER, DY_COMBOBOX,
hwndThis, (HMENU) IDC_DLGCALL_COMBO,
::GetInstanceHandle(), NULL);
if (NULL != m_hwndCombo)
{
// Set the icons
::SendMessage(m_hwndCombo, CBEM_SETIMAGELIST, 0, (LPARAM) m_himlIcon);
// Set the font:
::SendMessage(m_hwndCombo, WM_SETFONT, (WPARAM) GetDefaultFont(), 0);
// Limit the text
::SendMessage(m_hwndCombo, CB_LIMITTEXT, CCHMAXSZ_ADDRESS-1, 0L);
// Set extended user interface
::SendMessage(m_hwndCombo, CB_SETEXTENDEDUI, 1, 0L);
m_hwndComboEdit = (HWND) SendMessage(m_hwndCombo, CBEM_GETEDITCONTROL, 0, 0);
if (NULL != m_hwndComboEdit)
{
// Add a tooltip to the combo box (actually, the edit control)
AddToolTip(hwndThis, m_hwndComboEdit, IDS_DLGCALL_COMBO_TOOLTIP);
}
else
{
// Add a tooltip to the combo box
AddToolTip(hwndThis, m_hwndCombo, IDS_DLGCALL_COMBO_TOOLTIP);
}
}
CreatIconButton(hwndThis, IDS_TT_DELETE_ILS, IDM_DLGCALL_DELETE_ILS, IDI_DELETE);
CreatIconButton(hwndThis, IDS_TT_NEWWINDOW , IDM_DLGCALL_NEWWINDOW , IDI_NEWHTMLWINDOW);
CreatIconButton(hwndThis, IDS_TT_REFRESH , IDM_DLGCALL_REFRESH , IDI_REFRESH);
CreatIconButton(hwndThis, IDS_TT_HELP , ID_TB_HELP , IDI_HELP);
//////////////////////////////////
// GroupBox
m_hwndFrame = ::CreateWindowEx( 0, TEXT( "button" ), g_cszEmpty,
WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | WS_GROUP | BS_GROUPBOX,
0, 0, 0, 0,
hwndThis, (HMENU) -1,
::GetInstanceHandle(), NULL);
//////////////////////////////////
// Edit Control
CreateStaticText(hwndThis, IDS_DLGCALL_EDIT_HDR);
m_hwndEdit = ::CreateWindowEx(WS_EX_CLIENTEDGE, g_cszEdit, g_cszEmpty,
WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP | WS_CLIPCHILDREN |
ES_AUTOHSCROLL,
0, 0, 0, 0,
hwndThis, (HMENU) IDE_DLGCALL_NAME,
::GetInstanceHandle(), NULL);
if (NULL != m_hwndEdit)
{
// Set the font:
::SendMessage(m_hwndEdit, WM_SETFONT, (WPARAM) GetDefaultFont(), 0);
// Limit the text
::SendMessage(m_hwndEdit, EM_LIMITTEXT, CCHMAXSZ_ADDRESS-1, 0L);
// Add a tooltip to the edit control
AddToolTip(hwndThis, m_hwndEdit, IDS_DLGCALL_EDIT_TOOLTIP);
}
////////////////////////////////
// Main Listbox
m_hwndList = CreateWindowEx(WS_EX_CLIENTEDGE, g_cszListView, g_cszEmpty,
WS_CHILD | WS_CLIPCHILDREN | WS_BORDER | WS_TABSTOP | WS_VISIBLE |
LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS |
LVS_SORTASCENDING | LVS_NOSORTHEADER,
0, 0, 0, 0,
hwndThis, (HMENU) IDL_DLGCALL_LIST,
::GetInstanceHandle(), NULL);
if (NULL != m_hwndList)
{
ListView_SetExtendedListViewStyle(m_hwndList, LVS_EX_FULLROWSELECT);
ListView_SetImageList(m_hwndList, m_himlIcon, LVSIL_SMALL);
LV_COLUMN lvc;
ClearStruct(&lvc);
lvc.mask = LVCF_TEXT | LVCF_SUBITEM;
lvc.pszText = sz;
if (FLoadString(IDS_NAME, sz, CCHMAX(sz)))
{
lvc.iSubItem = 0;
ListView_InsertColumn(m_hwndList, IDI_DLGCALL_NAME, &lvc);
}
if (FLoadString(IDS_ADDRESS, sz, CCHMAX(sz)))
{
lvc.iSubItem = 1;
ListView_InsertColumn(m_hwndList, IDI_DLGCALL_ADDRESS, &lvc);
}
m_cVisible = ListView_GetCountPerPage(m_hwndList);
}
////////////////////////////////
// OwnerData Listbox
m_hwndOwnerDataList = CreateWindowEx(WS_EX_CLIENTEDGE, g_cszListView, g_cszEmpty,
WS_CHILD | WS_CLIPCHILDREN | WS_BORDER | WS_TABSTOP | WS_VISIBLE |
LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS |
LVS_SORTASCENDING | LVS_NOSORTHEADER | LVS_OWNERDATA,
0, 0, 0, 0,
hwndThis, (HMENU) IDL_DLGCALL_LISTOWNERDATA,
::GetInstanceHandle(), NULL);
if (NULL != m_hwndOwnerDataList)
{
ListView_SetExtendedListViewStyle(m_hwndOwnerDataList, LVS_EX_FULLROWSELECT);
ListView_SetImageList(m_hwndOwnerDataList, m_himlIcon, LVSIL_SMALL);
LV_COLUMN lvc;
ClearStruct(&lvc);
lvc.mask = LVCF_TEXT | LVCF_SUBITEM;
lvc.pszText = sz;
if (FLoadString(IDS_NAME, sz, CCHMAX(sz)))
{
lvc.iSubItem = 0;
ListView_InsertColumn(m_hwndOwnerDataList, IDI_DLGCALL_NAME, &lvc);
}
if (FLoadString(IDS_ADDRESS, sz, CCHMAX(sz)))
{
lvc.iSubItem = 1;
ListView_InsertColumn(m_hwndOwnerDataList, IDI_DLGCALL_ADDRESS, &lvc);
}
m_WndOwnerDataListOldWndProc = reinterpret_cast< WNDPROC >(GetWindowLongPtr(m_hwndOwnerDataList, GWLP_WNDPROC));
SetWindowLongPtr(m_hwndOwnerDataList, GWLP_USERDATA, reinterpret_cast< LONG_PTR >( this ));
SetWindowLongPtr(m_hwndOwnerDataList, GWLP_WNDPROC, reinterpret_cast< LONG_PTR >( OwnerDataListWndProc));
}
////////////////////////////////
// ILS Listbox
m_ilsListView = CreateWindowEx( WS_EX_CLIENTEDGE,
WC_LISTVIEW, // list view class
TEXT( "" ), // no default text
WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_TABSTOP |
LVS_REPORT | LVS_SINGLESEL | LVS_AUTOARRANGE | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS,
0, 0,
0, 0,
hwndThis,
(HMENU) IDL_DLGCALL_ILS_LISTVIEW,
::GetInstanceHandle(),
NULL );
if( m_ilsListView != NULL )
{
InitColumns();
// Associate the image list with the list view
ListView_SetImageList( m_ilsListView, m_himlIcon, LVSIL_SMALL);
// set the style to do drag and drop headers and full row select
ListView_SetExtendedListViewStyle( m_ilsListView, ListView_GetExtendedListViewStyle( m_ilsListView ) |
LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES );
}
TCHAR szWebDir[1024];
CDirectoryManager::get_webDirectoryUrl(szWebDir, ARRAY_ELEMENTS(szWebDir));
m_webView = CreateWindowEx( WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT,
TEXT( "AtlAxWin" ),
szWebDir,
WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | WS_TABSTOP,
0, 0,
0, 0,
hwndThis,
(HMENU) IDL_DLGCALL_WEB_VIEW,
::GetInstanceHandle(),
NULL );
//////////////////////////////////
// Security Control
FLoadString( IDS_SECURITY_CHECKBOX, sz, CCHMAX( sz ) );
HWND securityCheckBox;
securityCheckBox = ::CreateWindow(
TEXT( "button" ),
sz,
WS_CHILD | WS_TABSTOP | WS_VISIBLE | BS_AUTOCHECKBOX | BS_MULTILINE | BS_TOP,
0, 0, 0, 0,
hwndThis,
(HMENU) IDS_SECURITY_CHECKBOX,
::GetInstanceHandle(),
NULL );
if( securityCheckBox != NULL )
{
// Set the font:
::SendMessage(securityCheckBox, WM_SETFONT, (WPARAM) GetDefaultFont(), 0);
UpdateSecurityCheck(m_pConfRoom, hwndThis, IDS_SECURITY_CHECKBOX);
}
CreateButton( hwndThis, IDS_DLGCALL_CALL, IDOK );
CreateButton( hwndThis, IDS_DLGCALL_CLOSE, IDCANCEL );
// Finally, initialize the data in each list
InitAlv();
Layout();
if( m_ilsListView != NULL )
{
LoadColumnInfo();
}
if (m_pConfRoom->FIsConferenceActive())
{
// Simulate a call started to get all the states right
OnCallStarted();
}
ShowWindow(hwndThis, SW_SHOWNORMAL);
::EnableWindow(GetDlgItem(hwndThis, IDOK), FALSE);
if( m_pAlv )
{
SetFocus(m_hwndEdit);
if (!FEmptySz(m_pszDefault))
{
SetWindowText(m_hwndEdit, m_pszDefault);
}
}
else
{
hr = E_FAIL;
}
return hr;
}
bool
get_textRect
(
const HWND window,
RECT & rect,
const TCHAR * const measureText = NULL
);
//--------------------------------------------------------------------------//
// get_textRect. //
//--------------------------------------------------------------------------//
bool
get_textRect
(
const HWND window,
RECT & rect,
const TCHAR * const measureText
){
HDC dc = GetDC( window );
bool result = false;
if( dc != NULL )
{
HFONT font = SelectFont( dc, ::GetDefaultFont() );
if( measureText != NULL )
{
DrawText( dc, measureText, -1, &rect, DT_CALCRECT | DT_WORDBREAK );
result = true;
}
else
{
int length;
if( (length = ::SendMessage( window, WM_GETTEXTLENGTH, 0, 0 )) > 0 )
{
TCHAR * text = new TCHAR [ length + 1 ];
if( text != NULL )
{
::SendMessage( window, WM_GETTEXT, length + 1, (LPARAM) text );
DrawText( dc, text, -1, &rect, DT_CALCRECT | DT_WORDBREAK );
delete [] text;
result = true;
}
}
}
SelectFont( dc, font );
ReleaseDC( window, dc );
}
return( result );
} // End of get_textRect.
//--------------------------------------------------------------------------//
// CFindSomeone::Layout. //
//--------------------------------------------------------------------------//
void
CFindSomeone::Layout(void)
{
// BUGBUG georgep: Hard coded for now
static const int IconButtonWidth = 24;
static const int IconButtonHeight = 24;
static const int idIconButtons[] =
{
IDM_DLGCALL_DELETE_ILS,
IDM_DLGCALL_NEWWINDOW,
IDM_DLGCALL_REFRESH,
ID_TB_HELP,
};
static const int NumIconButtons = ARRAY_ELEMENTS(idIconButtons);
HWND hwnd = GetWindow();
HDWP hdwp = BeginDeferWindowPos(15);
// Get client area (inside margin/border)...
RECT rc;
GetClientRect(hwnd, &rc);
int clientWidth = rc.right - 2*DX_BORDER;
int clientHeight = rc.bottom - (DY_BORDER + DY_BORDER + m_dyButton);
int maxComboLabelWidth = (clientWidth - NumIconButtons*(DX_BORDER + IconButtonWidth)) / 2;
HWND comboLabel = GetDlgItem( hwnd, IDS_DLGCALL_HDR );
RECT comboRect;
RECT comboLabelRect;
GetWindowRect( m_hwndCombo, &comboRect );
SetRect( &comboLabelRect, 0, 0, maxComboLabelWidth, 0 );
get_textRect( comboLabel, comboLabelRect );
int comboHeight = RectHeight( comboRect );
int comboLabelWidth = RectWidth( comboLabelRect );
int comboLabelHeight = RectHeight( comboLabelRect );
int maxHeight = max( comboHeight, comboLabelHeight );
int comboLabelLeft = DX_BORDER;
int comboLabelTop = max( DY_BORDER, (DY_BORDER + ((maxHeight - comboLabelHeight) / 2)) );
hdwp = DeferWindowPos(hdwp,
comboLabel,
NULL,
comboLabelLeft,
comboLabelTop,
comboLabelWidth,
comboLabelHeight,
SWP_NOACTIVATE | SWP_NOZORDER );
int comboLeft = comboLabelLeft + comboLabelWidth + DX_BORDER;
int comboTop = max( DY_BORDER, (DY_BORDER + ((maxHeight - comboHeight) / 2)) );
int comboWidth = clientWidth - (comboLabelLeft + comboLabelWidth
+ NumIconButtons*(DX_BORDER + IconButtonWidth) );
hdwp = DeferWindowPos(hdwp,
m_hwndCombo,
NULL,
comboLeft,
comboTop,
comboWidth,
DY_COMBOBOX,
SWP_NOACTIVATE | SWP_NOZORDER );
{
for (int i=0; i<NumIconButtons; ++i)
{
hdwp = DeferWindowPos(hdwp,
GetDlgItem(hwnd, idIconButtons[i]),
NULL,
comboLeft + comboWidth + DX_BORDER + i*(IconButtonWidth+DX_BORDER),
comboTop,
IconButtonWidth,
IconButtonHeight,
SWP_NOACTIVATE | SWP_NOZORDER );
}
}
int frameTop = maxHeight + DY_BORDER;
hdwp = DeferWindowPos(hdwp,
m_hwndFrame,
NULL,
DX_BORDER,
frameTop,
clientWidth,
clientHeight - frameTop,
SWP_NOACTIVATE | SWP_NOZORDER );
// Add a little because groups draw inside their bounds
frameTop += 2 * DY_BORDER;
RECT editLabelRect;
HWND editLabel = GetDlgItem( hwnd, IDS_DLGCALL_EDIT_HDR );
int editLabelWidth = (clientWidth - (DX_BORDER * 6)) / 2;
SetRect( &editLabelRect, 0, 0, editLabelWidth, 0 );
get_textRect( editLabel, editLabelRect );
int editLabelHeight = RectHeight( editLabelRect );
int editLabelLeft = DY_BORDER * 3;
int editLabelTop = frameTop + DY_BORDER;
hdwp = DeferWindowPos(hdwp,
editLabel,
NULL,
editLabelLeft,
editLabelTop,
editLabelWidth,
editLabelHeight,
SWP_NOACTIVATE | SWP_NOZORDER );
int editTop = editLabelTop + editLabelHeight + DY_BORDER;
// Edit Control
hdwp = DeferWindowPos(hdwp,
m_hwndEdit,
NULL,
editLabelLeft,
editTop,
editLabelWidth,
comboHeight,
SWP_NOACTIVATE | SWP_NOZORDER );
int buttonTop = clientHeight - ((DY_BORDER * 3) / 2) - m_dyButton;
int listViewLeft = 3 * DX_BORDER;
int listViewTop = editTop + comboHeight + DY_BORDER;
int listViewWidth = clientWidth - (DX_BORDER * 4);
int listViewHeight = buttonTop - listViewTop - DY_BORDER;
int columns = _GetCurListViewNumColumns();
int columnWidth = listViewWidth / columns;
// ListBox
hdwp = DeferWindowPos(hdwp,
m_hwndList,
NULL,
listViewLeft,
listViewTop,
listViewWidth,
listViewHeight,
SWP_NOACTIVATE | SWP_NOZORDER );
hdwp = DeferWindowPos(hdwp,
m_hwndOwnerDataList,
NULL,
listViewLeft,
listViewTop,
listViewWidth,
listViewHeight,
SWP_NOACTIVATE | SWP_NOZORDER );
hdwp = DeferWindowPos(hdwp,
m_ilsListView,
NULL,
listViewLeft,
listViewTop,
listViewWidth,
listViewHeight,
SWP_NOACTIVATE | SWP_NOZORDER );
HWND hWndList = GetHwndList();
if( hWndList != m_ilsListView )
{
for( int i = 0; i < columns; i++ )
{
ListView_SetColumnWidth( hWndList, i, columnWidth );
}
}
InvalidateRect( ListView_GetHeader(hWndList), NULL, true );
m_cVisible = ListView_GetCountPerPage(hWndList);
{
int securityWidth = editLabelWidth - GetSystemMetrics( SM_CXSMICON );
HWND security = GetDlgItem( hwnd, IDS_SECURITY_CHECKBOX );
RECT securityRect;
SetRect( &securityRect, 0, 0, securityWidth, 0 );
get_textRect( security, securityRect );
// + 2 for the focus rect
int securityHeight = RectHeight( securityRect ) + 2;
int checkHeight = GetSystemMetrics(SM_CYMENUCHECK);
securityHeight = max (securityHeight, checkHeight);
hdwp = DeferWindowPos(hdwp,
security,
NULL,
listViewLeft,
buttonTop,
securityWidth,
securityHeight,
SWP_NOACTIVATE | SWP_NOZORDER );
}
HWND callButton = GetDlgItem( hwnd, IDOK );
hdwp = DeferWindowPos(hdwp,
callButton,
NULL,
clientWidth - DX_BORDER - m_dxButton,
buttonTop,
m_dxButton,
m_dyButton,
SWP_NOACTIVATE | SWP_NOZORDER );
hdwp = DeferWindowPos(hdwp,
m_webView,
NULL,
DX_BORDER,
frameTop,
clientWidth,
clientHeight - frameTop,
SWP_NOACTIVATE | SWP_NOZORDER );
// Center the close button at the bottom of the window
HWND closeButton = GetDlgItem( hwnd, IDCANCEL );
hdwp = DeferWindowPos(hdwp,
closeButton,
NULL,
(clientWidth - m_dxButton) / 2,
clientHeight + DY_BORDER,
m_dxButton,
m_dyButton,
SWP_NOACTIVATE | SWP_NOZORDER );
EndDeferWindowPos(hdwp);
} // End of CFindSomeone::Layout.
static BOOL IsInClient(HWND hwnd, POINT *ppt)
{
RECT rc;
GetClientRect(hwnd, &rc);
MapWindowPoints(hwnd, HWND_DESKTOP, (POINT *) &rc, 2);
return(PtInRect(&rc, *ppt));
}
void CFindSomeone::OnContextMenu(HWND hwnd, HWND hwndContext, UINT xPos, UINT yPos)
{
POINT pt = { xPos, yPos };
if (IsInClient(GetHwndList(), &pt))
{
m_pAlv->OnRClick(pt);
return;
}
if (IsInClient(GetWindow(), &pt))
{
DoHelpWhatsThis(reinterpret_cast<WPARAM>(hwndContext), _mpIdHelpDlgCall);
return;
}
FORWARD_WM_CONTEXTMENU(hwnd, hwndContext, xPos, yPos, CFrame::ProcessMessage);
}
LRESULT CFindSomeone::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
HANDLE_MSG(hwnd, WM_COMMAND , OnCommand);
HANDLE_MSG(hwnd, WM_CONTEXTMENU, OnContextMenu);
case WM_GETMINMAXINFO:
{
LPMINMAXINFO lpminmax = (LPMINMAXINFO) lParam;
lpminmax->ptMinTrackSize.x = DX_DLGCALL_MIN;
lpminmax->ptMinTrackSize.y = DY_DLGCALL_MIN;
return 0;
}
case WM_DISPLAY_MSG:
{
DisplayMsgId(hwnd, (int) wParam);
return 0;
}
case WM_CLOSE:
Destroy();
break;
case WM_CREATE:
{
HACCEL hAccel = LoadAccelerators(_Module.GetModuleInstance(), MAKEINTRESOURCE(IDA_DLGCALL));
if (NULL != hAccel)
{
m_pAccel = new CTranslateAccelTable(hwnd, hAccel);
if (NULL != m_pAccel)
{
AddTranslateAccelerator(m_pAccel);
}
}
// Must be done AFTER adding the accelerator table
AddModelessDlg(hwnd);
break;
}
case WM_DESTROY:
{
if (NULL != m_pAccel)
{
RemoveTranslateAccelerator(m_pAccel);
m_pAccel->Release();
m_pAccel = NULL;
}
RemoveModelessDlg(hwnd);
if (NULL != m_pAlv)
{
m_pAlv->ClearItems();
m_pAlv->ClearHwnd();
}
RegEntry re(DLGCALL_MRU_KEY, HKEY_CURRENT_USER);
// Save the window size/position
WINDOWPLACEMENT wp = { sizeof(wp), };
if (GetWindowPlacement(hwnd, &wp))
{
RECT rc = wp.rcNormalPosition;
rc.right -= rc.left;
rc.bottom -= rc.top;
re.SetValue(REGVAL_DLGCALL_POSITION, &rc, sizeof(rc));
}
// Save the selected view
TCHAR szServer[CCHMAXSZ_SERVER];
if (0 != GetWindowText(m_hwndComboEdit, szServer, CCHMAX(szServer)))
{
TRACE_OUT(("Saving last used directory is [%s]", szServer));
re.SetValue(REGVAL_DLGCALL_DEFDIR, szServer);
}
StoreColumnInfo();
return 0;
}
case WM_HELP:
{
DoHelp(lParam, _mpIdHelpDlgCall);
break;
}
case WM_NOTIFY:
{
switch (wParam)
{
case IDL_DLGCALL_LIST:
case IDL_DLGCALL_LISTOWNERDATA:
case IDL_DLGCALL_ILS_LISTVIEW:
return OnNotifyList(lParam);
case IDC_DLGCALL_COMBO:
OnNotifyCombo(lParam);
break;
default:
break;
}
break;
}
case WM_SETTINGCHANGE:
{
WINDOWPLACEMENT wp;
wp.length = sizeof(wp);
if (!GetWindowPlacement(hwnd, &wp))
break;
switch (wp.showCmd)
{
case SW_NORMAL:
case SW_RESTORE:
{
CalcDyText();
Layout();
break;
}
default:
break;
}
break;
}
case WM_SETCURSOR:
{
if (0 == g_cBusy)
break;
::SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_APPSTARTING)));
return TRUE;
}
case WM_SETFOCUS:
{
::SetFocus(m_hwndEdit);
return 0;
}
default:
break;
}
return(CFrame::ProcessMessage(hwnd, uMsg, wParam, lParam));
}
/* O N N O T I F Y L I S T */
/*-------------------------------------------------------------------------
%%Function: OnNotifyList
-------------------------------------------------------------------------*/
LRESULT CFindSomeone::OnNotifyList(LPARAM lParam)
{
LPNMHDR pnmh = (LPNMHDR) lParam;
HWND hwnd = GetWindow();
switch (pnmh->code)
{
case NM_DBLCLK:
{
OnCommand(hwnd, IDOK, NULL, 0);
break;
}
case LVN_KEYDOWN:
{
LPNMLVKEYDOWN pkdn = (LPNMLVKEYDOWN) lParam;
switch (pkdn->wVKey)
{
case VK_F5:
OnCommand(hwnd, IDM_DLGCALL_REFRESH, NULL, 0);
break;
case VK_DELETE:
OnCommand(hwnd, IDM_DLGCALL_DELETE, NULL, 0);
break;
default:
break;
}
break;
}
case LVN_ITEMCHANGED:
{
CConfRoom *pConfRoom = GetConfRoom();
if (m_fInEdit || NULL == pConfRoom || !pConfRoom->IsNewCallAllowed())
break;
int iSel = m_pAlv->GetSelection();
BOOL fEnable = (-1 != iSel);
EnableWindow(GetDlgItem(hwnd, IDOK), fEnable);
break;
}
case LVN_GETDISPINFO:
{
LV_DISPINFO *lpdi = (LV_DISPINFO *)lParam;
if (lpdi->item.mask & LVIF_TEXT)
{
switch( lpdi->item.iSubItem )
{
case 0:
m_pAlv->OnListGetColumn1Data(lpdi->item.iItem, lpdi->item.cchTextMax, lpdi->item.pszText);
break;
case 1:
m_pAlv->OnListGetColumn2Data(lpdi->item.iItem, lpdi->item.cchTextMax, lpdi->item.pszText);
break;
case 2:
m_pAlv->OnListGetColumn3Data(lpdi->item.iItem, lpdi->item.cchTextMax, lpdi->item.pszText);
break;
}
}
if( lpdi->item.mask & LVIF_IMAGE )
{
lpdi->item.iImage = m_pAlv->OnListGetImageForItem( lpdi->item.iItem );
}
break;
}
case LVN_ODCACHEHINT:
{
LPNMLVCACHEHINT lpCacheHint = reinterpret_cast< LPNMLVCACHEHINT > (lParam);
m_pAlv->OnListCacheHint(lpCacheHint->iFrom, lpCacheHint->iTo);
break;
}
case LVN_ODFINDITEM:
{
LPNMLVFINDITEM lpFindItem = reinterpret_cast< LPNMLVFINDITEM > (lParam);
if (0 == (lpFindItem->lvfi.flags & (LVFI_PARTIAL | LVFI_STRING)))
break;
return m_pAlv->OnListFindItem(lpFindItem->lvfi.psz);
}
case LVN_COLUMNCLICK:
{
if( m_pAlv == m_pUls )
{
// The user clicked on one of the column headings - sort by
// this column.
TRACE_OUT(("CFindSomeone::OnNotify called (NM_COLUMNCLICK)"));
NM_LISTVIEW *pNm = (NM_LISTVIEW *)lParam;
ASSERT(pNm);
if (pNm->iSubItem == m_iSortColumn)
{
m_fSortAscending = !m_fSortAscending;
}
else if( pNm->iSubItem != -1 )
{
m_fSortAscending = TRUE;
}
if( pNm->iSubItem != -1 )
{
m_iSortColumn = pNm->iSubItem;
}
else
{
pNm->iSubItem = m_iSortColumn;
}
SendMessage( pNm->hdr.hwndFrom, WM_SETREDRAW, FALSE, 0 );
ListView_SortItems( pNm->hdr.hwndFrom,
CompareWrapper,
(LPARAM) this );
SendMessage( pNm->hdr.hwndFrom, WM_SETREDRAW, TRUE, 0 );
}
break;
}
case NM_CUSTOMDRAW:
{
return DoCustomDraw((LPNMLVCUSTOMDRAW)lParam);
}
default:
break;
}
return 0;
}
/* D O C U S T O M D R A W */
/*-------------------------------------------------------------------------
%%Function: DoCustomDraw
-------------------------------------------------------------------------*/
LRESULT CFindSomeone::DoCustomDraw(LPNMLVCUSTOMDRAW lplvcd)
{
switch (lplvcd->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
{
return CDRF_NOTIFYITEMDRAW;
}
case CDDS_ITEMPREPAINT:
{
if (!m_pAlv->IsItemBold(lplvcd->nmcd.dwItemSpec))
break;
//get the existing font
HFONT hFont = (HFONT)SendMessage(m_hwndOwnerDataList, WM_GETFONT, 0, 0);
if (NULL == hFont)
break;
LOGFONT lf;
if (0 == GetObject(hFont, sizeof(lf), &lf))
break;
lf.lfWeight = FW_BOLD;
hFont = CreateFontIndirect(&lf);
if (NULL == hFont)
break;
SelectObject(lplvcd->nmcd.hdc, hFont);
return CDRF_NEWFONT | CDRF_NOTIFYPOSTPAINT;
}
case CDDS_ITEMPOSTPAINT:
{
HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
if (NULL != hFont)
{
//clean up stuff here
hFont = (HFONT)SelectObject(lplvcd->nmcd.hdc, hFont);
DeleteFont(hFont);
}
break;
}
default:
break;
}
return CDRF_DODEFAULT;
}
/* U P D A T E I L S S E R V E R */
/*-------------------------------------------------------------------------
%%Function: UpdateIlsServer
Update the current ILS server based on the text in the combo's edit control.
-------------------------------------------------------------------------*/
VOID CFindSomeone::UpdateIlsServer(void)
{
TCHAR szServer[CCHMAXSZ_SERVER];
if (0 == GetWindowText(m_hwndComboEdit, szServer, CCHMAX(szServer)))
return;
const TCHAR * const displayName = CDirectoryManager::get_displayName( szServer );
const TCHAR * const dnsName = CDirectoryManager::get_dnsName( szServer );
SetWindowText( m_hwndComboEdit, displayName );
int iSel = ::SendMessage(m_hwndCombo, CB_FINDSTRINGEXACT, (WPARAM) -1, (LPARAM) displayName );
if ((CB_ERR == iSel) && (NULL != m_pUls) && m_pUls->FAvailable())
{
RegEntry rePol(POLICIES_KEY, HKEY_CURRENT_USER);
//
// Assume this is an ILS server - and add it to the list ONLY if
// not prevented by policy.
//
if (!rePol.GetNumber(REGVAL_POL_NO_ADDING_NEW_ULS, DEFAULT_POL_NO_ADDING_NEW_ULS))
{
if (NULL != m_pMruServer)
{
if( m_pMruServer->AddNewEntry( dnsName ) )
{
iSel = AddAlvSz( m_pUls, displayName, m_iIlsFirst );
}
}
}
}
if (CB_ERR == iSel)
return;
if (NULL != m_pAlv)
{
m_pAlv->ClearItems();
}
if (iSel >= m_iIlsFirst)
{
if( NULL != m_pUls )
{
m_pAlv = m_pUls;
if( !CDirectoryManager::isWebDirectory( dnsName ) )
{
m_pUls->SetServer( dnsName );
// We have to send this twice so that we don't autocomplete..
SendMessage(m_hwndCombo, CB_SETCURSEL, (WPARAM) iSel, 0);
SendMessage(m_hwndCombo, CB_SETCURSEL, (WPARAM) iSel, 0);
}
}
}
ShowList(iSel);
}
LRESULT CFindSomeone::OnNotifyCombo(LPARAM lParam)
{
NMCOMBOBOXEX * pNmcbe = (NMCOMBOBOXEX*) lParam;
switch(pNmcbe->hdr.code)
{
case CBEN_ENDEDIT:
{
PNMCBEENDEDIT pnmcbee = (PNMCBEENDEDIT) lParam;
if (_T('\0') != pnmcbee->szText[0])
{
EndComboEdit(pnmcbee->iWhy);
}
break;
}
// NOTE: the IE 3.0 comctl32.dll sends us the wrong notification
// when running under NT. We handle it here, but if we are running
// on NT using the IE 4.0 comctl32.dll, it will be handled above.
case CBEN_ENDEDITW:
{
PNMCBEENDEDITW pnmcbee = (PNMCBEENDEDITW) lParam;
if (L'\0' != pnmcbee->szText[0])
{
EndComboEdit(pnmcbee->iWhy);
}
break;
}
default:
break;
}
return 0;
}
VOID CFindSomeone::EndComboEdit(int iWhy)
{
switch (iWhy)
{
case CBENF_RETURN:
{
if (SendMessage(m_hwndCombo, CB_GETDROPPEDSTATE, 0, 0))
{
// remove the dropdown
SendMessage(m_hwndCombo, CB_SHOWDROPDOWN, 0, 0);
}
UpdateIlsServer();
break;
}
case CBENF_KILLFOCUS:
{
// remove the dropdown
SendMessage(m_hwndCombo, CB_SHOWDROPDOWN, 0, 0);
break;
}
case CBENF_DROPDOWN:
default:
break;
}
}
static void DoAxMethod(HWND hwnd, LPWSTR szMethod)
{
IUnknown *pUnk;
if (SUCCEEDED(AtlAxGetControl(hwnd, &pUnk)))
{
CComPtr<IDispatch> spDispatch = com_cast<IDispatch>(pUnk);
if (spDispatch)
{
DISPID dispid;
if (SUCCEEDED(spDispatch->GetIDsOfNames(IID_NULL, &szMethod, 1,
LOCALE_USER_DEFAULT, &dispid)))
{
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
HRESULT hr = spDispatch->Invoke(
dispid,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_METHOD,
&dispparamsNoArgs, NULL, NULL, NULL);
}
}
pUnk->Release();
}
}
static void NewHtmlWindow(HWND hwnd)
{
IUnknown *pUnk;
if (SUCCEEDED(AtlAxGetControl(hwnd, &pUnk)))
{
CComPtr<IWebBrowser> spWeb = com_cast<IWebBrowser>(pUnk);
if (spWeb)
{
BSTR bstrLocation;
if (SUCCEEDED(spWeb->get_LocationURL(&bstrLocation)))
{
USES_CONVERSION;
LaunchRedirWebPage(OLE2T(bstrLocation));
SysFreeString(bstrLocation);
}
}
pUnk->Release();
}
}
/* O N C O M M A N D */
/*-------------------------------------------------------------------------
%%Function: OnCommand
-------------------------------------------------------------------------*/
void CFindSomeone::OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
ASSERT(NULL != hwnd);
switch (id)
{
case ID_TB_HELP:
FORWARD_WM_SYSCOMMAND(hwnd, SC_CONTEXTHELP, 0, 0, SendMessage);
break;
case IDM_DLGCALL_ENTER:
if (IsWindowActive(m_hwndCombo))
{
UpdateIlsServer();
}
else
{
HWND hwndFocus = GetFocus();
TCHAR szClass[20];
GetClassName(hwndFocus, szClass, ARRAY_ELEMENTS(szClass));
if (0 == lstrcmpi(szClass, TEXT("button"))
&& BS_PUSHBUTTON == (GetWindowStyle(hwndFocus)&(BS_PUSHBUTTON|BS_CHECKBOX|BS_RADIOBUTTON)))
{
// Push the button
OnCommand(hwnd, GetDlgCtrlID(hwndFocus), hwndFocus, BN_CLICKED);
}
else if (IsWindowEnabled(GetDlgItem(hwnd, IDOK)))
{
// Try to complete the call
OnCommand(hwnd, IDOK, NULL, 0);
}
else
{
MessageBeep(MB_ICONHAND);
}
}
break;
case IDC_DLGCALL_COMBO:
{
switch (codeNotify)
{
case CBN_EDITCHANGE:
{
OnEditChangeDirectory();
break;
}
case CBN_KILLFOCUS:
{
int iSel = ::SendMessage(m_hwndCombo, CB_GETCURSEL, 0, 0);
if (CB_ERR == iSel)
{
UpdateIlsServer();
}
else if (iSel != m_iSel)
{
ShowList(iSel);
}
break;
}
case CBN_SELENDOK:
{
int iSel = ::SendMessage(m_hwndCombo, CB_GETCURSEL, 0, 0);
// We have to send this so that we don't autocomplete..
SendMessage(m_hwndCombo, CB_SETCURSEL, (WPARAM) iSel, 0);
ShowList(iSel);
break;
}
default:
break;
} /* switch (HIWORD(wParam)) */
break;
}
case IDM_DLGCALL_CALL:
case IDOK:
{
CConfRoom *pConfRoom = GetConfRoom();
if (NULL == pConfRoom || !pConfRoom->IsNewCallAllowed())
{
WARNING_OUT(("Meeting settings prevent outgoing calls"));
break;
}
if (SUCCEEDED(HrGetSelection()))
{
onCall();
}
else
{
if( !hasValidUserInfo( m_pRai ) )
{
DisplayMsgErr( hwnd, IDS_NO_CALL_LOG_INFO );
}
else
{
TCHAR szName[CCHMAXSZ_NAME];
GetEditText(szName, CCHMAX(szName));
DisplayMsgErr(hwnd, IDS_ERR_CALLTO, szName);
}
}
break;
}
case IDCANCEL:
{
PostMessage( hwnd, WM_CLOSE, 0, 0 );
break;
}
case IDE_DLGCALL_NAME:
{
switch (codeNotify)
{
case EN_CHANGE:
{
TCHAR sz[CCHMAXSZ];
sz[0] = _T('\0');
GetWindowText(m_hwndEdit, sz, CCHMAX(sz));
int iSel = CFindSomeone::FindSzBySortedColumn(sz);
if (-1 != iSel)
{
HWND hwndCurr = GetHwndList();
// Select the item found
ListView_SetItemState(hwndCurr, iSel, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
int iTop = ListView_GetTopIndex(hwndCurr);
int cDiff = (iSel - iTop);
if ((cDiff < 0) || (cDiff > m_cVisible))
{
// Scroll the item into view
RECT rc;
ListView_GetItemRect(hwndCurr, iSel, &rc, LVIR_BOUNDS);
ListView_Scroll(hwndCurr, 0, cDiff * (rc.bottom - rc.top));
}
}
break;
}
default:
break;
} /* switch (HIWORD(wParam)) */
break;
}
case IDM_DLGCALL_NEWWINDOW:
NewHtmlWindow(m_webView);
break;
case IDM_DLGCALL_REFRESH:
if (IsWindowVisible(m_webView))
{
DoAxMethod(m_webView, L"Refresh");
break;
}
// Fall through
case IDM_DLGCALL_PROPERTIES:
case IDM_DLGCALL_DELETE:
case IDM_DLGCALL_SPEEDDIAL:
case IDM_DLGCALL_WAB:
case IDM_DLGCALL_STOP:
{
if (NULL != m_pAlv)
{
m_pAlv->OnCommand(GET_WM_COMMAND_MPS(id, hwndCtl, codeNotify));
}
break;
}
case IDM_DLGCALL_DELETE_ILS:
OnDeleteIlsServer();
break;
default:
break;
}
}
int CFindSomeone::GetEditText(LPTSTR psz, int cchMax)
{
ASSERT(NULL != m_hwndEdit);
int cch = GetWindowText(m_hwndEdit, psz, cchMax);
return TrimSz(psz);
}
HRESULT CFindSomeone::HrGetSelection(void)
{
HRESULT result = E_FAIL;
// Check if we have a selection
if( ListView_GetNextItem( GetHwndList(), -1, LVNI_ALL | LVNI_SELECTED ) != -1 )
{
m_pRai = m_pAlv->GetAddrInfo();
if( hasValidUserInfo( m_pRai ) )
{
result = S_OK;
}
}
return( result );
} // End of CFindSomeone::HrGetSelection.
/* F I N D S Z */
/*-------------------------------------------------------------------------
%%Function: FindSz
First the item that matches at least the first part of the string
from the current list.
-------------------------------------------------------------------------*/
int CFindSomeone::FindSz(LPCTSTR psz)
{
LV_FINDINFO lvfi;
ClearStruct(&lvfi);
lvfi.flags = LVFI_PARTIAL;
lvfi.psz = (LPTSTR) psz;
return ListView_FindItem(GetHwndList(), -1, &lvfi);
}
//--------------------------------------------------------------------------//
// CFindSomeone::FindSzBySortedColumn. //
//--------------------------------------------------------------------------//
int CFindSomeone::FindSzBySortedColumn(LPCTSTR psz)
{
ASSERT( psz != NULL );
TCHAR pszColumnText[ MAX_PATH ];
HWND hwndList = GetHwndList();
bool bSorted = hwndList == m_ilsListView;
int iSearchColumn = bSorted ? m_iSortColumn : 0;
int iStart = 0;
int iEnd = ListView_GetItemCount( hwndList ) - 1;
int iMid = iEnd / 2;
int iCompareLength = lstrlen( psz );
int iResult = -1;
bool bAscending = (m_fSortAscending != FALSE);
if( iEnd > 0 )
{
if( bSorted && ((iSearchColumn == COLUMN_INDEX_AUDIO) || (iSearchColumn == COLUMN_INDEX_VIDEO) ))
{
bSorted = false;
// The list is sorted by av capabilities.... perform a linear search on the first (unsorted) text column...
int iColumnOrder[ MAX_DIR_COLUMNS ];
if( ListView_GetColumnOrderArray( m_ilsListView, g_rgDLColumnInfo[ DLT_ULS ].nColumns, iColumnOrder ) )
{
if( (iColumnOrder[ 0 ] == COLUMN_INDEX_AUDIO) || (iColumnOrder[ 0 ] == COLUMN_INDEX_VIDEO) )
{
if( (iColumnOrder[ 1 ] == COLUMN_INDEX_AUDIO) || (iColumnOrder[ 1 ] == COLUMN_INDEX_VIDEO) )
{
iSearchColumn = 2;
}
else
{
iSearchColumn = 1;
}
}
else
{
iSearchColumn = 0;
}
iSearchColumn = iColumnOrder[iSearchColumn];
}
}
if (!bSorted)
{
// Do a linear search
for( int nn = 0; nn <= iEnd; nn++ )
{
ListView_GetItemText( hwndList, nn, iSearchColumn, pszColumnText, CCHMAX( pszColumnText ) );
if( iCompareLength < CCHMAX( pszColumnText ) - 1 )
{
pszColumnText[ iCompareLength ] = '\0'; // Only compare iCompareLength characters...
}
if( StringCompare( psz, pszColumnText ) == 0 )
{
iResult = nn;
break;
}
}
}
else
{
while( iStart <= iEnd )
{
pszColumnText[ 0 ] = '\0';
ListView_GetItemText( hwndList, iMid, iSearchColumn, pszColumnText, CCHMAX( pszColumnText ) );
if( iCompareLength < CCHMAX( pszColumnText ) - 1 )
{
pszColumnText[ iCompareLength ] = '\0'; // Only compare iCompareLength characters...
}
int iCompareResult = StringCompare( psz, pszColumnText );
bool pszIsLess = (iCompareResult <= 0);
if( iCompareResult == 0 )
{
// We've found a match but we will keep going because there may be more than one
// and we want to find the "first" one...
iResult = iMid;
}
else
{
if( !bAscending )
{
pszIsLess = !pszIsLess;
}
}
if( pszIsLess )
{
iEnd = iMid - 1;
}
else
{
iStart = iMid + 1;
}
iMid = iStart + ((iEnd - iStart) / 2);
}
}
}
return( iResult );
} // End of CFindSomeone::FindSzBySortedColumn.
VOID CFindSomeone::OnEditChangeDirectory(void)
{
if (m_fInEdit)
return;
TCHAR szEdit[CCHMAXSZ_ADDRESS];
TCHAR szBuff[CCHMAXSZ_ADDRESS];
szEdit[0] = _T('\0');
int cch = GetWindowText(m_hwndCombo, szEdit, CCHMAX(szEdit));
CharUpperBuff(szEdit, CCHMAX(szEdit));
if (0 == cch)
return;
// Check if anything changed
PTCHAR pchSrc = m_szDirectory;
PTCHAR pchDest = szEdit;
while ((_T('\0') != *pchSrc) && (*pchSrc == *pchDest))
{
// REVIEW: not DBCS safe
pchSrc++;
pchDest++;
}
if (_T('\0') == *pchDest)
{
lstrcpy(m_szDirectory, szEdit);
return; // quick exit - nothing to do
}
if (-1 == FindSzCombo(m_hwndCombo, szEdit, szBuff))
return;
m_fInEdit = TRUE;
AutoCompleteCombo(m_hwndCombo, &szBuff[cch]);
lstrcpyn(m_szDirectory, szBuff, cch+1);
CharUpperBuff(m_szDirectory, CCHMAX(m_szDirectory));
m_fInEdit = FALSE;
}
/* I N I T A L V */
/*-------------------------------------------------------------------------
%%Function: InitAlv
-------------------------------------------------------------------------*/
VOID CFindSomeone::InitAlv(void)
{
int iSelDefault = LB_ERR;
ASSERT( NULL == m_pAlv );
RegEntry reConf(CONFERENCING_KEY, HKEY_CURRENT_USER);
bool bGkEnabled = CALLING_MODE_GATEKEEPER == reConf.GetNumber(REGVAL_CALLING_MODE, CALLING_MODE_DIRECT );
#if USE_GAL
// Add each of the view items to the list
if ((NULL != m_pGAL) && m_pGAL->FAvailable())
{
AddAlv(m_pGAL);
if( !m_pAlv )
{
m_pAlv = m_pGAL;
}
}
#endif // #if USE_GAL
if((!bGkEnabled) && (NULL != m_pSpeedDial) && m_pSpeedDial->FAvailable())
{
AddAlv(m_pSpeedDial);
if( !m_pAlv )
{
m_pAlv = m_pSpeedDial;
}
}
if ( (!bGkEnabled) && ( NULL != m_pHistory) && m_pHistory->FAvailable())
{
AddAlv(m_pHistory);
if( !m_pAlv )
{
m_pAlv = m_pHistory;
}
}
if ((NULL != m_pWab) && m_pWab->FAvailable())
{
AddAlv(m_pWab);
if( !m_pAlv )
{
m_pAlv = m_pWab;
}
}
m_iIlsFirst = ::SendMessage(m_hwndCombo, CB_GETCOUNT, 0, 0);
// Add the list of ILS servers
if (bGkEnabled)
{
// If there is a customized Web View, we will show it in GK mode as
// well as in ILS mode
if ((NULL != m_pUls) && ConfPolicies::GetWebDirInfo())
{
AddAlvSz( m_pUls, CDirectoryManager::get_displayName( CDirectoryManager::get_webDirectoryIls() ));
}
}
else
{
if((NULL != m_pUls) && m_pUls->FAvailable() && (NULL != m_pMruServer) && !_IsDirectoryServicePolicyDisabled())
{
m_pAlv = m_pUls;
for( int i = m_pMruServer->GetNumEntries() - 1; i >= 0; i-- )
{
AddAlvSz( m_pUls, CDirectoryManager::get_displayName( m_pMruServer->GetNameEntry( i ) ) );
}
}
}
iSelDefault = CB_ERR;
if( m_pAlv )
{
// We know that there is at lest one directory server in the combobox
// Get the user's last selection
RegEntry reMru(DLGCALL_MRU_KEY, HKEY_CURRENT_USER);
LPTSTR psz = reMru.GetString(REGVAL_DLGCALL_DEFDIR);
if (!FEmptySz(psz))
{
TRACE_OUT(("Last directory was [%s]",psz));
iSelDefault = ::SendMessage(m_hwndCombo, CB_FINDSTRINGEXACT, (WPARAM) -1, (LPARAM) psz);
}
else
{
// This may be the first time, and there is no last use one in the registry
TCHAR szDirectoryName[CCHMAXSZ];
if( m_pAlv )
{
if( m_pAlv != m_pUls )
{
m_pAlv->GetName(szDirectoryName, CCHMAX(szDirectoryName));
iSelDefault = ::SendMessage(m_hwndCombo, CB_FINDSTRINGEXACT, (WPARAM) -1, (LPARAM) szDirectoryName);
}
else if( m_pMruServer->GetNumEntries() > 0 )
{
iSelDefault = m_iIlsFirst;
}
}
}
iSelDefault = (CB_ERR != iSelDefault) ? iSelDefault : 0;
ShowList(iSelDefault);
// We have to send this twice so that we don't autocomplete..
SendMessage(m_hwndCombo, CB_SETCURSEL, (WPARAM) iSelDefault, 0);
SendMessage(m_hwndCombo, CB_SETCURSEL, (WPARAM) iSelDefault, 0);
}
else
{
// The user has no directory services set up
DisplayMsgErr( NULL, IDS_NO_DIRECTORY_SERVICES_OR_ADDRESS_BOOKS );
}
}
bool CFindSomeone::_IsDirectoryServicePolicyDisabled()
{
RegEntry rePol(POLICIES_KEY, HKEY_CURRENT_USER);
return rePol.GetNumber( REGVAL_POL_NO_DIRECTORY_SERVICES, DEFAULT_POL_NO_DIRECTORY_SERVICES ) ? true : false;
}
int CFindSomeone::AddAlv(CALV * pAlv)
{
TCHAR sz[CCHMAXSZ];
pAlv->GetName(sz, CCHMAX(sz));
return AddAlvSz(pAlv, sz);
}
int CFindSomeone::AddAlvSz(CALV * pAlv, LPCTSTR psz, int cbIndex)
{
ASSERT(NULL != pAlv);
ASSERT(NULL != m_hwndCombo);
COMBOBOXEXITEM cbi;
ClearStruct(&cbi);
cbi.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE;
cbi.iItem = cbIndex;
cbi.iImage = pAlv->GetIconId(psz);
cbi.iSelectedImage = cbi.iImage;
cbi.pszText = (LPTSTR) psz;
cbi.cchTextMax = lstrlen(cbi.pszText);
int iIndex = ::SendMessage(m_hwndCombo, CBEM_INSERTITEM, 0, (LPARAM) &cbi);
if (CB_ERR != iIndex)
{
::SendMessage(m_hwndCombo, CB_SETITEMDATA, iIndex, (LPARAM) pAlv);
}
return iIndex;
}
/* S H O W L I S T */
/*-------------------------------------------------------------------------
%%Function: ShowList
-------------------------------------------------------------------------*/
VOID CFindSomeone::ShowList(int iSel)
{
HWND hwnd = GetWindow();
if (CB_ERR == iSel)
return;
m_iSel = iSel;
BOOL bPrevListWasOwnerData = m_pAlv->FOwnerData();
int nColsPrevListView = _GetCurListViewNumColumns();
BOOL bPrevChangedNumCols = FALSE;
// Clear any existing data
if (NULL != m_pAlv)
{
m_pAlv->ClearItems();
if( nColsPrevListView != _GetCurListViewNumColumns() )
{
bPrevChangedNumCols = TRUE;
}
}
// Get the new selection
m_pAlv = (CALV *) ::SendMessage(m_hwndCombo, CB_GETITEMDATA, iSel, 0);
ASSERT(m_pAlv != NULL);
ASSERT(m_pAlv != (CALV *) -1);
BOOL bCurListIsOwnerData = m_pAlv->FOwnerData();
bool webDir = false;
TCHAR szServer[CCHMAXSZ_SERVER];
szServer[0] = 0;
if (m_pAlv == m_pUls)
{
COMBOBOXEXITEM cbi;
ClearStruct(&cbi);
cbi.mask = CBEIF_TEXT;
cbi.iItem = iSel;
cbi.pszText = szServer;
cbi.cchTextMax = ARRAY_ELEMENTS(szServer);
::SendMessage(m_hwndCombo, CBEM_GETITEM, iSel, (LPARAM)&cbi);
TRACE_OUT(("CBEM_GETITEM got %s for text", szServer));
webDir = CDirectoryManager::isWebDirectory( szServer );
}
// Show or hide all windows between HELP and CANCEL
HWND start = GetDlgItem(hwnd, ID_TB_HELP);
HWND end = GetDlgItem(hwnd, IDCANCEL);
if (NULL != start)
{
UINT uShow = webDir ? SW_HIDE : SW_SHOW;
for (HWND child=::GetWindow(start, GW_HWNDNEXT);
child!=NULL && child!=end; child=::GetWindow(child, GW_HWNDNEXT))
{
ShowWindow(child, uShow);
}
ShowWindow(m_webView, SW_HIDE+SW_SHOW-uShow);
}
EnableWindow(GetDlgItem(hwnd, IDM_DLGCALL_NEWWINDOW), webDir);
EnableWindow( GetDlgItem( hwnd, IDM_DLGCALL_DELETE_ILS ), FALSE );
if (m_pAlv == m_pUls)
{
::ShowWindow( m_hwndOwnerDataList, SW_HIDE );
::ShowWindow( m_hwndList, SW_HIDE );
if( webDir )
{
::SetFocus( m_webView );
}
else
{
m_pUls->SetServer( CDirectoryManager::get_dnsName( szServer ) );
m_pAlv->ShowItems(GetHwndList());
::SetFocus( m_ilsListView );
RegEntry rePol( POLICIES_KEY, HKEY_CURRENT_USER );
if (!rePol.GetNumber(REGVAL_POL_NO_ADDING_NEW_ULS, DEFAULT_POL_NO_ADDING_NEW_ULS))
{
EnableWindow( GetDlgItem( hwnd, IDM_DLGCALL_DELETE_ILS ), TRUE );
}
}
}
else
{
if( m_ilsListView != NULL )
{
::ShowWindow( m_ilsListView, SW_HIDE );
::ShowWindow( m_webView, SW_HIDE );
m_pUls->CacheServerData();
}
if (m_pAlv->FOwnerData())
{
::ShowWindow(m_hwndList, SW_HIDE);
}
else
{
::ShowWindow(m_hwndOwnerDataList, SW_HIDE);
}
m_pAlv->ShowItems(GetHwndList());
::SetFocus( GetHwndList() );
}
if( bPrevChangedNumCols || ( bCurListIsOwnerData != bPrevListWasOwnerData ) || ( nColsPrevListView != _GetCurListViewNumColumns() ) )
{
Layout();
}
}
int CFindSomeone::_GetCurListViewNumColumns()
{
int nListViewColumns = DEFAULT_NUM_LISTVIEW_COLUMNS;
HWND hListViewHeader = NULL;
HWND hWndList = GetHwndList();
if( hWndList )
{
hListViewHeader = ListView_GetHeader( hWndList );
if( hListViewHeader )
{
nListViewColumns = Header_GetItemCount( hListViewHeader );
}
}
return nListViewColumns;
}
/* D L G C A L L S E T H E A D E R */
/*-------------------------------------------------------------------------
%%Function: DlgCallSetHeader
Set the listbox header text for the "address" / "email" / "status" field.
-------------------------------------------------------------------------*/
VOID DlgCallSetHeader(HWND hwndList, int ids)
{
HWND hwnd = ListView_GetHeader(hwndList);
if (NULL == hwnd)
return;
TCHAR sz[CCHMAXSZ];
if (!FLoadString(ids, sz, CCHMAX(sz)))
return;
HDITEM hdItem;
ClearStruct(&hdItem);
hdItem.mask = HDI_TEXT; // | HDI_IMAGE; hdItem.iImage = II_ASCENDING;
hdItem.pszText = sz;
hdItem.cchTextMax = lstrlen(hdItem.pszText);
Header_SetItem(hwnd, IDI_DLGCALL_ADDRESS, &hdItem);
}
/* D L G C A L L A D D I T E M */
/*-------------------------------------------------------------------------
%%Function: DlgCallAddItem
Add the name and address to the list, returning the position.
-------------------------------------------------------------------------*/
int DlgCallAddItem(HWND hwndList, LPCTSTR pszName, LPCTSTR pszAddress, int iImage, LPARAM lParam, int iItem, LPCTSTR pszComment)
{
LV_ITEM lvItem;
ClearStruct(&lvItem);
lvItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
lvItem.iItem = iItem;
lvItem.lParam = lParam;
lvItem.iImage = iImage;
lvItem.pszText = (LPTSTR) pszName;
lvItem.cchTextMax = lstrlen(lvItem.pszText);
int iPos = ListView_InsertItem(hwndList, &lvItem);
if (-1 != iPos)
{
ListView_SetItemText(hwndList, iPos, IDI_DLGCALL_ADDRESS, (LPTSTR) pszAddress);
if( pszComment )
{
ListView_SetItemText(hwndList, iPos, IDI_DLGCALL_COMMENT, (LPTSTR) pszComment);
}
}
return iPos;
}
/* C A L L T O S Z */
/*-------------------------------------------------------------------------
%%Function: CallToSz
Call an address using "CallTo:"
-------------------------------------------------------------------------*/
HRESULT CallToSz(LPCTSTR pcszAddress)
{
#ifdef DEBUG
RegEntry re(DEBUG_KEY, HKEY_LOCAL_MACHINE);
if (0 != re.GetNumber(REGVAL_DBG_FAKE_CALLTO, DEFAULT_DBG_FAKE_CALLTO))
{
MessageBox(NULL, pcszAddress, "Called", MB_OK);
return S_OK;
}
#endif /* DEBUG */
if (FEmptySz(pcszAddress))
return E_INVALIDARG;
TCHAR sz[MAX_PATH];
lstrcpy(sz, g_cszCallTo);
int cch = lstrlen(sz);
if (CCHMAX(sz) <= (cch + lstrlen(pcszAddress)))
return E_INVALIDARG; // the address won't fit
lstrcpy(&sz[cch], pcszAddress);
HINSTANCE hInst = ShellExecute(NULL, NULL, sz, NULL, NULL, SW_SHOWNORMAL);
return ((INT_PTR)hInst > 32) ? S_OK : E_FAIL;
}
//--------------------------------------------------------------------------//
// GetMruListServer. //
//--------------------------------------------------------------------------//
CMRUList *
GetMruListServer(void)
{
CMRUList * pMruList = new CMRUList;
if( pMruList != NULL )
{
pMruList->Load( DIR_MRU_KEY );
if( CDirectoryManager::isWebDirectoryEnabled() )
{
// Make sure the web directory is in the list...
pMruList->AppendEntry( CDirectoryManager::get_webDirectoryIls() );
}
const TCHAR * const defaultServer = CDirectoryManager::get_defaultServer();
if( lstrlen( defaultServer ) > 0 )
{
// Make sure the default server name is in the list and at the top...
pMruList->AddNewEntry( defaultServer );
}
}
return( pMruList );
} // End of GetMruListServer.
// The only purpose for this function is to avoid scrollbar tracking of the data
/* static */
LRESULT CALLBACK CFindSomeone::OwnerDataListWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
CFindSomeone* pThis = reinterpret_cast< CFindSomeone* >( GetWindowLongPtr( hwnd, GWLP_USERDATA ) );
WNDPROC lpPrevWndFunc = pThis->m_WndOwnerDataListOldWndProc;
bool bUserDroppedScrollSlider = false;
if (WM_VSCROLL == uMsg)
{
switch (LOWORD(wParam))
{
case SB_THUMBTRACK:
// don't track
return FALSE;
case SB_THUMBPOSITION:
bUserDroppedScrollSlider = true;
// fake a final SB_THUMBTRACK notification
CallWindowProc(lpPrevWndFunc, hwnd, uMsg, MAKEWPARAM(SB_THUMBTRACK, HIWORD(wParam)), lParam);
break;
default:
break;
}
}
LRESULT lRet = CallWindowProc(lpPrevWndFunc, hwnd, uMsg, wParam, lParam);
if( bUserDroppedScrollSlider )
{
ListView_SetItemState(hwnd, GetScrollPos( hwnd, SB_VERT ), LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
}
return lRet;
}
//--------------------------------------------------------------------------//
//--------------------------------------------------------------------------//
// copied from 2.11 dirlist.cpp. //
//--------------------------------------------------------------------------//
//--------------------------------------------------------------------------//
//--------------------------------------------------------------------------//
// CFindSomeone::InitColumns. //
//--------------------------------------------------------------------------//
BOOL CFindSomeone::InitColumns(void)
{
BOOL bRet = FALSE;
if (NULL != m_ilsListView)
{
// Remove all columns:
// NOTE: we could optimize by removing only extras and changing the rest
while( ListView_DeleteColumn( m_ilsListView, 0 ) ){};
// Now initialize the columns we will need
// Initialize the LV_COLUMN structure
// the mask specifies that the .fmt, .ex, width, and .subitem members
// of the structure are valid,
LV_COLUMN lvC; // List View Column structure
TCHAR szText[256]; // place to store some text
lvC.pszText = szText;
lvC.fmt = LVCFMT_LEFT; // left align the column
// Add the columns.
for (int index = 0; index < g_rgDLColumnInfo[DLT_ULS].nColumns; index++)
{
HD_ITEM hdi;
switch( index )
{
case COLUMN_INDEX_AUDIO:
hdi.iImage = II_AUDIO_COLUMN_HEADER;
lvC.mask = LVCF_SUBITEM;
break;
case COLUMN_INDEX_VIDEO:
hdi.iImage = II_VIDEO_COLUMN_HEADER;
lvC.mask = LVCF_SUBITEM;
break;
default:
hdi.iImage = -1;
lvC.mask = LVCF_TEXT | LVCF_FMT | LVCF_SUBITEM;
LoadString( ::GetInstanceHandle(),
ciColumnInfo[ index ].iColumnLabelIds,
szText,
CCHMAX(szText));
break;
}
lvC.iSubItem = index;
if( ListView_InsertColumn( m_ilsListView, index, &lvC ) == -1 )
{
WARNING_OUT(("Could not insert column %d in list view", index));
}
else if( hdi.iImage != -1 )
{
hdi.mask = HDI_IMAGE | HDI_FORMAT;
hdi.fmt = HDF_IMAGE;
Header_SetItem( ListView_GetHeader( m_ilsListView ), index, &hdi );
}
}
Header_SetImageList( ListView_GetHeader( m_ilsListView ), m_himlIcon );
bRet = TRUE;
}
// ISSUE: do we want to persist this data?
m_fSortAscending = TRUE;
m_iSortColumn = COLUMN_INDEX_LAST_NAME;
return bRet;
}
//--------------------------------------------------------------------------//
// CFindSomeone::LoadColumnInfo. //
//--------------------------------------------------------------------------//
BOOL
CFindSomeone::LoadColumnInfo(void)
{
RegEntry re(UI_KEY, HKEY_CURRENT_USER);
// load column info from registry:
LPLONG plColumns = NULL;
DWORD dwLength = re.GetBinary( g_rgDLColumnInfo[DLT_ULS].pszRVWidths,
(LPVOID*) &plColumns);
if (dwLength == (sizeof(LONG) * g_rgDLColumnInfo[DLT_ULS].nColumns))
{
// get width of each column
for (int i = 0; i < g_rgDLColumnInfo[DLT_ULS].nColumns; i++)
{
m_alColumns[i] = plColumns[i];
ListView_SetColumnWidth(m_ilsListView, i, m_alColumns[i]);
}
}
else
{
int iMinColumnPixels[ MAX_DIR_COLUMNS ];
int iPixelsPerChar = GetPixelsPerChar( m_ilsListView );
int ii;
// Loop through all the columns setting their minimum widths...
for( ii = 0; ii < g_rgDLColumnInfo[ DLT_ULS ].nColumns; ii++ )
{
if( (ii == COLUMN_INDEX_AUDIO) || (ii == COLUMN_INDEX_VIDEO) )
{
// We use a 16x16 icon, plus add 7 pixels for padding.
// There's also padding built into the icons to make them look more centered....
// The column header icons are aligned left and the column icons are aligned right...
iMinColumnPixels[ ii ] = 23;
}
else
{
iMinColumnPixels[ ii ] = ciColumnInfo[ ii ].iMinColumnChars * iPixelsPerChar;
}
}
// Loop through all but the last column setting each columns to it's minimum width...
for( ii = 0; ii < g_rgDLColumnInfo[ DLT_ULS ].nColumns - 1; ii++ )
{
ListView_SetColumnWidth( m_ilsListView, ii, iMinColumnPixels[ ii ] );
m_alColumns[ ii ] = ListView_GetColumnWidth( m_ilsListView, ii );
}
// The last column gets the rest...
int iLastColoumnIndex = g_rgDLColumnInfo[ DLT_ULS ].nColumns - 1;
ListView_SetColumnWidth( m_ilsListView, iLastColoumnIndex, LVSCW_AUTOSIZE_USEHEADER );
m_alColumns[ iLastColoumnIndex ] = ListView_GetColumnWidth( m_ilsListView, iLastColoumnIndex );
if( m_alColumns[ iLastColoumnIndex ] < iMinColumnPixels[ iLastColoumnIndex ] )
{
ListView_SetColumnWidth( m_ilsListView, iLastColoumnIndex, iMinColumnPixels[ iLastColoumnIndex ] );
m_alColumns[ iLastColoumnIndex ] = ListView_GetColumnWidth( m_ilsListView, iLastColoumnIndex );
}
}
// set column order
LPLONG plColumnOrder = NULL;
dwLength = re.GetBinary( g_rgDLColumnInfo[DLT_ULS].pszRVOrder,
(LPVOID*) &plColumnOrder);
if (dwLength == (sizeof(LONG) * g_rgDLColumnInfo[DLT_ULS].nColumns))
{
ListView_SetColumnOrderArray( m_ilsListView,
g_rgDLColumnInfo[DLT_ULS].nColumns,
plColumnOrder);
// load the sort column and direction
m_iSortColumn = re.GetNumber(g_rgDLColumnInfo[DLT_ULS].pszRVSortColumn, COLUMN_INDEX_LAST_NAME );
ASSERT(m_iSortColumn < g_rgDLColumnInfo[DLT_ULS].nColumns);
m_fSortAscending = re.GetNumber(g_rgDLColumnInfo[DLT_ULS].pszRVSortAscending, TRUE);
}
else
{
const static int iDefaultColumnOrder[] = { COLUMN_INDEX_AUDIO, COLUMN_INDEX_VIDEO, COLUMN_INDEX_LAST_NAME, COLUMN_INDEX_FIRST_NAME, COLUMN_INDEX_ADDRESS, COLUMN_INDEX_LOCATION, COLUMN_INDEX_COMMENTS };
ListView_SetColumnOrderArray( m_ilsListView, ARRAY_ELEMENTS( iDefaultColumnOrder ), iDefaultColumnOrder );
}
return TRUE;
}
//--------------------------------------------------------------------------//
// CFindSomeone::CompareWrapper. //
//--------------------------------------------------------------------------//
int
CALLBACK
CFindSomeone::CompareWrapper
(
LPARAM param1,
LPARAM param2,
LPARAM This
){
return( ((CFindSomeone *) This)->DirListViewCompareProc( param1, param2 ) );
} // End of CFindSomeone::CompareWrapper.
//--------------------------------------------------------------------------//
// CFindSomeone::DirListViewCompareProc. //
//--------------------------------------------------------------------------//
int
CFindSomeone::DirListViewCompareProc
(
LPARAM param1,
LPARAM param2
){
LV_ITEM lvi;
int result;
if( (m_iSortColumn == COLUMN_INDEX_AUDIO) || (m_iSortColumn == COLUMN_INDEX_VIDEO) )
{
lvi.mask = LVIF_IMAGE;
lvi.iItem = LParamToPos( param1 );
lvi.iSubItem = m_iSortColumn;
ListView_GetItem( m_ilsListView, &lvi );
int iImage1 = lvi.iImage;
lvi.iItem = LParamToPos( param2 );
ListView_GetItem( m_ilsListView, &lvi );
result = lvi.iImage - iImage1;
}
else
{
// BUGBUG: need better constant for max size
TCHAR szText1[ MAX_PATH ];
TCHAR szText2[ MAX_PATH ];
lvi.mask = LVIF_TEXT;
lvi.iItem = LParamToPos( param1 );
lvi.iSubItem = m_iSortColumn;
lvi.pszText = szText1;
lvi.cchTextMax = CCHMAX( szText1 );
ListView_GetItem( m_ilsListView, &lvi );
lvi.iItem = LParamToPos( param2 );
lvi.pszText = szText2;
ListView_GetItem( m_ilsListView, &lvi );
result = StringCompare( szText1, szText2 );
}
if( !m_fSortAscending )
{
result = -result;
}
return( result );
}
//--------------------------------------------------------------------------//
// CFindSomeone::LParamToPos. //
//--------------------------------------------------------------------------//
int CFindSomeone::LParamToPos(LPARAM lParam)
{
LV_FINDINFO lvF;
lvF.flags = LVFI_PARAM;
lvF.lParam = lParam;
return( ListView_FindItem( m_ilsListView, -1, &lvF ) ); // Note: retuns -1 on failure...
}
//--------------------------------------------------------------------------//
// CFindSomeone::StoreColumnInfo. //
//--------------------------------------------------------------------------//
void
CFindSomeone::StoreColumnInfo(void)
{
if( IsWindow( m_ilsListView ) )
{
RegEntry re( UI_KEY, HKEY_CURRENT_USER );
DWORD dwStyle = ::GetWindowLong( m_ilsListView, GWL_STYLE );
if( (dwStyle & LVS_TYPEMASK) == LVS_REPORT )
{
// get width of each column
for( int i = 0; i < g_rgDLColumnInfo[ DLT_ULS ].nColumns; i++ )
{
m_alColumns[ i ] = ListView_GetColumnWidth( m_ilsListView, i );
}
}
// save this back to registry
re.SetValue( g_rgDLColumnInfo[ DLT_ULS ].pszRVWidths,
(LPVOID) m_alColumns,
sizeof( LONG ) * g_rgDLColumnInfo[ DLT_ULS ].nColumns );
int anColumnOrder[MAX_DIR_COLUMNS];
if( ListView_GetColumnOrderArray( m_ilsListView,
g_rgDLColumnInfo[ DLT_ULS ].nColumns,
anColumnOrder ) )
{
// save the column order to registry
re.SetValue( g_rgDLColumnInfo[ DLT_ULS ].pszRVOrder,
(LPVOID) anColumnOrder,
sizeof( LONG ) * g_rgDLColumnInfo[ DLT_ULS ].nColumns );
}
// save the sort column and direction
re.SetValue(g_rgDLColumnInfo[ DLT_ULS ].pszRVSortColumn, m_iSortColumn);
re.SetValue(g_rgDLColumnInfo[ DLT_ULS ].pszRVSortAscending, m_fSortAscending);
}
} // End of CFindSomeone::StoreColumnInfo.
//--------------------------------------------------------------------------//
// CFindSomeone::onCall. //
//--------------------------------------------------------------------------//
void
CFindSomeone::onCall(void)
{
if( m_pRai != NULL )
{
const bool secure = (IsDlgButtonChecked( GetWindow(), IDS_SECURITY_CHECKBOX ) == BST_CHECKED);
const NM_ADDR_TYPE nmType = static_cast<NM_ADDR_TYPE>(m_pRai->rgDwStr[ 0 ].dw);
g_pCCallto->Callto( m_pRai->rgDwStr[ 0 ].psz, // pointer to the callto url to try to place the call with...
m_pRai->szName, // pointer to the display name to use...
nmType, // callto type to resolve this callto as...
true, // the pszCallto parameter is to be interpreted as a pre-unescaped addressing component vs a full callto...
&secure, // security preference, NULL for none. must be "compatible" with secure param if present...
false, // whether or not save in mru...
true, // whether or not to perform user interaction on errors...
GetWindow(), // if bUIEnabled is true this is the window to parent error/status windows to...
NULL ); // out pointer to INmCall * to receive INmCall * generated by placing call...
}
} // End of CFindSomeone::onCall.
//--------------------------------------------------------------------------//
// CFindSomeone::OnDeleteIlsServer. //
//--------------------------------------------------------------------------//
void CFindSomeone::OnDeleteIlsServer(void)
{
if( m_pMruServer != NULL )
{
int iSelectionIndex = ::SendMessage( m_hwndCombo, CB_GETCURSEL, 0, 0 );
if( iSelectionIndex != CB_ERR )
{
int iLength = ::SendMessage( m_hwndCombo, CB_GETLBTEXTLEN, iSelectionIndex, 0 );
TCHAR * pszIls = new TCHAR [ iLength + 1 ];
if( pszIls != NULL )
{
if( ::SendMessage( m_hwndCombo, CB_GETLBTEXT, iSelectionIndex, (LPARAM) pszIls ) != CB_ERR )
{
HWND hwndDialog = s_pDlgCall->GetWindow();
// First make sure this directory server isn't their default server....
if( lstrcmpi( pszIls, CDirectoryManager::get_defaultServer() ) == 0 )
{
::MessageBox( hwndDialog, RES2T( IDS_DLGCALL_CANT_DELETE_DEFAULT_ILS ), RES2T( IDS_MSGBOX_TITLE ), MB_SETFOREGROUND | MB_OK | MB_ICONEXCLAMATION );
}
else
{
// Next make them confirm they want to do this...
if( ::MessageBox( hwndDialog, RES2T( IDS_DLGCALL_CONFIRM_DELETE_ILS ), RES2T( IDS_MSGBOX_TITLE ), MB_SETFOREGROUND | MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2 ) == IDYES )
{
if( m_pMruServer->DeleteEntry( pszIls ) )
{
m_pMruServer->Save();
int iCount = ::SendMessage( m_hwndCombo, CB_DELETESTRING, iSelectionIndex, 0 );
if( iCount <= iSelectionIndex )
{
iSelectionIndex--;
}
::SendMessage( m_hwndCombo, CB_SETCURSEL, iSelectionIndex, 0 );
ShowList( iSelectionIndex );
}
}
}
}
delete [] pszIls;
}
}
}
} // End of CFindSomeone::OnDeleteIlsServer.
void CFindSomeone::OnCallStarted()
{
HWND hwnd = GetWindow();
m_secure = ::IsDlgButtonChecked( hwnd, IDS_SECURITY_CHECKBOX ) != 0;
UpdateSecurityCheck(m_pConfRoom, hwnd, IDS_SECURITY_CHECKBOX);
// BUGBUG georgep: We get notified before the actual conference state
// changes, so we need to disable manually
::EnableWindow( GetDlgItem(hwnd, IDS_SECURITY_CHECKBOX), FALSE );
}
void CFindSomeone::OnCallEnded()
{
HWND hwnd = GetWindow();
UpdateSecurityCheck(m_pConfRoom, hwnd, IDS_SECURITY_CHECKBOX);
::CheckDlgButton( hwnd, IDS_SECURITY_CHECKBOX, m_secure );
}
//--------------------------------------------------------------------------//
// StringCompare. //
//--------------------------------------------------------------------------//
int StringCompare( const TCHAR * const psz1, const TCHAR * const psz2 )
{
ASSERT( psz1 != NULL );
ASSERT( psz2 != NULL );
int iResult = CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, psz1, -1, psz2, -1 );
ASSERT( iResult != 0);
if( iResult == CSTR_LESS_THAN )
{
iResult = -1;
}
else if( iResult == CSTR_GREATER_THAN )
{
iResult = 1;
}
else
{
iResult = 0;
}
return( iResult );
} // End of StringCompare.
//--------------------------------------------------------------------------//
// GetDefaultRect. //
//--------------------------------------------------------------------------//
void GetDefaultRect(const HWND hwndParent, RECT & rcRect, const int iDefaultWidth, const int iDefaultHeight)
{
RECT rcWorkArea;
bool bResizeAndCenter = true;
if( !SystemParametersInfo( SPI_GETWORKAREA, 0, &rcWorkArea, 0 ) )
{
SetRect( &rcWorkArea, 0, 0, GetSystemMetrics( SM_CXSCREEN ) - 1, GetSystemMetrics( SM_CYSCREEN ) - 1 );
}
if( IsWindow( hwndParent ) )
{
GetWindowRect( hwndParent, &rcRect );
rcRect.left += DX_BORDER;
rcRect.top += DY_BORDER + GetSystemMetrics( SM_CYCAPTION );
rcRect.right = rcRect.left + iDefaultWidth;
rcRect.bottom = rcRect.top + iDefaultHeight;
if( (rcRect.left >= rcWorkArea.left) && (rcRect.top >= rcWorkArea.top) &&
(rcRect.right <= rcWorkArea.right) && (rcRect.bottom <= rcWorkArea.bottom) )
{
bResizeAndCenter = false;
}
}
if( bResizeAndCenter )
{
int iWidth = rcWorkArea.right - rcWorkArea.left;
if( iWidth > iDefaultWidth )
{
iWidth -= iDefaultWidth;
iWidth /= 2;
rcWorkArea.left += iWidth;
rcWorkArea.right = rcWorkArea.left + iDefaultWidth;
}
else
{
iWidth = (rcWorkArea.right - rcWorkArea.left) / 10;
rcWorkArea.left += iWidth;
rcWorkArea.right -= iWidth;
}
int iHeight = rcWorkArea.bottom - rcWorkArea.top;
if( iHeight > iDefaultHeight )
{
iHeight -= iDefaultHeight;
iHeight /= 2;
rcWorkArea.top += iHeight;
rcWorkArea.bottom = rcWorkArea.top + iDefaultHeight;
}
else
{
iHeight = (rcWorkArea.bottom - rcWorkArea.top) / 10;
rcWorkArea.top += iHeight;
rcWorkArea.bottom -= iHeight;
}
rcRect = rcWorkArea;
}
} // End of GetDefaultRect.
//--------------------------------------------------------------------------//
// GetPixelsPerChar. //
//--------------------------------------------------------------------------//
int GetPixelsPerChar(const HWND hwnd)
{
int iPixels = 10;
if( IsWindow( hwnd ) )
{
HDC hDC;
if( (hDC = GetDC( hwnd )) != NULL )
{
HFONT hFont;
if( (hFont = (HFONT) SendMessage( hwnd, WM_GETFONT, 0, 0 )) != NULL )
{
hFont = (HFONT) SelectObject( hDC, hFont );
TEXTMETRIC tmMetrics;
GetTextMetrics( hDC, &tmMetrics );
iPixels = tmMetrics.tmAveCharWidth;
SelectObject( hDC, hFont );
}
ReleaseDC( hwnd, hDC );
}
}
return( iPixels );
} // End of GetPixelsPerChar.