Fixed up the wait dialog.

This commit is contained in:
Justin Marshall
2026-05-06 23:43:11 -07:00
parent f238db4a34
commit 1a6bc0c447
2 changed files with 645 additions and 96 deletions
+576 -62
View File
@@ -2,9 +2,9 @@
===========================================================================
IceTech GPL Source Code
Copyright (C) 2026 Justin Marshall
Copyright (C) 2026 Justin Marshall
This file is part of the IceTech GPL Source Code (?IceTech Source Code?).
This file is part of the IceTech GPL Source Code (?IceTech Source Code?).
IceTech Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -38,101 +38,615 @@ If you have questions concerning this license or the applicable additional terms
static char THIS_FILE[] = __FILE__;
#endif
#define WAITDLG_TIMER_ANIMATE 1001
#define WAITDLG_TIMER_MS 33
// Runtime size. This makes the old tiny resource dialog larger without
// needing to edit the .rc file.
#define WAITDLG_WIDTH 560
#define WAITDLG_HEIGHT 260
/////////////////////////////////////////////////////////////////////////////
// CWaitDlg dialog
CWaitDlg::CWaitDlg(CWnd* pParent, const char* msg)
: CDialog(CWaitDlg::IDD, pParent) {
waitStr = msg ? msg : "Wait...";
text = waitStr;
titleStr = "IceTech Radiant";
CWaitDlg::CWaitDlg(CWnd* pParent, const char *msg)
: CDialog(CWaitDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CWaitDlg)
waitStr = msg;
//}}AFX_DATA_INIT
cancelPressed = false;
Create(CWaitDlg::IDD);
//g_pParentWnd->SetBusy(true);
cancelAllowed = false;
progressPercent = -1;
marqueeOffset = 0;
pulseFrame = 0;
colorBackTop = RGB(13, 17, 26);
colorBackBottom = RGB(24, 30, 45);
colorPanel = RGB(28, 35, 52);
colorPanelBorder = RGB(62, 78, 112);
colorText = RGB(236, 242, 255);
colorMutedText = RGB(148, 162, 190);
colorAccent = RGB(83, 169, 255);
colorAccent2 = RGB(127, 96, 255);
colorProgressBack = RGB(15, 20, 31);
colorDanger = RGB(255, 92, 112);
InitModernResources();
Create(CWaitDlg::IDD, pParent);
}
CWaitDlg::~CWaitDlg() {
g_pParentWnd->SetBusy(false);
KillTimer(WAITDLG_TIMER_ANIMATE);
FreeModernResources();
if (g_pParentWnd) {
g_pParentWnd->SetBusy(false);
}
}
void CWaitDlg::DoDataExchange(CDataExchange* pDX)
{
void CWaitDlg::DoDataExchange(CDataExchange* pDX) {
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CWaitDlg)
DDX_Text(pDX, IDC_WAITSTR, waitStr);
//}}AFX_DATA_MAP
}
// Keep the original DDX mapping alive for old resource compatibility.
DDX_Text(pDX, IDC_WAITSTR, waitStr);
}
BEGIN_MESSAGE_MAP(CWaitDlg, CDialog)
//{{AFX_MSG_MAP(CWaitDlg)
//}}AFX_MSG_MAP
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_TIMER()
ON_WM_SIZE()
ON_WM_CTLCOLOR()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CWaitDlg message handlers
// Modern resources
BOOL CWaitDlg::OnInitDialog()
{
void CWaitDlg::InitModernResources(void) {
LOGFONT lf;
memset(&lf, 0, sizeof(lf));
lf.lfHeight = -23;
lf.lfWeight = FW_SEMIBOLD;
lf.lfQuality = CLEARTYPE_QUALITY;
strcpy(lf.lfFaceName, "Segoe UI");
titleFont.CreateFontIndirect(&lf);
memset(&lf, 0, sizeof(lf));
lf.lfHeight = -15;
lf.lfWeight = FW_NORMAL;
lf.lfQuality = CLEARTYPE_QUALITY;
strcpy(lf.lfFaceName, "Segoe UI");
messageFont.CreateFontIndirect(&lf);
memset(&lf, 0, sizeof(lf));
lf.lfHeight = -12;
lf.lfWeight = FW_NORMAL;
lf.lfQuality = CLEARTYPE_QUALITY;
strcpy(lf.lfFaceName, "Segoe UI");
smallFont.CreateFontIndirect(&lf);
transparentBrush.CreateStockObject(NULL_BRUSH);
}
void CWaitDlg::FreeModernResources(void) {
if (titleFont.GetSafeHandle()) {
titleFont.DeleteObject();
}
if (messageFont.GetSafeHandle()) {
messageFont.DeleteObject();
}
if (smallFont.GetSafeHandle()) {
smallFont.DeleteObject();
}
if (transparentBrush.GetSafeHandle()) {
transparentBrush.DeleteObject();
}
}
/////////////////////////////////////////////////////////////////////////////
// Dialog init
BOOL CWaitDlg::OnInitDialog() {
CDialog::OnInitDialog();
//GetDlgItem(IDC_WAITSTR)->SetWindowText(waitStr);
GetDlgItem(IDC_WAITSTR)->SetFocus();
ModifyStyleEx(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE, 0);
ModifyStyle(WS_THICKFRAME, 0);
SetWindowText("Please wait");
ResizeAndCenterDialog();
CWnd* pWaitText = GetDlgItem(IDC_WAITSTR);
if (pWaitText && pWaitText->GetSafeHwnd()) {
pWaitText->ShowWindow(SW_HIDE);
}
CWnd* pCancelButton = GetDlgItem(IDCANCEL);
if (pCancelButton && pCancelButton->GetSafeHwnd()) {
pCancelButton->SetFont(&messageFont);
pCancelButton->SetWindowText("Cancel");
}
UpdateData(FALSE);
AllowCancel(false);
LayoutModernControls();
SetTimer(WAITDLG_TIMER_ANIMATE, WAITDLG_TIMER_MS, NULL);
ShowWindow(SW_SHOW);
// cancel disabled by default
AllowCancel( false );
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CWaitDlg::SetText(const char *msg, bool append) {
if (append) {
waitStr = text;
waitStr += "\r\n";
waitStr += msg;
} else {
waitStr = msg;
text = msg;
}
UpdateData(FALSE);
Invalidate();
Invalidate(FALSE);
UpdateWindow();
ShowWindow (SW_SHOWNORMAL);
return TRUE;
}
void CWaitDlg::AllowCancel( bool enable ) {
// this shows or hides the Cancel button
CWnd* pCancelButton = GetDlgItem (IDCANCEL);
ASSERT (pCancelButton);
if ( enable ) {
pCancelButton->ShowWindow (SW_NORMAL);
} else {
pCancelButton->ShowWindow (SW_HIDE);
void CWaitDlg::ResizeAndCenterDialog(void) {
CRect rcWindow;
GetWindowRect(&rcWindow);
int width = WAITDLG_WIDTH;
int height = WAITDLG_HEIGHT;
CWnd* pParent = GetParent();
CRect rcParent;
if (pParent && pParent->GetSafeHwnd()) {
pParent->GetWindowRect(&rcParent);
}
else {
SystemParametersInfo(SPI_GETWORKAREA, 0, &rcParent, 0);
}
int x = rcParent.left + ((rcParent.Width() - width) / 2);
int y = rcParent.top + ((rcParent.Height() - height) / 2);
SetWindowPos(NULL, x, y, width, height, SWP_NOZORDER | SWP_NOACTIVATE);
}
bool CWaitDlg::CancelPressed( void ) {
/////////////////////////////////////////////////////////////////////////////
// Public API
void CWaitDlg::SetText(const char* msg, bool append) {
if (append) {
waitStr = text.c_str();
waitStr += "\r\n";
waitStr += msg ? msg : "";
text = waitStr;
}
else {
waitStr = msg ? msg : "";
text = waitStr;
}
UpdateData(FALSE);
Invalidate(FALSE);
UpdateWindow();
ShowWindow(SW_SHOWNORMAL);
}
void CWaitDlg::SetTitleText(const char* title) {
titleStr = title ? title : "";
Invalidate(FALSE);
UpdateWindow();
}
void CWaitDlg::SetProgress(int percent) {
if (percent < 0) {
progressPercent = -1;
}
else {
if (percent > 100) {
percent = 100;
}
progressPercent = percent;
}
Invalidate(FALSE);
UpdateWindow();
}
void CWaitDlg::StepProgress(int amount) {
if (progressPercent < 0) {
progressPercent = 0;
}
progressPercent += amount;
if (progressPercent < 0) {
progressPercent = 0;
}
if (progressPercent > 100) {
progressPercent = 100;
}
Invalidate(FALSE);
UpdateWindow();
}
int CWaitDlg::GetProgress(void) const {
return progressPercent;
}
void CWaitDlg::AllowCancel(bool enable) {
cancelAllowed = enable;
CWnd* pCancelButton = GetDlgItem(IDCANCEL);
ASSERT(pCancelButton);
if (pCancelButton && pCancelButton->GetSafeHwnd()) {
pCancelButton->ShowWindow(enable ? SW_SHOW : SW_HIDE);
}
LayoutModernControls();
Invalidate(FALSE);
}
bool CWaitDlg::CancelPressed(void) {
PumpMessages();
return cancelPressed;
}
void CWaitDlg::PumpMessages(void) {
#if _MSC_VER >= 1300
MSG *msg = AfxGetCurrentMessage(); // TODO Robert fix me!!
MSG* msg = AfxGetCurrentMessage();
#else
MSG *msg = &m_msgCur;
MSG* msg = &m_msgCur;
#endif
while( ::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE) ) {
// pump message
if ( !AfxGetApp()->PumpMessage() ) {
while (::PeekMessage(msg, NULL, 0, 0, PM_NOREMOVE)) {
if (!AfxGetApp()->PumpMessage()) {
break;
}
}
return cancelPressed;
}
void CWaitDlg::OnCancel() {
cancelPressed = true;
}
/////////////////////////////////////////////////////////////////////////////
// Layout
void CWaitDlg::OnSize(UINT nType, int cx, int cy) {
CDialog::OnSize(nType, cx, cy);
LayoutModernControls();
Invalidate(FALSE);
}
void CWaitDlg::LayoutModernControls(void) {
if (!GetSafeHwnd()) {
return;
}
CRect rcClient;
GetClientRect(&rcClient);
CWnd* pCancelButton = GetDlgItem(IDCANCEL);
if (pCancelButton && pCancelButton->GetSafeHwnd()) {
const int buttonW = 112;
const int buttonH = 32;
const int margin = 26;
CRect rcButton;
rcButton.left = rcClient.right - margin - buttonW;
rcButton.top = rcClient.bottom - margin - buttonH;
rcButton.right = rcButton.left + buttonW;
rcButton.bottom = rcButton.top + buttonH;
pCancelButton->MoveWindow(rcButton);
}
}
/////////////////////////////////////////////////////////////////////////////
// Paint
BOOL CWaitDlg::OnEraseBkgnd(CDC* pDC) {
return TRUE;
}
HBRUSH CWaitDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) {
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(colorText);
return (HBRUSH)transparentBrush.GetSafeHandle();
}
void CWaitDlg::OnTimer(UINT_PTR nIDEvent) {
if (nIDEvent == WAITDLG_TIMER_ANIMATE) {
pulseFrame++;
marqueeOffset += 5;
if (marqueeOffset > 10000) {
marqueeOffset = 0;
}
Invalidate(FALSE);
return;
}
CDialog::OnTimer(nIDEvent);
}
void CWaitDlg::OnPaint() {
CPaintDC dcPaint(this);
CRect rcClient;
GetClientRect(&rcClient);
CDC memDC;
CBitmap memBmp;
CBitmap* oldBmp = NULL;
memDC.CreateCompatibleDC(&dcPaint);
memBmp.CreateCompatibleBitmap(&dcPaint, rcClient.Width(), rcClient.Height());
oldBmp = memDC.SelectObject(&memBmp);
DrawModernBackground(memDC, rcClient);
DrawHeader(memDC, rcClient);
DrawMessage(memDC, rcClient);
DrawProgress(memDC, rcClient);
dcPaint.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &memDC, 0, 0, SRCCOPY);
if (oldBmp) {
memDC.SelectObject(oldBmp);
}
}
void CWaitDlg::DrawModernBackground(CDC& dc, const CRect& rcClient) {
TRIVERTEX vertex[2];
vertex[0].x = rcClient.left;
vertex[0].y = rcClient.top;
vertex[0].Red = GetRValue(colorBackTop) << 8;
vertex[0].Green = GetGValue(colorBackTop) << 8;
vertex[0].Blue = GetBValue(colorBackTop) << 8;
vertex[0].Alpha = 0x0000;
vertex[1].x = rcClient.right;
vertex[1].y = rcClient.bottom;
vertex[1].Red = GetRValue(colorBackBottom) << 8;
vertex[1].Green = GetGValue(colorBackBottom) << 8;
vertex[1].Blue = GetBValue(colorBackBottom) << 8;
vertex[1].Alpha = 0x0000;
GRADIENT_RECT gRect;
gRect.UpperLeft = 0;
gRect.LowerRight = 1;
dc.GradientFill(vertex, 2, &gRect, 1, GRADIENT_FILL_RECT_V);
CRect panel = rcClient;
panel.DeflateRect(14, 14, 14, 14);
DrawRoundedRect(dc, panel, colorPanel, colorPanelBorder, 18);
// Top glass sheen.
CRect sheen = panel;
sheen.bottom = sheen.top + 70;
TRIVERTEX sheenVertex[2];
sheenVertex[0].x = sheen.left;
sheenVertex[0].y = sheen.top;
sheenVertex[0].Red = 60 << 8;
sheenVertex[0].Green = 78 << 8;
sheenVertex[0].Blue = 118 << 8;
sheenVertex[0].Alpha = 0x0000;
sheenVertex[1].x = sheen.right;
sheenVertex[1].y = sheen.bottom;
sheenVertex[1].Red = GetRValue(colorPanel) << 8;
sheenVertex[1].Green = GetGValue(colorPanel) << 8;
sheenVertex[1].Blue = GetBValue(colorPanel) << 8;
sheenVertex[1].Alpha = 0x0000;
dc.GradientFill(sheenVertex, 2, &gRect, 1, GRADIENT_FILL_RECT_V);
// Header separator.
CRect accent = panel;
accent.left += 24;
accent.right -= 24;
accent.top += 66;
accent.bottom = accent.top + 1;
CPen accentPen(PS_SOLID, 1, RGB(72, 91, 130));
CPen* oldPen = dc.SelectObject(&accentPen);
dc.MoveTo(accent.left, accent.top);
dc.LineTo(accent.right, accent.top);
dc.SelectObject(oldPen);
}
void CWaitDlg::DrawHeader(CDC& dc, const CRect& rcClient) {
CRect panel = rcClient;
panel.DeflateRect(14, 14, 14, 14);
CRect iconRc;
iconRc.left = panel.left + 26;
iconRc.top = panel.top + 20;
iconRc.right = iconRc.left + 30;
iconRc.bottom = iconRc.top + 30;
int glow = 20 + (pulseFrame % 50);
if (glow > 45) {
glow = 70 - glow;
}
COLORREF coreColor = RGB(
min(255, GetRValue(colorAccent) + glow),
min(255, GetGValue(colorAccent) + glow / 2),
min(255, GetBValue(colorAccent))
);
DrawRoundedRect(dc, iconRc, coreColor, RGB(155, 205, 255), 8);
CRect inner = iconRc;
inner.DeflateRect(7, 7, 7, 7);
DrawRoundedRect(dc, inner, RGB(18, 25, 38), RGB(150, 220, 255), 4);
CFont* oldFont = dc.SelectObject(&titleFont);
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(colorText);
CRect titleRc;
titleRc.left = iconRc.right + 14;
titleRc.top = panel.top + 17;
titleRc.right = panel.right - 26;
titleRc.bottom = titleRc.top + 30;
dc.DrawText(titleStr, &titleRc, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
dc.SelectObject(&smallFont);
dc.SetTextColor(colorMutedText);
CRect subRc = titleRc;
subRc.top += 28;
subRc.bottom = subRc.top + 20;
CString subText = "Working on the current Radiant task";
dc.DrawText(subText, &subRc, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
dc.SelectObject(oldFont);
}
void CWaitDlg::DrawMessage(CDC& dc, const CRect& rcClient) {
CRect panel = rcClient;
panel.DeflateRect(14, 14, 14, 14);
// Move status text higher and reserve a larger footer.
const int headerBottom = panel.top + 70;
const int footerHeight = cancelAllowed ? 138 : 108;
CRect textRc;
textRc.left = panel.left + 28;
textRc.top = headerBottom + 6;
textRc.right = panel.right - 28;
textRc.bottom = panel.bottom - footerHeight;
if (textRc.bottom < textRc.top + 26) {
textRc.bottom = textRc.top + 26;
}
CFont* oldFont = dc.SelectObject(&messageFont);
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(colorText);
CString drawText = waitStr;
if (drawText.IsEmpty()) {
drawText = "Please wait...";
}
dc.DrawText(drawText, &textRc, DT_LEFT | DT_TOP | DT_WORDBREAK | DT_END_ELLIPSIS);
dc.SelectObject(oldFont);
}
void CWaitDlg::DrawProgress(CDC& dc, const CRect& rcClient) {
CRect panel = rcClient;
panel.DeflateRect(14, 14, 14, 14);
// Push progress lower so it never overlaps the status text.
CRect barRc;
barRc.left = panel.left + 28;
barRc.right = panel.right - 28;
if (cancelAllowed) {
barRc.bottom = panel.bottom - 54;
}
else {
barRc.bottom = panel.bottom - 28;
}
barRc.top = barRc.bottom - 18;
DrawRoundedRect(dc, barRc, colorProgressBack, RGB(54, 68, 96), 9);
CRect fillRc = barRc;
fillRc.DeflateRect(2, 2, 2, 2);
if (progressPercent >= 0) {
int fillW = MulDiv(fillRc.Width(), progressPercent, 100);
CRect filled = fillRc;
filled.right = filled.left + fillW;
if (filled.Width() > 0) {
DrawRoundedRect(dc, filled, colorAccent, RGB(125, 205, 255), 8);
}
CString percentText;
percentText.Format("%d%%", progressPercent);
CFont* oldFont = dc.SelectObject(&smallFont);
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(colorMutedText);
CRect labelRc = barRc;
labelRc.top = barRc.bottom + 6;
labelRc.bottom = labelRc.top + 18;
dc.DrawText(percentText, &labelRc, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
dc.SelectObject(oldFont);
}
else {
const int chunkW = max(64, fillRc.Width() / 4);
const int travelW = fillRc.Width() + chunkW;
const int x = fillRc.left - chunkW + (marqueeOffset % travelW);
CRect chunk;
chunk.left = x;
chunk.right = x + chunkW;
chunk.top = fillRc.top;
chunk.bottom = fillRc.bottom;
CRect clipped;
clipped.IntersectRect(&chunk, &fillRc);
if (!clipped.IsRectEmpty()) {
DrawRoundedRect(dc, clipped, colorAccent, RGB(125, 205, 255), 8);
}
CRect glowChunk = chunk;
glowChunk.OffsetRect(-chunkW / 2, 0);
CRect glowClip;
glowClip.IntersectRect(&glowChunk, &fillRc);
if (!glowClip.IsRectEmpty()) {
DrawRoundedRect(dc, glowClip, colorAccent2, RGB(140, 120, 255), 8);
}
CFont* oldFont = dc.SelectObject(&smallFont);
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(colorMutedText);
CRect labelRc = barRc;
labelRc.top = barRc.bottom + 6;
labelRc.bottom = labelRc.top + 18;
CString label = "Processing...";
dc.DrawText(label, &labelRc, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
dc.SelectObject(oldFont);
}
}
void CWaitDlg::DrawRoundedRect(CDC& dc, const CRect& rc, COLORREF fill, COLORREF outline, int radius) {
CBrush brush(fill);
CPen pen(PS_SOLID, 1, outline);
CBrush* oldBrush = dc.SelectObject(&brush);
CPen* oldPen = dc.SelectObject(&pen);
dc.RoundRect(&rc, CPoint(radius, radius));
dc.SelectObject(oldBrush);
dc.SelectObject(oldPen);
}
+69 -34
View File
@@ -2,9 +2,9 @@
===========================================================================
IceTech GPL Source Code
Copyright (C) 2026 Justin Marshall
Copyright (C) 2026 Justin Marshall
This file is part of the IceTech GPL Source Code (?IceTech Source Code?).
This file is part of the IceTech GPL Source Code (?IceTech Source Code?).
IceTech Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,58 +25,93 @@ If you have questions concerning this license or the applicable additional terms
===========================================================================
*/
#if !defined(AFX_WAITDLG_H__2B7A6C91_8D3F_4BEE_B564_33A0CFFA241B__INCLUDED_)
#define AFX_WAITDLG_H__2B7A6C91_8D3F_4BEE_B564_33A0CFFA241B__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// WaitDlg.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CWaitDlg dialog
class CWaitDlg : public CDialog
{
// Construction
class CWaitDlg : public CDialog {
public:
CWaitDlg(CWnd* pParent = NULL, const char *msg = "Wait..."); // standard constructor
~CWaitDlg();
void SetText(const char *msg, bool append = false);
void AllowCancel( bool enable );
bool CancelPressed( void );
CWaitDlg(CWnd* pParent = NULL, const char* msg = "Wait...");
virtual ~CWaitDlg();
void SetText(const char* msg, bool append = false);
void AllowCancel(bool enable);
bool CancelPressed(void);
// New progress API.
// SetProgress(-1) = animated indeterminate marquee.
// SetProgress(0..100) = fixed progress amount.
void SetProgress(int percent);
void StepProgress(int amount = 1);
int GetProgress(void) const;
void SetTitleText(const char* title);
// Dialog Data
//{{AFX_DATA(CWaitDlg)
enum { IDD = IDD_DLG_WAIT };
CString waitStr;
//}}AFX_DATA
CString waitStr;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CWaitDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CWaitDlg)
virtual void DoDataExchange(CDataExchange* pDX);
virtual BOOL OnInitDialog();
virtual void OnCancel();
//}}AFX_MSG
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
DECLARE_MESSAGE_MAP()
private:
idStr text;
bool cancelPressed;
void InitModernResources(void);
void FreeModernResources(void);
void LayoutModernControls(void);
void ResizeAndCenterDialog(void);
void DrawModernBackground(CDC& dc, const CRect& rcClient);
void DrawHeader(CDC& dc, const CRect& rcClient);
void DrawMessage(CDC& dc, const CRect& rcClient);
void DrawProgress(CDC& dc, const CRect& rcClient);
void DrawRoundedRect(CDC& dc, const CRect& rc, COLORREF fill, COLORREF outline, int radius);
void PumpMessages(void);
private:
idStr text;
bool cancelPressed;
bool cancelAllowed;
CString titleStr;
int progressPercent; // -1 = indeterminate / marquee
int marqueeOffset;
int pulseFrame;
CFont titleFont;
CFont messageFont;
CFont smallFont;
CBrush transparentBrush;
COLORREF colorBackTop;
COLORREF colorBackBottom;
COLORREF colorPanel;
COLORREF colorPanelBorder;
COLORREF colorText;
COLORREF colorMutedText;
COLORREF colorAccent;
COLORREF colorAccent2;
COLORREF colorProgressBack;
COLORREF colorDanger;
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_WAITDLG_H__2B7A6C91_8D3F_4BEE_B564_33A0CFFA241B__INCLUDED_)
#endif // !defined(AFX_WAITDLG_H__2B7A6C91_8D3F_4BEE_B564_33A0CFFA241B__INCLUDED_)