![]() |
|
|
![]()
|
|
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
В классе CAsyncSocket есть переопределяемые функции типа OnAccept, OnReceive и т.д., в которых можно выполнять какие-то свои действия.
А кто их вызывает? Я имею в виду, какой поток вызывает сами эти функции? -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Переопредели у себя в классе A (class A : public CAsyncSocket) OnAccept, OnReceive, поставь бряк, а потом уже на нем просмтори стек вызовов -------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
А однозначного ответа на это нет что ли, зависит от ситуации?
-------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Так это же (стек вызовов) самое простое решение.
Добавлено @ 16:53 Debug->Windows->Call Stack -------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Ясно, щас займемся.
Просто до дебага я еще не скомпилировал ;) -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| Coocky |
|
|||
![]() GUI гуру ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2879 Регистрация: 16.2.2004 Где: Украина. Запорожь е Репутация: 25 Всего: 62 |
Dreamer_0x01
А зачем такие подробности, если не секрет? Что надо вообщем-то? -------------------- Верю в смерть после жизни, в любовь после секса ,в крем после бритья |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Мне нужно работу с сокетами запихать в отдельный поток.
и в этом отдельном потоке нужно ожидать приема данных сокетом. (Принцип простой - я запросил у внешнего устройства пакет данных и должен дождаться его получения). Фот собственно с ожиданием и возникли проблемы - как быть? В месте, где нужно ждать приема данных, так и просится создать цыкл какой-либо переменной, с заходом/выходом в критическую секцию, значение которой выставить по переопределяемой функции OnReceive класса сокета. Вот и думаю - будет работать или нет? Ведь если сокет создает свой поток при инициализации, то все будет нормально. А если эти вункции вызываются тем потоком, в котором создан экземпляр сокета - то мой цикл попросту заснет... -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 2 Всего: 146 |
Имхо ф-ция
-------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Функция вызывается не святым духом, а каким-то потоком. Каким? Моим, или каким-то другим, порожденным сокетом? Или оконным? Или главным потоком программы?
-------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 2 Всего: 146 |
Имхо в стеке будет адресс твоего потока , но инициатором будет система
-------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Так, посмотрел в дебаггере, кто вызывает эту функцию, написано, что WinMain. Это чей поток?
-------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 2 Всего: 146 |
-------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Romikgy прав.
Winsock (Ws2_32.dll) через ntdll.dll (NtDeviceIoControlFile, NtReadFile, NtWriteFile, NtCreateFile) обращается в kernel к девайсу \Device\AFD, которое отправляет TDI IRP-пакеты драйверам протокола, затем уже NDIS IRP-пакеты попадают в NDIS и через минипорт NDIS в драйвер сетевой карты, и потом в сеть. Если у тебя асинхронный сокет, то IRP пакет просто отмечается как отложенный (PENDING) и к тебе возвращается управление, а когда этот пакет "завершится" в kernel, он будет поставлен в очередь APC твоего потока и вот, когда твой поток получит управление (квант) он тебе и даст знать об OnReceive. -------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Coocky |
|
|||
![]() GUI гуру ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2879 Регистрация: 16.2.2004 Где: Украина. Запорожь е Репутация: 25 Всего: 62 |
Dreamer_0x01
что-то запарился ты с сокетами. Давай сюда проблему твою, сейчас решим -------------------- Верю в смерть после жизни, в любовь после секса ,в крем после бритья |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Да собственно что нужно.
Нужно, чтобы в программе были функции, работающие одинаково и с сокетами, и с ком-портом. То есть где-то у меня есть струтура, в которой хранится инфа о том, с каким устройством какое соединение установлено, и эти вункции в зависимости от полей этой структуры рабтают либо с те, либо с другим. И надо-то всего лишь адаптировать функции, использующие ReadFile(...) для работы с сокетами. То есть чтобы работа велась по тому же принципу: 1.В моем потоке команда типа Write отправляет информацию в сокет (это просто). 2.Мой прибор, работающий в режиме сервера, отвечает на этот запрос.(это сделано на отдельном контроллере). 3.В моем потоке команда типа Read ждет этого ответа прибора в течении какого-то времени. (У меня для этого используется таймаут ком-портов.) Все это работает в своем, специально выделенном для этого потоке. То есть мне самое сложное - грамотно дождаться ответа сокета в команде Read, так же, как это делается и для ком-порта. Пока что получается, но я бы сказал мягко говоря безграмотно - я наплодил кучу пользовательских сообщений, и вынес сокеты в отдельный поток, работает, но чувствую, что я с каждым днем перестаю понимать свой код =) -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| Coocky |
|
|||
![]() GUI гуру ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2879 Регистрация: 16.2.2004 Где: Украина. Запорожь е Репутация: 25 Всего: 62 |
Парралельно? Какие проблемы! просто в функции OnRecieve() управляй потоком для ком-портов Или я не правильно понял? Ты не прогу распиши, а проблему. Именно конкретно проблему! -------------------- Верю в смерть после жизни, в любовь после секса ,в крем после бритья |
|||
|
||||
| Dreamer_0x01 |
|
||||||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
поблема в том, что мне нужно сделать именно ОЖИДАНИЕ.
Рассмотрим на примере коннекта (его я тоже сделал по ожиданию) Вот класс, производного от CAsyncSocket:
Вот что порисходит по вызову функции OnConnect.
А вот собственно функия, которую я хочу вызывать вне класса (по аналогичному принципу я собираюсь вызывать и функцию Read, использующую флаг Ready, выставляемый в функции OnReceive, но этопотом..)
Я в функции OnConnect поставил бреакпоинт. И при запуске фуекции MakeConnect(...) просто проходит цикл опроса, пока не исчерпается таймаут, и все...На брекпоинт мы не попадаем, хотя соединение должно установиться. (Во всяком случае серверная часть написанная по-простому, OnAccept выдает). Вот я и не понимаю, кто должен вызвать функцию OnConnect ? -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
||||||
|
|||||||
| Coocky |
|
||||
![]() GUI гуру ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2879 Регистрация: 16.2.2004 Где: Украина. Запорожь е Репутация: 25 Всего: 62 |
Ты конектишься и хочешь работать только в том случае, если коннект удачный?
Но ответ от функции коннет занимает некоторое время, которое ты должен подождать, что б узнать результат соединения? Я правильно понял? Добавлено @ 19:15
Покажи мне код, где ты создаешь гнездо,и прослушиваешь запрос на соединение? Ты делаешь Listen() ?
Все виртуальные функции OnConnect(),OnAccept(),OnRecieve() должны быть перегружены в твоем классе,производном от CAsyncSocket, что у тебя и иметтся. Они вызываются когда СИСТЕМА генерирует события о прослушивании,приеме, закрытии и т.д. Как это происходит внутри МФС, и незнаю, да и ненадо это знать -------------------- Верю в смерть после жизни, в любовь после секса ,в крем после бритья |
||||
|
|||||
| Coocky |
|
|||
![]() GUI гуру ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2879 Регистрация: 16.2.2004 Где: Украина. Запорожь е Репутация: 25 Всего: 62 |
И вообще, покажи ,как ты создаешь гнезда в клинтской и серверной части.
Надеюсь у тебя их две -------------------- Верю в смерть после жизни, в любовь после секса ,в крем после бритья |
|||
|
||||
| Dreamer_0x01 |
|
||||||||||||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Именно. И то же самое для приема данных - нужно обязательно дождаться.
В смысле, Listen в серверной части? Обязательно! Но здась у меня именно клиентская, и я делаю именно Connetc. Она работоспособная, за это ручаюсь, так как в старой версией, где все сокеты были засунуты в оконные классы и им слались сообщения, все соединялось, передавалось как надо. И серверную часть я сейчас не трогаю, она в отдельном приложении. Но если такие уж сомнения, вот серверная часть, но она работает, проверялось не раз:
Вот создание прослушки:
И собственно вот:
Так что с серверной частью порядок, прослушку она делает, Ассепт по коннекту тоже... Вот в клиентской части, как видишь, возникли проблемы с ожиданием... -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
||||||||||||
|
|||||||||||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
А с обработкой сообщений всё Ок? WM_SOCKET_NOTIFY идут? Для теста удобно использовать сканер, например, XSpider - можно проверить (на localhost) клиента и сервер.
-------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Это что такое? -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| Coocky |
|
|||
![]() GUI гуру ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2879 Регистрация: 16.2.2004 Где: Украина. Запорожь е Репутация: 25 Всего: 62 |
Блин, так какую проблему рещать-проблему с синхронизацией ожидания и приема или проблему с неполучением сообщений? -------------------- Верю в смерть после жизни, в любовь после секса ,в крем после бритья |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Желательно, обе. Так как решив торую, первая тоже решится сама собой.
Ну либо принципиально другое красивое решение первой проблемы... Добавлено @ 15:54 Хорошо, я переформирую заново вопрос таким образом. Мне нужно иметь три функции: 1. Функция "Соединиться" - она должна послать запрос на соединение и дождаться результата. 2. Функция "Послать буфер данных". 3. Функция "Принять буфер данных" - должна иметь какой-то таймаут, в течение которого должна дождаться получения нужного количества байт из сокета. Как, сколько классов надо будет завернуть в это дело, сколько потоков наплодить - в общем-то без разницы, главное, чтобы работало. -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Смотри реализацию CAsyncSocket в sockcore.cpp OnReceive и т.п. OnXXX вызываются из обработчика WM_SOCKET_NOTIFY CSocketWnd::OnSocketNotify() -------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
да, но при чем тут СSocketWnd ?
Ведь CAsyncSocket унаследован от CObject...., а CSocketWnd лишь объявлен для него как "друг"... (смотрю файл afxsock.h) -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Смотри CAsyncSocket::AttachHandle() и выше. Видать $M решили извещения посылать через обычную очередь сообщений (для этого и СSocketWnd), если будешь ее "тормозить", то тогда и не дождёшься OnReceive и т.п.. -------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
блин, так что, в каждом сокете еще и оконный класс получается создается?
Во изващение... -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Окно ведь invisible! Мне оно не мешает. А как Windows XP переводится? Окошки XP?! Да? Чтобы поток был GUI он должен иметь окно (точнее очередь сообщений и т.п.), первичный поток всегда GUI-поток. Ну вот, MFC сделали по принципу "всё гениальное просто" и не стали придумывать колесо - сделали извещения через СSocketWnd -------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Да, но оконный класс я так понял, хоть и имеет свою очредь сообщений, но эта очередь сообщений должна "прокручиваться" каким-то интерфейсным потоком. Который я так понимаю является тем потоком, в котором я создаю сокет и объявляю AfxSocketInit, так?
Тогда мне наверное следует создать свой интерфейсный поток именно для этих целей, чтобы в ожидании не "усыплять" поток, который должен будет "прокручива" эту очередь сообщений. Правильно? -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| JoyEx |
|
||||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Сишный оконный класс всего лишь обслуживает настоящее Windows окно (subклассит), очередь сообщений есть у GUI-потока, она "прокручивается" всегда примерно вот так:
Там, где есть окно там и есть GUI поток.
ну да, чтобы не было deadlock (взаимоблокировки). -------------------- Если ты уже никого не боишься, значит ты самый страшный |
||||
|
|||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Вот, наконец-то я тогда начинаю понимать, почему не вызываются события сокета - потому что собственно некому их вызывать...
Ладно, щас попробуем все еще и в потоковые классы завернуть. Была у меня конечно идея использовать синхронный сокет (который CSocket), но там заче-то надо порождать классы CArchive, СSocketFile, по-моему, слишком тяжеловесно. Думаю, получится написать свой синхронный сокет, благо мне не та много от него надо. -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Dreamer_0x01
Зачем переделывать код? Надо всего лишь "прокачать" очередь сообщений, чтобы сообщения были обработаны родной оконой процедурой какого-то окна, а потом продолжать чё-то свое делать. -------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Это как? Притащить в оно цепочку указателей на мой сокет, и там принудительно сделать его DispatchMessage ? -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Нет.
С помощью PeekMessage()-TranslateMessage()-DispatchMessage() можно "прокачать" очередь в любом месте потока. Добавлено @ 20:26
-------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Не понимаю, в какое именно место мне надо такой код добавить?
-------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
там, где у тебя долго выполняется код Пока! Это сообщение отредактировал(а) JoyEx - 23.12.2005, 20:44 -------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
ВАХ! ну наконец-то заработало!
Единственное...поясни пожалуйста, почем в PeekMessage в качестве дескриптера окна передается NULL. -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| JoyEx |
|
||||||||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Чтобы вытаскивать из очереди сообщения всех окон данного потока, вот что пишут $M:
PeekMessage() в отличие от GetMessage() "прокачивает" очередь, т.е. если в очереди нету сообщений PeekMessage() возвращает управление (=0), а GetMessage() только при получении WM_QUIT. Вот тебе мой макет
Это ф-ция потока:
-------------------- Если ты уже никого не боишься, значит ты самый страшный |
||||||||
|
|||||||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Что ж, ты мне этой штукой (конструкцией с PeekMessage)очень помог, причем как выяснилось, не тоьлко в сокетах, а вообще в большинстве мест, где моя программа "подтормаживала".
Спасибо. Репутация "+". -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Dreamer_0x01, спасибо.
Для справки: В MS VС++ из Class View v7 очень удобно и быстро можно попасть на базовый класс (и его .cpp) через "Bases and Interfaces". -------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Visual C++/MFC/WTL | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |