Windows: два потока, обрабатывающие сообщения? - PullRequest
1 голос
/ 13 января 2012

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

Как мне этого добиться?

Ответы [ 3 ]

3 голосов
/ 13 января 2012

Вопреки тому, что написал Коди, вы определенно можете обрабатывать сообщения из нескольких потоков. Тем не менее, это не настраиваемая бесплатная для всех. Скорее окна имеют сродство к потоку: каждый поток будет получать сообщения, отправленные или опубликованные в окнах, созданных этим потоком. Невозможно доставить сообщения из какого-либо окна в какой-либо другой поток.

Для вашей конкретной ситуации, почему бы не создать рабочий поток со своим собственным скрытым окном и циклом сообщений? Каждый раз, когда главное окно получает сообщение, которое вы не хотите обрабатывать в главном потоке, отправьте его в другое окно, оно будет поставлено в очередь и обработано рабочим потоком.

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

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

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

Решение состоит в том, чтобы раскрутить другой поток (или два, или сколько вам нужно) и делегировать длительные, требующие большого объема вычислений задачи этому потоку.Вы по-прежнему будете обрабатывать сообщения в одном потоке пользовательского интерфейса, но внутри обработчиков сообщений вы будете передавать задачу вспомогательным потокам.Вы часто будете слышать это как шаблон «рабочий поток» или «фоновый поток».

Вы можете создавать дополнительные потоки, используя CreateThread функцию .Вы можете найти образец здесь .

В этом случае звучит так, что QueueUserWorkItem функция может быть более простой опцией.Пример кода:

DWORD CALLBACK ThreadProc(LPVOID p)
{
    HWND hWnd = reinterpret_cast<HWND>(p);

    for (int i = 0; i < 100000; ++i)
    {
        // do whatever
    }

    return 0;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_KEYDOWN: // or whatever message you want to respond to
        {
            QueueUserWorkItem(ThreadProc, hWnd, WT_EXECUTELONGFUNCTION);
            return 0;
        }
        // process other messages...
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

Требуемое чтение для пулов потоков Win32 здесь .

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

Вам нужен только один поток, обрабатывающий очередь сообщений, который Windows уже предоставляет. Если вы делаете что-то сложное в вычислительном отношении, вы должны отправить его в отдельный поток, создав новый с CreateThread. Если вы обнаружите, что постоянно этим занимаетесь, то держите этот поток постоянно там, но подайте сигнал, чтобы он работал, когда вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...