Solved

OnCtlColor problem...

Posted on 2000-02-23
9
1,271 Views
Last Modified: 2013-11-20
Basically, here goes:

CGraphicalComponent derives from CDialog
CColorStatic derives from CStatic

I want to change the foreground and background colors of a dialog box derived from CGraphicalComponent. CGraphicalComponent has two member variables (m_crefBackground and m_crefForeground) containing the appropriate colors to be used. It also creates a brush called m_brushBackground using CreateSolidBrush(m_crefBackground).

I have trapped WM_CTLCOLOR within CGraphicalComponent:

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

    return m_brushBackground;

//    return hbr;
}

This works ok with most controls (I had to write some more code for my push buttons but that is correct as push buttons do behave differently). However, my particular problem lies in the fact that one of my dialog's controls is a CColorStatic object (derived from CStatic) which needs to have its own background/foreground color.

Thus, I trapped the WM_CTLCOLOR_REFLECT message in the following handler:

HBRUSH CColorStatic::CtlColor(CDC* pDC, UINT nCtlColor)
{
    pDC->SetTextColor(m_crefForeground);
    pDC->SetBkColor(m_crefBackground);

    return (HBRUSH)m_brushBackground;
}

* Note that those m_crefForeground and m_crefBackground members are NOT the same as the ones from CGraphicalComponent - and their values are set through CColorStatic member functions in their parent dialog's WM_INITDIALOG handler.

--

The problem is, obviously, that the calling order is as follows:

1. CGraphicalComponent::OnCtlColor calls CDialog::OnCtlColor
2. CDialog::OnCtlColor reflects the message to the control
3. CColorStatic::CtlColor does its thing
4. CDialog::OnCtlColor returns the brush from CColorStatic::CtlColor if the reflection was trapped - otherwise it returns the default system brush for background painting (gray)
5. CGraphicalComponent::OnCtlColor ignores all of this and returns a custom background brush

---

Basically, here's what I want:

I want all my controls to use the custom brush from CGraphicalComponent BUT not the CColorStatic ones, which have their own background brush.

The only way I was able to make this work was by adding the following check at the beginning of CGraphicalComponent::OnCtlColor :

if(hbr == (HBRUSH)Default()) {
    return m_brushBackground;
}
else {
    return hbr;
}

..and although that solves the background brush problem, it does not help as far as textcolor/textbackground go (in the CColorStatic). The two SetTextColor and SetBkColor commands in CColorStatic::CtlColor are simply useless and my text defaults to typical black on gray.
0
Comment
Question by:bbousquet
  • 5
  • 2
  • 2
9 Comments
 
LVL 23

Expert Comment

by:naveenkohli
ID: 2552504
Why didn't you make check on nCtlColor parameter...

if (nCtlColor == CTLCOLOR_STATIC) {
// Do the didley for static control
}
else {
// go homer
}

Hope it helps.
0
 
LVL 23

Expert Comment

by:naveenkohli
ID: 2552530
Here is sample code from my application.. I am setting the text color only for static control.. You can return a differetn color brush for background.


HBRUSH COptionsDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
      HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
      
      switch (nCtlColor) {
            case CTLCOLOR_EDIT:
                  if (pWnd == &m_HorizNumEdit) {
                        pDC->SetTextColor (RGB (255, 255, 0));
                  }
                  break;
            case CTLCOLOR_STATIC:
                  pDC->SetTextColor (RGB(255, 255, 0));
                  break;
            default:
                  break;
      }
      
      // TODO: Return a different brush if the default is not desired
      return hbr;
}
0
 
LVL 2

Author Comment

by:bbousquet
ID: 2552552
Thanks but it doesn't solve my problem. CGraphicalComponent has absolutely no idea of the CColorStatic's colors. I have been able to get my desired behavior using the following:

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

    CBrush *pBrush = CBrush::FromHandle(hbr);
    if(pBrush != NULL) {
        LOGBRUSH logBrush;
        if(pBrush->GetLogBrush(&logBrush)) {
            if((logBrush.lbStyle == BS_SOLID                  ) &&
               (logBrush.lbColor == GetSysColor(COLOR_BTNFACE))   ) {
                pDC->SetBkColor  (m_crefBackground);
                pDC->SetTextColor(m_crefForeground);
                return m_brushBackground;
            }
        }
    }

    return hbr;
}

[I find this horrible but it is, in my own opinion, nicer than a dynamic_cast]

Any ideas, anyone?

0
 
LVL 2

Author Comment

by:bbousquet
ID: 2552624
Thanks but it doesn't solve my problem. CGraphicalComponent has absolutely no idea of the CColorStatic's colors. I have been able to get my desired behavior using the following:

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

    CBrush *pBrush = CBrush::FromHandle(hbr);
    if(pBrush != NULL) {
        LOGBRUSH logBrush;
        if(pBrush->GetLogBrush(&logBrush)) {
            if((logBrush.lbStyle == BS_SOLID                  ) &&
               (logBrush.lbColor == GetSysColor(COLOR_BTNFACE))   ) {
                pDC->SetBkColor  (m_crefBackground);
                pDC->SetTextColor(m_crefForeground);
                return m_brushBackground;
            }
        }
    }

    return hbr;
}

[I find this horrible but it is, in my own opinion, nicer than a dynamic_cast]

Any ideas, anyone?

0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 2

Author Comment

by:bbousquet
ID: 2552627
Oops. Sorry for the double-comment.
0
 
LVL 10

Accepted Solution

by:
RONSLOW earned 100 total points
ID: 2552804
How about this...

HBRUSH CGraphicalComponent::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
  LRESULT lResult;
  if (pWnd->SendChildNotifyLastMsg(&lResult)) {
    return (HBRUSH)lResult;
  }
  // do whatever you want for
  // everything else
  //
}
0
 
LVL 2

Author Comment

by:bbousquet
ID: 2553274
That's a pretty good idea. That looks a lot like what the CDialog does internally and I hadn't thought of moving that up to CGraphicalComponent.

I'll try this tomorrow and I'll get back to you after that. But I'm pretty sure you'll get your points!

Thanks!
0
 
LVL 2

Author Comment

by:bbousquet
ID: 2555120
RONSLOW,

I just tested your proposed answer and it works perfectly.

Thank you very much for an accurate and prompt answer.

Grade A awarded.
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2556185
Thank you .. it often helps to see what MFC does itself.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
substring method in java 1 79
ffmpeg - "rtsp://...... Operation not permitted" 4 69
withoutTen challenge 14 88
Change to event 1 74
Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
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.
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

747 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

13 Experts available now in Live!

Get 1:1 Help Now