Возможно SetWindowTextA не вызывает перерисовку функцией OnPaint. Очень на то похоже. При иницализации OnPaint вызывается один раз и рисует зеленый прямоугольник. А как только срабатывает таймер SetWindowTextA рисует используя системные цвета.
Тебе тогда надо не SetWindowTextA вызывать, а посылать сообщение для перерисовки, в котором у тебя кстати сам текст не выводится.
void CMyStatic2::OnPaint()
{
const MSG *msg = GetCurrentMessage();
DefWindowProc(msg->message,msg->wParam,msg->lParam);
RECT rect;
CClient dc(this);
GetClientRect(&rect);
CBrush brush(RGB(0,128,0)); // зелёный цвет фона
dc.SelectObject(&brush);
dc.FillRect(&rect,&brush);
dc.SetTextColor(RGB(255,0,0)); // красный цвет текста
}
Можно конечно и так, но намного проще не отрисовку полностью руками делать, а просто обрабатывать WM_ONCTLCOLOR в самом диалоге.
И не нужно никаких лишних классов.
Есть у меня поток hThread, в который в качестве данных посылается структура myStruct, в которой есть поле isthreadfinished типа bool, которое показывает, завершился ли этот поток или нет.
Есть таймер ID_TIMER_1, которому соответствует функция CMyClass::OnTimer, которая выводит бегущую строку с интервалом в полсекунды и завершает вывод бегущей строки, как только поток hThread завершит свою работу:
void CMyClass::OnTimer(UINT uTime)
{
if (myStruct.isthreadfinished==true)
// если поток завершён
{
KillTimer(ID_TIMER_1);
timerTest = false;
timerCount = 0;
m_IDC_STATIC1.SetWindowTextA(" Расчёт выполнен");
CloseHandle(hThread);
// прочие действия;return;
}
if (timerCount>=6) timerCount = 0;
if (timerCount==0) m_IDC_STATIC1.SetWindowTextA(" Расчёт выполняется");
if (timerCount==1) m_IDC_STATIC1.SetWindowTextA(" Расчёт выполняется .");
if (timerCount==2) m_IDC_STATIC1.SetWindowTextA(" Расчёт выполняется . .");
if (timerCount==3) m_IDC_STATIC1.SetWindowTextA(" Расчёт выполняется . . .");
if (timerCount==4) m_IDC_STATIC1.SetWindowTextA(" Расчёт выполняется . . . .");
if (timerCount==5) m_IDC_STATIC1.SetWindowTextA(" Расчёт выполняется . . . . .");
timerCount++;
}
В обычном случае, когда переменная m_IDC_STATIC1 относится к типу CStatic, всё работает нормально--бегущая строка чёрного цвета появляется на фоне стандартного диалога (оттенок серого цвета).
Но я захотел сменить цвет текста и цвет фона бегущей строки--чтобы эта строка была красного цвета, а цвет фона, на котором она появляется--зелёного цвета. Для этого я создал класс CMyStatic2 как потомок класса CStatic, в котором я переопределил метод OnPaint():
файл MyStatic2.h :
#include <afxwin.h>
class CMyStatic2 : public CStatic
{
protected:
void OnPaint();
DECLARE_MESSAGE_MAP()
public:
// открытые члены класса CMyStatic;
};
файл MyStatic2.cpp :
#include"stdafx.h"#include"MyStatic2.h"
BEGIN_MESSAGE_MAP (CMyStatic2, CStatic)
ON_WM_PAINT()
END_MESSAGE_MAP()
void CMyStatic2::OnPaint()
{
const MSG *msg = GetCurrentMessage();
DefWindowProc(msg->message,msg->wParam,msg->lParam);
RECT rect;
CClient dc(this);
GetClientRect(&rect);
CBrush brush(RGB(0,128,0)); // зелёный цвет фона
dc.SelectObject(&brush);
dc.FillRect(&rect,&brush);
dc.SetTextColor(RGB(255,0,0)); // красный цвет текста
}
А переменную m_IDC_STATIC1 в классе CMyClass я сменил с типа CStatic на тип CMyStatic2 .
В результате чего у меня при запуске потока и таймера на одну секунду появляется статитческое поле зелёного цвета, а потом оно меняется на стандартный цвет диалога (оттенок серого цвета) и бегущая строка в этом статическом поле имеет чёрный цвет.
В чём причина этого? Как исправить эту ошибку--то есть как сделать так, чтобы это статическое поле всегда имело зелёный цвет, а бегущая строка в нём всегда имела красный цвет?
1613 г. = 2024 г.
Re: Проблема с установкой цвета текста и фона бегущей строки
Здравствуйте, anatolym, Вы писали:
A>Здравствуйте, RussianFellow, Вы писали:
A>Возможно SetWindowTextA не вызывает перерисовку функцией OnPaint. Очень на то похоже. При иницализации OnPaint вызывается один раз и рисует зеленый прямоугольник. А как только срабатывает таймер SetWindowTextA рисует используя системные цвета. A>Тебе тогда надо не SetWindowTextA вызывать, а посылать сообщение для перерисовки, в котором у тебя кстати сам текст не выводится.
П.С.
Таймеры, наследование, жуть какая
А на WPF это все можно сделать на языке разметки.
Здравствуйте, anatolym, Вы писали:
A>Здравствуйте, RussianFellow, Вы писали:
A>Возможно SetWindowTextA не вызывает перерисовку функцией OnPaint. Очень на то похоже. При иницализации OnPaint вызывается один раз и рисует зеленый прямоугольник. А как только срабатывает таймер SetWindowTextA рисует используя системные цвета. A>Тебе тогда надо не SetWindowTextA вызывать, а посылать сообщение для перерисовки, в котором у тебя кстати сам текст не выводится.
Да, всё верно--у меня по SetWindowTextA не вызывалась перерисовка OnPaint.
CBrush brush(RGB(0,128,0)); // цвет фона--зелёный
dc.SelectObject(&brush);
dc.FillRect(&rect,&brush);
dc.SetTextColor(RGB(255,0,0)); // цвет текста--красный
dc.SetBkColor(RGB(0,128,0)); // цвет фона при тексте--зелёный
dc.DrawTextA(s,strlen(s),&rect,0);
А в функции CMyClass::OnTimer вместо
if (timeCount==0) m_IDC_STATIC1.setWindowTextA(" Расчёт выполняется");
я написал:
if (timeCount==0)
{
m_IDC_STATIC1.setText(" Расчёт выполняется");
m_IDC_STATIC1.RedrawWindow();
}
(И так для всех случаях timeCount, а также для случая, когда надо вывести надпись " Расчёт выполнен").
В результате у меня всё работает правильно!
P.S. Чем отличается CWnd::RedrawWindow от CWnd::UpdateWindow ?
1613 г. = 2024 г.
Re[3]: Проблема с установкой цвета текста и фона бегущей строки
Здравствуйте, RussianFellow, Вы писали:
RF>А в функции CMyClass::OnTimer вместо
RF>if (timeCount==0) m_IDC_STATIC1.setWindowTextA(" Расчёт выполняется");
RF>я написал:
RF>if (timeCount==0) RF>{ RF> m_IDC_STATIC1.setText(" Расчёт выполняется"); RF> m_IDC_STATIC1.RedrawWindow(); RF>}
RF>(И так для всех случаях timeCount, а также для случая, когда надо вывести надпись " Расчёт выполнен").
Это можно упаковать в цикл, как предложил выше AlexGin. Ибо дублирование не есть гуд.
RF>P.S. Чем отличается CWnd::RedrawWindow от CWnd::UpdateWindow ?
Это не знаю, или не помню MFC последний раз давно видел, и слава богу.
Re: Проблема с установкой цвета текста и фона бегущей строки
Здравствуйте, RussianFellow, Вы писали:
RF>P.S. Чем отличается CWnd::RedrawWindow от CWnd::UpdateWindow ?
CWnd::UpdateWindow — вызывает функцию API UpdateWindow(), которая тупо шлёт окну сообщение WM_PAINT, и оно перерисовывается полностью.
CWnd::RedrawWindow — вызывает функцию API RedrawWindow(), у которой несколько параметров и комбинаций флагов.
MFC вызывает её с какими-то значениями по умолчанию, видимо такие значения не вызывают полную перерисовку окна.
Re[3]: Проблема с установкой цвета текста и фона бегущей строки