STATBAR.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:20k
源码类别:

Windows编程

开发平台:

Visual C++

  1. // statbar.cpp : definition of old backward compatible CStatusBar
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12. #include "stdafx.h"
  13. #define _AFX_NO_OLE_SUPPORT
  14. #include <afxpriv.h>
  15. #include "statbar.h"
  16. #include "globals.h"
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. #define new DEBUG_NEW
  22. /////////////////////////////////////////////////////////////////////////////
  23. // CStatusBar creation etc
  24. struct AFX_STATUSPANE
  25. {
  26. UINT    nID;        // IDC of indicator: 0 => normal text area
  27. UINT    nStyle;     // style flags (SBPS_*)
  28. int     cxText;     // width of string area in pixels
  29. //   on both sides there is a 1 pixel gap and
  30. //    a one pixel border, making a pane 4 pixels wider
  31. LPCTSTR  lpszText;  // text in the pane
  32. };
  33. inline AFX_STATUSPANE* CStatusBar::_GetPanePtr(int nIndex) const
  34. {
  35. ASSERT(nIndex >= 0 && nIndex < m_nCount);
  36. ASSERT(m_pData != NULL);
  37. return ((AFX_STATUSPANE*)m_pData) + nIndex;
  38. }
  39. #ifdef AFX_INIT_SEG
  40. #pragma code_seg(AFX_INIT_SEG)
  41. #endif
  42. CStatusBar::CStatusBar()
  43. {
  44. m_hFont = NULL;
  45. // setup correct margins
  46. m_cxRightBorder = m_cxDefaultGap;
  47. m_cxSizeBox = 0;
  48. m_bHideSizeBox = FALSE;
  49. if (globalData.bWin4)
  50. {
  51. m_cxLeftBorder = 4;
  52. m_cyTopBorder = 2;
  53. m_cyBottomBorder = 0;
  54. m_cxRightBorder = 0;
  55. }
  56. if (globalData.hStatusFont == NULL)
  57. {
  58. // load status bar font
  59. CClientDC dc(NULL);
  60. LOGFONT logfont;
  61. memset(&logfont, 0, sizeof(logfont));
  62. logfont.lfWeight = FW_NORMAL;
  63. logfont.lfHeight = -MulDiv(globalData.bWin4 ? 8 : 10,
  64. globalData.cyPixelsPerInch, 72);
  65. lstrcpy(logfont.lfFaceName, _T("MS Sans Serif"));
  66. BOOL bCustom = AfxCustomLogFont(AFX_IDS_STATUS_FONT, &logfont);
  67. if (bCustom || !GetSystemMetrics(SM_DBCSENABLED))
  68. {
  69. // only set pitch & family if not a custom font
  70. if (!bCustom)
  71. logfont.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
  72. // 10 point height Sans Serif font (8 point for Win4)
  73. globalData.hStatusFont = ::CreateFontIndirect(&logfont);
  74. }
  75. if (globalData.hStatusFont == NULL)
  76. {
  77. if (!GetSystemMetrics(SM_DBCSENABLED))
  78. TRACE0("Warning: Using system font for status font.n");
  79. globalData.hStatusFont = (HFONT)::GetStockObject(SYSTEM_FONT);
  80. }
  81. }
  82. }
  83. void CStatusBar::OnSettingChange(UINT /*uFlags*/, LPCTSTR /* lpszSection */)
  84. {
  85. if (globalData.bWin4)
  86. {
  87. // get the drawing area for the status bar
  88. CRect rect;
  89. GetClientRect(rect);
  90. CalcInsideRect(rect, TRUE);
  91. // the size box is based off the size of a scrollbar
  92. m_cxSizeBox = min(GetSystemMetrics(SM_CXVSCROLL)+1, rect.Height());
  93. }
  94. }
  95. CStatusBar::~CStatusBar()
  96. {
  97. // free strings before freeing array of elements
  98. for (int i = 0; i < m_nCount; i++)
  99. VERIFY(SetPaneText(i, NULL, FALSE));    // no update
  100. }
  101. BOOL CStatusBar::PreCreateWindow(CREATESTRUCT& cs)
  102. {
  103. // in Win4, status bars do not have a border at all, since it is
  104. //  provided by the client area.
  105. if (globalData.bWin4 &&
  106. (m_dwStyle & (CBRS_ALIGN_ANY|CBRS_BORDER_ANY)) == CBRS_BOTTOM)
  107. {
  108. m_dwStyle &= ~(CBRS_BORDER_ANY|CBRS_BORDER_3D);
  109. }
  110. return CControlBar::PreCreateWindow(cs);
  111. }
  112. BOOL CStatusBar::Create(CWnd* pParentWnd, DWORD dwStyle, UINT nID)
  113. {
  114. ASSERT_VALID(pParentWnd);   // must have a parent
  115. // save the style
  116. m_dwStyle = (dwStyle & CBRS_ALL);
  117. // create the HWND
  118. CRect rect;
  119. rect.SetRectEmpty();
  120. LPCTSTR lpszClass = AfxRegisterWndClass(0, ::LoadCursor(NULL, IDC_ARROW),
  121. (HBRUSH)(COLOR_BTNFACE+1), NULL);
  122. if (!CWnd::Create(lpszClass, NULL, dwStyle, rect, pParentWnd, nID))
  123. return FALSE;
  124. // Note: Parent must resize itself for control bar to be resized
  125. // set initial font and calculate bar height
  126. SendMessage(WM_SETFONT, (WPARAM)globalData.hStatusFont);
  127. return TRUE;
  128. }
  129. BOOL CStatusBar::SetIndicators(const UINT* lpIDArray, int nIDCount)
  130. {
  131. ASSERT_VALID(this);
  132. ASSERT(nIDCount >= 1);  // must be at least one of them
  133. ASSERT(lpIDArray == NULL ||
  134. AfxIsValidAddress(lpIDArray, sizeof(UINT) * nIDCount, FALSE));
  135. // free strings before freeing array of elements
  136. for (int i = 0; i < m_nCount; i++)
  137. VERIFY(SetPaneText(i, NULL, FALSE));    // no update
  138. // first allocate array for panes and copy initial data
  139. if (!AllocElements(nIDCount, sizeof(AFX_STATUSPANE)))
  140. return FALSE;
  141. ASSERT(nIDCount == m_nCount);
  142. BOOL bOK = TRUE;
  143. if (lpIDArray != NULL)
  144. {
  145. ASSERT(m_hFont != NULL);        // must have a font !
  146. CString strText;
  147. CClientDC dcScreen(NULL);
  148. HGDIOBJ hOldFont = dcScreen.SelectObject(m_hFont);
  149. for (int i = 0; i < nIDCount; i++)
  150. {
  151. AFX_STATUSPANE* pSBP = _GetPanePtr(i);
  152. pSBP->nID = *lpIDArray++;
  153. if (pSBP->nID != 0)
  154. {
  155. if (!strText.LoadString(pSBP->nID))
  156. {
  157. TRACE1("Warning: failed to load indicator string 0x%04X.n",
  158. pSBP->nID);
  159. bOK = FALSE;
  160. break;
  161. }
  162. pSBP->cxText = dcScreen.GetTextExtent(strText,
  163. strText.GetLength()).cx;
  164. ASSERT(pSBP->cxText >= 0);
  165. if (!SetPaneText(i, strText, FALSE))
  166. {
  167. bOK = FALSE;
  168. break;
  169. }
  170. }
  171. else
  172. {
  173. // no indicator (must access via index)
  174. // default to 1/4 the screen width (first pane is stretchy)
  175. pSBP->cxText = ::GetSystemMetrics(SM_CXSCREEN) / 4;
  176. if (i == 0)
  177. pSBP->nStyle |= (SBPS_STRETCH | SBPS_NOBORDERS);
  178. }
  179. }
  180. dcScreen.SelectObject(hOldFont);
  181. }
  182. return bOK;
  183. }
  184. #ifdef AFX_CORE3_SEG
  185. #pragma code_seg(AFX_CORE3_SEG)
  186. #endif
  187. /////////////////////////////////////////////////////////////////////////////
  188. // CStatusBar attribute access
  189. int CStatusBar::CommandToIndex(UINT nIDFind) const
  190. {
  191. ASSERT_VALID(this);
  192. if (m_nCount <= 0)
  193. return -1;
  194. AFX_STATUSPANE* pSBP = _GetPanePtr(0);
  195. for (int i = 0; i < m_nCount; i++, pSBP++)
  196. if (pSBP->nID == nIDFind)
  197. return i;
  198. return -1;
  199. }
  200. UINT CStatusBar::GetItemID(int nIndex) const
  201. {
  202. ASSERT_VALID(this);
  203. return _GetPanePtr(nIndex)->nID;
  204. }
  205. void CStatusBar::GetItemRect(int nIndex, LPRECT lpRect) const
  206. {
  207. ASSERT_VALID(this);
  208. ASSERT(AfxIsValidAddress(lpRect, sizeof(RECT)));
  209. // return rectangle containing inset size
  210. ASSERT(nIndex >= 0 && nIndex < m_nCount);
  211. CRect rect;
  212. GetClientRect(rect);
  213. CalcInsideRect(rect, TRUE);
  214. // protect space for size box
  215. int cxSizeBox = m_bHideSizeBox ? 0 : m_cxSizeBox;
  216. int xMax = (rect.right -= cxSizeBox);
  217. if (cxSizeBox == 0)
  218. xMax += m_cxRightBorder + 1;
  219. // walk through to calculate extra space
  220. int cxExtra = rect.Width() + m_cxDefaultGap;
  221. AFX_STATUSPANE* pSBP = (AFX_STATUSPANE*)m_pData;
  222. for (int i = 0; i < m_nCount; i++, pSBP++)
  223. cxExtra -= (pSBP->cxText + CX_BORDER * 4 + m_cxDefaultGap);
  224. // if cxExtra <= 0 then we will not stretch but just clip
  225. for (i = 0, pSBP = (AFX_STATUSPANE*)m_pData; i < m_nCount; i++, pSBP++)
  226. {
  227. ASSERT(pSBP->cxText >= 0);
  228. int cxText = pSBP->cxText;
  229. if ((pSBP->nStyle & SBPS_STRETCH) && cxExtra > 0)
  230. {
  231. cxText += cxExtra;
  232. cxExtra = 0;
  233. }
  234. rect.right = rect.left + cxText + CX_BORDER * 4;
  235. rect.right = min(rect.right, xMax);
  236. if (i == nIndex)
  237. break;  // stop with correct rectangle (includes border)
  238. rect.left = rect.right + m_cxDefaultGap;
  239. rect.left = min(rect.left, xMax);
  240. }
  241. ASSERT(i == nIndex);
  242. *lpRect = rect;
  243. }
  244. UINT CStatusBar::GetPaneStyle(int nIndex) const
  245. {
  246. return _GetPanePtr(nIndex)->nStyle;
  247. }
  248. void CStatusBar::SetPaneStyle(int nIndex, UINT nStyle)
  249. {
  250. AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
  251. if (pSBP->nStyle != nStyle)
  252. {
  253. // just change the style of 1 pane, and invalidate it
  254. pSBP->nStyle = nStyle;
  255. CRect rect;
  256. GetItemRect(nIndex, &rect);
  257. InvalidateRect(rect);
  258. }
  259. }
  260. void CStatusBar::GetPaneInfo(int nIndex, UINT& nID, UINT& nStyle,
  261. int& cxWidth) const
  262. {
  263. ASSERT_VALID(this);
  264. AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
  265. nID = pSBP->nID;
  266. nStyle = pSBP->nStyle;
  267. cxWidth = pSBP->cxText;
  268. }
  269. void CStatusBar::SetPaneInfo(int nIndex, UINT nID, UINT nStyle, int cxWidth)
  270. {
  271. ASSERT_VALID(this);
  272. AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
  273. pSBP->nID = nID;
  274. SetPaneStyle(nIndex, nStyle);  // single pane invalidate
  275. if (cxWidth != pSBP->cxText)
  276. {
  277. // change width of one pane -> invalidate the entire status bar
  278. pSBP->cxText = cxWidth;
  279. Invalidate();
  280. }
  281. }
  282. void CStatusBar::GetPaneText(int nIndex, CString& s) const
  283. {
  284. ASSERT_VALID(this);
  285. AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
  286. s = pSBP->lpszText;
  287. }
  288. BOOL CStatusBar::SetPaneText(int nIndex, LPCTSTR lpszNewText, BOOL bUpdate)
  289. {
  290. ASSERT_VALID(this);
  291. AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
  292. if (pSBP->lpszText != NULL)
  293. {
  294. if (lpszNewText != NULL && lstrcmp(pSBP->lpszText, lpszNewText) == 0)
  295. return TRUE;        // nothing to change
  296. free((LPVOID)pSBP->lpszText);
  297. }
  298. BOOL bOK = TRUE;
  299. if (lpszNewText == NULL || *lpszNewText == '')
  300. {
  301. pSBP->lpszText = NULL;
  302. }
  303. else
  304. {
  305. pSBP->lpszText = _tcsdup(lpszNewText);
  306. if (pSBP->lpszText == NULL)
  307. bOK = FALSE; // old text is lost and replaced by NULL
  308. }
  309. if (bUpdate)
  310. {
  311. // invalidate the text of the pane - not including the border
  312. CRect rect;
  313. GetItemRect(nIndex, &rect);
  314. if (!(pSBP->nStyle & SBPS_NOBORDERS))
  315. rect.InflateRect(-CX_BORDER, -CY_BORDER);
  316. else
  317. rect.top -= CY_BORDER;  // base line adjustment
  318. InvalidateRect(rect);
  319. }
  320. return bOK;
  321. }
  322. /////////////////////////////////////////////////////////////////////////////
  323. // CStatusBar implementation
  324. CSize CStatusBar::CalcFixedLayout(BOOL, BOOL bHorz)
  325. {
  326. ASSERT_VALID(this);
  327. // recalculate based on font height + borders
  328. TEXTMETRIC tm;
  329. {
  330. CClientDC dcScreen(NULL);
  331. HGDIOBJ hOldFont = dcScreen.SelectObject(m_hFont);
  332. VERIFY(dcScreen.GetTextMetrics(&tm));
  333. dcScreen.SelectObject(hOldFont);
  334. }
  335. CRect rectSize;
  336. rectSize.SetRectEmpty();
  337. CalcInsideRect(rectSize, bHorz);    // will be negative size
  338. // sizeof text + 1 or 2 extra on top, 2 on bottom + borders
  339. return CSize(32767, tm.tmHeight - tm.tmInternalLeading +
  340. CY_BORDER * (globalData.bWin4 ? 4 : 3) - rectSize.Height());
  341. }
  342. void CStatusBar::DoPaint(CDC* pDC)
  343. {
  344. ASSERT_VALID(this);
  345. ASSERT_VALID(pDC);
  346. CControlBar::DoPaint(pDC);      // draw border
  347. CRect rect;
  348. GetClientRect(rect);
  349. CalcInsideRect(rect, TRUE);
  350. ASSERT(m_hFont != NULL);        // must have a font!
  351. HGDIOBJ hOldFont = pDC->SelectObject(m_hFont);
  352. // protect space for size box
  353. int cxSizeBox = m_bHideSizeBox ? 0 : m_cxSizeBox;
  354. int xMax = (rect.right -= cxSizeBox);
  355. if (cxSizeBox == 0)
  356. xMax += m_cxRightBorder + 1;
  357. // walk through to calculate extra space
  358. int cxExtra = rect.Width() + m_cxDefaultGap;
  359. AFX_STATUSPANE* pSBP = (AFX_STATUSPANE*)m_pData;
  360. for (int i = 0; i < m_nCount; i++, pSBP++)
  361. cxExtra -= (pSBP->cxText + CX_BORDER * 4 + m_cxDefaultGap);
  362. // if cxExtra <= 0 then we will not stretch but just clip
  363. for (i = 0, pSBP = (AFX_STATUSPANE*)m_pData; i < m_nCount; i++, pSBP++)
  364. {
  365. ASSERT(pSBP->cxText >= 0);
  366. int cxText = pSBP->cxText;
  367. if ((pSBP->nStyle & SBPS_STRETCH) && cxExtra > 0)
  368. {
  369. cxText += cxExtra;
  370. cxExtra = 0;
  371. }
  372. rect.right = rect.left + cxText + CX_BORDER * 4;
  373. rect.right = min(rect.right, xMax);
  374. if (!globalData.bWin32s || pDC->RectVisible(&rect))
  375. DrawStatusText(pDC, rect, pSBP->lpszText, pSBP->nStyle);
  376. rect.left = rect.right + m_cxDefaultGap;
  377. if (rect.left >= xMax)
  378. break;
  379. }
  380. pDC->SelectObject(hOldFont);
  381. // draw the size box in the bottom right corner
  382. if (cxSizeBox != 0)
  383. {
  384. int cxMax = min(cxSizeBox, rect.Height()+m_cyTopBorder);
  385. rect.left = xMax + (cxSizeBox - cxMax) + CX_BORDER;
  386. rect.bottom -= CX_BORDER;
  387. HPEN hPenOld = (HPEN)pDC->SelectObject(globalData.hpenBtnHilite);
  388. for (int i = 0; i < cxMax; i += 4)
  389. {
  390. pDC->MoveTo(rect.left+i, rect.bottom);
  391. pDC->LineTo(rect.left+cxMax, rect.bottom-cxMax+i);
  392. }
  393. pDC->SelectObject(globalData.hpenBtnShadow);
  394. for (i = 1; i < cxMax; i += 4)
  395. {
  396. pDC->MoveTo(rect.left+i, rect.bottom);
  397. pDC->LineTo(rect.left+cxMax, rect.bottom-cxMax+i);
  398. }
  399. for (i = 2; i < cxMax; i += 4)
  400. {
  401. pDC->MoveTo(rect.left+i, rect.bottom);
  402. pDC->LineTo(rect.left+cxMax, rect.bottom-cxMax+i);
  403. }
  404. pDC->SelectObject(hPenOld);
  405. }
  406. }
  407. void CStatusBar::DrawStatusText(CDC* pDC, const CRect& rect,
  408. LPCTSTR lpszText, UINT nStyle)
  409. {
  410. ASSERT_VALID(pDC);
  411. if (!(nStyle & SBPS_NOBORDERS))
  412. {
  413. // draw the borders
  414. COLORREF clrHilite;
  415. COLORREF clrShadow;
  416. if (nStyle & SBPS_POPOUT)
  417. {
  418. // reverse colors
  419. clrHilite = globalData.clrBtnShadow;
  420. clrShadow = globalData.clrBtnHilite;
  421. }
  422. else
  423. {
  424. // normal colors
  425. clrHilite = globalData.clrBtnHilite;
  426. clrShadow = globalData.clrBtnShadow;
  427. }
  428. pDC->Draw3dRect(rect, clrShadow, clrHilite);
  429. }
  430. // just support left justified text
  431. if (lpszText != NULL && !(nStyle & SBPS_DISABLED))
  432. {
  433. CRect rectText(rect);
  434. if (!(nStyle & SBPS_NOBORDERS)) // only adjust if there are borders
  435. rectText.InflateRect(-2*CX_BORDER, -CY_BORDER);
  436. else
  437. rectText.OffsetRect(0, -CY_BORDER); // baselines line up
  438. // background is already grey
  439. int nOldMode = pDC->SetBkMode(TRANSPARENT);
  440. COLORREF crTextColor = pDC->SetTextColor(globalData.clrBtnText);
  441. COLORREF crBkColor = pDC->SetBkColor(globalData.clrBtnFace);
  442. // align on bottom (since descent is more important than ascent)
  443. pDC->SetTextAlign(TA_LEFT | TA_BOTTOM);
  444. pDC->ExtTextOut(rectText.left, rectText.bottom,
  445. ETO_CLIPPED, &rectText, lpszText, lstrlen(lpszText), NULL);
  446. }
  447. }
  448. /////////////////////////////////////////////////////////////////////////////
  449. // CStatusBar message handlers
  450. BEGIN_MESSAGE_MAP(CStatusBar, CControlBar)
  451. //{{AFX_MSG_MAP(CStatusBar)
  452. ON_WM_NCHITTEST()
  453. ON_WM_SYSCOMMAND()
  454. ON_WM_SIZE()
  455. ON_MESSAGE(WM_SETFONT, OnSetFont)
  456. ON_MESSAGE(WM_GETFONT, OnGetFont)
  457. ON_MESSAGE(WM_SETTEXT, OnSetText)
  458. ON_MESSAGE(WM_GETTEXT, OnGetText)
  459. ON_MESSAGE(WM_GETTEXTLENGTH, OnGetTextLength)
  460. ON_MESSAGE(WM_SIZEPARENT, OnSizeParent)
  461. ON_WM_SETTINGCHANGE()
  462. //}}AFX_MSG_MAP
  463. END_MESSAGE_MAP()
  464. UINT CStatusBar::OnNcHitTest(CPoint point)
  465. {
  466. // hit test the size box - convert to HTCAPTION if so
  467. if (!m_bHideSizeBox && m_cxSizeBox != 0)
  468. {
  469. CRect rect;
  470. GetClientRect(rect);
  471. CalcInsideRect(rect, TRUE);
  472. int cxMax = min(m_cxSizeBox-1, rect.Height());
  473. rect.left = rect.right - cxMax;
  474. ClientToScreen(&rect);
  475. if (rect.PtInRect(point))
  476. return HTBOTTOMRIGHT;
  477. }
  478. return CControlBar::OnNcHitTest(point);
  479. }
  480. void CStatusBar::OnSysCommand(UINT nID, LPARAM lParam)
  481. {
  482. if (!m_bHideSizeBox && m_cxSizeBox != 0 && (nID & 0xFFF0) == SC_SIZE)
  483. {
  484. CFrameWnd* pFrameWnd = GetParentFrame();
  485. if (pFrameWnd != NULL)
  486. {
  487. pFrameWnd->SendMessage(WM_SYSCOMMAND, (WPARAM)nID, lParam);
  488. return;
  489. }
  490. }
  491. CControlBar::OnSysCommand(nID, lParam);
  492. }
  493. void CStatusBar::OnSize(UINT nType, int cx, int cy)
  494. {
  495. CControlBar::OnSize(nType, cx, cy);
  496. // adjust m_cxSizeBox if necessary
  497. OnSettingChange(0, NULL);
  498. // force repaint on resize (recalculate stretchy)
  499. Invalidate();
  500. }
  501. LRESULT CStatusBar::OnSetFont(WPARAM wParam, LPARAM)
  502. {
  503. m_hFont = (HFONT)wParam;
  504. ASSERT(m_hFont != NULL);
  505. return 0L;      // does not re-draw or invalidate - resize parent instead
  506. }
  507. LRESULT CStatusBar::OnGetFont(WPARAM, LPARAM)
  508. {
  509. return (LRESULT)(UINT)m_hFont;
  510. }
  511. LRESULT CStatusBar::OnSetText(WPARAM, LPARAM lParam)
  512. {
  513. int nIndex = CommandToIndex(0);
  514. if (nIndex < 0)
  515. return -1;
  516. return SetPaneText(nIndex, (LPCTSTR)lParam) ? 0 : -1;
  517. }
  518. LRESULT CStatusBar::OnGetText(WPARAM wParam, LPARAM lParam)
  519. {
  520. int nMaxLen = (int)wParam;
  521. if (nMaxLen == 0)
  522. return 0;       // nothing copied
  523. LPTSTR lpszDest = (LPTSTR)lParam;
  524. int nLen = 0;
  525. int nIndex = CommandToIndex(0); // use pane with ID zero
  526. if (nIndex >= 0)
  527. {
  528. AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
  529. nLen = pSBP->lpszText != NULL ? lstrlen(pSBP->lpszText) : 0;
  530. if (nLen > nMaxLen)
  531. nLen = nMaxLen - 1; // number of characters to copy (less term.)
  532. memcpy(lpszDest, pSBP->lpszText, nLen*sizeof(TCHAR));
  533. }
  534. lpszDest[nLen] = '';
  535. return nLen+1;      // number of bytes copied
  536. }
  537. LRESULT CStatusBar::OnGetTextLength(WPARAM, LPARAM)
  538. {
  539. int nLen = 0;
  540. int nIndex = CommandToIndex(0); // use pane with ID zero
  541. if (nIndex >= 0)
  542. {
  543. AFX_STATUSPANE* pSBP = _GetPanePtr(nIndex);
  544. if (pSBP->lpszText != NULL)
  545. nLen = lstrlen(pSBP->lpszText);
  546. }
  547. return nLen;
  548. }
  549. LRESULT CStatusBar::OnSizeParent(WPARAM wParam, LPARAM lParam)
  550. {
  551. AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam;
  552. if (lpLayout->hDWP != NULL)
  553. {
  554. // hide size box if parent is maximized
  555. CFrameWnd* pFrameWnd = GetParentFrame();
  556. if (pFrameWnd != NULL)
  557. {
  558. // the size box only appears when status bar is on the bottom
  559. //  of a non-maximized, sizeable frame window.
  560. CRect rectFrame;
  561. pFrameWnd->GetClientRect(rectFrame);
  562. BOOL bHideSizeBox = pFrameWnd->IsZoomed() ||
  563. !(pFrameWnd->GetStyle() & WS_THICKFRAME) ||
  564. rectFrame.bottom != lpLayout->rect.bottom ||
  565. rectFrame.right != lpLayout->rect.right;
  566. // update the size box hidden status, if changed
  567. if (bHideSizeBox != m_bHideSizeBox)
  568. {
  569. m_bHideSizeBox = bHideSizeBox;
  570. Invalidate();
  571. }
  572. }
  573. }
  574. return CControlBar::OnSizeParent(wParam, lParam);
  575. }
  576. /////////////////////////////////////////////////////////////////////////////
  577. // CStatusBar idle update through CStatusCmdUI class
  578. #define CStatusCmdUI COldStatusCmdUI
  579. class CStatusCmdUI : public CCmdUI      // class private to this file!
  580. {
  581. public: // re-implementations only
  582. virtual void Enable(BOOL bOn);
  583. virtual void SetCheck(int nCheck);
  584. virtual void SetText(LPCTSTR lpszText);
  585. };
  586. void CStatusCmdUI::Enable(BOOL bOn)
  587. {
  588. m_bEnableChanged = TRUE;
  589. CStatusBar* pStatusBar = (CStatusBar*)m_pOther;
  590. ASSERT(pStatusBar != NULL);
  591. ASSERT_KINDOF(CStatusBar, pStatusBar);
  592. ASSERT(m_nIndex < m_nIndexMax);
  593. UINT nNewStyle = pStatusBar->GetPaneStyle(m_nIndex) & ~SBPS_DISABLED;
  594. if (!bOn)
  595. nNewStyle |= SBPS_DISABLED;
  596. pStatusBar->SetPaneStyle(m_nIndex, nNewStyle);
  597. }
  598. void CStatusCmdUI::SetCheck(int nCheck) // "checking" will pop out the text
  599. {
  600. CStatusBar* pStatusBar = (CStatusBar*)m_pOther;
  601. ASSERT(pStatusBar != NULL);
  602. ASSERT_KINDOF(CStatusBar, pStatusBar);
  603. ASSERT(m_nIndex < m_nIndexMax);
  604. UINT nNewStyle = pStatusBar->GetPaneStyle(m_nIndex) & ~SBPS_POPOUT;
  605. if (nCheck != 0)
  606. nNewStyle |= SBPS_POPOUT;
  607. pStatusBar->SetPaneStyle(m_nIndex, nNewStyle);
  608. }
  609. void CStatusCmdUI::SetText(LPCTSTR lpszText)
  610. {
  611. ASSERT(m_pOther != NULL);
  612. ASSERT_KINDOF(CStatusBar, m_pOther);
  613. ASSERT(m_nIndex < m_nIndexMax);
  614. ((CStatusBar*)m_pOther)->SetPaneText(m_nIndex, lpszText);
  615. }
  616. void CStatusBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
  617. {
  618. CStatusCmdUI state;
  619. state.m_pOther = this;
  620. state.m_nIndexMax = (UINT)m_nCount;
  621. for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
  622. state.m_nIndex++)
  623. {
  624. state.m_nID = _GetPanePtr(state.m_nIndex)->nID;
  625. state.DoUpdate(pTarget, bDisableIfNoHndler);
  626. }
  627. // update the dialog controls added to the status bar
  628. UpdateDialogControls(pTarget, bDisableIfNoHndler);
  629. }
  630. /////////////////////////////////////////////////////////////////////////////
  631. // CStatusBar diagnostics
  632. #ifdef _DEBUG
  633. void CStatusBar::AssertValid() const
  634. {
  635. CControlBar::AssertValid();
  636. }
  637. void CStatusBar::Dump(CDumpContext& dc) const
  638. {
  639. CControlBar::Dump(dc);
  640. dc << "nm_hFont = " << (UINT)m_hFont;
  641. if (dc.GetDepth() > 0)
  642. {
  643. for (int i = 0; i < m_nCount; i++)
  644. {
  645. dc << "nstatus pane[" << i << "] = {";
  646. dc << "ntnID = " << _GetPanePtr(i)->nID;
  647. dc << "ntnStyle = " << _GetPanePtr(i)->nStyle;
  648. dc << "ntcxText = " << _GetPanePtr(i)->cxText;
  649. dc << "ntlpszText = " << _GetPanePtr(i)->lpszText;
  650. dc << "nt}";
  651. }
  652. }
  653. dc << "n";
  654. }
  655. #endif //_DEBUG
  656. #undef new
  657. #ifdef AFX_INIT_SEG
  658. #pragma code_seg(AFX_INIT_SEG)
  659. #endif
  660. IMPLEMENT_DYNAMIC(CStatusBar, CControlBar)