/***************************************************************************** * * 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); }