| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- #include "stdafx.h"
- #include "ProgressWnd.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- #define IDC_CANCEL 10
- #define IDC_TEXT 11
- #define IDC_PROGRESS 12
- LPCTSTR szSection = _T("Settings");
- LPCTSTR szEntryX = _T("X");
- LPCTSTR szEntryY = _T("Y");
- #define _CRT_NON_CONFORMING_SWPRINTFS 1
- /////////////////////////////////////////////////////////////////////////////
- // CProgressWnd
- CProgressWnd::CProgressWnd()
- {
- CommonConstruct();
- }
- CProgressWnd::CProgressWnd(CWnd* pParent, LPCTSTR pszTitle, BOOL bSmooth /* = FALSE */)
- {
- CommonConstruct();
- m_strTitle = pszTitle;
- Create(pParent, pszTitle, bSmooth);
- }
- void CProgressWnd::CommonConstruct()
- {
- m_nNumTextLines = 4;
- m_nPrevPos = 0;
- m_nPrevPercent = 0;
- m_nStep = 1;
- m_nMinValue = 0;
- m_nMaxValue = 100;
- m_strTitle = _T("Progress");
- m_strCancelLabel = _T(" Cancel ");
- m_bCancelled = FALSE;
- m_bModal = FALSE;
- m_bPersistantPosition = TRUE; // saves and restores position automatically
- }
- CProgressWnd::~CProgressWnd()
- {
- DestroyWindow();
- }
- BOOL CProgressWnd::Create(CWnd* pParent, LPCTSTR pszTitle, BOOL bSmooth /* = FALSE */)
- {
- BOOL bSuccess;
- m_strTitle = pszTitle;
- // Register window class
- CString csClassName = AfxRegisterWndClass(CS_OWNDC|CS_HREDRAW|CS_VREDRAW,
- ::LoadCursor(NULL, IDC_APPSTARTING),
- CBrush(::GetSysColor(COLOR_BTNFACE)));
- // Get the system window message font for use in the cancel button and text area
- NONCLIENTMETRICS ncm;
- ncm.cbSize = sizeof(NONCLIENTMETRICS);
- VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0));
- m_font.CreateFontIndirect(&(ncm.lfMessageFont));
- // If no parent supplied then try and get a pointer to it anyway
- if (!pParent)
- pParent = AfxGetMainWnd();
- // Create popup window
- //bSuccess = CreateEx(WS_EX_DLGMODALFRAME|WS_EX_TOPMOST, // Extended style
- bSuccess = CreateEx(WS_EX_DLGMODALFRAME,
- csClassName, // Classname
- pszTitle, // Title
- WS_POPUP|WS_BORDER|WS_CAPTION, // style
- 0,0, // position - updated soon.
- 390,130, // Size - updated soon
- pParent->GetSafeHwnd(), // handle to parent
- 0, // No menu
- NULL);
- if (!bSuccess) return FALSE;
- // Now create the controls
- CRect TempRect(0,0,10,10);
- bSuccess = m_Text.Create(_T(""), WS_CHILD|WS_VISIBLE|SS_NOPREFIX|SS_LEFTNOWORDWRAP,
- TempRect, this, IDC_TEXT);
- if (!bSuccess) return FALSE;
- DWORD dwProgressStyle = WS_CHILD|WS_VISIBLE;
- #ifdef PBS_SMOOTH
- if (bSmooth)
- dwProgressStyle |= PBS_SMOOTH;
- #endif
- bSuccess = m_wndProgress.Create(dwProgressStyle,TempRect, this, IDC_PROGRESS);
- if (!bSuccess) return FALSE;
- bSuccess = m_CancelButton.Create(m_strCancelLabel,
- WS_CHILD|WS_VISIBLE|WS_TABSTOP| BS_PUSHBUTTON,
- TempRect, this, IDC_CANCEL);
- if (!bSuccess) return FALSE;
- m_CancelButton.SetFont(&m_font, TRUE);
- m_Text.SetFont(&m_font, TRUE);
- // Resize the whole thing according to the number of text lines, desired window
- // width and current font.
- SetWindowSize(m_nNumTextLines, 390);
- // Center and show window
- if (m_bPersistantPosition)
- GetPreviousSettings();
- else
- CenterWindow();
- Show();
- return TRUE;
- }
- BOOL CProgressWnd::GoModal(LPCTSTR pszTitle /*=_T("Progress")"*/, BOOL bSmooth /*=FALSE*/)
- {
- CWnd *pMainWnd = AfxGetMainWnd();
- if (!::IsWindow(m_hWnd) && !Create(pMainWnd, pszTitle, bSmooth))
- return FALSE;
- // Disable main window
- if (pMainWnd)
- pMainWnd->EnableWindow(FALSE);
- // Re-enable this window
- EnableWindow(TRUE);
- m_bModal = TRUE;
- return TRUE;
- }
-
- void CProgressWnd::SetWindowSize(int nNumTextLines, int nWindowWidth /*=390*/)
- {
- int nMargin = 10;
- CSize EdgeSize(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE));
- CRect TextRect, CancelRect, ProgressRect;
- CSize CancelSize;
- // Set up a default size for the text area in case things go wrong
- TextRect.SetRect(nMargin,nMargin, nWindowWidth-2*nMargin, 100+2*nMargin);
- // Get DrawText to tell us how tall the text area will be (while we're at
- // it, we'll see how big the word "Cancel" is)
- CDC* pDC = GetDC();
- if (pDC) {
- CFont* pOldFont = pDC->SelectObject(&m_font);
- CString str = _T("M");
- for (int i = 0; i < nNumTextLines-1; i++) str += _T("\nM");
- pDC->DrawText(str, TextRect, DT_CALCRECT|DT_NOCLIP|DT_NOPREFIX);
- TextRect.right = TextRect.left + nWindowWidth;
- CancelSize = pDC->GetTextExtent(m_strCancelLabel + _T(" ")) +
- CSize(EdgeSize.cx*4, EdgeSize.cy*3);
- pDC->SelectObject(pOldFont);
- ReleaseDC(pDC);
- }
-
- // Work out how big (and where) the cancel button should be
- CancelRect.SetRect(TextRect.right-CancelSize.cx, TextRect.bottom+nMargin,
- TextRect.right, TextRect.bottom+nMargin + CancelSize.cy);
- // Work out how big (and where) the progress control should be
- ProgressRect.SetRect(TextRect.left, CancelRect.top + EdgeSize.cy,
- CancelRect.left-nMargin, CancelRect.bottom - EdgeSize.cy);
- // Resize the main window to fit the controls
- CSize ClientSize(nMargin + TextRect.Width() + nMargin,
- nMargin + TextRect.Height() + nMargin + CancelRect.Height() + nMargin);
- CRect WndRect, ClientRect;
- GetWindowRect(WndRect); GetClientRect(ClientRect);
- WndRect.right = WndRect.left + WndRect.Width()-ClientRect.Width()+ClientSize.cx;
- WndRect.bottom = WndRect.top + WndRect.Height()-ClientRect.Height()+ClientSize.cy;
- MoveWindow(WndRect);
- // Now reposition the controls...
- m_wndProgress.MoveWindow(ProgressRect);
- m_CancelButton.MoveWindow(CancelRect);
- m_Text.MoveWindow(TextRect);
- }
- void CProgressWnd::Clear()
- {
- SetText(_T(""));
- SetPos(0);
- m_bCancelled = FALSE;
- m_nPrevPos = 0;
- if (::IsWindow(GetSafeHwnd()))
- UpdateWindow();
- }
- void CProgressWnd::Hide()
- {
- if (!::IsWindow(GetSafeHwnd()))
- return;
- if (IsWindowVisible())
- {
- ShowWindow(SW_HIDE);
- ModifyStyle(WS_VISIBLE, 0);
- }
- }
- void CProgressWnd::Show()
- {
- if (!::IsWindow(GetSafeHwnd()))
- return;
- if (!IsWindowVisible())
- {
- ModifyStyle(0, WS_VISIBLE);
- ShowWindow(SW_SHOWNA);
- RedrawWindow(NULL,NULL,RDW_ERASE|RDW_FRAME|RDW_INVALIDATE);
- }
- }
- void CProgressWnd::SetRange(int nLower, int nUpper, int nStep /* = 1 */)
- {
- if (!::IsWindow(GetSafeHwnd()))
- return;
- #ifdef PBM_SETRANGE32
- ASSERT(-0x7FFFFFFF <= nLower && nLower <= 0x7FFFFFFF);
- ASSERT(-0x7FFFFFFF <= nUpper && nUpper <= 0x7FFFFFFF);
- m_wndProgress.SendMessage(PBM_SETRANGE32, (WPARAM) nLower, (LPARAM) nUpper);
- #else
- ASSERT(0 <= nLower && nLower <= 65535);
- ASSERT(0 <= nUpper && nUpper <= 65535);
- m_wndProgress.SetRange(nLower, nUpper);
- #endif
- m_nMaxValue = nUpper;
- m_nMinValue = nLower;
- m_nStep = nStep;
- m_wndProgress.SetStep(nStep);
- }
- int CProgressWnd::OffsetPos(int nPos)
- {
- if (!::IsWindow(GetSafeHwnd()))
- return m_nPrevPos;
- Show();
- return SetPos(m_nPrevPos + nPos);
- }
- int CProgressWnd::StepIt()
- {
- if (!::IsWindow(GetSafeHwnd()))
- return m_nPrevPos;
- Show();
- return SetPos(m_nPrevPos + m_nStep);
- }
- int CProgressWnd::SetStep(int nStep)
- {
- int nOldStep = m_nStep;
- m_nStep = nStep;
- if (!::IsWindow(GetSafeHwnd()))
- return nOldStep;
- return m_wndProgress.SetStep(nStep);
- }
- int CProgressWnd::SetPos(int nPos)
- {
- #ifdef PBM_SETRANGE32
- ASSERT(-0x7FFFFFFF <= nPos && nPos <= 0x7FFFFFFF);
- #else
- ASSERT(0 <= nPos && nPos <= 65535);
- #endif
- if (!::IsWindow(GetSafeHwnd()))
- return m_nPrevPos;
- Show();
- CString strTitle;
- // int nPercentage;
-
- m_nPrevPos = nPos;
- // if (m_nMaxValue > m_nMinValue)
- // nPercentage = (nPos*100)/(m_nMaxValue - m_nMinValue);
- // else
- // nPercentage = 0;
- // if (nPercentage != m_nPrevPercent)
- // {
- // m_nPrevPercent = nPercentage;
- // strTitle.Format(_T("%s [%d%%]"),m_strTitle,nPercentage);
- strTitle.Format(_T("%s"),m_strTitle);
- SetWindowText(strTitle);
- // }
- return m_wndProgress.SetPos(nPos);
- }
- void CProgressWnd::SetText(LPCTSTR fmt, ...)
- {
- if (!::IsWindow(GetSafeHwnd()))
- return;
- va_list args;
- TCHAR buffer[512];
- va_start(args, fmt);
- _vstprintf(buffer, fmt, args);
- va_end(args);
- m_Text.SetWindowText(buffer);
- }
- BEGIN_MESSAGE_MAP(CProgressWnd, CWnd)
- //{{AFX_MSG_MAP(CProgressWnd)
- ON_WM_ERASEBKGND()
- //}}AFX_MSG_MAP
- ON_BN_CLICKED(IDC_CANCEL, OnCancel)
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CProgressWnd message handlers
- BOOL CProgressWnd::OnEraseBkgnd(CDC* pDC)
- {
- // Fill background with Catchment background colour
- CBrush backBrush(GetSysColor(COLOR_BTNFACE));
- CBrush* pOldBrush = pDC->SelectObject(&backBrush);
- CRect rect;
- pDC->GetClipBox(&rect); // Erase the area needed
- pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
- pDC->SelectObject(pOldBrush);
- return TRUE;
- }
- void CProgressWnd::OnCancel()
- {
- m_bCancelled = TRUE;
- Hide();
- if (m_bModal)
- SendMessage(WM_CLOSE);
- CWnd *pWnd = AfxGetMainWnd();
- if (pWnd && ::IsWindow(pWnd->m_hWnd))
- pWnd->SetForegroundWindow();
- }
- BOOL CProgressWnd::DestroyWindow()
- {
- if (m_bPersistantPosition)
- SaveCurrentSettings();
- if (m_bModal)
- {
- m_bModal = FALSE;
- CWnd *pMainWnd = AfxGetMainWnd();
- if (pMainWnd)
- pMainWnd->EnableWindow(TRUE);
- }
-
- return CWnd::DestroyWindow();
- }
- void CProgressWnd::PeekAndPump(BOOL bCancelOnESCkey /*= TRUE*/)
- {
- if (m_bModal && ::GetFocus() != m_hWnd)
- SetFocus();
- MSG msg;
- while (!m_bCancelled && ::PeekMessage(&msg, NULL,0,0,PM_NOREMOVE))
- {
- if (bCancelOnESCkey && (msg.message == WM_CHAR) && (msg.wParam == VK_ESCAPE))
- OnCancel();
- // Cancel button disabled if modal, so we fake it.
- if (m_bModal && (msg.message == WM_LBUTTONUP))
- {
- CRect rect;
- m_CancelButton.GetWindowRect(rect);
- if (rect.PtInRect(msg.pt))
- OnCancel();
- }
-
- if (!AfxGetApp()->PumpMessage())
- {
- ::PostQuitMessage(0);
- return;
- }
- }
- }
- // Retores the previous window size from the registry
- void CProgressWnd::GetPreviousSettings()
- {
- int x = AfxGetApp()->GetProfileInt(szSection, szEntryX, -1);
- int y = AfxGetApp()->GetProfileInt(szSection, szEntryY, -1);
- if (x >= 0 && x < GetSystemMetrics(SM_CXSCREEN) &&
- y >= 0 && y < GetSystemMetrics(SM_CYSCREEN))
- {
- SetWindowPos(NULL, x,y, 0,0, SWP_NOSIZE|SWP_NOZORDER);
- }
- else
- CenterWindow();
- }
- // Saves the current window position registry
- void CProgressWnd::SaveCurrentSettings()
- {
- if (!IsWindow(m_hWnd))
- return;
- CRect rect;
- GetWindowRect(rect);
- AfxGetApp()->WriteProfileInt(szSection, szEntryX, rect.left);
- AfxGetApp()->WriteProfileInt(szSection, szEntryY, rect.top);
- }
- void CProgressWnd::HideCancel()
- {
- m_CancelButton.ShowWindow(SW_HIDE);
- UpdateData(FALSE);
- }
- void CProgressWnd::ShowCancel()
- {
- m_CancelButton.ShowWindow(SW_SHOW);
- UpdateData(FALSE);
- }
- void CProgressWnd::SetTitleText(CString csTitle)
- {
- m_strTitle = csTitle;
-
- CString title;
- title.Format(_T("%s"),m_strTitle);
-
- SetWindowText(title);
- }
|