• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2335
  • Last Modified:

Adding OnPaint to a dialog class in WTL

The class is declared as
class CMainDlg : public CDialogImpl<CMainDlg>
I want to handle WM_PAINT at the dialog, but I can't have the parent version run as well if I just put the handler in the message map, so the controls don't get drawn.  Unlike MFC where I call CDialog::OnPaint,
If I call CDialogImpl<CMainDlg>::OnPaint, the compiler dosn't like it at all.

10x
0
yossikally
Asked:
yossikally
  • 6
  • 5
1 Solution
 
Anthony2000Commented:
Have you modified the message map macros and added a handler for WM_PAINT?

example:
      BEGIN_MSG_MAP(CAboutDlg)
            MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
            MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
            COMMAND_ID_HANDLER(IDOK, OnCloseCmd)
            COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd)
                ALT_MSG_MAP(1)
                  MESSAGE_HANDLER(WM_PAINT, OnPaint)
                  MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
                  MESSAGE_HANDLER(WM_CANCELMODE, OnCancelMode)
      END_MSG_MAP()

The OnPaint function will be called for the dialog.

The actual function:
      LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
      {

                //**********    the rest of this code is just an example  ****************
            static TCHAR szText[] = _T("Pre-release (beta)");
            
            static int bRed = 255;            
            static int bDelta = -10;
            
            if (bRed < 30)
                  bDelta = 10;
            else if (bRed > 245)
                  bDelta = -10;

            bRed += bDelta;            

            RECT rc;
            m_warning.GetClientRect(&rc);

            CPaintDC dc(m_warning);
            CDC dcMem;            
            CBitmap bitmap;

            dcMem.CreateCompatibleDC(dc);
            bitmap.CreateCompatibleBitmap(dc, rc.right,  rc.bottom);      
            HBITMAP hOldBitmap = dcMem.SelectBitmap(bitmap);            
            
            dcMem.FillRect(&rc, GetSysColorBrush(COLOR_BTNFACE));
            dcMem.SetTextColor(RGB(bRed,0,0));
            dcMem.SetBkMode(TRANSPARENT);
            dcMem.SelectFont((HFONT)GetStockObject(DEFAULT_GUI_FONT));      
            dcMem.SetTextAlign(TA_CENTER);            
            dcMem.TextOut((rc.left + rc.right) / 2, 0, szText, sizeof szText / sizeof TCHAR - 1);
            dc.BitBlt(0, 0, rc.right,  rc.bottom, dcMem, 0, 0, SRCCOPY);
            dcMem.SelectBitmap(hOldBitmap);      

            return 0;
      }

0
 
yossikallyAuthor Commented:
I did.  I doesn't paint the controls then
0
 
Anthony2000Commented:
Could you post a sample app that demonstates the problem?
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
yossikallyAuthor Commented:
Basically, take the code you wrote, just associate the dialog witha a dialog resource with a coubple of buttons.  Then, if you have code as you show above, the buttons don't get drawn.  When I look at comparable MFC code, I see that the dialog's OnPaint calls the CDialog::OnPaint, but here, I could not find the right semantics to call a base class' OnPaint
0
 
Anthony2000Commented:
yossikally,

The above code is from one of my about boxes. It contains an OK button and it does get drawn. whether. I did discover that the OnPaint function is not called. Even though it looks like it is. I remember having some trouble with this. What version of WTL are you using and what compiler (VS6, VS 2003, VS2005, ...). I will create a simple skeleton and see if I can re-create what you are experiencing.
0
 
yossikallyAuthor Commented:
WTL 7.1  
If you can give me a sample of a dialog with one button, that draw a big X across its screen at its OnPaint, and also draws the button (Of course the button obscures the X), I will raise the points to 250 and gladly give them to you
0
 
yossikallyAuthor Commented:
Compiler - VS 6
0
 
