mirror of
https://github.com/jmarshall23/Hellfire.git
synced 2026-08-12 07:50:53 +02:00
351 lines
8.3 KiB
C++
351 lines
8.3 KiB
C++
//****************************************************************************
|
|
// Progress.cpp
|
|
// Diablo UI progress bar popup dialog
|
|
//
|
|
// By Frank Pearce
|
|
// created 9.26.96
|
|
//****************************************************************************
|
|
|
|
|
|
#include "pch.h"
|
|
|
|
|
|
//****************************************************************************
|
|
//****************************************************************************
|
|
#define PROGRESS_TIMER_ID 1
|
|
#define MILLISEC_PER_SEC 1000
|
|
#define CALLS_PER_SEC 20
|
|
#define USER_DELAY (MILLISEC_PER_SEC / sgCallsPerSec)
|
|
#define DEFAULT_DELAY (MILLISEC_PER_SEC / CALLS_PER_SEC)
|
|
|
|
#define FILL_X 0
|
|
#define FILL_Y 0
|
|
|
|
static LPBYTE sgBgBmp = NULL;
|
|
static LPBYTE sgBtnBmp = NULL;
|
|
|
|
// the progress bar background
|
|
static LPBYTE sgProgBgBmp = NULL;
|
|
static SIZE sgProgBgSize;
|
|
|
|
// the fill image for the progress bar
|
|
static LPBYTE sgProgFillBmp = NULL;
|
|
static SIZE sgProgFillSize;
|
|
|
|
// the current image based on percent complete
|
|
static LPBYTE sgProgBmp = NULL;
|
|
static SIZE sgProgSize;
|
|
|
|
static BOOL sgAbortable;
|
|
static DWORD sgCallsPerSec;
|
|
static PROGRESSFCN sgProgressFcn;
|
|
static int sgnResult;
|
|
static BOOL sgbEndDialog;
|
|
|
|
|
|
//****************************************************************************
|
|
//****************************************************************************
|
|
static void ProgressDraw(HWND window, int percent) {
|
|
RECT rect;
|
|
HWND child = GetDlgItem(window, IDC_UIGENERIC_PROGRESS);
|
|
|
|
// draw the bg
|
|
if (sgProgBgBmp)
|
|
SBltROP3(
|
|
sgProgBmp,
|
|
sgProgBgBmp,
|
|
sgProgSize.cx,
|
|
sgProgSize.cy,
|
|
sgProgSize.cx,
|
|
sgProgBgSize.cx,
|
|
NULL,
|
|
SRCCOPY
|
|
);
|
|
|
|
// draw the fill
|
|
if (sgProgFillBmp)
|
|
SBltROP3(
|
|
sgProgBmp + (FILL_Y * sgProgSize.cx) + FILL_X,
|
|
sgProgFillBmp,
|
|
((sgProgSize.cx - (2 * FILL_X)) * percent) / 100,
|
|
sgProgSize.cy - (2 * FILL_Y),
|
|
sgProgSize.cx,
|
|
sgProgFillSize.cx,
|
|
NULL,
|
|
SRCCOPY
|
|
);
|
|
|
|
// invalidate the region
|
|
GetWindowRect(child, &rect);
|
|
ScreenToClient(window, (LPPOINT)&rect.left);
|
|
ScreenToClient(window, (LPPOINT)&rect.right);
|
|
InvalidateRect(window, &rect, FALSE);
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//****************************************************************************
|
|
static void ProgressDestroy(HWND window) {
|
|
if (sgBgBmp) {
|
|
FREE(sgBgBmp);
|
|
sgBgBmp = NULL;
|
|
}
|
|
if (sgBtnBmp) {
|
|
FREE(sgBtnBmp);
|
|
sgBtnBmp = NULL;
|
|
}
|
|
if (sgProgBgBmp) {
|
|
FREE(sgProgBgBmp);
|
|
sgProgBgBmp = NULL;
|
|
}
|
|
if (sgProgFillBmp) {
|
|
FREE(sgProgFillBmp);
|
|
sgProgFillBmp = NULL;
|
|
}
|
|
if (sgProgBmp) {
|
|
FREE(sgProgBmp);
|
|
sgProgBmp = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//****************************************************************************
|
|
static void ProgressInit(HWND window, LPCSTR progresstext) {
|
|
PALETTEENTRY * pal;
|
|
HWND child;
|
|
RECT rect;
|
|
SIZE btnsize;
|
|
int BtnIDs[] = { IDCANCEL, 0 };
|
|
|
|
if (sgCallsPerSec)
|
|
SDlgSetTimer(window,PROGRESS_TIMER_ID,USER_DELAY,NULL);
|
|
else
|
|
SDlgSetTimer(window,PROGRESS_TIMER_ID,DEFAULT_DELAY,NULL);
|
|
|
|
// load ctrl/dlg bmps
|
|
LoadArtFile(
|
|
window,
|
|
NULL,
|
|
TEXT(""),
|
|
SDLG_STYLE_ANY,
|
|
SDLG_USAGE_BACKGROUND,
|
|
TEXT("ui_art\\spopup.pcx"),
|
|
&sgBgBmp,
|
|
NULL,
|
|
FALSE
|
|
);
|
|
|
|
if (SDrawGetFrameWindow() == GetParent(window))
|
|
UiAltFadeInit(window);
|
|
|
|
|
|
// load just the part of the palette the dialog uses
|
|
pal = UiPaletteEntry(0);
|
|
SDrawUpdatePalette(0, 10, &pal[0]); // Windows colors also
|
|
SDrawUpdatePalette(0x70, 144, &pal[0x70], TRUE);
|
|
|
|
|
|
UiLoadBmpFile(
|
|
TEXT("ui_art\\but_sml.pcx"),
|
|
&sgBtnBmp,
|
|
&btnsize
|
|
);
|
|
if (sgBtnBmp)
|
|
UiSetButtonBitmaps(window, BtnIDs, sgBtnBmp, &btnsize);
|
|
|
|
// load progress bar textures
|
|
UiLoadBmpFile(
|
|
TEXT("ui_art\\prog_bg.pcx"),
|
|
&sgProgBgBmp,
|
|
&sgProgBgSize
|
|
);
|
|
UiLoadBmpFile(
|
|
TEXT("ui_art\\prog_fil.pcx"),
|
|
&sgProgFillBmp,
|
|
&sgProgFillSize
|
|
);
|
|
|
|
// alloc/create a bitmap for the progress indicator
|
|
child = GetDlgItem(window, IDC_UIGENERIC_PROGRESS);
|
|
GetClientRect(child, &rect);
|
|
|
|
sgProgBmp = (LPBYTE) ALLOC(rect.right * rect.bottom);
|
|
if (!sgProgBmp)
|
|
return;
|
|
|
|
sgProgSize.cx = rect.right;
|
|
sgProgSize.cy = rect.bottom;
|
|
|
|
SDlgSetBitmap(
|
|
child,
|
|
NULL,
|
|
NULL,
|
|
SDLG_STYLE_ANY,
|
|
SDLG_USAGE_BACKGROUND,
|
|
sgProgBmp,
|
|
NULL,
|
|
rect.right,
|
|
rect.bottom
|
|
);
|
|
ProgressDraw(window, 0);
|
|
|
|
// set the text describing what progress is being monitored
|
|
child = GetDlgItem(window, IDC_PROGRESS_TEXT);
|
|
SetWindowText(child, progresstext);
|
|
|
|
// show/hide cancel button based on abortable flag
|
|
child = GetDlgItem(window, IDCANCEL);
|
|
ShowWindow(child, (sgAbortable ? SW_SHOWNORMAL : SW_HIDE));
|
|
EnableWindow(child, sgAbortable);
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//****************************************************************************
|
|
static void ProgressEndDialog(HWND window, int nResult) {
|
|
sgnResult = IDCANCEL;
|
|
sgbEndDialog = TRUE;
|
|
}
|
|
|
|
//****************************************************************************
|
|
//****************************************************************************
|
|
static void ProgressAbort(HWND window) {
|
|
SDlgKillTimer(window, PROGRESS_TIMER_ID);
|
|
if (SDrawGetFrameWindow() == GetParent(window))
|
|
UiVidFadeOut(DEFAULT_STEPS*2);
|
|
ProgressEndDialog(window, 0);
|
|
sgnResult = 0;
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//****************************************************************************
|
|
static void ProgressTimer(HWND window) {
|
|
int percent;
|
|
|
|
percent = sgProgressFcn();
|
|
|
|
if (percent >= 100) {
|
|
ProgressAbort(window);
|
|
}
|
|
else {
|
|
ProgressDraw(window, percent);
|
|
}
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//****************************************************************************
|
|
static BOOL CALLBACK ProgressDialogProc (HWND window,
|
|
UINT message,
|
|
WPARAM wparam,
|
|
LPARAM lparam) {
|
|
switch (message) {
|
|
|
|
case WM_COMMAND:
|
|
if (LOWORD(wparam) == IDCANCEL) {
|
|
SDlgKillTimer(window, PROGRESS_TIMER_ID);
|
|
|
|
if (SDrawGetFrameWindow() == GetParent(window))
|
|
UiVidFadeOut(DEFAULT_STEPS*2);
|
|
ProgressEndDialog(window, IDCANCEL);
|
|
}
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
ShowCursor(FALSE);
|
|
ProgressDestroy(window);
|
|
break;
|
|
|
|
case WM_INITDIALOG:
|
|
ProgressInit(window, (LPCSTR)lparam);
|
|
|
|
// Choose our cursors
|
|
UiSetWindowsCursors(SDrawGetFrameWindow());
|
|
UiSetWindowsCursors(window);
|
|
ShowCursor(TRUE);
|
|
return 1;
|
|
|
|
case WM_TIMER:
|
|
ProgressTimer(window);
|
|
break;
|
|
|
|
case WM_SYSKEYUP:
|
|
case WM_SYSKEYDOWN:
|
|
SendMessage(SDrawGetFrameWindow(), message, wparam, lparam);
|
|
break;
|
|
}
|
|
return SDlgDefDialogProc(window,message,wparam,lparam);
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//****************************************************************************
|
|
static void ProcessMessages(HWND hWnd) {
|
|
while (IsWindow(hWnd) && !sgbEndDialog) {
|
|
MSG message;
|
|
if (PeekMessage(&message,(HWND)0,0,0,PM_REMOVE)) {
|
|
if (message.message == WM_QUIT)
|
|
PostQuitMessage(message.wParam);
|
|
else if (!IsDialogMessage(hWnd,&message)) {
|
|
TranslateMessage(&message);
|
|
DispatchMessage(&message);
|
|
}
|
|
}
|
|
else {
|
|
SDlgCheckTimers();
|
|
SDlgUpdateCursor();
|
|
}
|
|
}
|
|
|
|
// Get rid of the window if it is killing itself
|
|
if (sgbEndDialog) {
|
|
DestroyWindow(hWnd);
|
|
sgbEndDialog = FALSE;
|
|
}
|
|
}
|
|
|
|
//****************************************************************************
|
|
//*
|
|
//* EXPORTED FUNCTIONS
|
|
//*
|
|
//****************************************************************************
|
|
|
|
|
|
//****************************************************************************
|
|
//****************************************************************************
|
|
BOOL APIENTRY UiProgressDialog(HWND parent,
|
|
LPCSTR progresstext,
|
|
BOOL abortable,
|
|
PROGRESSFCN progressfcn,
|
|
DWORD callspersec
|
|
) {
|
|
|
|
sgProgressFcn = progressfcn;
|
|
sgAbortable = abortable;
|
|
sgCallsPerSec = callspersec;
|
|
sgnResult = -1;
|
|
sgbEndDialog = FALSE;
|
|
|
|
HWND hWndProgress = SDlgCreateDialogParam(
|
|
global_hinstance,
|
|
TEXT("PROGRESS_DIALOG"),
|
|
parent,
|
|
ProgressDialogProc,
|
|
(LPARAM) progresstext
|
|
);
|
|
|
|
if (!hWndProgress)
|
|
return FALSE;
|
|
|
|
// Now process messages until dialog exits
|
|
// (that way we'll behave modal to the outside world of Diablo.exe)
|
|
ProcessMessages(hWndProgress);
|
|
|
|
if (sgnResult == IDCANCEL || sgnResult == -1)
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|