[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 5386
  • Last Modified:

Can I change the colour of a CDialog and CFormView?

Can I change the (bkgd) colour of a CDialog and CFormView? If so, how?
0
mwcmp
Asked:
mwcmp
  • 20
  • 10
  • 5
  • +2
5 Solutions
 
migelCommented:
Hi!
You can handle WM_CTLCOLORDLG in the your dialog class
for example:

// m_BackBrush is the CBrush object member of the your class (NOTE it must be created in the construxtor or OnInitDialog methods)
HBRUSH CColoredDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
   // Call the base class implementation first! Otherwise, it may
   // undo what we're trying to accomplish here.
   HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
  if (nCtlColor == CTLCOLOR_DLG || CTLCOLOR_STATIC  == nCtlColor)
   return  (HBRUSH)m_BackBrush;

return hbr;
}
0
 
mwcmpAuthor Commented:
error C2065: 'CTLCOLOR_DLG' : undeclared identifier
warning C4018: '==' : signed/unsigned mismatch
0
 
mwcmpAuthor Commented:
BTW. I had created m_BackBrush as gobal as I do not get what you mean by creating it in the OnInitDialog.
What I mean is, I created it as:
CBrush m_BackBrush(RGB(255,0,0));

How then can I create it in OnInitDialog, but use it in OnCtlColor?
0
2018 Annual Membership Survey

Here at Experts Exchange, we strive to give members the best experience. Help us improve the site by taking this survey today! (Bonus: Be entered to win a great tech prize for participating!)

 
millsoftCommented:
You need to declare:

CBrush m_BackBrush;

in the class header, and then initialize it in OnInitDialog:

m_BackBrush.CreateSolidBrush( RGB(255,0,0) );
0
 
millsoftCommented:
Then it will be available in OnCtlColor
0
 
millsoftCommented:
 if (nCtlColor == (UINT) CTLCOLOR_DLG || (UINT) CTLCOLOR_STATIC  == nCtlColor)
   return  (HBRUSH)m_BackBrush;
0
 
mwcmpAuthor Commented:
Still the same error:
>error C2065: 'CTLCOLOR_DLG' : undeclared identifier

Do I need to include anything? BTW, I am using EVC.
0
 
Jaime OlivaresSoftware ArchitectCommented:
in your dialog class declaration
   CBitmap m_bg;

in your dialog constructor:

    m_bg.CreateSolidBrush(RGB(255,127,127));        <---- red

Add OnCtrlColor handler:

HBRUSH CYourDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
      HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

      if (!m_bg.GetSafeHandle())
            return hbr;

      switch (nCtlColor) {
            //Edit controls need white background and black text
            //Note the 'return hbr' which is needed to draw the Edit
            //control's internal background (as opposed to text background)
            case CTLCOLOR_EDIT:
                  pDC->SetTextColor(RGB(0,0,0));
                  pDC->SetBkColor(RGB(255,255,255));
                  return hbr;
            //Static controls need black text and same background as m_brush
            case CTLCOLOR_STATIC:
                  LOGBRUSH logbrush;
                  fondo.GetLogBrush( &logbrush );
                  pDC->SetTextColor(RGB(0,0,0));
                  pDC->SetBkColor(logbrush.lbColor);
                  return m_bg;
                                // change background for some controls
            case CTLCOLOR_LISTBOX:
            case CTLCOLOR_SCROLLBAR:
            case CTLCOLOR_BTN:
            case CTLCOLOR_MSGBOX:
                                // change background for dialog itself
            case CTLCOLOR_DLG:
                  return m_bg;
            default:
                  return m_bg;
      }
}
0
 
mwcmpAuthor Commented:
>CBitmap m_bg;
Should this be CBrush? If so, I had changed it...

few errors>>
error C2065: 'fondo' : undeclared identifier
error C2228: left of '.GetLogBrush' must have class/struct/union type
error C2065: 'CTLCOLOR_SCROLLBAR' : undeclared identifier
error C2051: case expression not constant
error C2065: 'CTLCOLOR_DLG' : undeclared identifier
error C2051: case expression not constant

