2

Я запрашиваю строку с текстом, которую вывожу в textBox

char* log;
if (getLogMess(log)) logTextBox->Text += gcnew String(log) + "\n";

Что мне нужно сделать дальше:

  1. Сделать автоматический запрос новой строки
  2. Добавить возможность отключения и включения авто запросов.

Я хотел всё реализовать в отдельном потоке с бесконечным циклом, но в CLI нельзя изменять формы в отдельном потоке

void MyForm::updateLog() {
    char* log;
    while (true) {
        if (getLogMess(log)) logTextBox->Text += gcnew String(log) + "\n";
    }
}
Thread^ updateLogThread = gcnew Thread(gcnew ThreadStart(this, &MyForm::updateLog));
updateLogThread->Start();

Как быть?

UPD

Рабочий вариант:

delegate void StringArgReturningVoidDelegate();
Thread^ updateLogThread = gcnew Thread(gcnew ThreadStart(this, &MyForm::updateLog));
updateLogThread->Start();

char* log;
void MyForm::updateLog() {

    while (true) {
        if (this->logTextBox->InvokeRequired) {
            StringArgReturningVoidDelegate^ d =
                gcnew StringArgReturningVoidDelegate(this, &MyForm::updateLog);
            this->Invoke(d);
        } else {
            if (!getLogMess(log)) return;
            this->logTextBox->Text += gcnew String(log) + "\r\n";
        }
        Threading::Thread::Sleep(50);
    }
}
αλεχολυτ
  • 28,987
  • 13
  • 60
  • 119

1 Answers1

3

Invoke позволит вам изменить форму из любого потока. Вот пример его использования в моём проекте.

listBox_COM.Invoke(new Action(() => listBox_COM.Items.Add(data))); 
Rivand
  • 2,084
  • Прекрасно, спасибо! Я написал как logTextBox->Invoke(gcnew ThreadStart(this, &MyForm::updateLog)); – Виталий Mar 04 '18 at 13:05
  • @Виталий - по-моему, вы неправильно написали. Invoke должен вызываться в другом (не-gui) потоке. А у вас новый поток создаётся в Invoke. – Alexander Petrov Mar 04 '18 at 13:09
  • @AlexanderPetrov ага, несколько накосячил. Сейчас переделываю – Виталий Mar 04 '18 at 13:13