231 lines
5.3 KiB
C++
231 lines
5.3 KiB
C++
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Crytek Engine Source File.
|
|
// Copyright (C), Crytek Studios, 2002.
|
|
// -------------------------------------------------------------------------
|
|
// File name: waitprogress.cpp
|
|
// Version: v1.00
|
|
// Created: 10/5/2002 by Timur.
|
|
// Compilers: Visual Studio.NET
|
|
// Description:
|
|
// -------------------------------------------------------------------------
|
|
// History:
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "StdAfx.h"
|
|
#include "waitprogress.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
#define new DEBUG_NEW
|
|
static char BASED_CODE THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
bool CWaitProgress::m_bInProgressNow = false;
|
|
bool CWaitProgress::m_bCancel = false;
|
|
|
|
CWaitProgress::CWaitProgress(UINT nIDText, bool bStart)
|
|
: m_bStarted(false)
|
|
, m_hwndProgress(NULL)
|
|
{
|
|
char szText[1024];
|
|
VERIFY(LoadString( AfxGetInstanceHandle(),AFX_IDS_IDLEMESSAGE,szText,sizeof(szText) ));
|
|
|
|
m_bCancel = false;
|
|
|
|
m_strText = szText;
|
|
m_bIgnore = false;
|
|
if (bStart)
|
|
Start();
|
|
}
|
|
|
|
CWaitProgress::CWaitProgress(LPCTSTR lpszText, bool bStart)
|
|
: m_strText(lpszText)
|
|
, m_bStarted(false)
|
|
, m_hwndProgress(NULL)
|
|
{
|
|
m_bCancel = false;
|
|
m_bIgnore = false;
|
|
if (bStart)
|
|
Start();
|
|
}
|
|
|
|
CWaitProgress::~CWaitProgress()
|
|
{
|
|
if (m_bStarted)
|
|
Stop();
|
|
}
|
|
|
|
void CWaitProgress::Start()
|
|
{
|
|
if (m_bStarted)
|
|
Stop();
|
|
|
|
if (m_bInProgressNow)
|
|
{
|
|
// Do not affect previously started progress bar.
|
|
m_bIgnore = true;
|
|
m_bStarted = false;
|
|
return;
|
|
}
|
|
|
|
// display text in the status bar
|
|
GetIEditor()->SetStatusText( m_strText );
|
|
|
|
// switch on wait cursor
|
|
::AfxGetApp()->BeginWaitCursor();
|
|
|
|
m_bStarted = true;
|
|
m_percent = 0;
|
|
}
|
|
|
|
void CWaitProgress::Stop()
|
|
{
|
|
if (!m_bStarted)
|
|
return;
|
|
|
|
if (m_hwndProgress)
|
|
{
|
|
// clean up and destroy progress bar
|
|
CStatusBar* pStatusBar = DYNAMIC_DOWNCAST(CStatusBar, CWnd::FromHandle(::GetParent(m_hwndProgress)));
|
|
ASSERT_VALID(pStatusBar);
|
|
|
|
::DestroyWindow(m_hwndProgress);
|
|
m_hwndProgress = NULL;
|
|
|
|
m_cancelButton.DestroyWindow();
|
|
|
|
// remove progress bar pane
|
|
int anPart[32];
|
|
int nParts = pStatusBar->GetStatusBarCtrl().GetParts(31, anPart);
|
|
nParts--;
|
|
pStatusBar->GetStatusBarCtrl().SetParts(nParts, anPart+1);
|
|
}
|
|
|
|
// switch back to standard text in the status bar
|
|
char szIdle[1024];
|
|
LoadString( AfxGetInstanceHandle(),AFX_IDS_IDLEMESSAGE,szIdle,sizeof(szIdle) );
|
|
GetIEditor()->SetStatusText( szIdle );
|
|
|
|
// switch off wait cursor
|
|
::AfxGetApp()->EndWaitCursor();
|
|
|
|
m_bInProgressNow = false;
|
|
|
|
m_bStarted = false;
|
|
}
|
|
|
|
bool CWaitProgress::Step(int nPercentage)
|
|
{
|
|
if (m_bIgnore)
|
|
return true;
|
|
|
|
if (m_bCancel)
|
|
return false;
|
|
|
|
if (!m_bStarted)
|
|
Start();
|
|
|
|
if (m_percent == nPercentage)
|
|
return true;
|
|
|
|
m_percent = nPercentage;
|
|
|
|
::AfxGetApp()->RestoreWaitCursor();
|
|
|
|
if (nPercentage >= 0)
|
|
{
|
|
ASSERT(nPercentage <= 100);
|
|
// create or update a progress control in the status bar
|
|
if (m_hwndProgress == NULL)
|
|
CreateProgressControl();
|
|
|
|
if (m_hwndProgress)
|
|
::SendMessage(m_hwndProgress, PBM_SETPOS, (WPARAM)nPercentage, 0);
|
|
}
|
|
|
|
// Use the oportunity to process windows messages here.
|
|
MSG msg;
|
|
while( FALSE != ::PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )
|
|
{
|
|
::TranslateMessage( &msg );
|
|
::DispatchMessage( &msg );
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void CWaitProgress::SetText(LPCTSTR lpszText)
|
|
{
|
|
if (m_bIgnore)
|
|
return;
|
|
m_strText = lpszText;
|
|
GetIEditor()->SetStatusText( m_strText );
|
|
}
|
|
|
|
void CWaitProgress::CreateProgressControl()
|
|
{
|
|
ASSERT(m_hwndProgress == NULL);
|
|
|
|
// find status bar
|
|
CWnd* pMainWnd = ::AfxGetMainWnd();
|
|
if (pMainWnd == NULL)
|
|
return;
|
|
CStatusBar* pStatusBar = DYNAMIC_DOWNCAST(CStatusBar,
|
|
pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR, TRUE));
|
|
if (pStatusBar == NULL || pStatusBar->m_hWnd == NULL)
|
|
return;
|
|
|
|
CRect rc; // this will be the location for the progress bar pane
|
|
pStatusBar->GetItemRect(0, rc);
|
|
if (!m_strText.IsEmpty())
|
|
{
|
|
// adjust so that the text in the leftmost pane will not be covered
|
|
CClientDC dc(pStatusBar);
|
|
dc.SelectObject(pStatusBar->GetFont());
|
|
CSize sz = dc.GetTextExtent(m_strText);
|
|
TEXTMETRIC tm;
|
|
dc.GetTextMetrics(&tm);
|
|
rc.left += sz.cx + 2*tm.tmAveCharWidth;
|
|
}
|
|
int cx = rc.Width();
|
|
if (cx < 20)
|
|
{
|
|
// no sense in displaying such a small progress bar
|
|
//assert("ProgressDisplay would be too small\n");
|
|
return;
|
|
}
|
|
/*
|
|
else if (cx > 500)
|
|
{
|
|
// arbitrarily limiting progress bar width to 500 pixel
|
|
cx = 500;
|
|
rc.left = rc.right - cx;
|
|
}
|
|
*/
|
|
// Arbitary add 50 pixel to left of text.
|
|
rc.left += 50;
|
|
|
|
// add a pane between the text and the currently leftmost pane
|
|
int anPart[32];
|
|
int nParts = pStatusBar->GetStatusBarCtrl().GetParts(31, anPart+1);
|
|
anPart[0] = rc.left;
|
|
nParts++;
|
|
pStatusBar->GetStatusBarCtrl().SetParts(nParts, anPart);
|
|
pStatusBar->GetStatusBarCtrl().GetRect(1, rc);
|
|
|
|
int btnWidth = 60;
|
|
|
|
// create progress bar control
|
|
m_hwndProgress = ::CreateWindow(PROGRESS_CLASS, "",
|
|
WS_CHILD | WS_VISIBLE, rc.left+btnWidth, rc.top, rc.Width()-btnWidth, rc.Height(),
|
|
pStatusBar->m_hWnd, (HMENU)1, AfxGetInstanceHandle(), NULL);
|
|
|
|
// Specify Owner to be main window, to recieve cancel event.
|
|
m_cancelButton.Create( "Cancel",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(rc.left,rc.top,rc.left+btnWidth-1,rc.bottom),AfxGetMainWnd(),(UINT)ID_PROGRESSBAR_CANCEL );
|
|
m_cancelButton.SetParent( pStatusBar );
|
|
|
|
pStatusBar->UpdateWindow();
|
|
m_bInProgressNow = true;
|
|
}
|