Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

A drop-in replacement for MessageBox()

, 4 Jan 2005
Other articles describe replacements for MessageBox() with extra buttons for "Yes to All" and "No to All", but you still have to write the code to handle those buttons. This article presents a class that does all the work for you.
crhyesnotoalldialogapp.zip
CRHYesNoToAllDialogApp.dsp
CRHYesNoToAllDialogApp.dsw
Release
CRHYesNoToAllDialogApp.exe
res
CRHYesNoToAllDialogApp.ico
// CRHYesNoToAllDialog.cpp : implementation file
//

#include "stdafx.h"
#include "CRHYesNoToAllDialog.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////

#define N(array) (sizeof(array) / sizeof((array)[0]))

enum
{
    GAP_X                   =  4,
    GAP_Y                   =  6,
    MARGIN_X                =  7,
    MARGIN_Y                =  7,
    BUTTONWIDTH             = 42,
    BUTTONHEIGHT            = 13,
    BUTTON_DELTA_X          = BUTTONWIDTH + GAP_X,
    BUTTON_DELTA_Y          = BUTTONHEIGHT + GAP_Y,
    BUTTONS_WIDTH           = 4 * BUTTON_DELTA_X + BUTTONWIDTH,
    CONTROLS_MINIMUM_HEIGHT = 2 * BUTTON_DELTA_Y + BUTTONHEIGHT,
};

enum
{
    CONTROLS_BASE = 1000,
    IDC_BUTTON_YES,     
    IDC_BUTTON_NO,      
    IDC_BUTTON_YESTOALL,
    IDC_BUTTON_NOTOALL,
    IDC_BUTTON_CANCEL,
    IDC_BUTTON_STOP,    
    IDC_CRHPROGRESSCTRL,
};

CRHYesNoToAllDialog::CRHButtonInfo CRHYesNoToAllDialog::CRHButtonInfos[NBUTTONS] =
{
//    nID                  Text           pCButton             Style                  lx                             ty                                 Width        Height
    { IDC_BUTTON_YES,      "&Yes",        &c_CButton_Yes,      WS_GROUP | WS_TABSTOP, MARGIN_X + 0 * BUTTON_DELTA_X, 2 * MARGIN_Y + 0 * BUTTON_DELTA_Y, BUTTONWIDTH, BUTTONHEIGHT },
    { IDC_BUTTON_NO,       "&No",         &c_CButton_No,                  WS_TABSTOP, MARGIN_X + 1 * BUTTON_DELTA_X, 2 * MARGIN_Y + 0 * BUTTON_DELTA_Y, BUTTONWIDTH, BUTTONHEIGHT },
    { IDC_BUTTON_YESTOALL, "Y&es to All", &c_CButton_YesToAll,            WS_TABSTOP, MARGIN_X + 2 * BUTTON_DELTA_X, 2 * MARGIN_Y + 0 * BUTTON_DELTA_Y, BUTTONWIDTH, BUTTONHEIGHT },
    { IDC_BUTTON_NOTOALL,  "N&o to All",  &c_CButton_NoToAll,             WS_TABSTOP, MARGIN_X + 3 * BUTTON_DELTA_X, 2 * MARGIN_Y + 0 * BUTTON_DELTA_Y, BUTTONWIDTH, BUTTONHEIGHT },
    { IDC_BUTTON_CANCEL,   "Cancel",      &c_CButton_Cancel,              WS_TABSTOP, MARGIN_X + 4 * BUTTON_DELTA_X, 2 * MARGIN_Y + 0 * BUTTON_DELTA_Y, BUTTONWIDTH, BUTTONHEIGHT },
    { IDC_BUTTON_STOP,     "&Stop",       &c_CButton_Stop,     WS_GROUP | WS_TABSTOP, MARGIN_X + 0 * BUTTON_DELTA_X, 2 * MARGIN_Y + 1 * BUTTON_DELTA_Y, BUTTONS_WIDTH, BUTTONHEIGHT },
};

