Я знаю, что элементы управления 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;
}
Каков наилучший способ этого?
Спасибо заранее, лучший Грег
Не вдаваясь в подробности, вот как вы должны это делать. Я не строил, не оценивал и не модифицировал ваш базовый код, я только что обратился к вашей частичной части вопроса. Вы должны быть в состоянии взять это отсюда.
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);
}
Я бы добавил это как комментарий, но не могу прокомментировать: предлагаемое решение zadane так же плохо, как и исходный код, и может привести к взаимоблокировкам в зависимости от остальной части вашего кода, но, кроме того, он ничего не делает для решите свою проблему на самом деле, вы можете просто сделать это в основном потоке, так как концептуально, что он делает.
Это поможет, если вы сможете объяснить, почему вам нужно выполнить проверку в потоке, но, возможно, вы можете поиграть со следующей идеей:
Вы можете поймать события изменений для элемента управления редактирования, который, как я полагаю, вы уже делаете, затем после тайм-аута, количества изменений или того, что соответствует вашим критериям проверки, отправьте сообщение в рабочий поток (через PostMessage и потокобезопасный/синхронизированный или выделенный буфер для данных, подлежащих проверке). Подтвердите данные и отправьте сообщение в окно своему пользовательскому обработчику ON_MESSAGE (опять же, по PostMessage), чтобы графический интерфейс мог узнать результат проверки.
ControlThread
объявлен статическим , то вам также необходимо изменитьValidateEditControl()
вdlg->ValidateEditControl()
иthis->GetDlgItem(IDC_EDIT_HELLO)
кGetDlgItem(IDC_EDIT_HELLO)
, потому чтоValidateEditControl
является Funtion член и , следовательно ,this
уже подразумевается. Это определенно звучит так, как будто есть некоторая путаница вокруг всей проблемыstatic vs member
...