When subclassing a CEdit (MFC) in my ActiveX I had a problem with the stock properties BackColor and ForeColor, that was partially solved by the article Q148242 (if you are interested, look it up at
This way, I could enjoy the backcolor and the forecolor of my choice, but only once: I couldn't «change» them! I had a snippet of program, but not an ActiveX.
Here's my solution:
# Generate an MFC ActiveX Control Wizard application, and select the option that allows you to subclass an Edit control.
# With ClassWizard - Automation, build the stock properties BackColor and ForeColor.
# To handle an OCM_CTLCOLOREDIT reflected window message, declare the following handler function in the .H file of your control's class:
LRESULT OnOcmCtlColor(WPARAM wParam, LPARAM lParam);
# In the header file, declare these three variables:
bool bEven;
CBrush *pbr0, *pbr1;
# In the .CPP file of your control's class, add an ON_MESSAGE entry to the message map:
ON_MESSAGE(OCM_CTLCOLOREDIT, OnOcmCtlColor)
# Also in the .CPP file, implement the OnOcmCtlColor member function to process the reflected message:
LRESULT CTryEditCtrl::OnOcm_CtlColorEdit(WPARAM wParam, LPARAM lParam)
{
COLORREF bk = TranslateColor(GetBackColor()), fr = TranslateColor(GetForeColor());
if (bEven)
{
if (pbr1 != NULL)
{
pbr1->DeleteObject();
delete pbr1, pbr1 = NULL;
}
if (pbr0 == NULL)
pbr0 = new CBrush(bk);
CDC* pdc = CDC::FromHandle((HDC)wParam);
pdc->SetBkMode(TRANSPARENT);
pdc->SetBkColor(bk);
pdc->SetTextColor(fr);
HBRUSH far* hbr = (HBRUSH far*)pbr0->GetSafeHandle();
return ((DWORD)hbr);
}
else
{
if (pbr0 != NULL)
{
pbr0->DeleteObject();
delete pbr0, pbr0 = NULL;
}
if (pbr1 == NULL)
pbr1 = new CBrush(bk);
CDC* pdc = CDC::FromHandle((HDC)wParam);
pdc->SetBkMode(TRANSPARENT);
pdc->SetBkColor(bk);
pdc->SetTextColor(fr);
HBRUSH far* hbr = (HBRUSH far*)pbr1->GetSafeHandle();
return ((DWORD)hbr);
}
}
# Also in the .CPP file, through the ClassWizard-Message Maps, build the message handler OnBackColorChanged, and fill it with the following instruction:
bEven ? bEven = false : bEven = true;
# In the .cpp file's constructor, initialize the variables:
bEven = false;
pbr0 = pbr1 = NULL;
# and in the destructor, clena up the two brush pointers:
if (pbr0 != NULL)
{
pbr0->DeleteObject();
delete pbr0;
}
if (pbr1 != NULL)
{
pbr1->DeleteObject();
delete pbr1;
}
**************************************************
That's all: now the user of the ActiveX can change backcolor and forecolor at will.
This way, I could enjoy the backcolor and the forecolor of my choice, but only once: I couldn't «change» them! I had a snippet of program, but not an ActiveX.
Here's my solution:
# Generate an MFC ActiveX Control Wizard application, and select the option that allows you to subclass an Edit control.
# With ClassWizard - Automation, build the stock properties BackColor and ForeColor.
# To handle an OCM_CTLCOLOREDIT reflected window message, declare the following handler function in the .H file of your control's class:
LRESULT OnOcmCtlColor(WPARAM wParam, LPARAM lParam);
# In the header file, declare these three variables:
bool bEven;
CBrush *pbr0, *pbr1;
# In the .CPP file of your control's class, add an ON_MESSAGE entry to the message map:
ON_MESSAGE(OCM_CTLCOLOREDIT, OnOcmCtlColor)
# Also in the .CPP file, implement the OnOcmCtlColor member function to process the reflected message:
LRESULT CTryEditCtrl::OnOcm_CtlColorEdit(WPARAM wParam, LPARAM lParam)
{
COLORREF bk = TranslateColor(GetBackColor()), fr = TranslateColor(GetForeColor());
if (bEven)
{
if (pbr1 != NULL)
{
pbr1->DeleteObject();
delete pbr1, pbr1 = NULL;
}
if (pbr0 == NULL)
pbr0 = new CBrush(bk);
CDC* pdc = CDC::FromHandle((HDC)wParam);
pdc->SetBkMode(TRANSPARENT);
pdc->SetBkColor(bk);
pdc->SetTextColor(fr);
HBRUSH far* hbr = (HBRUSH far*)pbr0->GetSafeHandle();
return ((DWORD)hbr);
}
else
{
if (pbr0 != NULL)
{
pbr0->DeleteObject();
delete pbr0, pbr0 = NULL;
}
if (pbr1 == NULL)
pbr1 = new CBrush(bk);
CDC* pdc = CDC::FromHandle((HDC)wParam);
pdc->SetBkMode(TRANSPARENT);
pdc->SetBkColor(bk);
pdc->SetTextColor(fr);
HBRUSH far* hbr = (HBRUSH far*)pbr1->GetSafeHandle();
return ((DWORD)hbr);
}
}
# Also in the .CPP file, through the ClassWizard-Message Maps, build the message handler OnBackColorChanged, and fill it with the following instruction:
bEven ? bEven = false : bEven = true;
# In the .cpp file's constructor, initialize the variables:
bEven = false;
pbr0 = pbr1 = NULL;
# and in the destructor, clena up the two brush pointers:
if (pbr0 != NULL)
{
pbr0->DeleteObject();
delete pbr0;
}
if (pbr1 != NULL)
{
pbr1->DeleteObject();
delete pbr1;
}
**************************************************
That's all: now the user of the ActiveX can change backcolor and forecolor at will.