Let me begin with the goal: I'm going to set a static control's background as a dialog while the static control content is not a fixed string and after a switch case statement,changes. In other word, I'm going to set the background of a static control with a dynamic content to a dialog window with a static bimap image.
To arrive at this goal, three handle messages defined as below: OnEraseBkgnd(), OnDestroy(), OnCtlColor()
To show the texts, after each Switch case statement I set a SetWindowText function:
::SetWindowText(GetDlgItem(IDC_STATIC_FORM)->m_hWnd, ArrayName);
The only problem here was overlapping. All the texts from the previews events or cases remained at SetWindowText
. To solve this problem after each SetWindowText
a InvalidateRect(Null) defined and this problem also solved but during the procedure I received a dialog which was always blinking and if I say technically, flickering. I think the problem is just because of Invalidate which is applied to the whole dialog not just static control. The OnCtlColor is overriden for the dialog not the control. Since I just want the control to invalidate, then I must subclass the CStatic control, override only it's OnCtlColor (not the dialog's), and call only it's Invalidate instead.
My problem:
Assuming I have declared a variable for static control in the main code and initialised it in the constructor I defined a class named CSTATICCTRL with a base class CDialogEX then the message handlers were as follows:
Variable member defined as:
CSTATICCTRL m_STATIC_FORM;
and
BOOL CSTATICCTRL::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
CDC dcMemory;
dcMemory.CreateCompatibleDC(pDC);
CBitmap* pOldbitmap = dcMemory.SelectObject(&Background);
CRect rcClient;
const CSize& sbitmap = bitmapSize;
pDC->BitBlt(0, 0, sbitmap.cx, sbitmap.cy, &dcMemory, 0, 0, SRCCOPY);
/*The BitBlt function performs a bit-block transfer of the color data corresponding to a rectangle of pixels
from the specified source device context into a destination device context.*/
dcMemory.SelectObject(pOldbitmap);
return 1;
//return CDialogEx::OnEraseBkgnd(pDC);
}
HBRUSH CSTATICCTRL::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
//HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
if (pWnd->GetDlgCtrlID() == IDC_STATIC_FORM)
{
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(255, 255, 255));
Invalidate();
}
return (HBRUSH)GetStockObject(NULL_BRUSH);
}
void CSTATICCTRL::OnDestroy() //free the resources created for the bitmap,
{
CDialog::OnDestroy();
Background.DeleteObject(); // Delete Background bitmap
BrushHol.DeleteObject();
// Delete Brush
}
I left these messages on the main code too. Then I tried to invalidate the static control after each switch case in this way:
m_STATIC_FORM.Invalidate();
Furthermore a PreSubclassWindow() handle added at the end of new class as follows.
void CSTATICCTRL::PreSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
CDialogEx::PreSubclassWindow();
ModifyStyle(0, BS_OWNERDRAW); // make the button owner drawn
}
Nothing happened!I don't know what's wrong with my code!! In this new way the static control content changes but it's not transparent and overlaps still exist.
UPDATE:
Actually just now I realized that the new Class doesn't have any effect on the static control and dialog box after commenting some lines!! I think firstly I should active CSTATICCTRL then I can work on its handle messages.
For the dialog code these three handle messages are employed:
BOOL CMainDlg::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
//************************************************************************************
CDC dcMemory;
dcMemory.CreateCompatibleDC(pDC);
CBitmap* pOldbitmap = dcMemory.SelectObject(&Background);
CRect rcClient;
GetClientRect(&rcClient);
const CSize& sbitmap = bitmapSize;
pDC->BitBlt(0, 0, sbitmap.cx, sbitmap.cy, &dcMemory, 0, 0, SRCCOPY);
dcMemory.SelectObject(pOldbitmap);
return TRUE;
//return CDialog::OnEraseBkgnd(pDC);
}
void CMainDlg::OnDestroy() //free the resources created for the bitmap,
{
CDialog::OnDestroy();
// Delete Brush
}
HBRUSH CMainDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
// TODO: Change any attributes of the DC here
return (HBRUSH)GetStockObject(NULL_BRUSH);
}