Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

369 lines
12 KiB

  1. /*****************************************************************************
  2. *
  3. * statusbr.cpp - Take care of the status bar.
  4. *
  5. *****************************************************************************/
  6. #include "priv.h"
  7. #include "statusbr.h"
  8. // HACKHACK:
  9. // \nt\public\sdk\inc\multimon.h overrides the normal GetSystemMetrics() with
  10. // xGetSystemMetrics(). The problem is that you can't link because you need to
  11. // have at least one file in your project that #defines COMPILE_MULTIMON_STUBS
  12. // so that these stub override functions will get implemented.
  13. #define COMPILE_MULTIMON_STUBS
  14. #include "multimon.h"
  15. #define PANE_WIDTH_USERNAME 125
  16. #define STATUS_PANES 3
  17. //////////////////////////////////////////////////////////////////
  18. // General Text Pane
  19. //////////////////////////////////////////////////////////////////
  20. void CStatusBar::SetStatusMessage(UINT nMessageID, LPCTSTR pszExtra)
  21. {
  22. if (NULL == this)
  23. return;
  24. _InitStatusBar(); // This is a NO-OP if it's already inited.
  25. ASSERTNONCRITICAL;
  26. if (m_hwndStatus)
  27. {
  28. TCHAR szMsg[256] = TEXT("%s");
  29. TCHAR szBuf[1024];
  30. if (nMessageID)
  31. LoadString(g_hinst, nMessageID, szMsg, ARRAYSIZE(szMsg));
  32. wnsprintf(szBuf, ARRAYSIZE(szBuf), szMsg, pszExtra);
  33. // TraceMsg(TF_FTPSTATUSBAR, "CStatusBar::SetStatusMessage() Message=%s", szBuf);
  34. SendMessage(m_hwndStatus, SB_SETTEXT, STATUS_PANE_STATUS, (LPARAM)szBuf);
  35. SendMessage(m_hwndStatus, SB_SETTIPTEXT, STATUS_PANE_STATUS, (LPARAM)szBuf);
  36. UpdateWindow(m_hwndStatus);
  37. }
  38. }
  39. //////////////////////////////////////////////////////////////////
  40. // User Name Pane
  41. //////////////////////////////////////////////////////////////////
  42. void CStatusBar::SetUserName(LPCTSTR pszUserName, BOOL fAnnonymous)
  43. {
  44. TCHAR szTipText[MAX_PATH];
  45. TCHAR szStrTemplate[MAX_PATH];
  46. _InitStatusBar(); // This is a NO-OP if it's already inited.
  47. //TraceMsg(TF_FTPSTATUSBAR, "CStatusBar::SetUserName(pszUserName=%s, fAnnonymous=%d)", pszUserName, fAnnonymous);
  48. ASSERT(pszUserName);
  49. LoadString(HINST_THISDLL, IDS_USER_TEMPLATE, szStrTemplate, ARRAYSIZE(szStrTemplate));
  50. if (fAnnonymous)
  51. {
  52. TCHAR szAnnonymousName[MAX_PATH];
  53. LoadString(HINST_THISDLL, IDS_USER_ANNONYMOUS, szAnnonymousName, ARRAYSIZE(szAnnonymousName));
  54. wnsprintf(szTipText, ARRAYSIZE(szTipText), szStrTemplate, szAnnonymousName);
  55. }
  56. else
  57. wnsprintf(szTipText, ARRAYSIZE(szTipText), szStrTemplate, pszUserName);
  58. Str_SetPtr(&m_pszUserName, szTipText);
  59. LoadString(HINST_THISDLL, (fAnnonymous ? IDS_USER_ANNONTOOLTIP : IDS_USER_USERTOOLTIP), szStrTemplate, ARRAYSIZE(szStrTemplate));
  60. wnsprintf(szTipText, ARRAYSIZE(szTipText), szStrTemplate, pszUserName);
  61. Str_SetPtr(&m_pszUserNameTT, szTipText);
  62. _SetUserParts();
  63. }
  64. void CStatusBar::_SetUserParts(void)
  65. {
  66. SendMessage(m_hwndStatus, SB_SETTEXT, STATUS_PANE_USERNAME, (LPARAM)(m_pszUserName ? m_pszUserName : TEXT("")));
  67. SendMessage(m_hwndStatus, SB_SETTIPTEXT, STATUS_PANE_USERNAME, (LPARAM)(m_pszUserNameTT ? m_pszUserNameTT : TEXT("")));
  68. }
  69. //////////////////////////////////////////////////////////////////
  70. // Icons Panes (Read, Write, ...)
  71. //////////////////////////////////////////////////////////////////
  72. #define GET_RESID_FROM_PERMISSION(nType, nAllowed) (IDS_BEGIN_SB_TOOLTIPS + nType + (nAllowed ? 0 : 1))
  73. void CStatusBar::SetFolderAttribute(BOOL fWriteAllowed)
  74. {
  75. TCHAR szToolTip[MAX_PATH];
  76. _InitStatusBar(); // This is a NO-OP if it's already inited.
  77. m_fWriteAllowed = fWriteAllowed;
  78. LoadString(HINST_THISDLL, GET_RESID_FROM_PERMISSION(ITD_WriteAllowed, fWriteAllowed), szToolTip, ARRAYSIZE(szToolTip));
  79. _SetIconAndTip(ISLOT_WritePermission, fWriteAllowed ? ITD_WriteAllowed : ITD_WriteNotAllowed, szToolTip);
  80. }
  81. HRESULT CStatusBar::_SetIconAndTip(ICON_SLOT nIconSlot, ICON_TODISPLAY nIconToDisplay, LPCTSTR pszTip)
  82. {
  83. /*
  84. if (EVAL(m_hwndStatus))
  85. {
  86. if (!m_arhiconGeneral[nIconToDisplay])
  87. {
  88. m_arhiconGeneral[nIconToDisplay] = (HICON)LoadImage(HINST_THISDLL, MAKEINTRESOURCE(nIconToDisplay + IDI_WRITE_ALLOWED),
  89. IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
  90. }
  91. SendMessage(m_hwndStatus, SB_SETICON, STATUS_PANE_WRITEICON, (LPARAM)m_arhiconGeneral[nIconToDisplay]);
  92. SendMessage(m_hwndStatus, SB_SETTIPTEXT, STATUS_PANE_WRITEICON, (LPARAM)pszTip);
  93. }
  94. */
  95. return S_OK;
  96. }
  97. //////////////////////////////////////////////////////////////////
  98. // Zones Pane
  99. //////////////////////////////////////////////////////////////////
  100. void CStatusBar::UpdateZonesPane(LPCTSTR pszUrl)
  101. {
  102. _InitStatusBar(); // This is a NO-OP if it's already inited.
  103. if (EVAL(SUCCEEDED(_LoadZoneInfo(pszUrl))))
  104. EVAL(SUCCEEDED(_SetZone()));
  105. }
  106. HRESULT CStatusBar::_LoadZoneInfo(LPCTSTR pszUrl)
  107. {
  108. m_lCurrentZone = ZONE_UNKNOWN;
  109. if (!m_pism)
  110. CoCreateInstance(CLSID_InternetSecurityManager, NULL, CLSCTX_INPROC_SERVER, IID_IInternetSecurityManager, (void **)&m_pism);
  111. if (m_pism)
  112. {
  113. WCHAR wzUrl[MAX_URL_STRING];
  114. SHTCharToUnicode(pszUrl, wzUrl, ARRAYSIZE(wzUrl));
  115. m_pism->MapUrlToZone(wzUrl, (DWORD*)&m_lCurrentZone, 0);
  116. }
  117. return S_OK;
  118. }
  119. HRESULT CStatusBar::_SetZone(void)
  120. {
  121. ZONEATTRIBUTES za = {SIZEOF(za)};
  122. HICON hIcon = NULL;
  123. if (!m_arhiconZones[0])
  124. _CacheZonesIcons();
  125. if (m_pizm && (m_lCurrentZone != ZONE_UNKNOWN))
  126. {
  127. m_pizm->GetZoneAttributes(m_lCurrentZone, &za);
  128. hIcon = m_arhiconZones[m_lCurrentZone];
  129. }
  130. else
  131. _LoadStringW(HINST_THISDLL, IDS_ZONES_UNKNOWN, za.szDisplayName, ARRAYSIZE(za.szDisplayName));
  132. SendMessage(m_hwndStatus, SB_SETTEXTW, STATUS_PANE_ZONE, (LPARAM)za.szDisplayName);
  133. SendMessage(m_hwndStatus, SB_SETTIPTEXTW, STATUS_PANE_ZONE, (LPARAM)za.szDisplayName);
  134. SendMessage(m_hwndStatus, SB_SETICON, STATUS_PANE_ZONE, (LPARAM)hIcon);
  135. return S_OK;
  136. }
  137. void CStatusBar::_CacheZonesIcons(void)
  138. {
  139. DWORD dwZoneCount = 0;
  140. if (!m_pizm)
  141. CoCreateInstance(CLSID_InternetZoneManager, NULL, CLSCTX_INPROC_SERVER, IID_IInternetZoneManager, (void **)&m_pizm);
  142. if (m_pizm)
  143. {
  144. DWORD dwZoneEnum;
  145. if (EVAL(SUCCEEDED(m_pizm->CreateZoneEnumerator(&dwZoneEnum, &dwZoneCount, 0))))
  146. {
  147. for (int nIndex=0; (DWORD)nIndex < dwZoneCount; nIndex++)
  148. {
  149. DWORD dwZone;
  150. ZONEATTRIBUTES za = {sizeof(ZONEATTRIBUTES)};
  151. WORD iIcon=0;
  152. HICON hIcon = NULL;
  153. m_pizm->GetZoneAt(dwZoneEnum, nIndex, &dwZone);
  154. // get the zone attributes for this zone
  155. m_pizm->GetZoneAttributes(dwZone, &za);
  156. // Zone icons are in two formats.
  157. // wininet.dll#1200 where 1200 is the res id.
  158. // or foo.ico directly pointing to an icon file.
  159. // search for the '#'
  160. LPWSTR pwsz = StrChrW(za.szIconPath, TEXTW('#'));
  161. if (pwsz)
  162. {
  163. TCHAR szIconPath[MAX_PATH];
  164. // if we found it, then we have the foo.dll#00001200 format
  165. pwsz[0] = TEXTW('\0');
  166. SHUnicodeToTChar(za.szIconPath, szIconPath, ARRAYSIZE(szIconPath));
  167. iIcon = (WORD)StrToIntW(pwsz+1);
  168. ExtractIconEx(szIconPath,(INT)(-1*iIcon), NULL, &hIcon, 1 );
  169. }
  170. else
  171. hIcon = (HICON)ExtractAssociatedIconExW(HINST_THISDLL, za.szIconPath, (LPWORD)&iIcon, &iIcon);
  172. if (nIndex < MAX_NUM_ZONES_ICONS)
  173. m_arhiconZones[nIndex] = hIcon;
  174. }
  175. m_pizm->DestroyZoneEnumerator(dwZoneEnum);
  176. }
  177. }
  178. }
  179. HRESULT CStatusBar::Resize(LONG x, LONG y)
  180. {
  181. return _SetParts();
  182. }
  183. //////////////////////////////////////////////////////////////////
  184. // General Functions
  185. //////////////////////////////////////////////////////////////////
  186. HRESULT CStatusBar::_InitStatusBar(void)
  187. {
  188. HRESULT hr = S_OK;
  189. // Only reformat the StatusBar if we haven't yet, or
  190. // if someone formatted it away from us. (@!%*#)
  191. if ((!m_fInited) ||
  192. (STATUS_PANES != SendMessage(m_hwndStatus, SB_GETPARTS, 0, 0L)))
  193. {
  194. m_fInited = TRUE;
  195. hr = _SetParts();
  196. }
  197. return hr;
  198. }
  199. HRESULT CStatusBar::_SetParts(void)
  200. {
  201. HRESULT hr = S_OK;
  202. RECT rc;
  203. ASSERTNONCRITICAL;
  204. #ifdef OLD_STYLE_STATUSBAR
  205. SendMessage(hwnd, SB_SETTEXT, 1 | SBT_NOBORDERS, 0);
  206. #else // OLD_STYLE_STATUSBAR
  207. GetClientRect(m_hwndStatus, &rc);
  208. const UINT cxZone = ZoneComputePaneSize(m_hwndStatus);
  209. const UINT cxUserName = PANE_WIDTH_USERNAME;
  210. INT nStatusBarWidth = rc.right - rc.left;
  211. INT arnRtEdge[STATUS_PANES] = {1};
  212. INT nIconPaneWidth = GetSystemMetrics(SM_CXSMICON) + (GetSystemMetrics(SM_CXEDGE) * 4);
  213. INT nWidthReqd = cxZone + cxUserName + (nIconPaneWidth * 1);
  214. arnRtEdge[STATUS_PANE_STATUS] = max(1, nStatusBarWidth - nWidthReqd);
  215. nWidthReqd -= cxUserName;
  216. arnRtEdge[STATUS_PANE_USERNAME] = max(1, nStatusBarWidth - nWidthReqd);
  217. /*
  218. nWidthReqd -= (nIconPaneWidth);
  219. arnRtEdge[STATUS_PANE_WRITEICON] = max(1, nStatusBarWidth - nWidthReqd);
  220. */
  221. arnRtEdge[STATUS_PANE_ZONE] = -1;
  222. LRESULT nParts = 0;
  223. nParts = SendMessage(m_hwndStatus, SB_GETPARTS, 0, 0L);
  224. if (nParts != STATUS_PANES)
  225. {
  226. for ( int n = 0; n < nParts; n++)
  227. {
  228. SendMessage(m_hwndStatus, SB_SETTEXT, n, NULL);
  229. SendMessage(m_hwndStatus, SB_SETICON, n, NULL);
  230. }
  231. SendMessage(m_hwndStatus, SB_SETPARTS, 0, 0L);
  232. }
  233. SendMessage(m_hwndStatus, SB_SETPARTS, STATUS_PANES, (LPARAM)arnRtEdge);
  234. SendMessage(m_hwndStatus, SB_GETRECT, 1, (LPARAM)&rc);
  235. InflateRect(&rc, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
  236. SendMessage(m_hwndStatus, SB_SETTEXT, 1, (LPARAM)SZ_EMPTY);
  237. SendMessage(m_hwndStatus, SB_SETMINHEIGHT, GetSystemMetrics(SM_CYSMICON) + GetSystemMetrics(SM_CYBORDER) * 2, 0L);
  238. _SetZone();
  239. _SetUserParts();
  240. #endif // OLD_STYLE_STATUSBAR
  241. return hr;
  242. }
  243. /****************************************************\
  244. Constructor
  245. \****************************************************/
  246. CStatusBar::CStatusBar(HWND hwndStatus)
  247. {
  248. DllAddRef();
  249. // This needs to be allocated in Zero Inited Memory.
  250. // Assert that all Member Variables are inited to Zero.
  251. ASSERT(!m_pism);
  252. ASSERT(!m_pizm);
  253. ASSERT(!m_pszUserName);
  254. ASSERT(!m_pszUserNameTT);
  255. m_hwndStatus = hwndStatus;
  256. m_lCurrentZone = ZONE_UNKNOWN;
  257. LEAK_ADDREF(LEAK_CStatusBar);
  258. }
  259. /****************************************************\
  260. Destructor
  261. \****************************************************/
  262. CStatusBar::~CStatusBar(void)
  263. {
  264. int nIndex;
  265. IUnknown_Set((IUnknown **) &m_pism, NULL);
  266. IUnknown_Set((IUnknown **) &m_pizm, NULL);
  267. Str_SetPtr(&m_pszUserName, NULL);
  268. Str_SetPtr(&m_pszUserNameTT, NULL);
  269. for (nIndex = 0; nIndex < MAX_NUM_ZONES_ICONS; nIndex++)
  270. {
  271. if (m_arhiconZones[nIndex])
  272. DestroyIcon(m_arhiconZones[nIndex]);
  273. }
  274. for (nIndex = 0; nIndex < ITD_MAX; nIndex++)
  275. {
  276. if (m_arhiconGeneral[nIndex])
  277. DestroyIcon(m_arhiconGeneral[nIndex]);
  278. }
  279. ASSERTNONCRITICAL;
  280. SendMessage(m_hwndStatus, SB_SETTEXT, 1 | SBT_NOBORDERS, 0);
  281. DllRelease();
  282. LEAK_DELREF(LEAK_CStatusBar);
  283. }