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

682 lines
16 KiB
C++

/****************************************************************************
*
* FILE: StatBar.cpp
*
* CREATED: Chris Pirich (ChrisPi) 3-25-96
*
* CONTENTS: CConfStatusBar object
*
****************************************************************************/
#include "precomp.h"
#include "resource.h"
#include "statbar.h"
#include "NmLdap.h"
#include "call.h"
#include "cr.h"
#include "confwnd.h"
#include "ConfPolicies.h"
static inline void TT_AddToolInfo(HWND hwnd, TOOLINFO *pti)
{
SendMessage(hwnd, TTM_ADDTOOL, 0, reinterpret_cast<LPARAM>(pti));
}
static inline void TT_GetToolInfo(HWND hwnd, TOOLINFO *pti)
{
SendMessage(hwnd, TTM_GETTOOLINFO, 0, reinterpret_cast<LPARAM>(pti));
}
static inline void TT_SetToolInfo(HWND hwnd, TOOLINFO *pti)
{
SendMessage(hwnd, TTM_SETTOOLINFO, 0, reinterpret_cast<LPARAM>(pti));
}
// Status Bar area indexes
enum
{
ID_SBP_TEXT,
// ID_SBP_ULS,
ID_SBP_ICON,
NUM_STATUSBAR_WELLS
} ;
// Status Bar area measurements (pixels)
static const UINT DXP_SB_PROG = 96;
static const UINT DXP_SB_ULS = 0; // 220;
static const UINT DXP_SB_ICON = 22;
static const UINT DXP_SB_DEF_ICON = 40;
static const int IconBorder = 2;
static const int StatSepBorder = 2;
CConfStatusBar * CConfStatusBar::m_pStatusBar = NULL;
/****************************************************************************
*
* CLASS: CConfStatusBar
*
* MEMBER: CConfStatusBar
*
* PURPOSE: Constructs object
*
****************************************************************************/
CConfStatusBar::CConfStatusBar(CConfRoom* pcr) :
m_pcrParent (pcr),
m_fVisible (FALSE),
m_hwnd (NULL)
{
DebugEntry(CConfStatusBar::CConfStatusBar);
ASSERT(NULL == m_pStatusBar);
m_pStatusBar = this;
m_szULSStatus[0] = _T('\0');
for (int i=0; i<StatIconCount; ++i)
{
m_hIconStatus[i] = NULL;
m_idIconStatus[i] = 0;
}
DebugExitVOID(CConfStatusBar::CConfStatusBar);
}
/****************************************************************************
*
* CLASS: CConfStatusBar
*
* MEMBER: !CConfStatusBar
*
* PURPOSE: Destructs object
*
****************************************************************************/
CConfStatusBar::~CConfStatusBar()
{
DebugEntry(CConfStatusBar::~CConfStatusBar);
if (NULL != m_hwnd)
{
::DestroyWindow(m_hwnd);
}
m_pStatusBar = NULL;
for (int i=0; i<StatIconCount; ++i)
{
if (NULL != m_hIconStatus[i])
{
DestroyIcon(m_hIconStatus[i]);
}
}
DebugExitVOID(CConfStatusBar::~CConfStatusBar);
}
/****************************************************************************
*
* CLASS: CConfStatusBar
*
* MEMBER: OnDraw(LPDRAWITEMSTRUCT pdis)
*
* PURPOSE: Handles drawing the status bar icon
*
****************************************************************************/
BOOL CConfStatusBar::OnDraw(LPDRAWITEMSTRUCT pdis)
{
ASSERT(pdis);
if (NULL != (pdis->itemData))
{
int nLeft = pdis->rcItem.left;
int nTop = pdis->rcItem.top;
int xSmIcon = ::GetSystemMetrics(SM_CXSMICON);
int ySmIcon = ::GetSystemMetrics(SM_CYSMICON);
int nWidth = xSmIcon;
int nHeight = pdis->rcItem.bottom - pdis->rcItem.top;
if (nHeight > ySmIcon)
{
nTop += (nHeight - ySmIcon) / 2;
nHeight = ySmIcon;
}
for (int i=0; i<StatIconCount; ++i)
{
nLeft += IconBorder;
if (NULL != m_hIconStatus[i])
{
::DrawIconEx( pdis->hDC,
nLeft,
nTop,
m_hIconStatus[i],
nWidth,
nHeight,
0,
NULL,
DI_NORMAL);
}
nLeft += xSmIcon;
}
}
return TRUE;
}
VOID CConfStatusBar::ForwardSysChangeMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (NULL == m_hwnd)
return;
::SendMessage(m_hwnd, uMsg, wParam, lParam);
}
/****************************************************************************
*
* CLASS: CConfStatusBar
*
* MEMBER: Resize(WPARAM wParam, LPARAM lParam)
*
* PURPOSE: Handles window resizing
*
****************************************************************************/
VOID CConfStatusBar::Resize(WPARAM wParam, LPARAM lParam)
{
if (NULL != m_hwnd)
{
::SendMessage(m_hwnd, WM_SIZE, wParam, lParam);
ResizeParts();
}
}
/****************************************************************************
*
* CLASS: CConfStatusBar
*
* MEMBER: Create(HWND hwndParent)
*
* PURPOSE: Creates the status bar window
*
****************************************************************************/
BOOL CConfStatusBar::Create(HWND hwndParent)
{
DebugEntry(CConfStatusBar::Create);
BOOL bRet = FALSE;
m_hwnd = CreateStatusWindow(WS_CHILD | WS_BORDER,
g_szEmpty,
hwndParent,
ID_STATUS);
if (NULL != m_hwnd)
{
// Create the ToolTip
m_hwndLoginTT = CreateWindowEx(0,
TOOLTIPS_CLASS,
(LPSTR) NULL,
0, // styles
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
m_hwnd,
(HMENU) NULL,
::GetInstanceHandle(),
NULL);
// Add the ToolTips for the 2 icons
if (NULL != m_hwndLoginTT)
{
TOOLINFO ti;
ti.cbSize = sizeof(TOOLINFO);
ti.hwnd = m_hwnd;
ti.hinst = ::GetInstanceHandle();
ti.lpszText = const_cast<LPTSTR>(g_szEmpty);
SetRect(&ti.rect, 0, 0, 0, 0);
for (UINT i=0; i<StatIconCount; ++i)
{
ti.uId = i;
ti.uFlags = TTF_SUBCLASS;
TT_AddToolInfo(m_hwndLoginTT, &ti);
}
}
// create progress meter window
ResizeParts();
Update();
bRet = TRUE;
}
else
{
WARNING_OUT(("CConfStatusBar::Create - Unable to create status window"));
}
DebugExitBOOL(CConfStatusBar::Create, bRet);
return bRet;
}
/****************************************************************************
*
* CLASS: CConfStatusBar
*
* FUNCTION: ResizeParts()
*
* PURPOSE: Calculates the correct size of the status bar parts
*
****************************************************************************/
VOID CConfStatusBar::ResizeParts()
{
ASSERT(m_hwnd);
int xSmIcon = ::GetSystemMetrics(SM_CXSMICON);
#ifdef RESIZEABLE_WINDOW
UINT uIconPartWidth = DXP_SB_DEF_ICON;
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(ncm);
if (::SystemParametersInfo( SPI_GETNONCLIENTMETRICS,
0,
&ncm,
0))
{
m_nScrollWidth = ncm.iScrollWidth;
uIconPartWidth = DXP_SB_ICON + m_nScrollWidth;
}
#else // RESIZEABLE_WINDOW
// Room for 2 icons
UINT uIconPartWidth = StatSepBorder + IconBorder + xSmIcon
+ IconBorder + xSmIcon + IconBorder + StatSepBorder;
#endif // RESIZEABLE_WINDOW
// re-calculate positions of each tray part
RECT rc;
::GetWindowRect(m_hwnd, &rc);
DWORD dxp = rc.right - rc.left;
if (dxp > uIconPartWidth)
{
DWORD rgPos[NUM_STATUSBAR_WELLS]; // right edge positions for each part
rgPos[ID_SBP_TEXT] = dxp - (DXP_SB_ULS + uIconPartWidth);
// rgPos[ID_SBP_ULS] = dxp - uIconPartWidth;
rgPos[ID_SBP_ICON] = (DWORD) -1;
::SendMessage( m_hwnd,
SB_SETPARTS,
(WPARAM) ARRAY_ELEMENTS(rgPos),
(LPARAM) &rgPos);
if (m_hwndLoginTT)
{
TCHAR szTitle[MAX_PATH];
TOOLINFO ti;
ti.cbSize = sizeof(TOOLINFO);
ti.hwnd = m_hwnd;
int nIconsLeft = dxp - uIconPartWidth + StatSepBorder + IconBorder;
for (UINT i=0; i<StatIconCount; ++i)
{
ti.uId = i;
ti.lpszText = szTitle;
TT_GetToolInfo(m_hwndLoginTT, &ti);
// HACKHACK georgep: Just setting the height to a large number, since
// I don't know exactly where the icon will be drawn until it is drawn
SetRect(&ti.rect, nIconsLeft, 0, nIconsLeft + xSmIcon, 1000);
ti.uFlags = TTF_SUBCLASS;
TT_SetToolInfo(m_hwndLoginTT, &ti);
nIconsLeft += xSmIcon + IconBorder;
}
}
}
}
void CConfStatusBar::SetTooltip(StatIcon eIcon, LPCTSTR szTip)
{
TCHAR szTitle[MAX_PATH];
TOOLINFO ti;
ti.cbSize = sizeof(TOOLINFO);
ti.hwnd = m_hwnd;
ti.lpszText = szTitle;
ti.uId = eIcon;
TT_GetToolInfo(m_hwndLoginTT, &ti);
ti.lpszText = const_cast<LPTSTR>(szTip);
ti.uFlags = TTF_SUBCLASS;
TT_SetToolInfo(m_hwndLoginTT, &ti);
}
/****************************************************************************
*
* CLASS: CConfStatusBar
*
* MEMBER: RemoveHelpText()
*
* PURPOSE: Removes the status bar help text
*
****************************************************************************/
VOID CConfStatusBar::RemoveHelpText()
{
// Taking status bar out of simple mode
if (NULL != m_hwnd)
{
::SendMessage(m_hwnd, SB_SIMPLE, FALSE, 0);
}
}
/****************************************************************************
*
* CLASS: CConfStatusBar
*
* MEMBER: SetHelpText(LPCTSTR pcszText)
*
* PURPOSE: Sets the status bar help text
*
****************************************************************************/
VOID CConfStatusBar::SetHelpText(LPCTSTR pcszText)
{
// Putting status bar into simple mode
if (NULL != m_hwnd)
{
::SendMessage(m_hwnd, SB_SIMPLE, TRUE, 0);
// 255 means simple mode - only 1 pane
::SendMessage( m_hwnd,
SB_SETTEXT,
255 | SBT_NOBORDERS,
(LPARAM) pcszText);
}
}
/****************************************************************************
*
* CLASS: CConfStatusBar
*
* MEMBER: Show(BOOL fShow)
*
* PURPOSE: Handles the toggling of the status bar window
*
****************************************************************************/
VOID CConfStatusBar::Show(BOOL fShow)
{
DebugEntry(CConfStatusBar::Show);
fShow = fShow != FALSE;
if (m_fVisible != fShow)
{
m_fVisible = fShow;
if (NULL != m_hwnd)
{
::ShowWindow(m_hwnd, m_fVisible ? SW_SHOW : SW_HIDE);
}
// Force a resize
ResizeParts();
}
DebugExitVOID(CConfStatusBar::Show);
}
/****************************************************************************
*
* CLASS: CConfStatusBar
*
* MEMBER: GetHeight()
*
* PURPOSE: Returns the height in pixels of the status bar
*
****************************************************************************/
int CConfStatusBar::GetHeight()
{
RECT rc = {0, 0, 0, 0};
if (m_fVisible && (NULL != m_hwnd))
{
GetWindowRect(m_hwnd, &rc);
}
return (rc.bottom - rc.top);
}
/****************************************************************************
*
* CLASS: CConfStatusBar
*
* MEMBER: SetIcon(DWORD dwId)
*
* PURPOSE: Set the status bar icon
*
****************************************************************************/
VOID CConfStatusBar::SetIcon(StatIcon eIcon, DWORD dwId)
{
DWORD &idIconStatus = m_idIconStatus[eIcon];
HICON &hIconStatus = m_hIconStatus [eIcon];
if ((NULL != m_hwnd) && (dwId != idIconStatus))
{
TRACE_OUT(("Changing Icon from %d to %d", m_idIconStatus, dwId));
// REVIEW: what happens to old m_hIconStatus?
HICON hIcon = (HICON) ::LoadImage(::GetInstanceHandle(),
MAKEINTRESOURCE(dwId),
IMAGE_ICON,
::GetSystemMetrics(SM_CXSMICON),
::GetSystemMetrics(SM_CYSMICON),
LR_DEFAULTCOLOR);
if (NULL != hIcon)
{
idIconStatus = dwId;
if (NULL != hIconStatus)
{
::DestroyIcon(hIconStatus);
}
hIconStatus = hIcon;
::SendMessage( m_hwnd,
SB_SETTEXT,
ID_SBP_ICON | SBT_OWNERDRAW,
(LPARAM) hIconStatus);
}
else
{
WARNING_OUT(("Unable to load status bar icon id=%d", dwId));
}
}
}
/****************************************************************************
*
* CLASS: CConfStatusBar
*
* MEMBER: SetText(UINT uID, LPCTSTR pcszText)
*
* PURPOSE: Set the status bar text
*
****************************************************************************/
VOID CConfStatusBar::SetText(UINT uID, LPCTSTR pcszText)
{
lstrcpyn( m_szULSStatus, pcszText, CCHMAX(m_szULSStatus) );
if (NULL != m_hwnd)
{
::SendMessage(m_hwnd, SB_SETTEXT, uID, (LPARAM) pcszText);
}
}
/****************************************************************************
*
* CLASS: CConfStatusBar
*
* FUNCTION: Update()
*
* PURPOSE: Updates the status bar
*
****************************************************************************/
VOID CConfStatusBar::Update()
{
DBGENTRY(CConfStatusBar::Update);
ASSERT(m_pcrParent);
if (!m_fVisible)
return;
TCHAR szCallStatus[ MAX_PATH * 3 ]; // Call status is status + url and url can be 512 by itself...
UINT uCallIcon = 0;
DWORD dwCallTick = 0;
if (0 == dwCallTick)
{
// no current calls - check if switching a/v
dwCallTick = GetCallStatus(szCallStatus, CCHMAX(szCallStatus), &uCallIcon);
}
// if a call was started more recently than any other action, OR nothing is going on
// (in which case all ticks should equal zero), use the conference / call status
if (dwCallTick == 0)
{
// All ticks are zero - Get the default conference status bar info
m_pcrParent->GetConferenceStatus(szCallStatus, CCHMAX(szCallStatus), &uCallIcon);
}
SetText(ID_SBP_TEXT, szCallStatus);
SetIcon(StatConnect, uCallIcon);
SetTooltip(StatConnect, szCallStatus);
TCHAR szOldULSStatus[ARRAY_ELEMENTS(m_szULSStatus)];
lstrcpy(szOldULSStatus, m_szULSStatus);
switch( g_GkLogonState )
{
case NM_GK_IDLE:
uCallIcon = IDI_NETGRAY;
lstrcpy(m_szULSStatus, RES2T(ID_STATUS_NOT_LOGGED_ON_TO_GATEKEEPER));
break;
case NM_GK_LOGGING_ON:
uCallIcon = IDS_STATUS_WAITING;
lstrcpy(m_szULSStatus, RES2T(ID_STATUS_LOGING_ONTO_GATEKEEPER));
break;
case NM_GK_LOGGED_ON:
uCallIcon = IDI_NET;
lstrcpy(m_szULSStatus, RES2T(ID_STATUS_LOGGED_ONTO_GATEKEEPER));
break;
default:
uCallIcon = IDI_NETGRAY;
if(ConfPolicies::CallingMode_Direct == ConfPolicies::GetCallingMode())
{
if(g_pLDAP)
{
g_pLDAP->GetStatusText(m_szULSStatus, CCHMAX(m_szULSStatus), &uCallIcon);
}
else
{
lstrcpy(m_szULSStatus, RES2T(ID_STATUS_LOGGEDOFF));
}
}
else
{
lstrcpy(m_szULSStatus, RES2T(ID_STATUS_NOT_LOGGED_ON_TO_GATEKEEPER));
}
break;
}
if (lstrcmp(szOldULSStatus, m_szULSStatus))
{
SetTooltip(StatLogin, m_szULSStatus);
}
SetIcon(StatLogin, uCallIcon);
::UpdateWindow(m_hwnd);
}
/* F O R C E S T A T U S B A R U P D A T E */
/*-------------------------------------------------------------------------
%%Function: ForceStatusBarUpdate
Force an update of the status bar.
This can be called from any thread.
All main UI updates should be done from the main thread.
-------------------------------------------------------------------------*/
VOID ForceStatusBarUpdate(void)
{
CConfRoom * pcr = ::GetConfRoom();
if (NULL != pcr)
{
PostMessage(pcr->GetTopHwnd(), WM_STATUSBAR_UPDATE, 0, 0);
}
}
///////////////////////////////////////////////////////////////////////////
/* C M D V I E W S T A T U S B A R */
/*-------------------------------------------------------------------------
%%Function: CmdViewStatusBar
-------------------------------------------------------------------------*/
VOID CmdViewStatusBar(void)
{
CConfStatusBar * pStatusBar = CConfStatusBar::GetInstance();
if (NULL == pStatusBar)
return;
CConfRoom * pcr = ::GetConfRoom();
if (NULL == pcr)
return;
HWND hwnd = pcr->GetTopHwnd();
// Turn off redraws:
::SendMessage(hwnd, WM_SETREDRAW, FALSE, 0);
// Toggle visibility
pStatusBar->Show(!pStatusBar->FVisible());
::SendMessage(hwnd, WM_SETREDRAW, TRUE, 0);
pcr->ForceWindowResize();
UpdateUI(CRUI_STATUSBAR);
}
/* C H E C K M E N U _ V I E W S T A T U S B A R */
/*-------------------------------------------------------------------------
%%Function: CheckMenu_ViewStatusBar
-------------------------------------------------------------------------*/
BOOL CheckMenu_ViewStatusBar(HMENU hMenu)
{
BOOL fCheck = FALSE;
CConfStatusBar * pStatusBar = CConfStatusBar::GetInstance();
if (NULL != pStatusBar)
{
fCheck = pStatusBar->FVisible();
if (NULL != hMenu)
{
::CheckMenuItem(hMenu, IDM_VIEW_STATUSBAR,
fCheck ? MF_CHECKED : MF_UNCHECKED);
}
}
return fCheck;
}