>fondo.GetLogBrush( &logbrush );
Should fondo be m_bg?
0
 
Jaime OlivaresSoftware ArchitectCommented:
Sorry, translating from my own code...
'fondo' must be m_bg.
0
 
jimbucciCommented:
For a CFormview just handle the WM_ERASEBKGND message in the view class - OnEraseBkhgnd(CDC* pDC).
Here you get the DC of the view window.  You can then draw anything you want in this window.  For example - if you wanted to have a gradient background:

BOOL CMyView::OnEraseBkgnd(CDC* pDC)
{
   CView::OnEraseBkgnd(pDC);
   
   Brush pBrush[64];      // use 64 shades of cyan
   CRect rect,rectWnd;

   // Create brushes
   for( int i = 0; i < 64; i++ )
      pBrush[i].CreateSolidBrush( RGB( 0, 255 - (i * 4), 255 - (i * 4) ));
      
   CWnd* pWnd = pDC->GetWindow();
   pWnd->GetClientRect(&rectWnd);
   
   int nWidth = rectWnd.right;
   int nHeight = rectWnd.bottom;
      
   // Paint screen
   for( i=0; i < nHeight; i++ )
   {
      SetRect( &rect, 0, i, nWidth, i + 1);
      pDC->FillRect( &rect, &pBrush[ ( i * 63 ) / nHeight ] );
   }

   // release brushes to Windows
   for( i = 0; i < 64; i++ )
      DeleteObject( pBrush[i] );

   return TRUE;
}

Jim      
0
 
mwcmpAuthor Commented:
Hi Jim

>Brush pBrush[64];
This should be CBrush instead? As I get an error from it.

and also this error>>
>>error C2039: 'GetWindow' : is not a member of 'CDC'
        C:\Windows CE Tools\wce300\Pocket PC 2002\mfc\include\afxwin.h(590) : see declaration of 'CDC'
CWnd* pWnd = pDC->GetWindow();
0
 
mwcmpAuthor Commented:
Hi Jaime

error C2065: 'CTLCOLOR_SCROLLBAR' : undeclared identifier
error C2051: case expression not constant
 error C2065: 'CTLCOLOR_DLG' : undeclared identifier
error C2051: case expression not constant

Wat's the problem? Why  I keep having the same error...
0
 
jimbucciCommented:
Yes, Brush should be CBrush.
When I look up the help for CDC, GetWindow() is a member function - at least in non-Windows CE land.  Is this your platform?
Jim
0
 
mwcmpAuthor Commented:
Win CE
0
 
jimbucciCommented:
ok, well, then get the window from the view itself.
the this pointer is the pointer to the CWnd* of the view

CWnd* pWnd = (CWnd *) this;

Jim
0
 
mwcmpAuthor Commented:
my formView remains white..
0
 
mwcmpAuthor Commented:
Jim

Do you have any idea what went wrong?
0
 
jimbucciCommented:
Try just calling GetClientRect() - you're already in the view class.  Remove the call to get the CWnd * - it's not necessary.
Can you step thru the code?  I don't have a WinCE setup so I don't know what it entails for debugging.
Jim
0
 
mwcmpAuthor Commented:
Ok. There is no error, but the view is still white.
Any more suggestion?
0
 
jimbucciCommented:
Comment out the call to CView::OnEraseBkgnd(pDC) - although I don't know what affect that will have.
Jim
0
 
mwcmpAuthor Commented:
Haha. Still the same results.
0
 
Jaime OlivaresSoftware ArchitectCommented:
I think OnCtlColor is the proper way.
0
 
mwcmpAuthor Commented:
But the problem is I have all these errors

error C2065: 'CTLCOLOR_SCROLLBAR' : undeclared identifier
error C2051: case expression not constant
 error C2065: 'CTLCOLOR_DLG' : undeclared identifier
error C2051: case expression not constant
0
 
Jaime OlivaresSoftware ArchitectCommented:
don't know why is not defined but try with:
#define CTLCOLOR_DLG            4
#define CTLCOLOR_SCROLLBAR      5
0
 
