#include "copyProgress.h" #include #include #include extern HINSTANCE app_instance; extern void gsInstall_getDesktopExt(int *x, int *y); LRESULT CALLBACK copyProgressBar_windowProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: { CREATESTRUCT *createStruct = (CREATESTRUCT *) lParam; long *createParams; copyProgressBar *progressBar; createParams = (long *) createStruct->lpCreateParams; SetWindowLong(window, GWL_USERDATA, createParams[0]); progressBar = (copyProgressBar *) GetWindowLong(window, GWL_USERDATA); if (progressBar == NULL) { // TODO: error handling } CreateWindowEx( 0, "STATIC", (char *) createParams[1], WS_CHILD | WS_VISIBLE, 10, 5, 180, 20, window, (HMENU) 0, app_instance, NULL); } break; default: return(DefWindowProc(window, message, wParam, lParam)); } return 0; } void copyProgressBar::registerClass() { static BOOL registered = FALSE; if (registered == FALSE) { WNDCLASS classdef; classdef.style = 0; classdef.lpfnWndProc = copyProgressBar_windowProc; classdef.cbClsExtra = 0; classdef.cbWndExtra = sizeof(copyProgressBar *) + sizeof(long); classdef.hInstance = app_instance; classdef.hIcon = 0; classdef.hCursor = NULL; classdef.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); classdef.lpszMenuName = NULL; classdef.lpszClassName = "CopyProgressBar"; RegisterClass(&classdef); registered = TRUE; } } copyProgressBar::copyProgressBar(unsigned long totalSize, unsigned long totalFiles) { this->total = totalSize; this->totalFiles = totalFiles; this->copied = 0; this->copiedFiles = 0; this->showing = false; } copyProgressBar::copyProgressBar() { this->total = 0; this->totalFiles = 0; this->copied = 0; this->copiedFiles = 0; this->showing = false; } // just ensure everything is tidily terminated copyProgressBar::~copyProgressBar() { this->close(); } void copyProgressBar::init(unsigned long totalSize, unsigned long totalFiles) { this->total = totalSize; this->totalFiles = totalFiles; this->copied = 0; this->copiedFiles = 0; } void copyProgressBar::done(unsigned long bytesDone) { static char progressText[100] = "Remaining: "; static int progressTimePos = strlen(progressText); double seconds; // note the progress made by the extra bytes this->copied += bytesDone; this->copiedFiles += 1; // present the progress in the progress bar double percent = (double) this->copied / (double) this->total; percent = percent * 100; SendMessage(this->progressBar, PBM_SETPOS, (int) percent, 0L); // present time remaining seconds = difftime(time(NULL), this->startTime); if (this->copied == 0) { return; } seconds = seconds * (double) (this->total - this->copied) / (double) this->copied; sprintf(&progressText[progressTimePos], "%d:%02d %3.1fMb (%d files)", (int) (seconds / 60), ((int) seconds) % 60, double (this->total - this->copied) / (double) (1024 * 1024), this->totalFiles - this->copiedFiles); SetWindowText(this->progressTime, progressText); } void copyProgressBar::done(unsigned long bytesDone, LPSTR message) { this->done(bytesDone); this->message(message); } void copyProgressBar::message(LPSTR message) { SetWindowText(this->progressText, message); } void copyProgressBar::show() { long params[2]; int sx, sy, dx, dy; params[0] = (long) this; params[1] = (long) "Copying files...."; this->registerClass(); gsInstall_getDesktopExt(&sx, &sy); dx = (sx - 400) >> 1; dy = (sy - 110) >> 1; // Create the parent to hold the progress elements this->progressParent = CreateWindowEx( WS_EX_APPWINDOW, "CopyProgressBar", "Greenstone Installer", WS_VISIBLE, dx, dy, 400, 110, 0, (HMENU) 0, app_instance, (void *) params); // Create the progress bar itself this->progressBar = CreateWindowEx(0, PROGRESS_CLASS, NULL, WS_CHILD | WS_VISIBLE, 10, 60, 380, GetSystemMetrics(SM_CYVSCROLL), this->progressParent, (HMENU) 0, app_instance, NULL); // Create the text reporter this->progressText = CreateWindowEx(0, "STATIC", "", WS_CHILD | SS_LEFT | WS_VISIBLE, 10, 5, 380, 20, this->progressParent, (HMENU) 0, app_instance, NULL); // Create the time reporter this->progressTime = CreateWindowEx(0, "STATIC", "", WS_CHILD | SS_LEFT | WS_VISIBLE, 10, 30, 380, 20, this->progressParent, (HMENU) 0, app_instance, NULL); // Note that we are now showing the progress bar this->showing = true; } // ensure that if the windows are showing, they are closed before the object // is destroyed void copyProgressBar::close() { if (this->showing == true) { ShowWindow(this->progressBar, SW_HIDE); DestroyWindow(this->progressBar); ShowWindow(this->progressParent, SW_HIDE); DestroyWindow(this->progressParent); this->showing = false; } }