每次更改文本时,CStatic都不会失效

时间:2013-09-06 13:12:55

标签: c++ text static mfc invalidation

我正在尝试动态更改CStatic控件的文本。我的成员变量名为mStatic CStatic。我已将ID更改为IDC_MYSTATIC而非IDC_STATIC

当我想要更改控件的文本时,我正在调用mStatic.SetWindowText("asdfasdf")。我定期在计时器中这样做。

现在我遇到的问题是,在调用SetWindowText()后,之前的文字没有被删除。它一直堆积起来,直到我在屏幕上弄得一团糟。

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

为什么窗口无效?

4 个答案:

答案 0 :(得分:2)

有同样的问题。以下code修正了它:

mStatic.SetWindowText("New text");
CRect rect;
mStatic.GetWindowRect(&rect);
ScreenToClient(&rect);
InvalidateRect(&rect);
UpdateWindow();

答案 1 :(得分:1)

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

使用SS_SIMPLE样式的静态控件可以更快地显示文本,还可以 - MSDN describes - “SS_SIMPLE静态控件在显示文本时不会清除控件的显示区域。如果显示较短的字符串,则会显示原始字符串中比新的较短字符串长的部分。”

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

答案 2 :(得分:0)

SetWindowText()调用来自另一个线程时,此knowledge base support article描述了同样的问题。这是你的计时器在做什么?

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

  mStatic.SetWindowText("asdfasdf");
  CRect clientRect;
  mStatic.GetClientRect(clientRect);
  mStatic.InvalidateRect(clientRect);

答案 3 :(得分: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;
}