Solved

Can I change the colour of a CDialog and CFormView?

Posted on 2004-08-10
39
5,280 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 

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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Turn a spreadsheet into a vba executable. 2 102
ShiftLeft challenge 21 95
matchUp  challenge 9 131
Bartender label printing - switch on and off graphics 3 91
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
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.
Are you ready to implement Active Directory best practices without reading 300+ pages? You're in luck. In this webinar hosted by Skyport Systems, you gain insight into Microsoft's latest comprehensive guide, with tips on the best and easiest way…

734 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