进度条

// cpp:

// ProgressWnd.cpp : implementation file
//
// Written by Chris Maunder (Chris.Maunder@cbr.clw.csiro.au)
// Copyright 1998.
//
// CProgressWnd is a drop-in popup progress window for use in
// programs that a time consuming. Check out the header file
// or the accompanying HTML doc file for details.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed by any means PROVIDING it is not sold for
// profit without the authors written consent, and providing that this
// notice and the authors name is included. If the source code in
// this file is used in any commercial application then an email to
// the me would be nice.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to your
// computer, causes your pet cat to fall ill, increases baldness or
// makes you car start emitting strange noises when you start it up.
//
// Expect bugs.
//
// Please use and enjoy. Please let me know of any bugs/mods/improvements
// that you have found/implemented and I will fix/incorporate them into this
// file.

#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

/
// 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_bCancelled    = FALSE;
    m_bSuccess      = FALSE;
}

CProgressWnd::~CProgressWnd()
{
    DestroyWindow();
}

BOOL CProgressWnd::Create(CWnd* pParent, LPCTSTR pszTitle, BOOL bSmooth /* = FALSE */)
{
    // 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
    m_bSuccess = CreateEx(WS_EX_DLGMODALFRAME,            // Extended style
                          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 (!m_bSuccess) return FALSE;

    // Now create the controls
 CRect TempRect(0,0,10,10);

    m_bSuccess = m_Text.Create(_T(""), WS_CHILD|WS_VISIBLE|SS_NOPREFIX|SS_LEFTNOWORDWRAP, TempRect, this, IDC_TEXT);
    if (!m_bSuccess) return FALSE;

    DWORD dwProgressStyle = WS_CHILD|WS_VISIBLE;
#ifdef PBS_SMOOTH   
    if (bSmooth)
       dwProgressStyle |= PBS_SMOOTH;
#endif
    m_bSuccess = m_wndProgress.Create(dwProgressStyle, TempRect, this, IDC_PROGRESS);
    if (!m_bSuccess) return FALSE;

    m_bSuccess = m_CancelButton.Create(_T("Cancel"), WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_PUSHBUTTON,
                                       TempRect, this, IDC_CANCEL);
    if (!m_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
    CenterWindow();
    Show();

    return TRUE;
}

void CProgressWnd::SetWindowSize(int nNumTextLines, int nWindowWidth /*=390*/)
{
    int nMargin = 10;

    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(_T(" Cancel "))+CSize(8,6);
        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, TextRect.bottom+nMargin,
                         CancelRect.left-nMargin, CancelRect.bottom);


    // 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 (m_bSuccess)
        UpdateWindow();
}

void CProgressWnd::Hide() 
{
    if (!m_bSuccess || !::IsWindow(GetSafeHwnd())) return;

    Clear();
    if (::GetWindowLong(GetSafeHwnd(), GWL_STYLE) & WS_VISIBLE)
    {
        ShowWindow(SW_HIDE);
        ModifyStyle(WS_VISIBLE, 0);
    }
}

void CProgressWnd::Show() 
{
    if (!m_bSuccess || !::IsWindow(GetSafeHwnd())) return;

    if ((::GetWindowLong(GetSafeHwnd(), GWL_STYLE) & WS_VISIBLE) == 0)
    {
        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 (!m_bSuccess) return;

    // To take advantage of the Extended Range Values we use the PBM_SETRANGE32
    // message intead of calling CProgressCtrl::SetRange directly. If this is
    // being compiled under something less than VC 5.0, the necessary defines
    // may not be available.
#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 (!m_bSuccess) return m_nPrevPos;
    return SetPos(m_nPrevPos + nPos); 
}

int CProgressWnd::StepIt()               
{
    if (!m_bSuccess) return m_nPrevPos;
    return SetPos(m_nPrevPos + m_nStep);
}

int CProgressWnd::SetStep(int nStep)
{
    int nOldStep = m_nStep;
    m_nStep = nStep;
    if (!m_bSuccess) 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 (!m_bSuccess) return m_nPrevPos;

    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);
        SetWindowText(strTitle);
    }
    return m_wndProgress.SetPos(nPos);       
}