/////////////////////////////////////////////////////////////////////////////
// CRHYesNoToAllDialog dialog


CRHYesNoToAllDialog::CRHYesNoToAllDialog(bool Topmost, CWnd* pParent /*=NULL*/)
	: CDialog(CRHYesNoToAllDialog::IDD, pParent)
// vvv CRH
, CRHpParent(pParent)
, CRHTopmost(Topmost)
// ^^^ CRH
{
	//{{AFX_DATA_INIT(CRHYesNoToAllDialog)
	//}}AFX_DATA_INIT

// vvv CRH
        bEnableParent = FALSE;
        hWndParent = NULL;

        CRHYesToAll = false;
        CRHNoToAll = false;
        CRHCancel = false;

        CRHOnPaintShouldEndModalLoop = false;

        CRHIconWidthPlusGap = 0;
        CRHIconHeight = 0;
// ^^^ CRH
}


void CRHYesNoToAllDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CRHYesNoToAllDialog)
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CRHYesNoToAllDialog, CDialog)
	//{{AFX_MSG_MAP(CRHYesNoToAllDialog)
	ON_WM_PAINT()
	ON_WM_ERASEBKGND()
	ON_WM_WINDOWPOSCHANGED()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_BUTTON_YES, OnButtonYes)
	ON_BN_CLICKED(IDC_BUTTON_NO, OnButtonNo)
	ON_BN_CLICKED(IDC_BUTTON_YESTOALL, OnButtonYestoall)
	ON_BN_CLICKED(IDC_BUTTON_NOTOALL, OnButtonNotoall)
	ON_BN_CLICKED(IDC_BUTTON_CANCEL, OnButtonCancel)
	ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRHYesNoToAllDialog message handlers

