Solved

Can I change the colour of a CDialog and CFormView?

Posted on 2004-08-10
39
5,212 Views
Last Modified: 2013-11-20
Can I change the (bkgd) colour of a CDialog and CFormView? If so, how?
0
Comment
Question by:mwcmp
  • 20
  • 10
  • 5
  • +2
39 Comments
 
LVL 12

Assisted Solution

by:migel
migel earned 25 total points
ID: 11766453
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
 

Author Comment

by:mwcmp
ID: 11766560
error C2065: 'CTLCOLOR_DLG' : undeclared identifier
warning C4018: '==' : signed/unsigned mismatch
0
 

Author Comment

by:mwcmp
ID: 11766594
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
 
LVL 5

Assisted Solution

by:millsoft
millsoft earned 25 total points
ID: 11766618
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
 
LVL 5

Expert Comment

by:millsoft
ID: 11766622
Then it will be available in OnCtlColor
0
 
LVL 5

Expert Comment

by:millsoft
ID: 11766634
 if (nCtlColor == (UINT) CTLCOLOR_DLG || (UINT) CTLCOLOR_STATIC  == nCtlColor)
   return  (HBRUSH)m_BackBrush;
0
 

Author Comment

by:mwcmp
ID: 11766682
Still the same error:
>error C2065: 'CTLCOLOR_DLG' : undeclared identifier

Do I need to include anything? BTW, I am using EVC.
0
 
LVL 55

Accepted Solution

by:
Jaime Olivares earned 150 total points
ID: 11767495
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
 

Author Comment

by:mwcmp
ID: 11769379
>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
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11772593
Sorry, translating from my own code...
'fondo' must be m_bg.
0
 
LVL 3

Expert Comment

by:jimbucci
ID: 11772599
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
 

Author Comment

by:mwcmp
ID: 11774389
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
 

Author Comment

by:mwcmp
ID: 11774459
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
 
LVL 3

Expert Comment

by:jimbucci
ID: 11774714
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
 

Author Comment

by:mwcmp
ID: 11774811
Win CE
0
 
LVL 3

Expert Comment

by:jimbucci
ID: 11774950
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
 

Author Comment

by:mwcmp
ID: 11775029
my formView remains white..
0
 

Author Comment

by:mwcmp
ID: 11775473
Jim

Do you have any idea what went wrong?
0
 
LVL 3

Expert Comment

by:jimbucci
ID: 11775571
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
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 

Author Comment

by:mwcmp
ID: 11776208
Ok. There is no error, but the view is still white.
Any more suggestion?
0
 
LVL 3

Expert Comment

by:jimbucci
ID: 11776234
Comment out the call to CView::OnEraseBkgnd(pDC) - although I don't know what affect that will have.
Jim
0
 

Author Comment

by:mwcmp
ID: 11776271
Haha. Still the same results.
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11776284
I think OnCtlColor is the proper way.
0
 

Author Comment

by:mwcmp
ID: 11776335
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
 
LVL 55

Assisted Solution

by:Jaime Olivares
Jaime Olivares earned 150 total points
ID: 11776412
don't know why is not defined but try with:
#define CTLCOLOR_DLG            4
#define CTLCOLOR_SCROLLBAR      5
0
 

Author Comment

by:mwcmp
ID: 11776639
Jaime
Ok. Thanks. It works now.
Can that piece of code work for CFormView too?
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11776655
Not tried, just do it.
0
 
LVL 3

Expert Comment

by:jimbucci
ID: 11776709
It must be a WinCE thing - because the code I gave you works on a Windows PC - Win2K.
Jim
0
 

Author Comment

by:mwcmp
ID: 11776894
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
 

Author Comment

by:mwcmp
ID: 11776915
What is the equivlent of OnInitDialog for a view?
0
 
LVL 3

Expert Comment

by:jimbucci
ID: 11776940
OnInitialUpdate()
0
 
LVL 3

Expert Comment

by:jimbucci
ID: 11776955
Does WinCE send a WM_ERASEBKGND message?
0
 

Author Comment

by:mwcmp
ID: 11777054
>Does WinCE send a WM_ERASEBKGND message?
I suppose not.


OnCtlColor don't seems to work for view
0
 
LVL 3

Expert Comment

by:jimbucci
ID: 11777120
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
 

Author Comment

by:mwcmp
ID: 11777268
Hmm.. Can't seems to work either
0
 

Author Comment

by:mwcmp
ID: 11785533
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
 

Author Comment

by:mwcmp
ID: 11785659
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
 
LVL 3

Assisted Solution

by:jimbucci
jimbucci earned 100 total points
ID: 11786739
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
 

Author Comment

by:mwcmp
ID: 11790581
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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now