1

Take this variable mapping in a CDialog:

DDX_Check(pDX, IDC_CHECK_PREVIEW_CURRENT_WEEK, m_bPreviewCurrentWeek);

By design in the IDE it to map to a BOOL variable instead of a bool variable.

I know that under normal circumstances you can just use a bool variable wherever TRUE or FALSE is used. But, when I try changing my member variable to a bool it fails to compile on the DDX_Check routine.

Can we use bool with a checkbox control?

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
  • 3
    No. The API takes an int (or BOOL), which is not interchangeable with bool. Just make a property method `bool IsThisChecked() const {return m_bChecked != 0;}` – franji1 May 10 '22 at 21:02
  • 1
    No, you can't, unless you write an overloaded `DDX_Check` function that takes a `bool &` as third parameter instead of an `BOOL`. – Jabberwocky May 11 '22 at 07:14
  • @Jabberwocky Thanks for the reminder. Added an answer. – Andrew Truckle May 11 '22 at 12:25
  • This question does not even make sense. How you could ever represent the `BST_INDETERMINATE` with a boolean? – sergiol May 13 '22 at 14:15
  • @sergiol Because with the standard checkbox mechanism in MFC I am not using the Tri state functionality. It is a simple toggle on or off. So it does not apply. Just like it does not apply in the MFC native code. See my answer. – Andrew Truckle May 13 '22 at 15:12

1 Answers1

1

@Jabberwocky's comment reminded me that I have already implemented some custom DDX routines:

So I delved into the MFC source and modified a copy in my own cpp file:

void AFXAPI DDX_CheckBool(CDataExchange* pDX, int nIDC, bool& value)
{
    pDX->PrepareCtrl(nIDC);
    HWND hWndCtrl;
    pDX->m_pDlgWnd->GetDlgItem(nIDC, &hWndCtrl);
    if (pDX->m_bSaveAndValidate)
    {
        value = static_cast<bool>(::SendMessage(hWndCtrl, BM_GETCHECK, 0, 0L));
        //ASSERT(value >= 0 && value <= 2);
    }
    else
    {
        //if (value < 0 || value > 2)
        //{
        //  TRACE(traceAppMsg, 0, "Warning: dialog data checkbox value (%d) out of range.\n",
        //      value);
        //  value = 0;  // default to off
        //}
        ::SendMessage(hWndCtrl, BM_SETCHECK, static_cast<WPARAM>(value), 0L);
    }
}

I commented out the validation checks since bool has only one of two values anyway. Shout if you think that was a mistake.

So I am now able to do this:

DDX_CheckBool(pDX, IDC_CHECK_SELECT_NAMES, m_bSelectStartingNames);

It works fine.

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164