Anthony2000Commented:
I will give a try, but, I will not be able to do it until this evening EST.
0
 
Anthony2000Commented:
yossikally,

I have a version of the about box that I think might do what you want, here is the code.

#if !defined(_ABOUT_H_)
#define _ABOUT_H_

class CAboutDlg :
      public CDialogImpl<CAboutDlg>,
      public CAuxThunk<CAboutDlg>
{
      DWORD                   m_timer;      
      CContainedWindow m_warning;

public:

      CAboutDlg() :
            m_warning(_T("STATIC"), this, 1)
      {
            m_timer = 10;
            InitThunk((TMFP)OnTimer, this);
      }

      enum { IDD = IDD_ABOUT };

      BEGIN_MSG_MAP(CAboutDlg)
            MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
            MESSAGE_HANDLER(WM_DESTROY,    OnDestroy)
            COMMAND_ID_HANDLER(IDOK,       OnCloseCmd)
            COMMAND_ID_HANDLER(IDCANCEL,   OnCloseCmd)
        ALT_MSG_MAP(1)
                MESSAGE_HANDLER(WM_PAINT,      OnPaintWarning)
                  MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgndWarning)
      END_MSG_MAP()

      LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
      {
            CenterWindow(GetParent());

        OutputDebugString("on init\n");
      
            m_warning.SubclassWindow(GetDlgItem(IDC_WARNING));

            return TRUE;
      }

      LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
      {
            ::KillTimer(0, m_timer);
            return 0;
      }

      LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
      {
            EndDialog(wID);
            return 0;
      }

      VOID OnTimer(HWND, UINT, UINT_PTR, DWORD)      
      {
            HWND hWnd = GetDlgItem(IDC_WARNING);
            ::InvalidateRect(hWnd, 0, FALSE);
            ::UpdateWindow(hWnd);
      }

      LRESULT OnPaintWarning(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
      {
       
            static TCHAR szText[] = _T("Pre-release (beta)");
            
            static int bRed = 255;            
            static int bDelta = -10;
            
            if (bRed < 30)
                  bDelta = 10;
            else if (bRed > 245)
                  bDelta = -10;

            bRed += bDelta;            

            RECT rc;
            m_warning.GetClientRect(&rc);

            CPaintDC dc(m_warning);
            CDC dcMem;            
            CBitmap bitmap;

            dcMem.CreateCompatibleDC(dc);
            bitmap.CreateCompatibleBitmap(dc, rc.right,  rc.bottom);      
            HBITMAP hOldBitmap = dcMem.SelectBitmap(bitmap);            
            
            dcMem.FillRect(&rc, GetSysColorBrush(COLOR_BTNFACE));
            dcMem.SetTextColor(RGB(bRed,0,0));
            dcMem.SetBkMode(TRANSPARENT);
            dcMem.SelectFont((HFONT)GetStockObject(DEFAULT_GUI_FONT));      
            dcMem.SetTextAlign(TA_CENTER);            
            dcMem.TextOut((rc.left + rc.right) / 2, 0, szText, sizeof szText / sizeof TCHAR - 1);
            dc.BitBlt(0, 0, rc.right,  rc.bottom, dcMem, 0, 0, SRCCOPY);
            dcMem.SelectBitmap(hOldBitmap);      

        OutputDebugString("on paint\n");
            return 0;
      }

      LRESULT OnEraseBkgndWarning(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
      {
            return 0;
      }
};

#endif


let me know if you need something else.
0
 
Anthony2000Commented:
BTW, did the code solve your problem? I still cannot explain why the OnPaint does not work as one would expect. And I noticed that you gave a grade of "C"? It probably would have been better to just delete the question. I'm sorry I could not give a better solution with a better explanation.
0
 
yossikallyAuthor Commented:
It's ok I appreciate the effort.  I posted the same questions in several forums, and haven't got the precise answer.
0

Featured Post

Independent Software Vendors: 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!

  • 6
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now