具有 WS_EX_TRANSPARENT 样式的静态控件未重新绘制

发布于 2024-07-10 02:12:38 字数 396 浏览 7 评论 0原文

我正在尝试创建一个在绘制 32 位位图时实现每像素 alpha 混合的控件。

我扩展了 CWnd 并在资源编辑器中使用静态控件。 我成功地正确绘制了 Alpha 通道,但静态控件仍然继续绘制灰色背景。

我重写了 OnEraseBkgnd 以防止控件绘制背景,但它不起作用。 我最终设法使用 WS_EX_TRANSPARENT 来做到这一点。

我现在的问题是我的控制权置于其他控制权之上。 第一次绘制对话框时一切正常...但是如果我单击“父”控件(即我控制下的控件),我的控件不会收到 WM_PAINT 消息。 所以就不再画了。

如果我最小化应用程序并再次最大化它,控件将再次绘制。

请问有人可以给点提示吗? 我对这个控制感到疯狂!

谢谢。

I am trying to create a control that implements the per-pixel alpha blend while painting a 32-bit bitmap.

I extended a CWnd and use static control in the resource editor. I managed to paint the alpha channel correctly but still the static control keep painting the gray background.

I overwrote the OnEraseBkgnd to prevent the control from painting the background but it didn't worked. I finally managed to do it by using WS_EX_TRANSPARENT.

My problem now is that my control is placed over other control. The first time the dialog is painted all works fine...but if I click over the "parent" control (ie the one beneath my control) my control doesn't received the WM_PAINT message. So it is not painted anymore.

If I minimize the aplication and maximized it again the controls are painted again.

Please, can anybody give a hint? I am getting crazy with this control!!!

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

何止钟意 2024-07-17 02:12:39
BEGIN_MESSAGE_MAP(CTransparentStatic, CStatic)
    ON_WM_ERASEBKGND()
    ON_WM_CTLCOLOR_REFLECT()
END_MESSAGE_MAP()

BOOL CTransparentStatic::OnEraseBkgnd(CDC* /*pDC*/)
{
    // Prevent from default background erasing.
    return FALSE;
}

BOOL CTransparentStatic::PreCreateWindow(CREATESTRUCT& cs)
{
    cs.dwExStyle |= WS_EX_TRANSPARENT;
    return CStatic::PreCreateWindow(cs);
}

HBRUSH CTransparentStatic::CtlColor(CDC* pDC, UINT /*nCtlColor*/)
{
    pDC->SetBkMode(TRANSPARENT);
    return reinterpret_cast<HBRUSH>(GetStockObject(NULL_BRUSH));
}

void CTransparentStatic::PreSubclassWindow()
{
    CStatic::PreSubclassWindow();

    const LONG_PTR exStyle = GetWindowLongPtr(m_hWnd, GWL_EXSTYLE);
    SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, exStyle | WS_EX_TRANSPARENT);
}
BEGIN_MESSAGE_MAP(CTransparentStatic, CStatic)
    ON_WM_ERASEBKGND()
    ON_WM_CTLCOLOR_REFLECT()
END_MESSAGE_MAP()

BOOL CTransparentStatic::OnEraseBkgnd(CDC* /*pDC*/)
{
    // Prevent from default background erasing.
    return FALSE;
}

BOOL CTransparentStatic::PreCreateWindow(CREATESTRUCT& cs)
{
    cs.dwExStyle |= WS_EX_TRANSPARENT;
    return CStatic::PreCreateWindow(cs);
}

HBRUSH CTransparentStatic::CtlColor(CDC* pDC, UINT /*nCtlColor*/)
{
    pDC->SetBkMode(TRANSPARENT);
    return reinterpret_cast<HBRUSH>(GetStockObject(NULL_BRUSH));
}

void CTransparentStatic::PreSubclassWindow()
{
    CStatic::PreSubclassWindow();

    const LONG_PTR exStyle = GetWindowLongPtr(m_hWnd, GWL_EXSTYLE);
    SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, exStyle | WS_EX_TRANSPARENT);
}
爱她像谁 2024-07-17 02:12:39

我认为,如果您同时处理 WM_ERASEBKGNDWM_PAINT 消息,那么您应该覆盖所有绘画选项,而不必求助于使用 WS_EX_TRANSPARENT 样式。

您确定您的代码没有将这些消息传递给默认处理吗?

另一种选择可能是对静态控件进行子类化,以确保您的代码是唯一处理这两条消息的代码。

I would have though that if you are processing both the WM_ERASEBKGND and the WM_PAINT messages then you should have cover all the painting options, without having to resort to using the WS_EX_TRANSPARENT style.

Are you sure your code is not passing these messages on to the default processing?

One other option might be to subclass the static control, just to make sure your code is the only one handling these two messages.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文