BOOL CProgressBar::Resize() { if (!IsWindow(GetSafeHwnd())) return FALSE; CStatusBar *pStatusBar = GetStatusBar(); if (!pStatusBar) return FALSE; // Redraw the window text if (IsWindowVisible()) { pStatusBar->SetPaneText(m_nPane, m_strMessage); pStatusBar->UpdateWindow(); } // Calculate how much space the text takes up CClientDC dc(pStatusBar); CFont *pOldFont = dc.SelectObject(pStatusBar->GetFont()); CSize size = dc.GetTextExtent(m_strMessage); // Length of text int margin = dc.GetTextExtent(_T(" ")).cx * 2; // Text margin dc.SelectObject(pOldFont); // Now calculate the rectangle in which we will draw the progress bar CRect rc; pStatusBar->GetItemRect(m_nPane, rc); // Position left of progress bar after text and right of progress bar // to requested percentage of status bar pane if (!m_strMessage.IsEmpty()) rc.left += (size.cx + 2*margin); rc.right -= (rc.right - rc.left) * (100 - m_nSize) / 100; if (rc.right < rc.left) rc.right = rc.left; // Leave a litle vertical margin (10%) between the top and bottom of the bar int Height = rc.bottom - rc.top; rc.bottom -= Height/10; rc.top += Height/10; // If the window size has changed, resize the window if (rc != m_Rect) { MoveWindow(&rc); m_Rect = rc; } return TRUE; }
// Create the CProgressCtrl as a child of the status bar positioned // over the first pane, extending "nSize" percentage across pane. // Sets the range to be 0 to MaxValue, with a step of 1. BOOL CProgressBar::Create(LPCTSTR strMessage, int nSize /*=100*/, int MaxValue /*=100*/, BOOL bSmooth /*=FALSE*/, int nPane /*=0*/) { BOOL bSuccess = FALSE; CStatusBar *pStatusBar = GetStatusBar(); if (!pStatusBar) return FALSE; DWORD dwStyle = WS_CHILD|WS_VISIBLE; #ifdef PBS_SMOOTH if (bSmooth) dwStyle |= PBS_SMOOTH; #endif // Until m_nPane is initialized, Resize() must not be called. But it can be called (which // happens in multi-threaded programs) in CProgressBar::OnEraseBkgnd after the control is // created in CProgressBar::Create. m_strMessage = strMessage; m_nSize = nSize; m_nPane = nPane; m_strPrevText = pStatusBar->GetPaneText(m_nPane); // Get CRect coordinates for requested status bar pane CRect PaneRect; pStatusBar->GetItemRect(nPane, &PaneRect); // Create the progress bar bSuccess = CProgressCtrl::Create(dwStyle, PaneRect, pStatusBar, 1); ASSERT(bSuccess); if (!bSuccess) return FALSE; // Set range and step SetRange(0, MaxValue); SetStep(1); m_strMessage = strMessage; m_nSize = nSize; m_nPane = nPane; m_strPrevText = pStatusBar->GetPaneText(m_nPane); // Resize the control to its desired width Resize(); return TRUE; }
// Create the CProgressCtrl as a child of the status bar positioned // over the first pane, extending "nSize" percentage across pane. // Sets the range to be 0 to MaxValue, with a step of 1. BOOL CProgressBar::Create(LPCTSTR strMessage, int nSize /*=100*/, int MaxValue /*=100*/, BOOL bSmooth /*=FALSE*/, int nPane /*=0*/) { BOOL bSuccess = FALSE; CStatusBar *pStatusBar = GetStatusBar(); if (!pStatusBar) return FALSE; DWORD dwStyle = WS_CHILD|WS_VISIBLE; #ifdef PBS_SMOOTH if (bSmooth) dwStyle |= PBS_SMOOTH; #endif // Get CRect coordinates for requested status bar pane CRect PaneRect; pStatusBar->GetItemRect(nPane, &PaneRect); // Create the progress bar bSuccess = CProgressCtrl::Create(dwStyle, PaneRect, pStatusBar, 1); ASSERT(bSuccess); if (!bSuccess) return FALSE; // Set range and step SetRange(0, MaxValue); SetStep(1); m_strMessage = strMessage; m_nSize = nSize; m_nPane = nPane; m_strPrevText = pStatusBar->GetPaneText(m_nPane); // Resize the control to its desired width Resize(); return TRUE; }