Всем доброго вечера! Пишу сетевой движок для работы под управлением операционной системы семейства Windows. Модель ввода/вывода я выбрал WSAAsyncSelect(), то есть мне понадобится окно и функция обработчик сообщений от операционной системы. А так как некоторые программы могут быть консольными, я решил чтобы библиотека сама создавала окно и обрабатывала сообщения. Раз она это будет делать сама, то для этого ей нужен отдельный поток. Создал поток. Поток регистрирует класс, создаёт окно и инициализирует работу с Windows сокетами через WSAStartup(). В этот момент основной поток программы ждёт созданный поток. Ждёт он два события: либо если поток завершится, либо если поток освободит указанное мною событие. Если поток завершится, я могу получить код его завершения, то есть узнать причину. Если же освободиться заранее определённое мною событие, то это значит что поток всё инициализировал и вошёл в цикл отлова сообщений от операционной системы. Вроде всё нормально. Но как выяснилось дальше, я совсем забыл про особенность потоков. Первое что я заметил, когда пытался создать сокет в основном потоке, через socket(), так это то, что мне приходила ошибка WSANOTINITIALISED (Или приложение не вызвало WSAStartup(), или произошла ошибка в WSAStartup()). Странно, я же её вызывал и она завершилась успешно в потоке. Тогда я переместил функцию инициализации работы с Windows сокетами в основной поток. Думал всё будет отлично. У меня объявлено так: Код (Text): HINSTANCE appInstance; HWND window; Конструктор же обнуляет значения: Код (Text): appInstance=0; window=0; И вот у меня созданный поток успешно завершает: Код (Text): window=CreateWindowEx(...); Успешно, то есть window не равна нулю. А потом из основного потока, когда я обращаюсь к window, оно содержит ноль. Я конечно до сих пор не понимаю почему там ноль. Ведь значение то общее. Одно дело что тут я вспомнил что у каждого потока своя таблица объектов ядра. Поэтому я и не могу в основном потоке использовать окно, созданное в дочернем потоке. Но почему ноль-то?! В общем не могу сейчас придумать, как бы мне всё это заставить правильно работать. Добиться нужно следующего: - Всего в программе должно быть два потока: основной поток программы и один дочерний поток. - Дочерний поток должен обрабатывать сообщения от операционной системы, чтобы определять события для сокетов (FD_ACCEPT, FD_CLOSE, FD_READ и FD_WRITE). - Основной поток программы устанавливает функции обратного вызова, которые вызывает дочерний поток при приходе какого-то события для сокета. - Как только функция обратного вызова сработала, пользователь оповещается что можно что-то сделать с сокетом (например считать данные) и уже может вызвать нужную функцию. Не состыковка проявилась вот в каком месте: Код (Text): #include "DNetTCP\DNetTCP.h" void NetEvent(DNetTCP::IClient* _client,DNetTCP::EventType _eventType); int main(void) { DNetTCP::Result result; DNetTCP::ICore* core=0; DNetTCP::IClient* client=0; DNetTCP::ParametersFunctionsClient pfc; memset(&pfc,0,sizeof(DNetTCP::ParametersFunctionsClient)); result=DNetTCP::CreateCore(&core); if(result!=DNetTCP::Ok) { MessageBox(0,TEXT("Вот так вот!"),TEXT("Ошибка"),MB_ICONERROR); return -1; } result=core->Start(); // Инициализируется работа с сокетами в основном потоке и создаётся дочерний поток if(result!=DNetTCP::Ok) { core->Release(); MessageBox(0,TEXT("Вот так вот!"),TEXT("Ошибка"),MB_ICONERROR); return -1; } pfc.functionsGlobal.disconnect=&NetEvent; pfc.functionsGlobal.disconnectError=&NetEvent; pfc.functionsGlobal.message=&NetEvent; pfc.functionsGlobal.error=&NetEvent; result=core->CreateClient(&client); if(result!=DNetTCP::Ok) { core->Release(); MessageBox(0,TEXT("Вот так вот!"),TEXT("Ошибка"),MB_ICONERROR); return -1; } result=client->Start(); // А тут уже я не вижу окно if(result!=DNetTCP::Ok) { core->Release(); MessageBox(0,TEXT("Вот так вот!"),TEXT("Ошибка"),MB_ICONERROR); return -1; } result=client->Connect("46.33.224.184",27015,&pfc); if(result==DNetTCP::Ok) MessageBox(0,TEXT("Подключились!"),TEXT("Успех"),MB_ICONERROR); else MessageBox(0,TEXT("Не подключились!"),TEXT("Ошибка"),MB_ICONERROR); Sleep(5000); client->Release(); core->Release(); return 0; } void NetEvent(DNetTCP::IClient* _client,DNetTCP::EventType _eventType) { } В момент когда я делаю: Код (Text): result=client->Start(); Там внутри у меня проверяется значение window (нужно чтобы связать сокет с событием и указать в какое окно слать). Получается что я из первичного потока хочу указать окно, а окно то у меня создано и обрабатывается в дочернем потоке. Подскажи-те, как выкрутиться? Модель ввода/вывода не предлагать сменить.