Пользовательский класс CLed не всегда меняет цвет - PullRequest
2 голосов
/ 25 мая 2019

У меня есть пользовательский интерфейс, в котором я хочу изменить цвет изображения в соответствии со стабильностью соединения, имитируя светодиод ON / OFF. Но проблема в том, что он работает только когда идет красный. И на самом деле, в другом «светодиоде» он горит зеленым, не сообщая.

Прямоугольник, который становится красным на изображениях

Я пробовал с такими вещами, как m_statusMotor.UpdateWindow () или даже UpdateData (0). Однако это не работает. При отладке я видел, что значение m_statusMotor.m_color правильно меняется на 0, но не меняет цвет светодиода.

Так вот, что делает мой класс CLed:

void CLed::OnPaint()
{
  CPaintDC dc(this);
  CRect r;
  GetClientRect(r);
  CBrush b1;
  switch(m_color){
  case 0:
    b1.CreateSolidBrush(RGB(0, 255, 0)); // verde
    break;
  case 1:
    b1.CreateSolidBrush(RGB(255, 0, 0)); // rojo
    break;
  case 2:
    b1.CreateSolidBrush(RGB(255, 118, 0)); // ambar
    break;
  default:
    b1.CreateSolidBrush(RGB(160, 160, 160)); // gris
    break;
  }
  dc.SelectObject(&b1);
  dc.Rectangle(r);
}

Здесь оно меняется на красный:

if(!misoc1.Connect(m_ipMotor, m_portMotor)){
                            if(!connectedmotor) m_log.AddString("No conecta con el puerto de motor"); 
                            connectedmotor = true;
                            firststrmotor = false;
                            m_statusMotor.m_color = 1;
                            m_statusMotor.Invalidate(true);
                            m_log.UpdateWindow();
                            UpdateData(0);
                            m_statusMotor.UpdateWindow();

                    }else connectedmotor = false;

И вот где он становится зеленым

    if(!firststrmotor){
                        m_log.AddString("Motor OK");
                        m_log.UpdateWindow();
                        m_statusMotor.m_color = 0;
                        UpdateData(0);
                        m_statusMotor.UpdateWindow();

                    }

m_statusMotor относится к классу CLed;

Есть идеи, почему это работает несколько раз, а иногда нет ??

1 Ответ

3 голосов
/ 26 мая 2019
function1()
{
    m_statusMotor.m_color = 1;
    m_statusMotor.Invalidate(true);
    m_statusMotor.UpdateWindow();
    ...
}

function2()
{
    m_statusMotor.m_color = 0;
    m_statusMotor.UpdateWindow();
    ...
}

В первой функции, которую вы правильно назвали Invalidate, за которой следует необязательный UpdateWindow (UpdateWindow может быть полезно здесь, если функция блокирует сообщения Windows)

Во второй функции, которую вы забыли вызвать Invalidate, вы только что вызвали UpdateWindow, которая в этом случае не имеет никакого эффекта. Нечего делать недействительным, поэтому сообщения рисования отправляться не будут, как описано в документации:

UpdateWindow:

Функция UpdateWindow обновляет клиентскую область указанного окно, отправив сообщение WM_PAINT в окно, если окно Обновление региона не пусто. Функция отправляет сообщение WM_PAINT непосредственно к оконной процедуре указанного окна, минуя очередь приложений. Если область обновления пуста, сообщение отсутствует отправлено.

Поэтому, позвоните Invalidate(), а затем необязательно UpdateWindow().

Или позвоните по номеру RedrawWindow(), что немедленно сделает недействительным и обновит, как отмечено в комментариях.

Примечание, рассмотрите возможность использования CDC::FillSolidRect в вашей функции OnPaint.

...