void CProgressWnd::SetText(LPCTSTR fmt, ...)
{
    if (!m_bSuccess) 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;
}

// h:

// ProgressWnd.h : header file
//
// Written by Chris Maunder (Chris.Maunder@cbr.clw.csiro.au)
// Copyright 1998.
//
// CProgressWnd is a drop-in popup progress window for use in
// programs that a time consuming. Check out the accompanying HTML
// doc file for details.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed by any means PROVIDING it is not sold for
// profit without the authors written consent, and providing that this
// notice and the authors name is included. If the source code in
// this file is used in any commercial application then an email to
// me would be nice.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to your
// computer, causes your pet cat to fall ill, increases baldness or
// makes you car start emitting strange noises when you start it up.
//
// Expect bugs.
//
// Please use and enjoy. Please let me know of any bugs/mods/improvements
// that you have found/implemented and I will fix/incorporate them into this
// file.


#ifndef _INCLUDE_PROGRESSWND_H
#define _INCLUDE_PROGRESSWND_H

/
// CProgressWnd window

class CProgressWnd : public CWnd
{
// Construction/Destruction
public:
    CProgressWnd();
    CProgressWnd(CWnd* pParent, LPCTSTR pszTitle, BOOL bSmooth = FALSE);
    virtual ~CProgressWnd();

    BOOL Create(CWnd* pParent, LPCTSTR pszTitle, BOOL bSmooth = FALSE);

protected:
    void CommonConstruct();

// Operations
public:
    void SetRange(int nLower, int nUpper, int nStep = 1);
                                                    // Set range and step size
    int OffsetPos(int nPos);                        // Same as CProgressCtrl
    int StepIt();                                   //    "
    int SetStep(int nStep);                         //    "
    int SetPos(int nPos);                           //    "

    void SetText(LPCTSTR fmt, ...);                 // Set text in text area

    void Clear();                                   // Clear text, reset bar
    void Hide();                                    // Hide window
    void Show();                                    // Show window

    BOOL Success() { return m_bSuccess; }           // Was the creation successful?
    BOOL Cancelled() {return m_bCancelled == true;} // Was "Cancel" hit?

 void SetWindowSize(int nNumTextLines, int nWindowWidth = 390);

   
// Implementation
protected:
    BOOL m_bSuccess;
    bool m_bCancelled;
    int  m_nPrevPos, m_nPrevPercent;
    int  m_nStep;
    int  m_nMaxValue, m_nMinValue;
    int  m_nNumTextLines;

    CStatic       m_Text;
    CProgressCtrl m_wndProgress;
    CButton       m_CancelButton;
    CString       m_strTitle;
    CFont         m_font;

// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CProgressWnd)
    //}}AFX_VIRTUAL

// Generated message map functions
protected:
    //{{AFX_MSG(CProgressWnd)
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    //}}AFX_MSG
    afx_msg void OnCancel();
    DECLARE_MESSAGE_MAP()
};


#endif
/

/使用:

#include "ProgressWnd.h"

void CMainFrame::OnTestSmoothbar()
{
 CProgressWnd wndProgress(this, "Progress", TRUE);

 wndProgress.SetRange(0,5000);
 wndProgress.SetText("This is a progress window.../n/n"
      "Try dragging it around or hitting Cancel.");

 for (int i = 0; i < 5000; i++) {
  wndProgress.StepIt();
  PeekAndPump();

  if (wndProgress.Cancelled()) {
   MessageBox("Progress Cancelled");
   break;
  }
 } 
}

void CMainFrame::OnTestStdbar()
{
 CProgressWnd wndProgress(this, "Progress");

 wndProgress.SetRange(0,5000);
 wndProgress.SetText("This is a progress window.../n/n"     
      "Try dragging it around or hitting Cancel.");

 for (int i = 0; i < 5000; i++) {
  wndProgress.StepIt();
  PeekAndPump();

  if (wndProgress.Cancelled()) {
   MessageBox("Progress Cancelled");
   break;
  }
 } 
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值