1

I am using owner drawn dialog. I like to give the shadow for my sub-dialog. Is it possible?

Thank in advance.

bala
  • 275
  • 2
  • 3
  • 13

1 Answers1

2

Sure, it's possible. You could tweak your dialog background using OnEraseBkgnd().

As an example, I have put shadows on the OK and Cancel buttons of a dialog (CDialogControlShadowDlg) ...

First, some declarations in the header file of your dialog class:

// Implementation
protected:
    HICON m_hIcon;

    CRect ComputeDrawingRect(int control_id);   // <-- !!!
    void DrawShadow(CDC* pDC, CRect &r);        // <-- !!!

    // Generated message map functions
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);        // <-- !!!
    DECLARE_MESSAGE_MAP()
};

Then add OnEraseBkgnd to your message map in the .cpp file:

BEGIN_MESSAGE_MAP(CDialogControlShadowDlg, CDialog)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_WM_ERASEBKGND()          // <-- !!!
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

Last, but not least, the member function definitions:

// gets the actual drawing location of a control relative to the dialog frame
CRect CDialogControlShadowDlg::ComputeDrawingRect(int control_id)
{
    CRect r;
    GetDlgItem(control_id)->GetWindowRect(&r);
    ScreenToClient(&r);

    return r;
}

#define SHADOW_WIDTH 6  
// draws the actual shadow
void CDialogControlShadowDlg::DrawShadow(CDC* pDC, CRect &r)
{
    DWORD dwBackgroundColor = GetSysColor(COLOR_BTNFACE);
    DWORD dwDarkestColor = RGB(GetRValue(dwBackgroundColor)/2, 
                            GetGValue(dwBackgroundColor)/2,
                            GetBValue(dwBackgroundColor)/2); // dialog background halftone as base color for shadow
    int nOffset;
    for (nOffset = SHADOW_WIDTH; nOffset > 0; nOffset--)
    {
        DWORD dwCurrentColorR = (GetRValue(dwDarkestColor)*(SHADOW_WIDTH-nOffset)
                                 + GetRValue(dwBackgroundColor)*nOffset) / SHADOW_WIDTH;
        DWORD dwCurrentColorG = (GetGValue(dwDarkestColor)*(SHADOW_WIDTH-nOffset)
                                 + GetGValue(dwBackgroundColor)*nOffset) / SHADOW_WIDTH;
        DWORD dwCurrentColorB = (GetBValue(dwDarkestColor)*(SHADOW_WIDTH-nOffset) 
                                + GetBValue(dwBackgroundColor)*nOffset) / SHADOW_WIDTH;
        pDC->FillSolidRect(r + CPoint(nOffset, nOffset), RGB(dwCurrentColorR, dwCurrentColorG, dwCurrentColorB));
    }
}

BOOL CDialogControlShadowDlg::OnEraseBkgnd( CDC* pDC )
{
    // draw dialog background
    CRect rdlg;
    GetClientRect(&rdlg);
    DWORD dwBackgroundColor = GetSysColor(COLOR_BTNFACE);
    pDC->FillSolidRect(rdlg, dwBackgroundColor); 

    // draw shadows
    CRect r1, r2;
    r1 = ComputeDrawingRect(IDOK);
    r2 = ComputeDrawingRect(IDCANCEL);
    DrawShadow(pDC, r1);
    DrawShadow(pDC, r2);

    return TRUE;
}

After applying these modifications, the dialog should look like this:

screenshot
(source: easyct.de)

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
thomiel
  • 2,467
  • 22
  • 37
  • Nice one, You used DrawShadow for button. Can I use this for a CDialog? – bala Feb 26 '14 at 03:52
  • You create your child windows dynamically in in your dialog, if I understand you right. They behave pretty much the same as buttons, when GetWindowRect() is called -- unless you have modified them to have triangular shape. :) – thomiel Feb 26 '14 at 09:45
  • You also might want to try setting the child dialog's CS_DROPSHADOW window style upon creation. But whether or not a shadow is visible depends upon operating system and currently used theme. – thomiel Feb 26 '14 at 09:53
  • I already tried CS_DROPSHADOW but In that case when I try to hide my dialog by using ShowWindow() it's going to hide the dialog only shadow is not hiding. – bala Feb 27 '14 at 03:37
  • Then this owner drawn shadow is the proper solution for your owner drawn dialogs. :) – thomiel Feb 27 '14 at 08:19
  • Why do you think it's not working for a dialog? What did you try? Where is the problem? The only thing you need is a GetWindowRect() from your child dialogs. This cannot be so difficult. – thomiel Feb 27 '14 at 11:11