如何为Owner Drawn Dialog启用阴影

时间:2014-02-24 05:24:13

标签: c++ mfc shadow cdialog

我正在使用所有者绘制的对话框。我喜欢给我的子对话框留下阴影。可能吗?

提前感谢。

1 个答案:

答案 0 :(得分:2)

当然,这是可能的。您可以使用OnEraseBkgnd()调整对话框背景。

举个例子,我在对话框的OK和Cancel按钮上放了阴影(CDialogControlShadowDlg)......

首先,对话框类的头文件中的一些声明:

// 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()
};

然后将OnEraseBkgnd添加到.cpp文件中的消息映射中:

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

最后但并非最不重要的是,成员函数定义:

// 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;
}

应用这些修改后,对话框应如下所示:

screenshot http://www.easyct.de/images/dialogcontrolshadow.png