void CRHYesNoToAllDialog::CRHDisplay()
{
    // vvv code copied from CDialog::DoModal() in DLGCORE.CPP and modified (see http://www.codeproject.com/dialog/notmodaldialogs.asp)
    // disable parent (before creating dialog)
    /*HWND*/ hWndParent = PreModal();
    //AfxUnhookWindowCreate();
    /*BOOL*/ bEnableParent = FALSE;
    if (hWndParent != NULL && ::IsWindowEnabled(hWndParent))
    {
	    ::EnableWindow(hWndParent, FALSE);
	    bEnableParent = TRUE;
    }
    // ^^^ code copied from CDialog::DoModal() in DLGCORE.CPP and modified (see http://www.codeproject.com/dialog/notmodaldialogs.asp)

    // vvv see http://www.codeproject.com/dialog/xmessagebox.asp XMessageBox.cpp
    NONCLIENTMETRICS ncm;
    memset(&ncm, 0, sizeof(ncm));
    ncm.cbSize = sizeof(ncm);
    ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
    vCFont.CreateFontIndirect(&ncm.lfMessageFont);
    // ^^^ see http://www.codeproject.com/dialog/xmessagebox.asp XMessageBox.cpp

    int FacenameNWideChars = ::MultiByteToWideChar(CP_ACP, 0, 
                                                   ncm.lfMessageFont.lfFaceName, sizeof(ncm.lfMessageFont.lfFaceName),
                                                   NULL, 0);
    int FacenameNBytes = FacenameNWideChars * sizeof(WCHAR);

    struct X
    {
        DLGTEMPLATE vDLGTEMPLATE;
        struct
        {
            WORD Menu;
            WORD Class;
            WORD Caption;
            WORD PointSize;
            char FaceName[4];
        } dbInfo;
    };
    char *buffer = new char[sizeof(X) + FacenameNBytes];
    X *pX = (X *)buffer;
    memset(pX, 0, sizeof(X) + FacenameNBytes);

    pX->vDLGTEMPLATE.style = WS_POPUP | WS_BORDER | WS_CAPTION | WS_VISIBLE | DS_SETFONT;
    pX->vDLGTEMPLATE.dwExtendedStyle = 0;
    pX->vDLGTEMPLATE.cdit = 0;
    pX->vDLGTEMPLATE.x = 0;
    pX->vDLGTEMPLATE.y = 0;
    pX->vDLGTEMPLATE.cx = MARGIN_X + BUTTONS_WIDTH + MARGIN_X;
    pX->vDLGTEMPLATE.cy = MARGIN_Y + GAP_Y + CONTROLS_MINIMUM_HEIGHT + MARGIN_Y;
    pX->dbInfo.PointSize = (WORD)ncm.lfMessageFont.lfHeight;
    ::MultiByteToWideChar(CP_ACP, 0, 
                          ncm.lfMessageFont.lfFaceName, sizeof(ncm.lfMessageFont.lfFaceName),
                          (LPWSTR)pX->dbInfo.FaceName, FacenameNWideChars);
    VERIFY(CreateIndirect(&pX->vDLGTEMPLATE, CRHpParent));
    delete[] buffer;

    if (CRHTopmost)
        SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
            // see http://www.codeproject.com/dialog/dlgboxtricks.asp
    ShowWindow(SW_SHOWNORMAL);

    {
        CRect vCRect;

        c_CButton_Yes.GetWindowRect(vCRect);    // get the screen coordinates of the Yes button
        ScreenToClient(&vCRect);                // convert to coordinates within the dialog box
        CRHLeftMarginWidth = CRHButtonsLeft = vCRect.left;
        CRHButtonsTopOriginal = CRHButtonsTop = vCRect.top;

        GetWindowRect(&vCRect);
        CRHMinimumWidth  = vCRect.Width();
        CRHMinimumHeight = vCRect.Height();

        c_CButton_Stop.GetWindowRect(&vCRect);
        CRHMarginsWidth = CRHMinimumWidth - vCRect.Width();
    
        CRHFindWindowPosition();

        if (CRHIconHeight != 0)
        {
            SetWindowPos(NULL,
                         0, 0,
                         CRHMinimumWidth, CRHMinimumHeight + CRHIconHeight,
                         SWP_NOMOVE);
        }
    }

    CRHAutoAnswer(false);
        // enable/diable buttons and set the focus appropriately
}

CRHYesNoToAllDialog::~CRHYesNoToAllDialog()
{
    // vvv code copied from CDialog::DoModal() in DLGCORE.CPP (see http://www.codeproject.com/dialog/notmodaldialogs.asp)
    if (bEnableParent)
	    ::EnableWindow(hWndParent, TRUE);
    if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd)
	    ::SetActiveWindow(hWndParent);
    // ^^^ code copied from CDialog::DoModal() in DLGCORE.CPP (see http://www.codeproject.com/dialog/notmodaldialogs.asp)
}

void CRHYesNoToAllDialog::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos) 
{
	CDialog::OnWindowPosChanged(lpwndpos);
	
	// TODO: Add your message handler code here
// vvv CRH
        CRHFindWindowPosition();
// ^^^ CRH
}

void CRHYesNoToAllDialog::CRHFindWindowPosition()
{
        CRect vCRect;
        GetWindowRect(&vCRect);
        CRHCentreX = vCRect.CenterPoint().x;
        CRHCentreY = vCRect.CenterPoint().y;
        CRHTop     = vCRect.top;
}

void CRHYesNoToAllDialog::OnOK() 
{
	// TODO: Add extra validation here
	
	//CRH CDialog::OnOK();
}

void CRHYesNoToAllDialog::OnCancel() 
{
	// TODO: Add extra cleanup here
// vvv CRH
        OnButtonCancel();
// ^^^ CRH
	//CRH CDialog::OnCancel();
}

void CRHYesNoToAllDialog::OnButtonYes() 
{
	// TODO: Add your control notification handler code here
// vvv CRH
        EndModalLoop(IDYES);
// ^^^ CRH
}

