Рабочие потоки и элементы управления MFC

0

Я знаю, что элементы управления MFC GUI недоступны непосредственно из рабочего потока, но, например, они получают, передавая этому потоку указатель на экземпляр объекта, который владеет элементами управления. Моя проблема в том, что я действительно уверен в том, как это происходит, когда я вызываю функции в рамках рабочего потока, которым необходимо получить доступ к элементам управления MFC. Пожалуйста, рассмотрите следующий код:

//header: 
class CMyDlg  : public CDialog
{
  ...
  ...
  ...
  afx_msg void OnButtonControl();
  static UNIT ControlThread(LPVOID pParam);
  bool ValidateEditControl();
}

//cpp
void CMyDlg::OnButtonControl()
    {
      CString Text = "Hello";
      GetDlgItem(IDC_EDIT_HELLO)->SetWindowText(Text);
      m_hControlThread = AxtBeginThread(ControlThread, this);

    }

    UINT CMyDlg::ControlThread(LPVOID pParam)
    {
      CMyDlg *dlg = (CMyDlg*) pParam;
      CString Text = "Hello";
      while(SomethingIsTrue) {
        bool Ret = dlg->ValidateEditControl();
        if (!Ret) //Someone changed ControlEntry -> change it back
          dlg->GetDlgItem(IDC_EDIT_HELLO)->SetWindowText(Text);
      }
      AfxEndThread(0);
    } 

    bool CMyDlg::ValidateEditControl()
    {
      CString Text;
      this->GetDlgItem(IDC_EDIT_HELLO)->GetWindowText(Text); // do I need the "this" pointer here, or for general how do I access my MFC control at this point?
      if (Text == "Hello")
        return true;
      else
        return false;
    }

Каков наилучший способ этого?

Спасибо заранее, лучший Грег

  • 0
    Ваш код не скомпилируется. Первая причина заключается в том, что функция ControlThread должна быть объявлена как статическая. Исправление, которое приведет к другим ошибкам, поэтому предпосылка вашего вопроса выключена.
  • 0
    Если ControlThread объявлен статическим , то вам также необходимо изменить ValidateEditControl() в dlg->ValidateEditControl() и this->GetDlgItem(IDC_EDIT_HELLO) к GetDlgItem(IDC_EDIT_HELLO) , потому что ValidateEditControl является Funtion член и , следовательно , this уже подразумевается. Это определенно звучит так, как будто есть некоторая путаница вокруг всей проблемы static vs member ...
Показать ещё 7 комментариев
Теги:
mfc
controls
worker

2 ответа

-1

Не вдаваясь в подробности, вот как вы должны это делать. Я не строил, не оценивал и не модифицировал ваш базовый код, я только что обратился к вашей частичной части вопроса. Вы должны быть в состоянии взять это отсюда.

UINT CMyDlg::ControlThread(LPVOID pParam)
{
  HWND hWnd = (HWND) pParam;
  CString Text = "Hello";
  while(SomethingIsTrue) {
    bool Ret = SendMessage(HwND, VALIDATE_CONTROL,0,0 );
    if (!Ret) //Someone changed ControlEntry -> change it back
     SendMessage(CHANGE_EDIT_HELLO, &Text, 0);
  }
  AfxEndThread(0);
}
-3

Я бы добавил это как комментарий, но не могу прокомментировать: предлагаемое решение zadane так же плохо, как и исходный код, и может привести к взаимоблокировкам в зависимости от остальной части вашего кода, но, кроме того, он ничего не делает для решите свою проблему на самом деле, вы можете просто сделать это в основном потоке, так как концептуально, что он делает.

Это поможет, если вы сможете объяснить, почему вам нужно выполнить проверку в потоке, но, возможно, вы можете поиграть со следующей идеей:

Вы можете поймать события изменений для элемента управления редактирования, который, как я полагаю, вы уже делаете, затем после тайм-аута, количества изменений или того, что соответствует вашим критериям проверки, отправьте сообщение в рабочий поток (через PostMessage и потокобезопасный/синхронизированный или выделенный буфер для данных, подлежащих проверке). Подтвердите данные и отправьте сообщение в окно своему пользовательскому обработчику ON_MESSAGE (опять же, по PostMessage), чтобы графический интерфейс мог узнать результат проверки.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню