3

我正在尝试动态更改CStatic控件的文本。我的成员变量被称为mStatic类型CStatic。我已将 ID 更改为IDC_MYSTATIC而不是IDC_STATIC.

mStatic.SetWindowText("asdfasdf")当我想更改控件的文本时,我正在调用。我定期在计时器中执行此操作。

现在我有一个问题,在我调用SetWindowText(). 它一直在堆积,直到我在屏幕上弄得一团糟。

父窗口具有带位图背景的分层属性。我还设置了 color_key 属性,因此位图的某种颜色被视为透明(即它不会被绘制,并且会让鼠标消息通过)。mStatic 控件绘制在具有位图背景的不透明部分上。

为什么窗口不失效?

4

4 回答 4

3

有同样的问题。以下代码修复了它:

mStatic.SetWindowText("New text");
CRect rect;
mStatic.GetWindowRect(&rect);
ScreenToClient(&rect);
InvalidateRect(&rect);
UpdateWindow();
于 2016-03-27T20:19:13.293 回答
1

也许您的静态文本控件启用了 SS_SIMPLE 样式。您可以检查资源文件上的样式标志或使用 GetStyle()。

具有 SS_SIMPLE 样式的静态控件更快地显示文本,而且 - 正如MSDN 所描述的 - “SS_SIMPLE 静态控件在显示文本时不会清除控件的显示区域。如果显示较短的字符串,则原始字符串中比新字符串长的部分显示较短的字符串。”

从样式标志中清除 SS_SIMPLE,CStatic 将表现“正常”。

于 2015-11-16T09:44:48.683 回答
0

知识库支持文章SetWindowText()描述了从另一个线程进行调用时的相同问题。那是你的计时器在做什么吗?

如果是这样,解决方案可能只是:

  mStatic.SetWindowText("asdfasdf");
  CRect clientRect;
  mStatic.GetClientRect(clientRect);
  mStatic.InvalidateRect(clientRect);
于 2013-09-06T13:44:35.503 回答
0

正如其他人已经提到的那样,静态控件不一定会在绘制文本之前擦除其背景。

我发现将静态控件子类化并从那里强制控件无效是一个更好的解决方案。这使得人们可以轻松地在所有具有透明背景的静态文本上实现它,而无需进行额外的调用以使其父类中的控件无效。

从控件本身中捕获控件文本更改的一种方法是对WM_SETTEXT消息做出反应并从那里强制失效:

int CStaticT::OnSetText(LPCTSTR text)
{
    LRESULT res = Default();
    Invalidate();
    UpdateWindow();
    return res;
}

这是从我的一个类中提取的一个简短示例,说明了此类子类控件的外观:

//////////////////////////////////////////////////////////////////////////
// Header
//////////////////////////////////////////////////////////////////////////
class CStaticT : public CStatic
{
    DECLARE_DYNAMIC(CStaticT)

public:
    CStaticT();
    virtual ~CStaticT();

protected:
    afx_msg int OnSetText(LPCTSTR text);
    DECLARE_MESSAGE_MAP()

private:
    BOOL m_InitialSet;
};

//////////////////////////////////////////////////////////////////////////
// Implementation
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CStaticT, CStatic)
CStaticT::CStaticT()
{
    m_InitialSet = FALSE;
}

CStaticT::~CStaticT()
{
}

BEGIN_MESSAGE_MAP(CStaticT, CStatic)
    ON_WM_SETTEXT()
END_MESSAGE_MAP()

int CStaticT::OnSetText(LPCTSTR text)
{
    LRESULT res = Default();

    // I've noticed issues when this forces the invalidation
    // of the static control before the parent's background
    // is painted completely.
    // This is a cheap workaround, skipping the initial setting
    // of the text by the subclassing call.
    // You have to test if this works out for your environment.
    if (!m_InitialSet)
    {
        m_InitialSet = TRUE;
        return res;
    }

    // Force of the invalidation
    Invalidate();
    UpdateWindow();

    return res;
}
于 2017-12-28T15:49:02.653 回答