STM_SETIMAGE不会使静态控件失效/重绘。

3
有人能告诉我,当使用STM_SETIMAGE消息更改位图后,静态控件不使其区域失效是否正常吗?
我使用带有SS_BITMAP样式的静态控件,并使用以下代码设置其图片。
    HBITMAP DestBmp;
    // Paint on DestBmp...

    HBITMAP hOldBmp = (HBITMAP) ::SendMessage(hStatic, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) DestBmp);
    if (hOldBmp)
        DeleteObject(hOldBmp);

    // *** Why do I need this? ***
    ::InvalidateRect(hStatic, NULL, FALSE);

如果我不调用InvalidateRect,静态控件就不会重绘。这是STM_SETIMAGE的正常行为吗,还是我做错了什么?MSDN文档没有提到需要在STM_SETIMAGE之后调用InvalidateRect,而且这很奇怪,例如在调用SetWindowText之后,你不需要调用InvalidateRect。这让我觉得我的代码可能有问题。
更新:
这是在我的 .rc 文件中定义控件的方式。
CONTROL         "",IDC_IMAGE_PREVIEW,"Static",SS_BITMAP | NOT WS_VISIBLE,29,293,15,13

“NOT WS_VISIBLE”标志不是问题,我稍后使用“ShowWindow(SW_SHOW);”使控件可见。

您的窗口是否使用了 SS_CENTERIMAGE、SS_REALSIZECONTROL 或 SS_RIGHTJUST 样式?这些样式可能会影响在 STM_SETIMAGE 后是否重新绘制。 - CoreyStup
不,它没有任何那些标志。我已经更新了问题,并在.rc文件中添加了控件的定义。 - sashoalm
我一直在努力确定为什么 STM_SETIMAGE 对我也没有更新,并刚刚找到了你的帖子。果然 - 添加 InvalidateRect 也使我的代码工作,但我想知道为什么这是必要的! - holtavolt
@holtavolt 我把解决方法作为答案添加上去,这样人们就不会错过它。但是我现在已经转用C#了,所以不太可能再回顾那个问题了。 - sashoalm
1个回答

2

由于目前还没有真正的解释,而且这个问题正在受到关注,我会在这里添加我的解决方法。调用InvalidateRect()来强制控件重新绘制。

HBITMAP hOldBmp = (HBITMAP) ::SendMessage(hStatic, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) DestBmp);
.....
::InvalidateRect(hStatic, NULL, FALSE);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接