mwcmpAuthor Commented:
Jaime
Ok. Thanks. It works now.
Can that piece of code work for CFormView too?
0
 
Jaime OlivaresSoftware ArchitectCommented:
Not tried, just do it.
0
 
jimbucciCommented:
It must be a WinCE thing - because the code I gave you works on a Windows PC - Win2K.
Jim
0
 
mwcmpAuthor Commented:
It can't seems to work for view.
If that of a dialog is CTLCOLOR_DLG, what's the value for that o a view?
0
 
mwcmpAuthor Commented:
What is the equivlent of OnInitDialog for a view?
0
 
jimbucciCommented:
OnInitialUpdate()
0
 
jimbucciCommented:
Does WinCE send a WM_ERASEBKGND message?
0
 
mwcmpAuthor Commented:
>Does WinCE send a WM_ERASEBKGND message?
I suppose not.


OnCtlColor don't seems to work for view
0
 
jimbucciCommented:
Can you debug your app in WinCE?
OnCtlColor is used for windows controls that are child controls of a window - doesn't get called when a view has no controls.

What if you try setting the the brush color to one color RGB(0,0,255) instead of multiple brushes...
Jim
0
 
mwcmpAuthor Commented:
Hmm.. Can't seems to work either
0
 
mwcmpAuthor Commented:
How abotu RedrawWindow or using a CStatic?
I read about people using them to change their view colour. But I tried and it still remains white. How should I use them?
0
 
mwcmpAuthor Commented:
void CGuiderView::OnDraw(CDC* pDC)
{
      CGuiderDoc* pDoc = GetDocument();
      ASSERT_VALID(pDoc);
      
            CStatic myStatic;
      CRect rect;
      GetClientRect(&rect);
            int nX = rect.left;
            int nY = rect.top;
      myStatic.Create(NULL, WS_CHILD|WS_VISIBLE|SS_CENTER,
            CRect(0,0,nX,nY), this);

      CBrush bb(RGB(255,127,127));
      pDC->FillRect( &rect, &bb);
      myStatic.Invalidate() ;
}

And I manage to change the background colour of my view. But the problem is, the background of my button and static control did not change.
What should I do?
0
 
jimbucciCommented:
mwcmp,

The pDC is the DC of your view - the controls are not affected.
To change the color of a static you need to handle the WM_CTLCOLOR message.  You return an HBRUSH from the call.  But in there you can check the id of the control and change its background.  Here is some code:

HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
   HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
   switch (nCtlColor)      
   {
      case CTLCOLOR_STATIC:
         switch (pWnd->GetDlgCtrlID())
         {
            case IDC_WELCOMETEXT:
      SetStaticFont( pWnd, 6 );
                pDC->SetTextColor(RGB(0, 0, 255));
      break;
           
            default:
               break;
         }
      break;

      default:
         break;
    }

   // TODO: Return a different brush if the default is not desired
   return hbr;
}

This should do the trick.
Jim
0
 
mwcmpAuthor Commented:
What if I had used the code that you had posted, but only that it is in the OnDraw()

void CGuiderView::OnDraw(CDC* pDC)
{
      //CGuiderDoc* pDoc = GetDocument();
      //ASSERT_VALID(pDoc);
      
      CBrush pBrush[64];     // use 64 shades of cyan
      
      for( int i = 0; i < 64; i++ )
                     pBrush[i].CreateSolidBrush( RGB( 0, 255 - (i * 4), 255 - (i * 4) ));

      CRect rect,rectWnd;
      int nWidth, nHeight;

      GetClientRect(&rectWnd);

      nWidth = rectWnd.right;
      nHeight = rectWnd.bottom;

      for( i=0; i < nHeight; i++ )
      {
            SetRect( &rect, 0, i, nWidth, i + 1);
            pDC->FillRect( &rect, &pBrush[ ( i * 63 ) / nHeight ] );
      }

      for( i = 0; i < 64; i++ )
            DeleteObject( pBrush[i] );
}

for this, I cannot set them to gradient colour too, am I right?
the method that you had suggeted only change the colour of the controls into a single colour. Am I right?
0

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

  • 20
  • 10
  • 5
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now