如何将静态控件背景设置为对话框背景? [英] how to set a static control background as a dialog background?

查看:286
本文介绍了如何将静态控件背景设置为对话框背景?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的主要代码中有一个回调函数,它包含在Switch case语句中。在每种情况下,我定义了一个 SetWindowText 函数,以在对话框(或父窗口)上创建的静态控件中打印文本,如下所示:

There is a call back function in my main code which included by Switch case statements. After each case I defined a SetWindowText function to print a text in a static Control which created on a dialog (or parent window),something like this:

::SetWindowText(GetDlgItem(IDC_STATIC)->m_hWnd, "loading");

我将设置静态控件的背景作为对话框的背景。一切都很顺利,除了相互放置的所有案例的文本之外,我收到一个带有重叠文本的静态控件,这样一些东西:

I am going to set background of static control as the background of dialog. Everything goes well except the text of all the cases which place on each other and I receive a static control with overlapped texts, somthing like this:

我不知道为什么在每一步中不关闭静态窗口,避免这种问题。
我添加了 OnEraseBkgnd OnDestroy OnCtlColor 消息如下:

I don't know why in each step it does not close the static window to avoid such kind of problems. I added OnEraseBkgnd, OnDestroy, OnCtlColor messages as follow:

BOOL CmainDlg::OnEraseBkgnd(CDC* pDC)
{
    // TODO: Add your message handler code here and/or call default

    CDC dcMemory;
    dcMemory.CreateCompatibleDC(pDC);
    CBitmap* pOldbitmap = dcMemory.SelectObject(&CBmp);
    CRect rcClient;
    GetClientRect(&rcClient);
    const CSize& sbitmap = bitmapSize;
    pDC->BitBlt(0, 0, sbitmap.cx, sbitmap.cy, &dcMemory, 0, 0, SRCCOPY);
    dcMemory.SelectObject(pOldbitmap);
    return TRUE;

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



    if (pWnd->GetDlgCtrlID() == IDC_STATIC)
        //Example of changing Text colour specific to a certain 
        //Static Text Contol in this case IDC_STATIC.
    {
        pWnd->GetExStyle() & (WS_EX_TRANSPARENT);
        pDC->SetBkMode(TRANSPARENT);
        pDC->SetTextColor(RGB(255, 255, 255));

    }
    if (pWnd->GetDlgCtrlID() == IDC_OPERATION)

    {
        pWnd->GetExStyle() & (WS_EX_TRANSPARENT);
        pDC->SetBkMode(TRANSPARENT);
        pDC->SetTextColor(RGB(255, 255, 0));

        // Return handle to our CBrush object
    }
        return reinterpret_cast<HBRUSH>(GetStockObject(NULL_BRUSH));
    }

void CmainDlg::OnDestroy()
{
    CDialog::OnDestroy();

    // TODO: Add your message handler code here
    Background.DeleteObject(); // Delete Background bitmap
    BrushHol.DeleteObject();
}
//subclass the static control, just to make sure the code is the only one handling WM_ERASEBKGND and WM_PAINT messages.
void CmainDlg::PreSubclassWindow()
{
    CWnd::PreSubclassWindow();

    const LONG_PTR exStyle = GetWindowLongPtr(m_hWnd, GWL_EXSTYLE);
    SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, exStyle | WS_EX_TRANSPARENT);
}

更新:

我评论过 OnEraseBkgnd OnDestroy OnCtlColor 函数。所以我收到了相同的重叠文本,现在更确定一点,我可以说这个问题来自 setWindowText ,因为在完成每个案例后,文本仍然保留在静态控制窗口中,我在每个交换机状态下定义。
我尝试使用以下命令,但没有发生任何事情:

I commented OnEraseBkgnd, OnDestroy, OnCtlColor functions. So I received the same overlapped texts and now with a bit more certainty I can say the problem comes from setWindowText because after finishing each Case the text remains on static control window which I defined in each of switch case statments. I tried to use the following commands but nothing happened:

EnableWindow( GetDlgItem(m_hWnd, IDC_STATIC), FALSE);
m_static.EnableWindow(FALSE);

::SetDlgItemText(m_hWnd, IDC_STATIC, "");

我会感谢任何帮助。

推荐答案

绘图不透明:

使用 m_Brush > CreateSolidBrush ,并使用 SetBkMode(OPAQUE)而不是 TRANSPARENT

Initialize m_Brush with CreateSolidBrush and use SetBkMode(OPAQUE) instead of TRANSPARENT

