370 lines
12 KiB
C++
370 lines
12 KiB
C++
/*****************************************************************************
|
|
*
|
|
* statusbr.cpp - Take care of the status bar.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include "priv.h"
|
|
#include "statusbr.h"
|
|
|
|
// HACKHACK:
|
|
// \nt\public\sdk\inc\multimon.h overrides the normal GetSystemMetrics() with
|
|
// xGetSystemMetrics(). The problem is that you can't link because you need to
|
|
// have at least one file in your project that #defines COMPILE_MULTIMON_STUBS
|
|
// so that these stub override functions will get implemented.
|
|
#define COMPILE_MULTIMON_STUBS
|
|
#include "multimon.h"
|
|
|
|
|
|
#define PANE_WIDTH_USERNAME 125
|
|
#define STATUS_PANES 3
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// General Text Pane
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
void CStatusBar::SetStatusMessage(UINT nMessageID, LPCTSTR pszExtra)
|
|
{
|
|
if (NULL == this)
|
|
return;
|
|
|
|
_InitStatusBar(); // This is a NO-OP if it's already inited.
|
|
|
|
ASSERTNONCRITICAL;
|
|
if (m_hwndStatus)
|
|
{
|
|
TCHAR szMsg[256] = TEXT("%s");
|
|
TCHAR szBuf[1024];
|
|
|
|
if (nMessageID)
|
|
LoadString(g_hinst, nMessageID, szMsg, ARRAYSIZE(szMsg));
|
|
wnsprintf(szBuf, ARRAYSIZE(szBuf), szMsg, pszExtra);
|
|
|
|
// TraceMsg(TF_FTPSTATUSBAR, "CStatusBar::SetStatusMessage() Message=%s", szBuf);
|
|
SendMessage(m_hwndStatus, SB_SETTEXT, STATUS_PANE_STATUS, (LPARAM)szBuf);
|
|
SendMessage(m_hwndStatus, SB_SETTIPTEXT, STATUS_PANE_STATUS, (LPARAM)szBuf);
|
|
UpdateWindow(m_hwndStatus);
|
|
}
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// User Name Pane
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
void CStatusBar::SetUserName(LPCTSTR pszUserName, BOOL fAnnonymous)
|
|
{
|
|
TCHAR szTipText[MAX_PATH];
|
|
TCHAR szStrTemplate[MAX_PATH];
|
|
|
|
_InitStatusBar(); // This is a NO-OP if it's already inited.
|
|
//TraceMsg(TF_FTPSTATUSBAR, "CStatusBar::SetUserName(pszUserName=%s, fAnnonymous=%d)", pszUserName, fAnnonymous);
|
|
|
|
ASSERT(pszUserName);
|
|
LoadString(HINST_THISDLL, IDS_USER_TEMPLATE, szStrTemplate, ARRAYSIZE(szStrTemplate));
|
|
|
|
if (fAnnonymous)
|
|
{
|
|
TCHAR szAnnonymousName[MAX_PATH];
|
|
|
|
LoadString(HINST_THISDLL, IDS_USER_ANNONYMOUS, szAnnonymousName, ARRAYSIZE(szAnnonymousName));
|
|
wnsprintf(szTipText, ARRAYSIZE(szTipText), szStrTemplate, szAnnonymousName);
|
|
}
|
|
else
|
|
wnsprintf(szTipText, ARRAYSIZE(szTipText), szStrTemplate, pszUserName);
|
|
|
|
|
|
Str_SetPtr(&m_pszUserName, szTipText);
|
|
|
|
LoadString(HINST_THISDLL, (fAnnonymous ? IDS_USER_ANNONTOOLTIP : IDS_USER_USERTOOLTIP), szStrTemplate, ARRAYSIZE(szStrTemplate));
|
|
wnsprintf(szTipText, ARRAYSIZE(szTipText), szStrTemplate, pszUserName);
|
|
Str_SetPtr(&m_pszUserNameTT, szTipText);
|
|
_SetUserParts();
|
|
}
|
|
|
|
|
|
void CStatusBar::_SetUserParts(void)
|
|
{
|
|
SendMessage(m_hwndStatus, SB_SETTEXT, STATUS_PANE_USERNAME, (LPARAM)(m_pszUserName ? m_pszUserName : TEXT("")));
|
|
SendMessage(m_hwndStatus, SB_SETTIPTEXT, STATUS_PANE_USERNAME, (LPARAM)(m_pszUserNameTT ? m_pszUserNameTT : TEXT("")));
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Icons Panes (Read, Write, ...)
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
#define GET_RESID_FROM_PERMISSION(nType, nAllowed) (IDS_BEGIN_SB_TOOLTIPS + nType + (nAllowed ? 0 : 1))
|
|
|
|
void CStatusBar::SetFolderAttribute(BOOL fWriteAllowed)
|
|
{
|
|
TCHAR szToolTip[MAX_PATH];
|
|
|
|
_InitStatusBar(); // This is a NO-OP if it's already inited.
|
|
|
|
m_fWriteAllowed = fWriteAllowed;
|
|
LoadString(HINST_THISDLL, GET_RESID_FROM_PERMISSION(ITD_WriteAllowed, fWriteAllowed), szToolTip, ARRAYSIZE(szToolTip));
|
|
_SetIconAndTip(ISLOT_WritePermission, fWriteAllowed ? ITD_WriteAllowed : ITD_WriteNotAllowed, szToolTip);
|
|
}
|
|
|
|
HRESULT CStatusBar::_SetIconAndTip(ICON_SLOT nIconSlot, ICON_TODISPLAY nIconToDisplay, LPCTSTR pszTip)
|
|
{
|
|
/*
|
|
if (EVAL(m_hwndStatus))
|
|
{
|
|
if (!m_arhiconGeneral[nIconToDisplay])
|
|
{
|
|
m_arhiconGeneral[nIconToDisplay] = (HICON)LoadImage(HINST_THISDLL, MAKEINTRESOURCE(nIconToDisplay + IDI_WRITE_ALLOWED),
|
|
IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
|
|
}
|
|
|
|
SendMessage(m_hwndStatus, SB_SETICON, STATUS_PANE_WRITEICON, (LPARAM)m_arhiconGeneral[nIconToDisplay]);
|
|
SendMessage(m_hwndStatus, SB_SETTIPTEXT, STATUS_PANE_WRITEICON, (LPARAM)pszTip);
|
|
}
|
|
*/
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Zones Pane
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
void CStatusBar::UpdateZonesPane(LPCTSTR pszUrl)
|
|
{
|
|
_InitStatusBar(); // This is a NO-OP if it's already inited.
|
|
if (EVAL(SUCCEEDED(_LoadZoneInfo(pszUrl))))
|
|
EVAL(SUCCEEDED(_SetZone()));
|
|
}
|
|
|
|
HRESULT CStatusBar::_LoadZoneInfo(LPCTSTR pszUrl)
|
|
{
|
|
m_lCurrentZone = ZONE_UNKNOWN;
|
|
if (!m_pism)
|
|
CoCreateInstance(CLSID_InternetSecurityManager, NULL, CLSCTX_INPROC_SERVER, IID_IInternetSecurityManager, (void **)&m_pism);
|
|
|
|
if (m_pism)
|
|
{
|
|
WCHAR wzUrl[MAX_URL_STRING];
|
|
|
|
SHTCharToUnicode(pszUrl, wzUrl, ARRAYSIZE(wzUrl));
|
|
m_pism->MapUrlToZone(wzUrl, (DWORD*)&m_lCurrentZone, 0);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CStatusBar::_SetZone(void)
|
|
{
|
|
ZONEATTRIBUTES za = {SIZEOF(za)};
|
|
HICON hIcon = NULL;
|
|
|
|
if (!m_arhiconZones[0])
|
|
_CacheZonesIcons();
|
|
|
|
if (m_pizm && (m_lCurrentZone != ZONE_UNKNOWN))
|
|
{
|
|
m_pizm->GetZoneAttributes(m_lCurrentZone, &za);
|
|
hIcon = m_arhiconZones[m_lCurrentZone];
|
|
}
|
|
else
|
|
_LoadStringW(HINST_THISDLL, IDS_ZONES_UNKNOWN, za.szDisplayName, ARRAYSIZE(za.szDisplayName));
|
|
|
|
SendMessage(m_hwndStatus, SB_SETTEXTW, STATUS_PANE_ZONE, (LPARAM)za.szDisplayName);
|
|
SendMessage(m_hwndStatus, SB_SETTIPTEXTW, STATUS_PANE_ZONE, (LPARAM)za.szDisplayName);
|
|
SendMessage(m_hwndStatus, SB_SETICON, STATUS_PANE_ZONE, (LPARAM)hIcon);
|
|
return S_OK;
|
|
}
|
|
|
|
void CStatusBar::_CacheZonesIcons(void)
|
|
{
|
|
DWORD dwZoneCount = 0;
|
|
|
|
if (!m_pizm)
|
|
CoCreateInstance(CLSID_InternetZoneManager, NULL, CLSCTX_INPROC_SERVER, IID_IInternetZoneManager, (void **)&m_pizm);
|
|
|
|
if (m_pizm)
|
|
{
|
|
DWORD dwZoneEnum;
|
|
|
|
if (EVAL(SUCCEEDED(m_pizm->CreateZoneEnumerator(&dwZoneEnum, &dwZoneCount, 0))))
|
|
{
|
|
for (int nIndex=0; (DWORD)nIndex < dwZoneCount; nIndex++)
|
|
{
|
|
DWORD dwZone;
|
|
ZONEATTRIBUTES za = {sizeof(ZONEATTRIBUTES)};
|
|
WORD iIcon=0;
|
|
HICON hIcon = NULL;
|
|
|
|
m_pizm->GetZoneAt(dwZoneEnum, nIndex, &dwZone);
|
|
|
|
// get the zone attributes for this zone
|
|
m_pizm->GetZoneAttributes(dwZone, &za);
|
|
|
|
// Zone icons are in two formats.
|
|
// wininet.dll#1200 where 1200 is the res id.
|
|
// or foo.ico directly pointing to an icon file.
|
|
// search for the '#'
|
|
LPWSTR pwsz = StrChrW(za.szIconPath, TEXTW('#'));
|
|
|
|
if (pwsz)
|
|
{
|
|
TCHAR szIconPath[MAX_PATH];
|
|
// if we found it, then we have the foo.dll#00001200 format
|
|
pwsz[0] = TEXTW('\0');
|
|
SHUnicodeToTChar(za.szIconPath, szIconPath, ARRAYSIZE(szIconPath));
|
|
iIcon = (WORD)StrToIntW(pwsz+1);
|
|
ExtractIconEx(szIconPath,(INT)(-1*iIcon), NULL, &hIcon, 1 );
|
|
}
|
|
else
|
|
hIcon = (HICON)ExtractAssociatedIconExW(HINST_THISDLL, za.szIconPath, (LPWORD)&iIcon, &iIcon);
|
|
|
|
if (nIndex < MAX_NUM_ZONES_ICONS)
|
|
m_arhiconZones[nIndex] = hIcon;
|
|
}
|
|
m_pizm->DestroyZoneEnumerator(dwZoneEnum);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
HRESULT CStatusBar::Resize(LONG x, LONG y)
|
|
{
|
|
return _SetParts();
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// General Functions
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CStatusBar::_InitStatusBar(void)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Only reformat the StatusBar if we haven't yet, or
|
|
// if someone formatted it away from us. (@!%*#)
|
|
if ((!m_fInited) ||
|
|
(STATUS_PANES != SendMessage(m_hwndStatus, SB_GETPARTS, 0, 0L)))
|
|
{
|
|
m_fInited = TRUE;
|
|
hr = _SetParts();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CStatusBar::_SetParts(void)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
RECT rc;
|
|
|
|
ASSERTNONCRITICAL;
|
|
|
|
#ifdef OLD_STYLE_STATUSBAR
|
|
SendMessage(hwnd, SB_SETTEXT, 1 | SBT_NOBORDERS, 0);
|
|
#else // OLD_STYLE_STATUSBAR
|
|
|
|
GetClientRect(m_hwndStatus, &rc);
|
|
const UINT cxZone = ZoneComputePaneSize(m_hwndStatus);
|
|
const UINT cxUserName = PANE_WIDTH_USERNAME;
|
|
|
|
INT nStatusBarWidth = rc.right - rc.left;
|
|
INT arnRtEdge[STATUS_PANES] = {1};
|
|
INT nIconPaneWidth = GetSystemMetrics(SM_CXSMICON) + (GetSystemMetrics(SM_CXEDGE) * 4);
|
|
INT nWidthReqd = cxZone + cxUserName + (nIconPaneWidth * 1);
|
|
|
|
arnRtEdge[STATUS_PANE_STATUS] = max(1, nStatusBarWidth - nWidthReqd);
|
|
|
|
nWidthReqd -= cxUserName;
|
|
arnRtEdge[STATUS_PANE_USERNAME] = max(1, nStatusBarWidth - nWidthReqd);
|
|
|
|
/*
|
|
nWidthReqd -= (nIconPaneWidth);
|
|
arnRtEdge[STATUS_PANE_WRITEICON] = max(1, nStatusBarWidth - nWidthReqd);
|
|
*/
|
|
|
|
arnRtEdge[STATUS_PANE_ZONE] = -1;
|
|
|
|
LRESULT nParts = 0;
|
|
nParts = SendMessage(m_hwndStatus, SB_GETPARTS, 0, 0L);
|
|
if (nParts != STATUS_PANES)
|
|
{
|
|
for ( int n = 0; n < nParts; n++)
|
|
{
|
|
SendMessage(m_hwndStatus, SB_SETTEXT, n, NULL);
|
|
SendMessage(m_hwndStatus, SB_SETICON, n, NULL);
|
|
}
|
|
SendMessage(m_hwndStatus, SB_SETPARTS, 0, 0L);
|
|
}
|
|
|
|
SendMessage(m_hwndStatus, SB_SETPARTS, STATUS_PANES, (LPARAM)arnRtEdge);
|
|
|
|
SendMessage(m_hwndStatus, SB_GETRECT, 1, (LPARAM)&rc);
|
|
InflateRect(&rc, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
|
|
|
|
SendMessage(m_hwndStatus, SB_SETTEXT, 1, (LPARAM)SZ_EMPTY);
|
|
SendMessage(m_hwndStatus, SB_SETMINHEIGHT, GetSystemMetrics(SM_CYSMICON) + GetSystemMetrics(SM_CYBORDER) * 2, 0L);
|
|
_SetZone();
|
|
_SetUserParts();
|
|
|
|
#endif // OLD_STYLE_STATUSBAR
|
|
return hr;
|
|
}
|
|
|
|
|
|
/****************************************************\
|
|
Constructor
|
|
\****************************************************/
|
|
CStatusBar::CStatusBar(HWND hwndStatus)
|
|
{
|
|
DllAddRef();
|
|
|
|
// This needs to be allocated in Zero Inited Memory.
|
|
// Assert that all Member Variables are inited to Zero.
|
|
ASSERT(!m_pism);
|
|
ASSERT(!m_pizm);
|
|
ASSERT(!m_pszUserName);
|
|
ASSERT(!m_pszUserNameTT);
|
|
|
|
m_hwndStatus = hwndStatus;
|
|
m_lCurrentZone = ZONE_UNKNOWN;
|
|
|
|
LEAK_ADDREF(LEAK_CStatusBar);
|
|
}
|
|
|
|
|
|
/****************************************************\
|
|
Destructor
|
|
\****************************************************/
|
|
CStatusBar::~CStatusBar(void)
|
|
{
|
|
int nIndex;
|
|
|
|
IUnknown_Set((IUnknown **) &m_pism, NULL);
|
|
IUnknown_Set((IUnknown **) &m_pizm, NULL);
|
|
|
|
Str_SetPtr(&m_pszUserName, NULL);
|
|
Str_SetPtr(&m_pszUserNameTT, NULL);
|
|
|
|
for (nIndex = 0; nIndex < MAX_NUM_ZONES_ICONS; nIndex++)
|
|
{
|
|
if (m_arhiconZones[nIndex])
|
|
DestroyIcon(m_arhiconZones[nIndex]);
|
|
}
|
|
|
|
for (nIndex = 0; nIndex < ITD_MAX; nIndex++)
|
|
{
|
|
if (m_arhiconGeneral[nIndex])
|
|
DestroyIcon(m_arhiconGeneral[nIndex]);
|
|
}
|
|
|
|
ASSERTNONCRITICAL;
|
|
SendMessage(m_hwndStatus, SB_SETTEXT, 1 | SBT_NOBORDERS, 0);
|
|
|
|
DllRelease();
|
|
LEAK_DELREF(LEAK_CStatusBar);
|
|
}
|