c ++ многопоточный графический интерфейс Windows (доступ к формам) - PullRequest
2 голосов
/ 05 января 2012

Я написал простое консольное приложение, использующее сокеты Windows для работы в качестве прокси между сервером и клиентом.Я решил создать графический интерфейс для просмотра всех входящих / исходящих пакетов в режиме реального времени (например, очень простой wireshark).

Соединение между сервером и клиентом выполняется в потоке, отличном от цикла сообщений.Когда сервер / клиент отправляет пакет, я бы хотел, чтобы он отображался (например, добавлялся в простой текстовый элемент управления) немедленно.

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

Я нашел несколько решений в: - Управляемом c ++- C ++ / CLI - C #, но не любой без использования платформы .NET.(Я действительно новичок в этой теме графического интерфейса, поэтому я даже не уверен, что вы можете использовать формы Windows без .NET)

Может быть, QT + C ++ мог бы решить эту проблему, но есть ли какое-либо иное решение, кроме этого?Если нет, то можно ли написать обертку на C # / Java для собственного кода C ++?

Должно быть много приложений, написанных на C / C ++, которые используют графический интерфейс, каков общий способ сделать это?

Ответы [ 3 ]

2 голосов
/ 05 января 2012

Вы абсолютно правы, что не можете получить доступ к окну в другом потоке.Правильный способ обработать это - отправить сообщение с помощью команды Win32 API :: PostMessage (или, если вы используете библиотеку оболочки вокруг Win32, любую функцию в этой оболочке, которая в конечном итоге вызывает PostMessage).Вот полезная ссылка от Microsoft относительно очередей сообщений: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644928(v=vs.85).aspx

1 голос
/ 05 января 2012

Существует альтернативный, бесплатный и с открытым исходным кодом, называемый Nana C ++ Library (http://stdex.sourceforge.net), чисто C ++ GUI-библиотека. Используя библиотеку Nana, проблема многопоточности может быть легко решена. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *.

0 голосов
/ 05 января 2012

Быстрое и грязное решение Win32 будет включать критическую секцию, текстовый буфер и таймер в потоке пользовательского интерфейса.

Определите несколько глобалов ...

CRITICAL_SECTION bufferLock; // critical section (to be initialized somewhere)
char dataBuffer[65536]; // contains the data that will be sent to the form
int newdata = 0; // how much data we got (this variable must be atomic, int is ok)
char uiDataBuffer[65536]; // data available to the form
int overflow = 0; // just in case...

Таймер пользовательского интерфейса

void onTimer ()
{
     if (overflow)
     {
          // handle this
     }
     else
     if (newdata) // new data to display
     {
          // take the lock, copy the data and release the lock quickly
          EnterCriticalSection(&bufferLock);
          int dataread = newdata;
          memcpy(uiDataBuffer, dataBuffer, dataread);
          newdata = 0;
          LeaveCriticalSection(&bufferLock);

          // TODO: append the text in uiDataBuffer[] to your text control
     }
}

Для вызова из рабочего потока:

void sendData (char* data, int size)
{
    EnterCriticalSection (&bufferLock);
    if(size+newdata > 65536)
        overflow = 1;
    else
    {
        memcpy(dataBuffer+newdata, data, size);
        newdata += size;
    }
    LeaveCriticalSection (&bufferLock);
}

Код не проверен. Размер буфера и частота таймера должны быть скорректированы.

Можно избежать опроса буфера с таймером, используя PostMessage () (с пользовательским сообщением), чтобы сигнализировать пользовательскому интерфейсу о доступности новых данных.

Если производительность является проблемой, обмен данными между производителем и потребительским потоком также может быть очень эффективно выполнен с помощью очереди FIFO без блокировки.

Только PostMessage () не является решением для обмена данными между потоками.

...