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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每次更改文本时,CStatic都不会失效相关的知识,希望对你有一定的参考价值。

我试图动态更改CStatic控件的文本。我的成员变量叫做mStatic类型的CStatic。我已将ID更改为IDC_MYSTATIC而不是IDC_STATIC

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

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

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

为什么窗口无效?

答案

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

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

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

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

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

另一答案

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

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

  mStatic.SetWindowText("asdfasdf");
  CRect clientRect;
  mStatic.GetClientRect(clientRect);
  mStatic.InvalidateRect(clientRect);
另一答案

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

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

从控件本身中捕获控件文本更改的一种方法是对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;
}

以上是关于每次更改文本时,CStatic都不会失效的主要内容,如果未能解决你的问题,请参考以下文章

片段附加到其主机后,每次都不会调用 FragmentOnAttachListener

每次重启后都会添加片段(Android)

UICollectionViewFlowLayout 在方向更改时不会失效

Android - 在运行时更改自定义标题视图

BottomNavigationView - 如何避免重新创建片段并重用它们

软输入键盘隐藏编辑文本