void CRHYesNoToAllDialog::OnButtonNo() 
{
	// TODO: Add your control notification handler code here
// vvv CRH
        EndModalLoop(IDNO);
// ^^^ CRH
}

void CRHYesNoToAllDialog::OnButtonYestoall() 
{
	// TODO: Add your control notification handler code here
// vvv CRH
        CRHYesToAll = true;
        CRHAutoAnswer(true);
        EndModalLoop(IDYES);
// ^^^ CRH
}

void CRHYesNoToAllDialog::OnButtonNotoall() 
{
	// TODO: Add your control notification handler code here
// vvv CRH
        CRHNoToAll = true;
        CRHAutoAnswer(true);
        EndModalLoop(IDNO);
// ^^^ CRH
}

void CRHYesNoToAllDialog::OnButtonCancel() 
{
	// TODO: Add your control notification handler code here
// vvv CRH
        /* if we're autoanswering the questions then treat this as a Stop,
           if we're not autoanswering the questions then treat this as a Cancel ... */
        if (CRHYesToAll || CRHNoToAll)
        {
            OnButtonStop();
        }
        else
        {
            CRHCancel = true;
            EndModalLoop(IDCANCEL);
        }
// ^^^ CRH
}

void CRHYesNoToAllDialog::OnButtonStop() 
{
	// TODO: Add your control notification handler code here
// vvv CRH
        CRHYesToAll = false;
        CRHNoToAll = false;
        CRHAutoAnswer(false);
        EndModalLoop(0);
// ^^^ CRH
}

int CRHYesNoToAllDialog::CRHMessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption, UINT nType /*= MB_OK*/)
{
    CRHType = nType;
    CRHDetermineDefaultButton();

    // if we haven't actually displayed the box yet then do it now ...
    if (m_hWnd == NULL)
        CRHDisplay();

    if (lpszCaption == NULL)
	lpszCaption = AfxGetAppName();

    // set the title of the dialog box, but only if it's changed (to prevent it flickering) ...
    CString vCString;
    GetWindowText(vCString);
    if (vCString.Compare(lpszCaption) != 0)
        SetWindowText(lpszCaption);

    if (CRHCancel)
        return(IDCANCEL);

    CRHAdjustSizes(lpszText);
    c_CStatic_Question.SetWindowText(lpszText);
    Invalidate();

    if (CRHYesToAll || CRHNoToAll)
    {
        CRHOnPaintShouldEndModalLoop = true;
            // so that RunModalLoop() won't end until OnPaint() (or OnButtonStop()) gets called
        RunModalLoop();
        CRHOnPaintShouldEndModalLoop = false;
            // in case it was the EndModalLoop() in OnButtonStop() that stopped us

        if (CRHYesToAll)
            return(IDYES);
        if (CRHNoToAll)
            return(IDNO);
    }

    CRHSetDefaultButton();

    int rc = RunModalLoop();
    // rc is now IDYES or IDNO, according to which OnButton...() routine called EndModalLoop()
    return(rc);
}

void CRHYesNoToAllDialog::CRHSetDefaultButton()
{
    SetDefID(DefaultButtonID);
    GotoDlgCtrl(pDefaultButton);
        /* This is better than c_CButton_Yes.SetFocus(), because that would
           go straight to the window manager, bypassing the dialog manager.
           See http://weblogs.asp.net/oldnewthing/archive/2004/08/02/205624.aspx */
}

void CRHYesNoToAllDialog::CRHAutoAnswer(bool Flag)
{
    c_CButton_Yes.EnableWindow(!Flag);
    c_CButton_No.EnableWindow(!Flag);
    c_CButton_YesToAll.EnableWindow(!Flag);
    c_CButton_NoToAll.EnableWindow(!Flag);
    c_CButton_Stop.EnableWindow(Flag);

    if (Flag)
    {
        SetDefID(IDC_BUTTON_STOP);
        GotoDlgCtrl(&c_CButton_Stop);
            /* This is better than c_CButton_Stop.SetFocus(), because that would
               go straight to the window manager, bypassing the dialog manager.
               See http://weblogs.asp.net/oldnewthing/archive/2004/08/02/205624.aspx */
    }
    else
        CRHSetDefaultButton();
}

