CStatic не делает недействительными каждый раз, когда его текст изменяется

Я пытаюсь динамически изменить текст CStatic контроль. Моя переменная-член называется mStatic типа CStatic, Я изменил идентификатор на IDC_MYSTATIC вместо IDC_STATIC,

я звоню mStatic.SetWindowText("asdfasdf") когда я хочу изменить текст элемента управления. Я делаю это периодически в таймере.

Теперь у меня проблема в том, что предыдущий текст не стирается после того, как я SetWindowText(), Это только продолжает накапливаться, пока я не получу беспорядок на экране.

Родительское окно имеет многоуровневое свойство с растровым фоном. Я также установил свойство color_key, чтобы определенный цвет растрового изображения рассматривался как прозрачный (т.е. он не будет прорисован и пропустит сообщения мыши). Элемент управления mStatic рисуется на непрозрачных частях, имеющих фоновый рисунок.

Почему окно не становится недействительным?

2

Решение

Была такая же проблема. Следующие код починил это:

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

Другие решения

Возможно, для вашего статического текстового элемента управления включен стиль SS_SIMPLE. Вы можете проверить флаги стиля в файле ресурсов или с помощью GetStyle ().

Статическое управление в стиле SS_SIMPLE отображает текст быстрее, но также — как MSDN описывает
«Статические элементы управления SS_SIMPLE не очищают область отображения элемента управления при отображении текста. Если отображается более короткая строка, отображается часть исходной строки, которая длиннее новой более короткой строки».

Удалите SS_SIMPLE из флагов стиля, и CStatic будет вести себя «нормально».

1

это статья поддержки базы знаний описывает ту же проблему, когда SetWindowText() звонок сделан из другого потока. Это то, что делает твой таймер?

Если это так, решение может быть просто:

  mStatic.SetWindowText("asdfasdf");
CRect clientRect;
mStatic.GetClientRect(clientRect);
mStatic.InvalidateRect(clientRect);
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;
}
0
По вопросам рекламы [email protected]