我正在尝试动态更改CStatic
控件的文本。我的成员变量名为mStatic
CStatic
。我已将ID更改为IDC_MYSTATIC
而非IDC_STATIC
。
当我想要更改控件的文本时,我正在调用mStatic.SetWindowText("asdfasdf")
。我定期在计时器中这样做。
现在我遇到的问题是,在调用SetWindowText()
后,之前的文字没有被删除。它一直堆积起来,直到我在屏幕上弄得一团糟。
父窗口具有带位图背景的分层属性。我还设置了color_key属性,因此位图的某种颜色被视为透明(即,它不会被绘制并且会让鼠标消息通过)。 mStatic控件绘制在不透明的部分上,具有位图背景。
为什么窗口无效?
答案 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;
}