BOOL CRHYesNoToAllDialog::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default
// vvv CRH
        if (CRHOnPaintShouldEndModalLoop)
            return(1);  // claim that we've erased the background
// ^^^ CRH
	return CDialog::OnEraseBkgnd(pDC);
}

void CRHYesNoToAllDialog::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
// vvv CRH
        if (CRHOnPaintShouldEndModalLoop)
        {
            CRHOnPaintShouldEndModalLoop = false;
            EndModalLoop(0);
        }
// ^^^ CRH
	// Do not call CDialog::OnPaint() for painting messages
}

void CRHYesNoToAllDialog::CRHUpdateProgressBar(int SoFar, int Total)
{
    c_CRHProgressCtrl.SetRange32(0, Total);
    c_CRHProgressCtrl.SetPos(SoFar);
}

void CRHYesNoToAllDialog::CRHAdjustSizes(LPCTSTR lpszText)
{
    CFont m_DefaultFont;
    CString str(lpszText);
    CWnd *pMyWnd = this;

    // vvv see http://msdn.microsoft.com/msdnmag/issues/1000/c/default.aspx

    // create window DC
    CWindowDC dc(pMyWnd);

    CRect rc(0,0,0,0);

    // select font into DC
    CFont* pOldFont = dc.SelectObject(&vCFont);
    // compute text size
    dc.DrawText(str, rc, DT_CALCRECT | DT_EXPANDTABS);

    // restore old font�required
    dc.SelectObject(pOldFont);

    // ^^^ see http://msdn.microsoft.com/msdnmag/issues/1000/c/default.aspx

    if (rc.right  > CRHQuestionWidth
     || rc.bottom > CRHQuestionHeight)
    {
        int DeltaX = 0;
        int DeltaY = 0;
        int Width = max(CRHMinimumWidth, CRHIconWidthPlusGap + max(CRHQuestionWidth, rc.right) + CRHMarginsWidth);

        if (CRHQuestionWidth < rc.right)
        {
            CRHQuestionWidth = rc.right;

            int ButtonsLeftNew = CRHLeftMarginWidth + (Width - CRHMinimumWidth) / 2;
            DeltaX = ButtonsLeftNew - CRHButtonsLeft;
            CRHButtonsLeft = ButtonsLeftNew;
        }

        if (CRHQuestionHeight < rc.bottom)
        {
            CRHQuestionHeight = rc.bottom;

            int ButtonsTopNew = CRHButtonsTopOriginal;
            if (CRHQuestionHeight > CRHIconHeight)
                ButtonsTopNew += (CRHQuestionHeight - CRHIconHeight);

            DeltaY = ButtonsTopNew - CRHButtonsTop;
            CRHButtonsTop = ButtonsTopNew;
        }

        if (DeltaX != 0 || DeltaY != 0)
            CRHMoveControls(DeltaX, DeltaY);

        int QuestionTop = CRHTopMarginHeight;
        if (CRHIconHeight > CRHQuestionHeight)
            QuestionTop += (CRHIconHeight - CRHQuestionHeight) / 2;
        c_CStatic_Question.SetWindowPos(NULL, 
                                        CRHLeftMarginWidth + CRHIconWidthPlusGap, QuestionTop,
                                        CRHQuestionWidth, CRHQuestionHeight, 
                                        0);

        int Height = CRHMinimumHeight + max(CRHIconHeight, CRHQuestionHeight);
        SetWindowPos(NULL, 
                     CRHCentreX - Width / 2, CRHCentreY - Height / 2,
                     Width, 
                     Height, 
                     0);

        UpdateWindow(); // if we don't do this the controls don't get repainted
    }
}

