What is the default background color of a CEdit control placed in some CPropertyPage?
What puzzles me is that the background color differs when a host of CEdit is changed. That is, if one has a dialog with a CTabCtrl in it which has CEdit, the background of a read-only CEdit is grey (I suppose it is the default one in Windows). However if a CPropertySheet and CPropertyPage is used instead of a CDialog the background of the read-only CEdit is white.
With CDialog:

And with CPropertySheet:

The code used to construct these windows:
CDialog based
// DialogWithEdit.h
#pragma once
class CDialogWithEdit : public CDialog
{
DECLARE_DYNAMIC(CDialogWithEdit)
public:
CDialogWithEdit(CWnd* pParent = NULL); // standard constructor
virtual ~CDialogWithEdit();
enum { IDD = IDD_DIALOG1 };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnInitDialog();
DECLARE_MESSAGE_MAP()
private:
CEdit m_regularEdit;
CEdit m_readOnlyEdit;
};
// DialogWithEdit.cpp : implementation file
#include "stdafx.h"
#include "PropertySheetTest.h"
#include "DialogWithEdit.h"
#include "afxdialogex.h"
IMPLEMENT_DYNAMIC(CDialogWithEdit, CDialog)
CDialogWithEdit::CDialogWithEdit(CWnd* pParent /*=NULL*/)
: CDialog(CDialogWithEdit::IDD, pParent){ }
CDialogWithEdit::~CDialogWithEdit(){ }
void CDialogWithEdit::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CDialogWithEdit, CDialog)
END_MESSAGE_MAP()
BOOL CDialogWithEdit::OnInitDialog ()
{
BOOL retVal = CDialog::OnInitDialog ();
WCHAR tabStr[5] = {0};
wcscpy (tabStr, L"Tab1");
TCITEM tab1 = {0};
tab1.mask = TCIF_TEXT;
tab1.cchTextMax = 5;
tab1.pszText = tabStr;
CTabCtrl * tabCtrl = (CTabCtrl*) GetDlgItem (IDC_TAB1);
tabCtrl->InsertItem (0, &tab1);
RECT tabRc = {0};
tabCtrl->GetItemRect (0, &tabRc);
m_readOnlyEdit.Create (WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_AUTOHSCROLL|ES_READONLY, CRect (10, 30, 100, 50), GetDlgItem (IDC_TAB1), 5);
m_readOnlyEdit.SetWindowText (L"read only");
m_regularEdit.Create (WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_AUTOHSCROLL, CRect (110, 30, 200, 50), GetDlgItem (IDC_TAB1), 5+1);
m_regularEdit.SetWindowText (L"editable");
return retVal;
}
CPropertySheet based
// SheetX.h
#pragma once
#include "PageX.h"
class CSheetX : public CPropertySheet
{
DECLARE_DYNAMIC(CSheetX)
public:
CSheetX(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
CSheetX(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
virtual ~CSheetX();
protected:
DECLARE_MESSAGE_MAP()
private:
CPageX m_pageX;
};
// SheetX.cpp : implementation file
#include "stdafx.h"
#include "PropertySheetTest.h"
#include "SheetX.h"
IMPLEMENT_DYNAMIC(CSheetX, CPropertySheet)
CSheetX::CSheetX(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
:CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
{ AddPage (&m_pageX); }
CSheetX::CSheetX(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
:CPropertySheet(pszCaption, pParentWnd, iSelectPage)
{ AddPage (&m_pageX); }
CSheetX::~CSheetX() { }
BEGIN_MESSAGE_MAP(CSheetX, CPropertySheet)
END_MESSAGE_MAP()
// PaheX.h
#pragma once
class CPageX : public CPropertyPage
{
DECLARE_DYNAMIC(CPageX)
public:
CPageX();
virtual ~CPageX();
enum { IDD = IDD_PAGEX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnInitDialog ();
DECLARE_MESSAGE_MAP()
private:
CEdit m_readOnlyEdit;
CEdit m_regularEdit;
};
// PageX.cpp : implementation file
#include "stdafx.h"
#include "PropertySheetTest.h"
#include "PageX.h"
#define ID_EDITCTRL 151
IMPLEMENT_DYNAMIC(CPageX, CPropertyPage)
CPageX::CPageX()
: CPropertyPage(CPageX::IDD){ }
CPageX::~CPageX(){ }
void CPageX::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
}
BOOL CPageX::OnInitDialog ()
{
BOOL retVal = CPropertyPage::OnInitDialog ();
m_readOnlyEdit.Create (WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_AUTOHSCROLL|ES_READONLY, CRect (10,10,100,30), this, ID_EDITCTRL);
m_readOnlyEdit.SetWindowText (L"read only");
m_regularEdit.Create (WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_AUTOHSCROLL, CRect (110,10,200,30), this, ID_EDITCTRL+1);
m_regularEdit.SetWindowText (L"editable");
return retVal;
}
BEGIN_MESSAGE_MAP(CPageX, CPropertyPage)
END_MESSAGE_MAP()
I could add a workaround for the white background color by handling WM_CTLCOLORSTATIC in the CPropertyPage and returning brush of the default dialog background color. But this does not seem right to me. On the other hand msdn says that WM_CTLCOLORSTATIC is sent to the parent in order for it to specify the background color. Since the parent of the CEdit control in question is a CPropertyPage I would guess that’s why it returns the white brush.
Or maybe I am doing something wrong with the CPropertyPage?
It is the default Windows behaviour. Thus one has to choose: to stick with default windows behaviour or transfer WM_CTLCOLORSTATIC message from the CPropertyPage to the CPropertySheet which returns its background color (which is grey by default). On classic theme everything works correctly because the colour of the CPropertyPage is grey.