绘图透明:

按照Adrian McCarthy的回答, return(HBRUSH)GetStockObject(NULL_BRUSH) / code> ,而不是返回 m_Brush

Follow Adrian McCarthy's answer and return (HBRUSH)GetStockObject(NULL_BRUSH) for static controls instead of returning m_Brush.

确保对话框没有 WS_CLIPCHILDREN 标志,否则当您在静态控件中重写文本时,您将遇到相同的重叠问题。

Make sure dialog doesn't have WS_CLIPCHILDREN flag, otherwise you run in to the same overlap problem when you re-write the text in static control.

应该这样做。

另一个选项,此代码将其他控件与背景图像(编辑控件,单选按钮和复选框)对话框可以具有 WS_CLIPCHILDREN 标志,但如果是b,静态控件将需要一个正的ID e重绘( IDC_STATIC 通常设置为-1)。对话框项目也需要 WS_EX_TRANSPARENT 标志。我没有测试这么多。

Another option, this code will blend other controls with background image (edit controls, radio buttons and check boxes) Dialog can have WS_CLIPCHILDREN flag, but static control will need a positive id if it is to be redrawn (IDC_STATIC is usually set to -1). Dialog items will need WS_EX_TRANSPARENT flag as well. I didn't test this much.

不要忘记将 ON_WM_DESTROY 添加到邮件地图。

Don't forget to add ON_WM_DESTROY to message map.

class TDlg : public CDialogEx
{
public:
    std::map<int, HBRUSH> BrushMap;
    CBitmap Bitmap;

    TDlg(int id, CWnd *wnd) : CDialogEx(id, wnd){};
    void MakeBrush(CDC *pdc, CDC &memdc, int id);
    BOOL OnEraseBkgnd(CDC* pDC);
    void OnDestroy();
    BOOL OnInitDialog();
    HBRUSH OnCtlColor(CDC* pDC, CWnd* wnd, UINT nCtlColor);

    DECLARE_MESSAGE_MAP()
};

BOOL TDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    Bitmap.LoadBitmap(IDB_BITMAP1);
    return 1;
}

void TDlg::OnDestroy()
{
    CDialogEx::OnDestroy();
    Bitmap.DeleteObject();
    for (std::map<int, HBRUSH>::iterator it = BrushMap.begin(); it != BrushMap.end(); ++it)
        if (it->second)
            DeleteObject(it->second);
}

void TDlg::MakeBrush(CDC *pdc, CDC &memdc, int id)
{
    CWnd *item = GetDlgItem(id);

    CRect rc;
    item->GetClientRect(&rc);
    item->MapWindowPoints(this, &rc);

    CBitmap bmp;
    bmp.CreateCompatibleBitmap(&memdc, rc.Width(), rc.Height());
    memdc.SelectObject(bmp);
    memdc.BitBlt(0, 0, rc.Width(), rc.Height(), pdc, rc.left, rc.top, SRCCOPY);
    BrushMap[id] = CreatePatternBrush(bmp);
}

BOOL TDlg::OnEraseBkgnd(CDC* pDC)
{
    BITMAP bm;
    Bitmap.GetBitmap(&bm);

    CDC memdc;
    memdc.CreateCompatibleDC(pDC);
    CBitmap* pOldbitmap = memdc.SelectObject(&Bitmap);
    pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memdc, 0, 0, SRCCOPY);

    //BrushMap should be intialized once
    if (!BrushMap.size())
        for (CWnd *p = GetWindow(GW_CHILD); p; p = p->GetNextWindow(GW_HWNDNEXT))
            if (p->GetDlgCtrlID() > 0)
                MakeBrush(pDC, memdc, p->GetDlgCtrlID());

    memdc.SelectObject(pOldbitmap);

    return TRUE;
}

HBRUSH TDlg::OnCtlColor(CDC* pDC, CWnd* wnd, UINT nCtlColor)
{
    HBRUSH br = CDialogEx::OnCtlColor(pDC, wnd, nCtlColor);

    pDC->SetTextColor(RGB(255, 0, 0));
    pDC->SetBkMode(TRANSPARENT);

    int id = wnd->GetDlgCtrlID();
    if (id > 0 && BrushMap[id])
        return BrushMap[id];

    if (nCtlColor == CTLCOLOR_STATIC)
        return (HBRUSH)GetStockObject(NULL_BRUSH);

    return br;
}

这篇关于如何将静态控件背景设置为对话框背景?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