void CRHYesNoToAllDialog::CRHMoveControls(int DeltaX, int DeltaY)
{
    /* we have to call SetWindowPos() for the controls in reverse order
       (if we don't then the tab order for the controls ends up backwards) ... */
    for (int ControlN = N(CRHControlInfos) - 1; ControlN >= 0; ControlN--)
    {
        CRHControlInfo *pCRHControlInfo = &CRHControlInfos[ControlN];
        CWnd *pControl = pCRHControlInfo->pControl;

        pCRHControlInfo->left += DeltaX;
        pCRHControlInfo->top  += DeltaY;
        pControl->SetWindowPos(NULL,
                               pCRHControlInfo->left, pCRHControlInfo->top,
                               0, 0,
                               SWP_NOSIZE);
    }
}

BOOL CRHYesNoToAllDialog::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
// vvv CRH

    char *IconID = NULL;
    if ((CRHType & (MB_ICONHAND | MB_ICONSTOP | MB_ICONERROR)) != 0)
        IconID = IDI_HAND;
    else
    if ((CRHType & MB_ICONQUESTION) != 0)
        IconID = IDI_QUESTION;
    else
    if ((CRHType & (MB_ICONEXCLAMATION | MB_ICONWARNING)) != 0)
        IconID = IDI_EXCLAMATION;
    else
    if ((CRHType & (MB_ICONASTERISK | MB_ICONINFORMATION)) != 0)
        IconID = IDI_ASTERISK;

    // create the Icon control if necessary ...
    if (IconID != NULL)
    {
        HICON vHICON = ::LoadIcon(NULL, IconID);
        int IconWidth = ::GetSystemMetrics(SM_CXICON);
        CRHIconHeight = ::GetSystemMetrics(SM_CYICON);

        CRect vCRect(MARGIN_X, MARGIN_Y,
                     MARGIN_X, MARGIN_Y);
        MapDialogRect(&vCRect);
        vCRect.right  = vCRect.left + IconWidth;
        vCRect.bottom = vCRect.top + CRHIconHeight;

        c_CStatic_Icon.Create("", SS_ICON | WS_CHILD, vCRect, this);
        c_CStatic_Icon.SetIcon(vHICON);
        c_CStatic_Icon.ShowWindow(SW_SHOWNORMAL);

        CRHIconWidthPlusGap = vCRect.right;
    }

    // create the Question control ...
    {
        CRect vCRect(MARGIN_X,                 MARGIN_Y,
                     MARGIN_X + BUTTONS_WIDTH, MARGIN_Y);
        MapDialogRect(&vCRect);
        vCRect.left += CRHIconWidthPlusGap;

        c_CStatic_Question.Create("", SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_CHILD, vCRect, this);
        c_CStatic_Question.SetFont(&vCFont);
        c_CStatic_Question.ShowWindow(SW_SHOWNORMAL);

        CRHTopMarginHeight = vCRect.top;
        CRHQuestionHeight = 0;
        CRHQuestionWidth = 0;
    }

    // create the Button controls ...
    for (int ButtonN = 0; ButtonN < N(CRHButtonInfos); ButtonN++)
    {
        CRHButtonInfo *pCRHButtonInfo = &CRHButtonInfos[ButtonN];
        CButton *pCButton = &(this->*(pCRHButtonInfo->pCButton));

        CRect vCRect(pCRHButtonInfo->lx,                         pCRHButtonInfo->ty, 
                     pCRHButtonInfo->lx + pCRHButtonInfo->Width, pCRHButtonInfo->ty + pCRHButtonInfo->Height);
        MapDialogRect(&vCRect);
        vCRect.top    += CRHIconHeight;
        vCRect.bottom += CRHIconHeight;

        pCButton->Create(pCRHButtonInfo->Text, pCRHButtonInfo->Style | WS_CHILD | WS_VISIBLE, vCRect, this, pCRHButtonInfo->nID);
        pCButton->SetFont(&vCFont);
        pCButton->ShowWindow(SW_SHOWNORMAL);

        CRHControlInfos[ButtonN].pControl = pCButton;
    }

    // create the Progress Bar control ...
    {
        CRect vCRect(MARGIN_X,                 2 * MARGIN_Y + 2 * BUTTON_DELTA_Y, 
                     MARGIN_X + BUTTONS_WIDTH, 2 * MARGIN_Y + 2 * BUTTON_DELTA_Y + BUTTONHEIGHT);
        MapDialogRect(&vCRect);
        vCRect.top    += CRHIconHeight;
        vCRect.bottom += CRHIconHeight;

        c_CRHProgressCtrl.Create(PBS_SMOOTH, vCRect, this, IDC_CRHPROGRESSCTRL);
        c_CRHProgressCtrl.ShowWindow(SW_SHOWNORMAL);

        CRHControlInfos[N(CRHControlInfos) - 1].pControl = &c_CRHProgressCtrl;
    }

    /* find out where the Buttons and the Progress Bar controls are
       (so that we can move them down if the question goes onto 2 or more lines) ... */
    for (int ControlN = 0; ControlN < N(CRHControlInfos); ControlN++)
    {
        CRHControlInfo *pCRHControlInfo = &CRHControlInfos[ControlN];
        CWnd *pControl = pCRHControlInfo->pControl;

        CRect vCRect;
        pControl->GetWindowRect(vCRect);    // get the screen coordinates of the control
        ScreenToClient(&vCRect);            // convert to coordinates within the dialog box
        pCRHControlInfo->left = vCRect.left;
        pCRHControlInfo->top  = vCRect.top;
    }

