windows-nt/Source/XPSP1/NT/printscan/ui/wiaacmgr/postplug/progressinfo.h
2020-09-26 16:20:57 +08:00

182 lines
6.2 KiB
C++

#ifndef __ProgressInfo_h__
#define __ProgressInfo_h__
#include <windows.h>
#include "stdstring.h"
#include "httpfilepost.h"
enum TRANSFER_STATUS
{
TRANSFER_FATAL_ERROR = -1, // transfer is aborting due to unrecoverable error
TRANSFER_OK, // currently not used
TRANSFER_SKIPPING_FILE, // file transfer failed, non-fatal, continuing with remaining files
TRANSFER_SESSION_INITIATE, // beginning batch file transfer (only agragate vars are valid)
TRANSFER_FILE_INITATE, // starting the transfer of a file (current file vars are now valid)
TRANSFER_FILE_TRANSFERING, // all vars reflect current progress
TRANSFER_FILE_COMPLETE, // file has completed transfering
TRANSFER_SESSION_COMPLETE, // session compelete, last callback that will be sent unless
// there is an unrecoverable error in which case
// TRANSFER_FATAL_ERROR will be the final message
};
#include <MMSystem.h> // Windows Multimedia Support (for timeGetTime())
class CProgressInfo;
class CWebCabPublisher;
typedef UINT (*CS_PROGRESS_PROC)(CProgressInfo*);
#define STATUS_BUFFSIZE 1024
class CProgressInfo
{
public:
// while the upload/download thread is updating the variables,
// critsec will be locked. users of this class must lock
// this critsec before accessing the variables, or they
// may get only partially updated values
CRITICAL_SECTION critsec;
DWORD dwStatusCallback; // status from WinInet
char szStatusString[STATUS_BUFFSIZE]; //buffer for status message
TRANSFER_STATUS dwStatus;
DWORD dwErrorCount; // count of errors encountered this transfer
CStdString strFilename; // full path of the currently transfering file
CStdString strTitle; // friendly (user specified) title of the file
DWORD dwTotalFiles; // total count of files to transfer
DWORD dwDoneFiles; // count of files done
DWORD dwTotalBytes; // total bytes to transfer
DWORD dwTotalDone; // bytes transfered
DWORD dwCurrentBytes; // total bytes to transfer for this file
DWORD dwCurrentDone; // bytes transfered for this file
DWORD dwStartMS; // time started (milliseconds)
DWORD dwTransferRate; // (estimated) transfer rate
time_t timeElapsed; // time elapsed
time_t timeRemaining; // (estimated) time remaining
DWORD dwOverallPercent; // overall percent done
DWORD dwCurrentPercent; // percent done for this file
// these two are used for updating a progress ctrl
DWORD dwOverallPos; // (estimated) overall progress (range 0-ffffffff)
DWORD dwCurrentPos; // (estimated) current progress (range 0-ffffffff)
CS_PROGRESS_PROC pfnProgress; // pointer to callback function
LPARAM lParam; // lParam (caller defined value passed back to caller)
// caller returns 0 to continue, non-zero to abort (value will be reason for abort)
// if caller didn't specify a callback, then assume continue (0)
void NotifyCaller()
{
if(pfnProgress && (*pfnProgress)(this))
{
ThrowUploaderException(0);
}
}
void StartSession(DWORD dwCountFiles, DWORD dwCountBytes)
{
InitializeCriticalSection(&critsec);
EnterCriticalSection(&critsec);
{ // critical section
dwStatus = TRANSFER_SESSION_INITIATE;
dwErrorCount = 0;
strFilename = "";
dwTotalFiles = dwCountFiles;
dwDoneFiles = 0;
dwTotalDone = 0;
dwTotalBytes = dwCountBytes;
dwTotalDone = 0;
dwCurrentBytes = 0;
dwCurrentDone = 0;
dwStartMS = timeGetTime();
dwTransferRate = 0;
timeElapsed = 0;
timeRemaining = 0;
dwOverallPercent = 0;
dwCurrentPercent = 0;
dwOverallPos = 0;
dwCurrentPos = 0;
}
LeaveCriticalSection(&critsec);
NotifyCaller();
}
void EndSession(UINT uSuccess)
{
EnterCriticalSection(&critsec);
{
dwStatus = uSuccess ? TRANSFER_SESSION_COMPLETE : TRANSFER_FATAL_ERROR;
}
LeaveCriticalSection(&critsec);
//DeleteCriticalSection(&critsec);
NotifyCaller();
}
void StartFile(const CStdString& name, const CStdString& title, DWORD size)
{
EnterCriticalSection(&critsec);
{ // critical section
dwStatus = TRANSFER_FILE_INITATE;
strFilename = name;
strTitle = title;
dwCurrentBytes = size;
dwCurrentDone = 0;
dwCurrentPercent = 0;
dwCurrentPos = 0;
}
LeaveCriticalSection(&critsec);
NotifyCaller();
}
void UpdateProgress(DWORD dwBytesTransfered)
{
EnterCriticalSection(&critsec);
{ // critical section
dwStatus = TRANSFER_FILE_TRANSFERING;
dwTotalDone += dwBytesTransfered;
dwCurrentDone += dwBytesTransfered;
dwOverallPos = dwTotalBytes ? MulDiv(dwTotalDone, 0xFFFF, dwTotalBytes) : 0;
dwCurrentPos = dwCurrentBytes ? MulDiv(dwCurrentDone, 0xFFFF, dwCurrentBytes) : 0;
dwOverallPercent = (dwOverallPos * 100) / 0xFFFF;
dwCurrentPercent = (dwCurrentPos * 100) / 0xFFFF;
DWORD dwElapsedMS = timeGetTime() - dwStartMS;
dwTransferRate = MulDiv(dwTotalDone, 1000, dwElapsedMS);
DWORD dwTimeRemaining = MulDiv(dwElapsedMS, dwTotalBytes, dwTotalDone) - dwElapsedMS;
timeRemaining = dwTimeRemaining / 1000;
timeElapsed = dwElapsedMS / 1000;
}
LeaveCriticalSection(&critsec);
NotifyCaller();
}
void EndFile()
{
EnterCriticalSection(&critsec);
{ // critical section
dwStatus = TRANSFER_FILE_COMPLETE;
dwDoneFiles++;
}
LeaveCriticalSection(&critsec);
NotifyCaller();
}
};
#endif //__ProgressInfo_h__