// ^^^ CRH
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CRHYesNoToAllDialog::CRHDetermineDefaultButton()
{
    UINT ButtonInfo = (CRHType & (MB_DEFBUTTON1 | MB_DEFBUTTON2 | MB_DEFBUTTON3 | MB_DEFBUTTON4 | MB_DEFBUTTON5));
    switch (ButtonInfo)
    {
    default:            DefaultButtonID = IDC_BUTTON_YES;       pDefaultButton = &c_CButton_Yes;        break;
    case MB_DEFBUTTON2: DefaultButtonID = IDC_BUTTON_NO;        pDefaultButton = &c_CButton_No;         break;
    case MB_DEFBUTTON3: DefaultButtonID = IDC_BUTTON_YESTOALL;  pDefaultButton = &c_CButton_YesToAll;   break;
    case MB_DEFBUTTON4: DefaultButtonID = IDC_BUTTON_NOTOALL;   pDefaultButton = &c_CButton_NoToAll;    break;
    case MB_DEFBUTTON5: DefaultButtonID = IDC_BUTTON_CANCEL;    pDefaultButton = &c_CButton_Cancel;     break;
    }
}

/////////////////////////////////////////////////////////////////////////////
// CRHProgressCtrl

CRHProgressCtrl::CRHProgressCtrl()
{
}

CRHProgressCtrl::~CRHProgressCtrl()
{
}


BEGIN_MESSAGE_MAP(CRHProgressCtrl, CProgressCtrl)
	//{{AFX_MSG_MAP(CRHProgressCtrl)
	ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRHProgressCtrl message handlers

BOOL CRHProgressCtrl::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default
// vvv CRH
    return(1);
// ^^^ CRH
	return CProgressCtrl::OnEraseBkgnd(pDC);
}

// vvv CRH
// ^^^ CRH

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Chris Hills
Software Developer (Senior)
United Kingdom United Kingdom
I've been programming computers since about 1968. I started at school with Algol 60 on an Elliott 803. From there I progressed through the Z80 and other microprocessors to the PC, DOS and Windows, Pascal, C and C++.
 
My other interests include astronomy and classical music. All of my contributions to Code Project have arisen from programs I've written in these areas.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 4 Jan 2005
Article Copyright 2005 by Chris Hills
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid