Уголок Wiz'а
У вас нет необходимых прав для просмотра вложений в этом сообщении.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
{04.09.2016} [21:30.48] Попытка установить соединение c 192.168.0.25:3001
{04.09.2016} [21:30.57] Wiz> Привет
{04.09.2016} [21:31.09] Не удалось установить соединение! (err=10060)
{04.09.2016} [21:31.34] Попытка установить соединение c 192.168.0.25:3001
{04.09.2016} [21:31.55] Не удалось установить соединение! (err=10060)
{04.09.2016} [21:32.15] Попытка установить соединение c 192.168.0.25:3001
{04.09.2016} [21:32.36] Не удалось установить соединение! (err=10060)
{04.09.2016} [21:33.51] Попытка установить соединение c 192.168.0.25:3001
{04.09.2016} [21:34.12] Не удалось установить соединение! (err=10060)
{04.09.2016} [21:30.57] Wiz> Привет
{04.09.2016} [21:31.09] Не удалось установить соединение! (err=10060)
{04.09.2016} [21:31.34] Попытка установить соединение c 192.168.0.25:3001
{04.09.2016} [21:31.55] Не удалось установить соединение! (err=10060)
{04.09.2016} [21:32.15] Попытка установить соединение c 192.168.0.25:3001
{04.09.2016} [21:32.36] Не удалось установить соединение! (err=10060)
{04.09.2016} [21:33.51] Попытка установить соединение c 192.168.0.25:3001
{04.09.2016} [21:34.12] Не удалось установить соединение! (err=10060)
{02:33:40.167} Попытка установить соединение c cool:3000
{02:33:41.128} Не удалось установить соединение! (err=10061)
{02:33:45.575} Попытка установить соединение c i486:3000
{02:33:45.665} Установлено соединение!
{02:33:45.935} Guest --> Hello, All!
{02:33:45.935} Сейчас в чате:Guest, Роман, Моника
{02:33:59.234} В чат вошел: Второй
{02:34:00.055} Второй >> nnh
{02:35:26.540} В чат вошел: Третий
{02:35:27.221} Третий >> Я третий...
Тест привет!, как дела у вас ???
Как у вас дела ???
Тест
{02:36:10.363} Третий>>Привет всем!
{02:37:20.684} Третий>>В настоящее время практически на всех компьютерах имеется параллельный порт, через который можно подключить различные стандартные устройства: принтеры, сканеры, дисковые накопители и т.д.В настоящее время практически на всех компьютерах имеется параллельный порт, через который можно подключить различные стандартные устройства: принтеры, сканеры, дисковые накопители и т.д.В настоящее время практически на всех компьютерах имеется параллельный порт, через который можно подключить различные стандартные устройства: принтеры, сканеры, дисковые накопители и т.д.
{02:37:38.770} Третий>>В настоящее время практически на всех компьютерах имеется параллельный порт, через который можно подключить различные стандартные устройства: принтеры, сканеры, дисковые накопители и т.d
{02:38:41.250} Роман>>Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.sssКроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.sssКроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.sssКроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный портff
{02:39:22.369} Моника>>Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольКроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких кку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт_
{02:33:41.128} Не удалось установить соединение! (err=10061)
{02:33:45.575} Попытка установить соединение c i486:3000
{02:33:45.665} Установлено соединение!
{02:33:45.935} Guest --> Hello, All!
{02:33:45.935} Сейчас в чате:Guest, Роман, Моника
{02:33:59.234} В чат вошел: Второй
{02:34:00.055} Второй >> nnh
{02:35:26.540} В чат вошел: Третий
{02:35:27.221} Третий >> Я третий...
Тест привет!, как дела у вас ???
Как у вас дела ???
Тест
{02:36:10.363} Третий>>Привет всем!
{02:37:20.684} Третий>>В настоящее время практически на всех компьютерах имеется параллельный порт, через который можно подключить различные стандартные устройства: принтеры, сканеры, дисковые накопители и т.д.В настоящее время практически на всех компьютерах имеется параллельный порт, через который можно подключить различные стандартные устройства: принтеры, сканеры, дисковые накопители и т.д.В настоящее время практически на всех компьютерах имеется параллельный порт, через который можно подключить различные стандартные устройства: принтеры, сканеры, дисковые накопители и т.д.
{02:37:38.770} Третий>>В настоящее время практически на всех компьютерах имеется параллельный порт, через который можно подключить различные стандартные устройства: принтеры, сканеры, дисковые накопители и т.d
{02:38:41.250} Роман>>Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.sssКроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.sssКроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.sssКроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный портff
{02:39:22.369} Моника>>Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольКроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких кку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт. Этим объясняется актуальность разработки.Кроме того, параллельный порт можно использовать для подключения нестандартных устройств, таких как АЦП. АЦП позволяет вводить в ЭВМ аналоговые сигналы, преобразованные в цифровой код. Таким образом, ЭВМ легко можно превратить в цифровой осцилограф со всеми вытекающими из этого преимуществами, поскольку существующие платы АЦП промышленного производства слишком дороги. В данном случае, любой студент, изучивший основы схемотехники, может достаточно лего собрать самостоятельно схему АЦП преобразователя и подключить его к ЭВМ через параллельный порт_
Фильм "Назад в будущее" часть 2
[00:51:46] Попытка установить соединение c localhost:3000
[00:51:46] Установлено соединение!
[00:51:49] Хаюшки!
[00:51:49] Wiz> Привет
[00:51:51]
[00:51:51] [00:51:44] Запуск сервера(порт 3000). Ожидаются подключения...
[00:51:51] [00:51:49] В чат вошел пользователь: ALEHA
[00:51:51] [00:51:49] Wiz>Привет
[00:51:51] Сейчас в чате:Wiz, ALEHA
[00:51:54] Связь с сервером прекращена
[00:51:56] Попытка установить соединение c localhost:3000
[00:51:56] Установлено соединение!
[00:51:59] Хаюшки!
[00:51:59] Wiz> Привет
[00:52:00]
[00:52:00] [00:51:44] Запуск сервера(порт 3000). Ожидаются подключения...
[00:52:00] [00:51:49] В чат вошел пользователь: ALEHA
[00:52:00] [00:51:49] Wiz>Привет
[00:52:01] [00:51:51] ALEHA> Хаюшки!
[00:52:01] [00:51:54] ALEHA(17961) отключился
[00:52:01] [00:51:59] В чат вошел пользователь: ALEHA
[00:52:01] [00:51:59] Wiz>Привет
[00:52:01] Сейчас в чате:Wiz, ALEHA
[00:52:14] Связь с сервером прекращена
[00:52:16] Попытка установить соединение c localhost:3000
[00:52:16] Установлено соединение!
[00:52:19] Хаюшки!
[00:52:19] Wiz> Привет
[00:52:20]
[00:52:21] [00:51:44] Запуск сервера(порт 3000). Ожидаются подключения...
[00:52:21] [00:51:49] В чат вошел пользователь: ALEHA
[00:52:21] [00:51:49] Wiz>Привет
[00:52:21] [00:51:51] ALEHA> Хаюшки!
[00:52:21] [00:51:54] ALEHA(17961) отключился
[00:52:21] [00:51:59] В чат вошел пользователь: ALEHA
[00:52:21] [00:51:59] Wiz>Привет
[00:52:21] [00:52:00] ALEHA> Хаюшки!
[00:52:21] [00:52:14] ALEHA(22028) отключился
[00:52:21] [00:52:19] В чат вошел пользователь: ALEHA
[00:52:21] [00:52:19] Wiz>Привет
[00:52:21] Сейчас в чате:Wiz, ALEHA
[00:51:46] Установлено соединение!
[00:51:49] Хаюшки!
[00:51:49] Wiz> Привет
[00:51:51]
[00:51:51] [00:51:44] Запуск сервера(порт 3000). Ожидаются подключения...
[00:51:51] [00:51:49] В чат вошел пользователь: ALEHA
[00:51:51] [00:51:49] Wiz>Привет
[00:51:51] Сейчас в чате:Wiz, ALEHA
[00:51:54] Связь с сервером прекращена
[00:51:56] Попытка установить соединение c localhost:3000
[00:51:56] Установлено соединение!
[00:51:59] Хаюшки!
[00:51:59] Wiz> Привет
[00:52:00]
[00:52:00] [00:51:44] Запуск сервера(порт 3000). Ожидаются подключения...
[00:52:00] [00:51:49] В чат вошел пользователь: ALEHA
[00:52:00] [00:51:49] Wiz>Привет
[00:52:01] [00:51:51] ALEHA> Хаюшки!
[00:52:01] [00:51:54] ALEHA(17961) отключился
[00:52:01] [00:51:59] В чат вошел пользователь: ALEHA
[00:52:01] [00:51:59] Wiz>Привет
[00:52:01] Сейчас в чате:Wiz, ALEHA
[00:52:14] Связь с сервером прекращена
[00:52:16] Попытка установить соединение c localhost:3000
[00:52:16] Установлено соединение!
[00:52:19] Хаюшки!
[00:52:19] Wiz> Привет
[00:52:20]
[00:52:21] [00:51:44] Запуск сервера(порт 3000). Ожидаются подключения...
[00:52:21] [00:51:49] В чат вошел пользователь: ALEHA
[00:52:21] [00:51:49] Wiz>Привет
[00:52:21] [00:51:51] ALEHA> Хаюшки!
[00:52:21] [00:51:54] ALEHA(17961) отключился
[00:52:21] [00:51:59] В чат вошел пользователь: ALEHA
[00:52:21] [00:51:59] Wiz>Привет
[00:52:21] [00:52:00] ALEHA> Хаюшки!
[00:52:21] [00:52:14] ALEHA(22028) отключился
[00:52:21] [00:52:19] В чат вошел пользователь: ALEHA
[00:52:21] [00:52:19] Wiz>Привет
[00:52:21] Сейчас в чате:Wiz, ALEHA
[14:33:33] Попытка установить соединение c localhost:3000
[14:33:33] Установлено соединение!
[14:33:33] Send info для sock=9310640 noname user(0) о Ronald(17295)
[14:33:33] Ronald>Хаюшки!
[14:33:33] получена инфа от Wiz(0)
[14:33:33] получена инфа от Bas(22105)
[14:33:33] получена инфа от Ronald(3039)
[14:33:33] получена инфа от Bas(16542)
[14:33:33] получена инфа от Ronald(25372)
[14:33:33] получена инфа от Bas(2091)
[14:33:34] [14:33:29] Send info для sock=9310496 Bas(2091) о Wiz(0)
[14:33:34] [14:33:29] Send info для sock=9310496 Bas(2091) о Bas(22105)
[14:33:34] [14:33:29] Send info для sock=9310496 Bas(2091) о Ronald(3039)
[14:33:34] [14:33:29] Send info для sock=9310496 Bas(2091) о Bas(16542)
[14:33:34] [14:33:29] Send info для sock=9310496 Bas(2091) о Ronald(25372)
[14:33:34] [14:33:29] Wiz>Привет
[14:33:34] [14:33:29] получена инфа от Bas(2091)
[14:33:34] [14:33:29] Send info для sock=9311456 Bas(22105) о Bas(2091)
[14:33:34] [14:33:29] Send info для sock=9311856 Ronald(3039) о Bas(2091)
[14:33:34] [14:33:29] Send info для sock=9317248 Bas(16542) о Bas(2091)
[14:33:34] [14:33:29] Send info для sock=9310560 Ronald(25372) о Bas(2091)
[14:33:34] [14:33:29] Bas> дела то как у вас
[14:33:34] [14:33:33] В чат вошел пользователь: Ronald
[14:33:34] [14:33:33] Send info для sock=9310432 Ronald(17295) о Wiz(0)
[14:33:34] [14:33:33] Send info для sock=9310432 Ronald(17295) о Bas(22105)
[14:33:34] [14:33:33] Send info для sock=9310432 Ronald(17295) о Ronald(3039)
[14:33:34] [14:33:33] Send info для sock=9310432 Ronald(17295) о Bas(16542)
[14:33:34] [14:33:33] Send info для sock=9310432 Ronald(17295) о Ronald(25372)
[14:33:34] [14:33:33] Send info для sock=9310432 Ronald(17295) о Bas(2091)
[14:33:34] Сейчас в чате:Wiz, Bas, Ronald, Bas, Ronald, Bas, Ronald
[14:33:34] Wiz> Привет
[14:33:38] В чат вошел пользователь: Bas
[14:33:38] получена инфа от Bas(31785)
[14:33:39] Bas> дела то как у вас
[14:33:44] В чат вошел пользователь: Ronald
[14:33:44] получена инфа от Ronald(19028)
[14:33:45] Ronald> Хаюшки!
[14:34:14] В чат вошел пользователь: Ronald
[14:34:14] получена инфа от Ronald(1405)
[14:34:15] Ronald> Хаюшки!
[14:34:16] В чат вошел пользователь: Ronald
[14:34:17] получена инфа от Ronald(6342)
[14:34:18] Ronald> Хаюшки!
[14:34:18] В чат вошел пользователь: Ronald
[14:34:19] получена инфа от Ronald(12162)
[14:34:20] Ronald> Хаюшки!
[14:34:21] В чат вошел пользователь: Ronald
[14:34:21] получена инфа от Ronald(20829)
[14:34:22] Ronald> Хаюшки!
[14:34:23] В чат вошел пользователь: Ronald
[14:34:23] получена инфа от Ronald(20861)
[14:34:24] Ronald> Хаюшки!
[14:34:33] В чат вошел пользователь: Ronald
[14:34:34] получена инфа от Ronald(22399)
[14:34:35] Ronald> Хаюшки!
[14:34:42] В чат вошел пользователь: Ronald
[14:34:43] получена инфа от Ronald(19522)
[14:34:43] Ronald> Хаюшки!
[14:35:06] удалили пользователя Ronald
[14:35:07] Ronald(22399) отключился
[14:35:08] удалили пользователя Ronald
[14:35:08] Ronald(20829) отключился
[14:35:09] удалили пользователя Ronald
[14:35:09] Ronald(20861) отключился
[14:35:10] удалили пользователя Ronald
[14:35:10] Ronald(19522) отключился
[14:35:15] удалили пользователя Ronald
[14:35:15] Ronald(12162) отключился
[14:35:18] удалили пользователя Ronald
[14:35:18] Ronald(6342) отключился
[14:35:19] удалили пользователя Ronald
[14:35:19] Ronald(1405) отключился
[14:35:20] удалили пользователя Ronald
[14:35:20] Ronald(19028) отключился
[14:35:21] удалили пользователя Bas
[14:35:21] Bas(31785) отключился
[14:33:33] Установлено соединение!
[14:33:33] Send info для sock=9310640 noname user(0) о Ronald(17295)
[14:33:33] Ronald>Хаюшки!
[14:33:33] получена инфа от Wiz(0)
[14:33:33] получена инфа от Bas(22105)
[14:33:33] получена инфа от Ronald(3039)
[14:33:33] получена инфа от Bas(16542)
[14:33:33] получена инфа от Ronald(25372)
[14:33:33] получена инфа от Bas(2091)
[14:33:34] [14:33:29] Send info для sock=9310496 Bas(2091) о Wiz(0)
[14:33:34] [14:33:29] Send info для sock=9310496 Bas(2091) о Bas(22105)
[14:33:34] [14:33:29] Send info для sock=9310496 Bas(2091) о Ronald(3039)
[14:33:34] [14:33:29] Send info для sock=9310496 Bas(2091) о Bas(16542)
[14:33:34] [14:33:29] Send info для sock=9310496 Bas(2091) о Ronald(25372)
[14:33:34] [14:33:29] Wiz>Привет
[14:33:34] [14:33:29] получена инфа от Bas(2091)
[14:33:34] [14:33:29] Send info для sock=9311456 Bas(22105) о Bas(2091)
[14:33:34] [14:33:29] Send info для sock=9311856 Ronald(3039) о Bas(2091)
[14:33:34] [14:33:29] Send info для sock=9317248 Bas(16542) о Bas(2091)
[14:33:34] [14:33:29] Send info для sock=9310560 Ronald(25372) о Bas(2091)
[14:33:34] [14:33:29] Bas> дела то как у вас
[14:33:34] [14:33:33] В чат вошел пользователь: Ronald
[14:33:34] [14:33:33] Send info для sock=9310432 Ronald(17295) о Wiz(0)
[14:33:34] [14:33:33] Send info для sock=9310432 Ronald(17295) о Bas(22105)
[14:33:34] [14:33:33] Send info для sock=9310432 Ronald(17295) о Ronald(3039)
[14:33:34] [14:33:33] Send info для sock=9310432 Ronald(17295) о Bas(16542)
[14:33:34] [14:33:33] Send info для sock=9310432 Ronald(17295) о Ronald(25372)
[14:33:34] [14:33:33] Send info для sock=9310432 Ronald(17295) о Bas(2091)
[14:33:34] Сейчас в чате:Wiz, Bas, Ronald, Bas, Ronald, Bas, Ronald
[14:33:34] Wiz> Привет
[14:33:38] В чат вошел пользователь: Bas
[14:33:38] получена инфа от Bas(31785)
[14:33:39] Bas> дела то как у вас
[14:33:44] В чат вошел пользователь: Ronald
[14:33:44] получена инфа от Ronald(19028)
[14:33:45] Ronald> Хаюшки!
[14:34:14] В чат вошел пользователь: Ronald
[14:34:14] получена инфа от Ronald(1405)
[14:34:15] Ronald> Хаюшки!
[14:34:16] В чат вошел пользователь: Ronald
[14:34:17] получена инфа от Ronald(6342)
[14:34:18] Ronald> Хаюшки!
[14:34:18] В чат вошел пользователь: Ronald
[14:34:19] получена инфа от Ronald(12162)
[14:34:20] Ronald> Хаюшки!
[14:34:21] В чат вошел пользователь: Ronald
[14:34:21] получена инфа от Ronald(20829)
[14:34:22] Ronald> Хаюшки!
[14:34:23] В чат вошел пользователь: Ronald
[14:34:23] получена инфа от Ronald(20861)
[14:34:24] Ronald> Хаюшки!
[14:34:33] В чат вошел пользователь: Ronald
[14:34:34] получена инфа от Ronald(22399)
[14:34:35] Ronald> Хаюшки!
[14:34:42] В чат вошел пользователь: Ronald
[14:34:43] получена инфа от Ronald(19522)
[14:34:43] Ronald> Хаюшки!
[14:35:06] удалили пользователя Ronald
[14:35:07] Ronald(22399) отключился
[14:35:08] удалили пользователя Ronald
[14:35:08] Ronald(20829) отключился
[14:35:09] удалили пользователя Ronald
[14:35:09] Ronald(20861) отключился
[14:35:10] удалили пользователя Ronald
[14:35:10] Ronald(19522) отключился
[14:35:15] удалили пользователя Ronald
[14:35:15] Ronald(12162) отключился
[14:35:18] удалили пользователя Ronald
[14:35:18] Ronald(6342) отключился
[14:35:19] удалили пользователя Ronald
[14:35:19] Ronald(1405) отключился
[14:35:20] удалили пользователя Ronald
[14:35:20] Ronald(19028) отключился
[14:35:21] удалили пользователя Bas
[14:35:21] Bas(31785) отключился
{03:39:32.550} Попытка установить соединение c i486:3000
{03:39:34.463} Установлено соединение!
{03:39:37.257} Сервак_i486 --> Вы подключились к чат серверу. Дружеских разговоров вам
{03:39:37.307} Сейчас в чате:Сервак_i486, Роман, Моника, Wiz, Avan, КОЗEРОГ, Avan, Wiz, Моника, Wiz, Avan, КОЗEРОГ, Avan, Wiz, Моника, Wiz, Avan, КОЗEРОГ, Avan, Wiz, Wiz, Моника, Avan, Wiz, КОЗEРОГ, Моника
{03:39:37.307} КОЗEРОГ >> хай
{03:39:38.068} В чат вошел: КОЗEРОГ
{03:39:39.250} КОЗEРОГ >> хай
{03:39:39.250} В чат вошел: Wiz
{03:39:40.652} Wiz >> Вошел
{03:39:40.652} В чат вошел: Моника
{03:39:42.014} Моника >> Хаюшки!
{03:39:42.064} В чат вошел: Wiz
{03:39:43.626} Wiz >> Вошел
{03:39:45.348} В чат вошел: Avan
{03:39:45.358} Avan >> Ууууу!!!
{03:39:47.211} В чат вошел: Avan
{03:39:47.221} В чат вошел: Wiz
{03:39:47.251} Avan >> Ууууу!!!
{03:39:48.613} Wiz >> Вошел
{03:39:49.795} В чат вошел: Моника
{03:39:51.487} Моника >> Хаюшки!
n
{03:40:20.409} В чат вошел: КОЗEРОГ
{03:40:22.071} КОЗEРОГ >> хай
{03:40:24.505} В чат вошел: Avan
{03:40:26.257} Avan >> Ууууу!!!
{03:40:28.951} В чат вошел: Avan
{03:40:30.583} Avan >> Ууууу!!!
Привет, как дела ?
Привет, к алло ????
{03:41:36.658} КОЗEРОГ>>Всем привет!
Привет, как дела ????
{03:42:51.296} КОЗEРОГ>>ВСЕМ ПРИВЕТ! ПУСТЬ ВСЕГДА БУДЕТ СОЛНЦЕ!!!
{03:42:57.555} удалили пользователя КОЗEРОГ
{03:42:58.676} КОЗEРОГ(24965) отключился
{03:43:06.398} удалили пользователя Avan
{03:43:07.489} Avan(18423) отключился
{03:43:16.162} удалили пользователя КОЗEРОГ
{03:43:17.213} КОЗEРОГ(20352) отключился
{03:43:20.828} удалили пользователя КОЗEРОГ
{03:43:21.850} КОЗEРОГ(4556) отключился
{03:43:23.662} удалили пользователя Wiz
{03:43:24.624} Wiz(29413) отключился
{03:43:28.840} удалили пользователя КОЗEРОГ
{03:43:29.751} КОЗEРОГ(6683) отключился
{03:43:30.682} удалили пользователя КОЗEРОГ
{03:43:30.692} КОЗEРОГ(7566) отключился
{03:43:31.634} удалили пользователя КОЗEРОГ
{03:43:31.634} КОЗEРОГ(21006) отключился
{03:43:32.545} удалили пользователя Моника
{03:43:32.555} Моника(12309) отключился
{03:43:33.406} удалили пользователя Wiz
{03:43:33.416} Wiz(17376) отключился
{03:43:34.228} удалили пользователя Моника
{03:43:34.238} Моника(14532) отключился
{03:43:34.999} удалили пользователя Wiz
{03:43:35.009} Wiz(12341) отключился
{03:43:35.740} удалили пользователя Моника
{03:43:35.750} Моника(32683) отключился
{03:43:36.451} удалили пользователя Wiz
{03:43:36.461} Wiz(1940) отключился
{03:43:37.132} удалили пользователя Wiz
{03:43:37.152} Wiz(30459) отключился
{03:43:37.162} удалили пользователя Wiz
{03:43:37.162} Wiz(10804) отключился
{03:43:37.162} удалили пользователя Wiz
{03:43:37.192} Wiz(11163) отключился
{03:43:37.803} удалили пользователя Wiz
{03:43:37.813} Wiz(43) отключился
{03:43:38.964} удалили пользователя Моника
{03:43:39.555} Моника(5964) отключился
{03:43:39.555} удалили пользователя Моника
{03:43:39.565} Моника(30130) отключился
{03:43:39.836} удалили пользователя Wiz
{03:43:39.856} Wiz(16199) отключился
{03:43:39.856} удалили пользователя Wiz
{03:43:39.896} Wiz(11719) отключился
{03:43:40.296} удалили пользователя Wiz
{03:43:40.547} Wiz(1024) отключился
{03:43:41.027} Сервер разорвал соединение
_
{03:39:34.463} Установлено соединение!
{03:39:37.257} Сервак_i486 --> Вы подключились к чат серверу. Дружеских разговоров вам
{03:39:37.307} Сейчас в чате:Сервак_i486, Роман, Моника, Wiz, Avan, КОЗEРОГ, Avan, Wiz, Моника, Wiz, Avan, КОЗEРОГ, Avan, Wiz, Моника, Wiz, Avan, КОЗEРОГ, Avan, Wiz, Wiz, Моника, Avan, Wiz, КОЗEРОГ, Моника
{03:39:37.307} КОЗEРОГ >> хай
{03:39:38.068} В чат вошел: КОЗEРОГ
{03:39:39.250} КОЗEРОГ >> хай
{03:39:39.250} В чат вошел: Wiz
{03:39:40.652} Wiz >> Вошел
{03:39:40.652} В чат вошел: Моника
{03:39:42.014} Моника >> Хаюшки!
{03:39:42.064} В чат вошел: Wiz
{03:39:43.626} Wiz >> Вошел
{03:39:45.348} В чат вошел: Avan
{03:39:45.358} Avan >> Ууууу!!!
{03:39:47.211} В чат вошел: Avan
{03:39:47.221} В чат вошел: Wiz
{03:39:47.251} Avan >> Ууууу!!!
{03:39:48.613} Wiz >> Вошел
{03:39:49.795} В чат вошел: Моника
{03:39:51.487} Моника >> Хаюшки!
n
{03:40:20.409} В чат вошел: КОЗEРОГ
{03:40:22.071} КОЗEРОГ >> хай
{03:40:24.505} В чат вошел: Avan
{03:40:26.257} Avan >> Ууууу!!!
{03:40:28.951} В чат вошел: Avan
{03:40:30.583} Avan >> Ууууу!!!
Привет, как дела ?
Привет, к алло ????
{03:41:36.658} КОЗEРОГ>>Всем привет!
Привет, как дела ????
{03:42:51.296} КОЗEРОГ>>ВСЕМ ПРИВЕТ! ПУСТЬ ВСЕГДА БУДЕТ СОЛНЦЕ!!!
{03:42:57.555} удалили пользователя КОЗEРОГ
{03:42:58.676} КОЗEРОГ(24965) отключился
{03:43:06.398} удалили пользователя Avan
{03:43:07.489} Avan(18423) отключился
{03:43:16.162} удалили пользователя КОЗEРОГ
{03:43:17.213} КОЗEРОГ(20352) отключился
{03:43:20.828} удалили пользователя КОЗEРОГ
{03:43:21.850} КОЗEРОГ(4556) отключился
{03:43:23.662} удалили пользователя Wiz
{03:43:24.624} Wiz(29413) отключился
{03:43:28.840} удалили пользователя КОЗEРОГ
{03:43:29.751} КОЗEРОГ(6683) отключился
{03:43:30.682} удалили пользователя КОЗEРОГ
{03:43:30.692} КОЗEРОГ(7566) отключился
{03:43:31.634} удалили пользователя КОЗEРОГ
{03:43:31.634} КОЗEРОГ(21006) отключился
{03:43:32.545} удалили пользователя Моника
{03:43:32.555} Моника(12309) отключился
{03:43:33.406} удалили пользователя Wiz
{03:43:33.416} Wiz(17376) отключился
{03:43:34.228} удалили пользователя Моника
{03:43:34.238} Моника(14532) отключился
{03:43:34.999} удалили пользователя Wiz
{03:43:35.009} Wiz(12341) отключился
{03:43:35.740} удалили пользователя Моника
{03:43:35.750} Моника(32683) отключился
{03:43:36.451} удалили пользователя Wiz
{03:43:36.461} Wiz(1940) отключился
{03:43:37.132} удалили пользователя Wiz
{03:43:37.152} Wiz(30459) отключился
{03:43:37.162} удалили пользователя Wiz
{03:43:37.162} Wiz(10804) отключился
{03:43:37.162} удалили пользователя Wiz
{03:43:37.192} Wiz(11163) отключился
{03:43:37.803} удалили пользователя Wiz
{03:43:37.813} Wiz(43) отключился
{03:43:38.964} удалили пользователя Моника
{03:43:39.555} Моника(5964) отключился
{03:43:39.555} удалили пользователя Моника
{03:43:39.565} Моника(30130) отключился
{03:43:39.836} удалили пользователя Wiz
{03:43:39.856} Wiz(16199) отключился
{03:43:39.856} удалили пользователя Wiz
{03:43:39.896} Wiz(11719) отключился
{03:43:40.296} удалили пользователя Wiz
{03:43:40.547} Wiz(1024) отключился
{03:43:41.027} Сервер разорвал соединение
_
[14:31:25] Попытка установить соединение c localhost:3000
[14:31:25] Установлено соединение!
[14:31:25] Send info для sock=9310640 noname user(0) о Ronald(25860)
[14:31:25] Ronald>Хаюшки!
[14:31:25] получена инфа от Wiz(0)
[14:31:25] получена инфа от Bas(14875)
[14:31:25]
[14:31:25] [14:31:20] Запуск сервера(порт 3000). Ожидаются подключения...
[14:31:26] [14:31:22] В чат вошел пользователь: Bas
[14:31:26] [14:31:22] Send info для sock=9311456 Bas(14875) о Wiz(0)
[14:31:26] [14:31:22] Wiz>Привет
[14:31:26] [14:31:22] получена инфа от Bas(14875)
[14:31:26] [14:31:22] Bas> дела то как у вас
[14:31:26] [14:31:25] В чат вошел пользователь: Ronald
[14:31:26] [14:31:25] Send info для sock=9311856 Ronald(25860) о Wiz(0)
[14:31:26] [14:31:25] Send info для sock=9311856 Ronald(25860) о Bas(14875)
[14:31:26] Сейчас в чате:Wiz, Bas, Ronald
[14:31:26] Wiz> Привет
[14:31:29] В чат вошел пользователь: Bas
[14:31:29] получена инфа от Bas(6403)
[14:31:30] Bas> дела то как у вас
[14:32:00] g
[14:32:01] h
[14:32:02] j
[14:32:03] k
[14:32:04] f
[14:32:05] g
[14:32:06] z
[14:32:07] z
[14:32:08] x
[14:32:09] x
[14:32:09] x
[14:32:10] x
[14:32:11] c
[14:32:12] v
[14:32:12] b
[14:32:13] n
[14:32:14] m
[14:32:14] ,
[14:32:15] .
[14:32:16] n
[14:32:19] d
[14:32:19] g
[14:32:19] p
[14:32:19] f
[14:32:19] k
[14:32:19] g
[14:32:19] ]
[14:32:19] d
[14:32:20] f
[14:32:20] p
[14:32:20] g
[14:32:20] ]
[14:32:20] d
[14:32:20] p
[14:32:20] f
[14:32:20] k
[14:32:20] g
[14:32:20] ]
[14:32:20] d
[14:32:20] p
[14:32:20] f
[14:32:20] g
[14:32:21] k
[14:32:21] ]
[14:32:21] p
[14:32:21] d
[14:32:21] f
[14:32:21] g
[14:32:21] k
[14:32:21] ]
[14:32:21] d
[14:32:21] p
[14:32:21] f
[14:32:21] k
[14:32:21] g
[14:32:21] ]
[14:32:21] d
[14:32:21] p
[14:32:21] f
[14:32:21] k
[14:32:21] g
[14:32:21] ]
[14:32:22] d
[14:32:22] p
[14:32:22] f
[14:32:22] k
[14:32:22] g
[14:32:22] ]
[14:32:22] d
[14:32:22] p
[14:32:22] f
[14:32:22] k
[14:32:22] g
[14:32:22] ]
[14:32:22] d
[14:32:22] f
[14:32:22] p
[14:32:22] k
[14:32:22] g
[14:32:22] ]
[14:32:22] d
[14:32:22] p
[14:32:23] f
[14:32:23] g
[14:32:23] k
[14:32:23] ]
[14:32:23] d
[14:32:23] p
[14:32:23] f
[14:32:23] g
[14:32:23] k
[14:32:23] ]
[14:32:23] d
[14:32:23] p
[14:32:23] f
[14:32:23] g
[14:32:23] k
[14:32:23] d
[14:32:23] ]
[14:32:24] p
[14:32:24] f
[14:32:24] k
[14:32:24] g
[14:32:24] ]
[14:32:24] d
[14:32:24] f
[14:32:24] p
[14:32:24] g
[14:32:24] k
[14:32:24] ]
[14:32:24] d
[14:32:24] f
[14:32:24] p
[14:32:24] g
[14:32:24] k
[14:32:24] ]
[14:32:24] d
[14:32:24] p
[14:32:24] f
[14:32:25] g
[14:32:25] k
[14:32:25] ]
[14:32:25] d
[14:32:25] f
[14:32:25] p
[14:32:25] g
[14:32:25] k
[14:32:25] ]
[14:32:25] d
[14:32:25] f
[14:32:25] p
[14:32:25] g
[14:32:25] k
[14:32:25] d
[14:32:25] ]
[14:32:25] p
[14:32:25] f
[14:32:25] g
[14:32:25] k
[14:32:27]
[14:32:27] Ожидаю инфо...(996192) отключился
[14:32:44] Cервер останавливается
[14:32:44] Сервер разорвал соединение
[14:31:25] Установлено соединение!
[14:31:25] Send info для sock=9310640 noname user(0) о Ronald(25860)
[14:31:25] Ronald>Хаюшки!
[14:31:25] получена инфа от Wiz(0)
[14:31:25] получена инфа от Bas(14875)
[14:31:25]
[14:31:25] [14:31:20] Запуск сервера(порт 3000). Ожидаются подключения...
[14:31:26] [14:31:22] В чат вошел пользователь: Bas
[14:31:26] [14:31:22] Send info для sock=9311456 Bas(14875) о Wiz(0)
[14:31:26] [14:31:22] Wiz>Привет
[14:31:26] [14:31:22] получена инфа от Bas(14875)
[14:31:26] [14:31:22] Bas> дела то как у вас
[14:31:26] [14:31:25] В чат вошел пользователь: Ronald
[14:31:26] [14:31:25] Send info для sock=9311856 Ronald(25860) о Wiz(0)
[14:31:26] [14:31:25] Send info для sock=9311856 Ronald(25860) о Bas(14875)
[14:31:26] Сейчас в чате:Wiz, Bas, Ronald
[14:31:26] Wiz> Привет
[14:31:29] В чат вошел пользователь: Bas
[14:31:29] получена инфа от Bas(6403)
[14:31:30] Bas> дела то как у вас
[14:32:00] g
[14:32:01] h
[14:32:02] j
[14:32:03] k
[14:32:04] f
[14:32:05] g
[14:32:06] z
[14:32:07] z
[14:32:08] x
[14:32:09] x
[14:32:09] x
[14:32:10] x
[14:32:11] c
[14:32:12] v
[14:32:12] b
[14:32:13] n
[14:32:14] m
[14:32:14] ,
[14:32:15] .
[14:32:16] n
[14:32:19] d
[14:32:19] g
[14:32:19] p
[14:32:19] f
[14:32:19] k
[14:32:19] g
[14:32:19] ]
[14:32:19] d
[14:32:20] f
[14:32:20] p
[14:32:20] g
[14:32:20] ]
[14:32:20] d
[14:32:20] p
[14:32:20] f
[14:32:20] k
[14:32:20] g
[14:32:20] ]
[14:32:20] d
[14:32:20] p
[14:32:20] f
[14:32:20] g
[14:32:21] k
[14:32:21] ]
[14:32:21] p
[14:32:21] d
[14:32:21] f
[14:32:21] g
[14:32:21] k
[14:32:21] ]
[14:32:21] d
[14:32:21] p
[14:32:21] f
[14:32:21] k
[14:32:21] g
[14:32:21] ]
[14:32:21] d
[14:32:21] p
[14:32:21] f
[14:32:21] k
[14:32:21] g
[14:32:21] ]
[14:32:22] d
[14:32:22] p
[14:32:22] f
[14:32:22] k
[14:32:22] g
[14:32:22] ]
[14:32:22] d
[14:32:22] p
[14:32:22] f
[14:32:22] k
[14:32:22] g
[14:32:22] ]
[14:32:22] d
[14:32:22] f
[14:32:22] p
[14:32:22] k
[14:32:22] g
[14:32:22] ]
[14:32:22] d
[14:32:22] p
[14:32:23] f
[14:32:23] g
[14:32:23] k
[14:32:23] ]
[14:32:23] d
[14:32:23] p
[14:32:23] f
[14:32:23] g
[14:32:23] k
[14:32:23] ]
[14:32:23] d
[14:32:23] p
[14:32:23] f
[14:32:23] g
[14:32:23] k
[14:32:23] d
[14:32:23] ]
[14:32:24] p
[14:32:24] f
[14:32:24] k
[14:32:24] g
[14:32:24] ]
[14:32:24] d
[14:32:24] f
[14:32:24] p
[14:32:24] g
[14:32:24] k
[14:32:24] ]
[14:32:24] d
[14:32:24] f
[14:32:24] p
[14:32:24] g
[14:32:24] k
[14:32:24] ]
[14:32:24] d
[14:32:24] p
[14:32:24] f
[14:32:25] g
[14:32:25] k
[14:32:25] ]
[14:32:25] d
[14:32:25] f
[14:32:25] p
[14:32:25] g
[14:32:25] k
[14:32:25] ]
[14:32:25] d
[14:32:25] f
[14:32:25] p
[14:32:25] g
[14:32:25] k
[14:32:25] d
[14:32:25] ]
[14:32:25] p
[14:32:25] f
[14:32:25] g
[14:32:25] k
[14:32:27]
[14:32:27] Ожидаю инфо...(996192) отключился
[14:32:44] Cервер останавливается
[14:32:44] Сервер разорвал соединение
Показать
// ECHO_TCP_IPDlg.cpp : implementation file
//
#include "stdafx.h"
#include <shellapi.h>
#include <Afxsock.h>
#include <atlbase.h>
#include <vector>
#include <mmsystem.h>
#include "ECHO_TCP_IP.h"
#include "ECHO_TCP_IPDlg.h"
#include "RegKeyAdv.h"
#include "sockets.h"
#include "aboutbox.h"
#include "statusdialog.h"
CString ENDL="\r\n";
CString PathTextLog,PathRtfLog;
CFile RtfFile;
CString _S="";
int ShowSendRecvInfo=false;
const int LIST_ITEM_HEIGHT=30;
const UINT MAX_MESSAGE_LEN=1024;
int INPUT_HEI=300;
const BYTE RING_SYMBOL='Ё'; //символ, по принятии которого звучит "вызов"
const BYTE RING_SYMBOL2='Й'; //символ, по принятии которого звучит "вызов"
char __MAIN__DATE__[]=__DATE__;
char __MAIN__TIME__[]=__TIME__;
const CString CopyRightString="TCP/IP Chat. (c) 2005 - 2010 Евгений Лапшин";
#define ID_POPUP_SHOW 0xF001
#define ID_POPUP_EXIT 0xF002
//COLORREF BackGroundColor=RGB(255,255,255);
COLORREF BackGroundColor=RGB(20,20,20);
CUserSettings
LocalSettings, //наши настройки
SystemSettings, //системные настройки
HistorySettings;//настройки для показа истории
DWORD UnID=0;
/*
typedef struct _charformat2 {
UINT cbSize;
DWORD dwMask;
DWORD dwEffects;
LONG yHeight;
LONG yOffset;
COLORREF crTextColor;
BYTE bCharSet;
BYTE bPitchAndFamily;
TCHAR szFaceName[LF_FACESIZE];
WORD wWeight;
SHORT sSpacing;
COLORREF crBackColor;
LCID lcid;
DWORD dwReserved;
SHORT sStyle;
WORD wKerning;
BYTE bUnderlineType;
BYTE bAnimation;
BYTE bRevAuthor;
BYTE bReserved1;
} CHARFORMAT2;
typedef struct _charformat {
UINT cbSize;
DWORD dwMask;
DWORD dwEffects;
LONG yHeight;
LONG yOffset;
COLORREF crTextColor;
BYTE bCharSet;
BYTE bPitchAndFamily;
TCHAR szFaceName[LF_FACESIZE];
} CHARFORMAT;
*/
void WizSelectionCharFormat(CRichEditCtrl & rich, CHARFORMAT & charformat)
{
CHARFORMAT ch=charformat;
CHARFORMAT2 ch2;
ch2.cbSize=0;
ch2.dwMask=
CFM_COLOR |
CFM_SIZE |
CFM_FACE |
CFM_CHARSET;
ch2.dwEffects=0;
ch2.yHeight=0;
ch2.yOffset=0;
ch2.crTextColor=0;
ch2.bCharSet=0;
ch2.bPitchAndFamily=0;
//TCHAR szFaceName[LF_FACESIZE];
ch2.wWeight=0;
ch2.sSpacing=0;
ch2.crBackColor=0;
ch2.lcid=0;
ch2.dwReserved=0;
ch2.sStyle=0;
ch2.wKerning=0;
ch2.bUnderlineType=0;
ch2.bAnimation=0;
ch2.bRevAuthor=0;
// ch2.bReserved1=0;
ch2.cbSize=sizeof(ch2);
//ch2.dwMask=ch.dwMask;
ch2.dwEffects=ch.dwEffects;
ch2.yHeight=ch.yHeight;
ch2.yOffset=ch.yOffset;
ch2.crTextColor=ch.crTextColor;
ch2.bCharSet=DEFAULT_CHARSET;
ch2.bPitchAndFamily=ch.bPitchAndFamily;
strcpy(ch2.szFaceName, ch.szFaceName);
ch2.crBackColor=RGB(0,255,0);
LOGFONT lf= {0};
lf.lfCharSet=ch.bCharSet;
lf.lfHeight=LIST_ITEM_HEIGHT;
lf.lfWidth=10;
lf.lfPitchAndFamily=ch.bPitchAndFamily;
lf.lfCharSet=DEFAULT_CHARSET;
rich.SetSelectionCharFormat(ch2);
}
//переводит число в CString
CString itos(int n)
{
CString m;
m.Format("%i",n);
return m;
}
static DWORD CALLBACK
MyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
CFile* pFile = (CFile*) dwCookie;
pFile->Write(pbBuff, cb);
*pcb = cb;
return 0;
}
//возвращает истину если все символы строки пробельные
bool AllSpace(CString &s)
{
for(int i=0; i<s.GetLength(); i++)
{
if (s!=' ') return false;
}
return true;
}
//bool need_show_cursor=true;
bool need_invalidate=false;
CString RegistryBase="Software\\TcpIpChat\\";
#define NO_NEW_LINE false
#define NEW_LINE true
#define PutData UpdateData(false)
#define GetData UpdateData(true)
CECHO_TCP_IPDlg* dialog=NULL;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CStatusDialog * StatusDialog;
#define STOP_SOUND 1
#define SOUND_STOP 1
CString GetLocalTimeString()
{
SYSTEMTIME t;
GetLocalTime(&t);
CString c;
//c.Format("{%02i:%02i:%02i.%03i} ", t.wHour, t.wMinute, t.wSecond,t.wMilliseconds);
c.Format("{%02i.%02i.%02i} [%02i:%02i.%02i] ", t.wDay, t.wMonth, t.wYear,
t.wHour, t.wMinute, t.wSecond);
return c;
}
struct CURSORINFO
{
CRichEditCtrl* rich;
char String[2];
char sym; //символ, используемый в качестве курсора
int count;
CURSORINFO()
{
sym='_';
String[0]=sym;
String[1]=0;
count=0;
}
void Show()
{
String[0]=sym;
count=0;
}
void Hide()
{
String[0]=' ';
count=0;
}
void LinkRichEdit(CRichEditCtrl * r)
{
rich=r;
}
//стираем курсор
void Erase()
{
//стираем последний символ в RichEdit'оре
//rich->SendMessage(WM_KEYDOWN, VK_BACK,0);
}
//отрисовка курсора
void Draw() {}
/* {
CHARFORMAT a={0};
//настраиваем системные настройки
a.cbSize=sizeof(CHARFORMAT);
a.yHeight=LocalSettings.cf.yHeight;
a.crTextColor=RGB(255,255,255);
//strcpy(a.szFaceName,"Terminal");
a.dwMask=
CFM_COLOR |
CFM_SIZE |
CFM_FACE
;
a.bPitchAndFamily=FIXED_PITCH;
a.bCharSet=DEFAULT_CHARSET;
rich->ReplaceSel(Cursor.String);
}
*/
} Cursor;
CServerSocket* ServerSocket=NULL;
const DWORD InfoTimeOut=4000; //время на получение информации от пользователя
//информация о присоединеных пользователях
struct CConnectedUserInfo
{
CConnectedUserInfo() : CountInfoReceive(0), socket_connect(NULL) {}
CClientSocket* socket_connect; //сокет удаленного пользователя
CString ip; //ip адрес
CString domainaddr; //доменное имя
DWORD unicalid;
DWORD startime; //время подключения
CUserSettings RemoteSettings; //настройка удаленного пользователя
void SendInfo(CUserSettings &info)
{
BYTE buf=ESCAPE_CODE;
int size=1+sizeof(info);
BYTE *bufer=new BYTE[size];
bufer[0]=ESCAPE_CODE;
CopyMemory(bufer+1,&info,sizeof(info));
socket_connect->SendData(bufer,size);
delete bufer;
if (ShowSendRecvInfo)
{
CString m;
m.Format("Send info для sock=%i ",DWORD(socket_connect));
m+=_S+RemoteSettings.NickName+"("+itos(RemoteSettings.uid)+")";
m+=_S+" о "+info.NickName+"("+itos(info.uid)+")"+ENDL;
dialog->ChatWindowAddStringUID(m,SYSTEM_UID);
}
}
int CountInfoReceive;
CString RecvString; //принимаемые текстовые данные
bool EchoToClient;//=false;
bool ConvertOemToAnsi;//=false;
};
std::vector<CConnectedUserInfo> UserInfo;
enum
{
SOUND_BLA,
SOUND_MLA,
SOUND_CLICK,
SOUND_RING1,
SOUND_RING2,
SOUND_MESSAGE1,
SOUND_MESSAGE2,
SOUND_LOL1,
SOUND_LOL2,
SOUND_NEWUSER,
SOUND_DISCONNECT,
SOUND_SOUND1,
SOUND_SOUND2,
SOUND_SOUND3,
SOUND_SOUND4,
SOUND_SOUND5,
SOUND_SOUND6
};
void CECHO_TCP_IPDlg::Sound(int type, int stop=false)
{
if (!SettingBox.m_sound_enable) return;
char *fname=NULL;
switch (type)
{
case SOUND_BLA:
{
fname="bla.wav";
break;
}
case SOUND_CLICK:
{
fname="click.wav";
break;
}
case SOUND_RING1:
{
fname="ring1.wav";
break;
}
case SOUND_RING2:
{
fname="ring2.wav";
break;
}
case SOUND_MESSAGE1:
{
fname="message.wav";
break;
}
case SOUND_MESSAGE2:
{
fname="message.wav";
break;
}
case SOUND_LOL1:
{
fname="lol1.wav";
break;
}
case SOUND_LOL2:
{
fname="lol2.wav";
break;
}
case SOUND_NEWUSER:
{
fname="newuser.wav";
break;
}
case SOUND_DISCONNECT:
{
fname="disconnect.wav";
break;
}
case SOUND_SOUND1:
{
fname="sound1.wav";
break;
}
case SOUND_SOUND2:
{
fname="sound2.wav";
break;
}
case SOUND_SOUND3:
{
fname="sound3.wav";
break;
}
case SOUND_SOUND4:
{
fname="sound4.wav";
break;
}
case SOUND_SOUND5:
{
fname="sound5.wav";
break;
}
case SOUND_SOUND6:
{
fname="sound6.wav";
break;
}
}
if (fname)
{
if (stop==1) sndPlaySound(NULL,SND_ASYNC);
sndPlaySound(_S+"Sound\\"+fname,SND_ASYNC | SND_NOSTOP);
}
}
int GetUserIndex(DWORD sock)
{
for(int i=0; i<UserInfo.size(); i++)
if ( DWORD(UserInfo.socket_connect) ==sock) return i;
//if (i== UserInfo.size())
//potencial bug
return -1;
}
//посылает строку всем пользователям
void send_all(const CString& m)
{
if (UserInfo.size()==0) return;
//если мы сервер
if (ServerSocket)
{
//поочереди посылаем строку каждому пользователю из списка
for(int i=0; i<UserInfo.size(); i++)
{
UserInfo.socket_connect->SendStringWithUID(m,0);
}
}
//иначе мы клиент и посылаем строку серверу
else
{
UserInfo[0].socket_connect->SendStringWithUID(m,UnID);
}
}
//CClientSocket* ConnectedSocket=NULL;
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
public:
virtual BOOL DestroyWindow();
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
afx_msg void OnMenuLoadLog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
ON_COMMAND(ID_MENU_LOAD_LOG, OnMenuLoadLog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CECHO_TCP_IPDlg dialog
CECHO_TCP_IPDlg::CECHO_TCP_IPDlg(CWnd* pParent /*=NULL*/)
: CDialog(CECHO_TCP_IPDlg::IDD, pParent)
{
dialog=this;
//{{AFX_DATA_INIT(CECHO_TCP_IPDlg)
m_richtext = _T(" ");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_hide=false;
CHARFORMAT &a=SystemSettings.cf;
//настраиваем системные настройки
a.yHeight=200;
a.crTextColor=RGB(50,255,100);
a.cbSize=sizeof(CHARFORMAT);
strcpy(a.szFaceName,"System");
//strcpy(a.szFaceName,"");
a.dwMask=
CFM_COLOR |
CFM_SIZE |
CFM_FACE |
CFM_CHARSET
;
a.bPitchAndFamily=VARIABLE_PITCH;
//a.bCharSet=RUSSIAN_CHARSET;
a.bCharSet=DEFAULT_CHARSET;
strcpy(SystemSettings.NickName, "System");
CHARFORMAT b=SystemSettings.cf;
b.crTextColor=RGB(240,200,250);
HistorySettings.cf=b;
}
void CECHO_TCP_IPDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CECHO_TCP_IPDlg)
DDX_Control(pDX, IDC_USER_LIST, m_user_list);
DDX_Control(pDX, IDC_INPUT, m_input);
DDX_Control(pDX, IDC_INPUT_BOX, m_input_box);
DDX_Control(pDX, IDC_RICHEDIT, m_richedit);
DDX_Text(pDX, IDC_RICHEDIT, m_richtext);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CECHO_TCP_IPDlg, CDialog)
//{{AFX_MSG_MAP(CECHO_TCP_IPDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_SEND, OnSend)
ON_WM_TIMER()
ON_WM_LBUTTONDOWN()
ON_WM_CLOSE()
ON_WM_RBUTTONDOWN()
ON_WM_SIZE()
ON_COMMAND(ID_MENU_CONNECT, OnMenuConnect)
ON_COMMAND(ID_MENU_RUN_SERVER, OnMenuRunServer)
ON_COMMAND(ID_MENU_SETTING_BOX, OnMenuSettingBox)
ON_COMMAND(ID_FILE_EXIT, OnFileExit)
ON_NOTIFY(EN_SETFOCUS, IDC_INPUT, OnSetfocusInput)
ON_NOTIFY(NM_CLICK, IDC_INPUT, OnClickInput)
ON_EN_KILLFOCUS(IDC_INPUT_BOX, OnKillfocusInputBox)
ON_EN_SETFOCUS(IDC_INPUT_BOX, OnSetfocusInputBox)
ON_NOTIFY(NM_RETURN, IDC_INPUT, OnReturnInput)
ON_COMMAND(ID_MENU_STOP_SERVER, OnMenuStopServer)
ON_WM_MOUSEWHEEL()
ON_COMMAND(ID_ABOUT, OnAbout)
ON_WM_DESTROY()
ON_COMMAND(ID_FILE_SEND, OnFileSend)
ON_COMMAND(IDC_CLEAR_LOG, OnClearLog)
ON_COMMAND(IDC_CRASH, OnCrash)
ON_COMMAND(IDC_DISCONNECT, OnDisconnect)
ON_NOTIFY(NM_CLICK, IDC_RICHEDIT, OnClickRichedit)
ON_NOTIFY(NM_RCLICK, IDC_RICHEDIT, OnRclickRichedit)
ON_NOTIFY(NM_DBLCLK, IDC_RICHEDIT, OnDblclkRichedit)
ON_NOTIFY(NM_RDBLCLK, IDC_RICHEDIT, OnRdblclkRichedit)
ON_LBN_SELCHANGE(IDC_USER_LIST, OnSelchangeUserList)
ON_WM_DRAWITEM()
ON_COMMAND(ID_MENU_LOAD_LOG, OnMenuLoadLog)
ON_WM_MEASUREITEM()
ON_WM_CTLCOLOR()
ON_BN_CLICKED(IDC_CONNECT, OnConnect)
ON_WM_CHAR()
ON_BN_CLICKED(IDC_RUN_SERVER, OnRunServer)
// ON_COMMAND(ID_CRASH_SERVER, OnCrashServer)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CECHO_TCP_IPDlg message handlers
BOOL CECHO_TCP_IPDlg::OnInitDialog()
{
CDialog::OnInitDialog();
LoadLibrary("riched32.dll");
SYSTEMTIME time;
GetLocalTime(&time);
PathTextLog.Format("logs\\%02i-%02i-%i_[%02i_%02i_%02i].log",time.wDay,time.wMonth,time.wYear,time.wHour,time.wMinute,time.wSecond);
PathRtfLog.Format("logs\\%02i-%02i-%i_[%02i_%02i_%02i].rtf",time.wDay,time.wMonth,time.wYear,time.wHour,time.wMinute,time.wSecond);
// m_richedit.SetFocus();
//генерируем сами себе свой идентификатор
rest:
srand(GetTickCount());
UnID=1+rand();
//это возможно в случае если rand()+1 станет равным нулю
if (UnID==0) goto rest;
//делаем системный шрифт "Tahoma"
strcpy(SystemSettings.cf.szFaceName,"Tahoma");
char buf[1024];
//получаем командную строку
char *command=GetCommandLine();
CString Cscom=command;
//если имеется ключевое слово HIDE
if (strstr(command,"hide")==NULL)
{
CRegKey reg;
reg.Create(HKEY_CURRENT_USER,
"Software\\Microsoft\\Windows\\CurrentVersion\\Run");
//получаем текушую директорию
GetCurrentDirectory(1024,buf);
//добавляем название приложения
strcat(buf,"\\echo_tcp_ip.exe hide");
reg.SetValue(buf,"TCP_IP_CHAT");
reg.Close();
GetCurrentDirectory(1024,buf);
reg.Create(HKEY_CURRENT_USER,"Software\\ECHO_TCP_IP");
reg.SetValue(buf,"CurDir");
reg.Close();
}
//запускаем скрыто
else
{
CRegKey reg;
reg.Create(HKEY_CURRENT_USER,"Software\\ECHO_TCP_IP");
DWORD count=1024;
//получаем текущий путь
reg.QueryValue(buf,"CurDir",&count);
reg.Close();
SetCurrentDirectory(buf);
}
AddIcon();
Cursor.LinkRichEdit(&m_richedit);
SetTimer(1, 100,NULL);
SettingBox.LoadSettings();
LocalSettings=SettingBox.GetUserSettings();
ShowSendRecvInfo=SettingBox.m_system_message;
m_richedit.SetBackgroundColor(false, BackGroundColor);
// m_user_list.SetBackgroundColor(false, RGB(10,10,10));
{
CHARFORMAT cf= {0};
cf=LocalSettings.cf;
cf.yHeight=INPUT_HEI;
m_input.SetBackgroundColor(false,BackGroundColor);
WizSelectionCharFormat(m_input, cf);
//m_input.SetEventMask()
}
ChatWindowAddStringUID("Ok"+ENDL,SYSTEM_UID);
CRect r;
GetWindowRect(&r);
CRegKeyAdv reg;
DWORD x,y,cx,cy;
reg.QueryValue( x, "PosX");
reg.QueryValue( y, "PosY");
reg.QueryValue( cx, "WinCX");
reg.QueryValue( cy, "WinCY");
if (!cx && !cy) cx=r.Width(), cy=r.Height();
MoveWindow(x,y, cx,cy);
PutData;
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
m_input_box.SetFocus();
if (SettingBox.m_connect_on_start) OnConnect();
else if (SettingBox.m_run_server_on_start) OnRunServer();
SynchroMenuButtons();
SetTitle();
return FALSE; // return TRUE unless you set the focus to a control
}
void CECHO_TCP_IPDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
void CECHO_TCP_IPDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CECHO_TCP_IPDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CECHO_TCP_IPDlg::OnRunServer()
{
ServerSocket=new CServerSocket;
UnID=0;
if (!ServerSocket->Create(SettingBox.m_port, SOCK_STREAM, FD_WRITE
| FD_READ | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
{
delete ServerSocket;
ServerSocket=NULL;
MessageBox("Не удается создать сервер");
return;
}
CString mes;
mes.Format("Запуск сервера(порт %i). Ожидаются подключения..."+ENDL, SettingBox.m_port);
ChatWindowAddStringUID(mes,SYSTEM_UID);
ServerSocket->Listen(1);
SynchroMenuButtons();
m_input_box.SetFocus();
LocalSettings.uid=0; //признак сервера
}
void CECHO_TCP_IPDlg::OnReceive(const CString &str, DWORD sock)
{
CString z=str;
BYTE k=str[0];
if (k!=RING_SYMBOL) Sound(SOUND_CLICK);
else Sound(SOUND_RING2);
ScrollRich();
//это применимо только к серверу
ChatWindowAddStringUID(z, UserInfo[GetUserIndex(sock)].RemoteSettings.uid);
if (SettingBox.m_auto_chat_show) ShowWindow(SW_SHOWNORMAL);
}
//послать целую строку
void CECHO_TCP_IPDlg::OnSend()
{
CString tmp,src;
m_input.GetWindowText(src);
if (src.GetLength()==0) return;
if (src.GetLength()>MAX_MESSAGE_LEN)
{
MessageBox("Посылаемое ваше сообщение слишком велико!\r\nУменьшите размер сообщение и повторите попытку", "Внимание!");
return;
}
if (AllSpace(src)) return;
if (src.GetLength() == 2)
{
if (
(src[0]==13 && src[1]==10)
||
( src[0]==10 && src[1]==13)
)
return;
}
CString z;
m_richedit.GetWindowText(z);
char k=z.Right(2)[0];
//if (k!='\r' && k!='\n') tmp+=ENDL;
GetData;
CString ss=src+ENDL;
send_all(ss);
ChatWindowAddStringUID(_S+LocalSettings.NickName+"> "+ss,UnID);
m_input.SetWindowText("");
}
BOOL CECHO_TCP_IPDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if (m_hide==true) ShowWindow(SW_HIDE);//,m_hide=false;
// if (pMsg->message== WM_QUIT)
// {
// MessageBox("WM_QUIT");
// }
if (pMsg->message == WM_RBUTTONDOWN)
{
OnMenuSettingBox();
return true;
}
if (pMsg->message == WM_COMMAND)
{
for(int i=0; i<UserInfo.size(); i++)
if (DWORD(UserInfo.socket_connect) == pMsg->wParam)
//удаляем пользователя
{
//DisconnectUser()
//UserInfo.socket_connect->Close();
OnRemoteClose(0, (DWORD)UserInfo.socket_connect);
//delete UserInfo.socket_connect;
//UserInfo.erase(&UserInfo);
//MessageBox("DISCONNECT ? ARE YOU SURE ?");
}
}
if (pMsg->message == WM_KEYDOWN)
{
//if (GetFocus() != GetDlgItem(IDC_INPUT)) return true;
BYTE key=pMsg->wParam;
if (key==17) return true;
if (key==27) return true;
//ChatWindowAddStringUID("?", UnID, NO_NEW_LINE);
//MessageBeep(MB_OK);
//CString m;
//m_input.GetWindowText(m);
//m_input.SetWindowText(m+itos(key)+" ");
switch (key)
{
case 13:
{
if (GetFocus() == GetDlgItem(IDC_INPUT_BOX))
{
/* Cursor.Show();
ChatWindowAddStringUID(ENDL,SYSTEM_UID);
send_all(ENDL);
*/
}
//else
if (GetFocus() == GetDlgItem(IDC_INPUT))
{
OnSend();
}
return true;
}
case VK_UP:
m_richedit.LineScroll(-1);
return 0;
case VK_DOWN:
m_richedit.LineScroll(1);
return 0;
}
}
/* if ( pMsg->message == WM_CHAR)
{
ScrollRich();
BYTE m=pMsg->wParam;
if (m==13) return true;
if (GetFocus() != GetDlgItem(IDC_INPUT_BOX)) return false;
if (m!=RING_SYMBOL) Sound(SOUND_CLICK);
else Sound(SOUND_RING);
if (m<32 && m!=8) return true;
Cursor.Show();
ChatWindowAddStringUID(m, UnID, NO_NEW_LINE);
//if (!ServerSocket) return false;
//если нет подключения к клиенту/серверу - не вводим ничего
if (UserInfo.size()==0) return true;
CString buf;
buf+=m;
//if (ConvertOemToAnsi) CharToOem(buf,buf);
send_all(buf);
return true;
}
*/
return CDialog::PreTranslateMessage(pMsg);
}
void CECHO_TCP_IPDlg::OnTimer(UINT nIDEvent)
{
SynchroMenuButtons();
//if (GetFocus() != GetDlgItem(IDC_INPUT_BOX)) return;
if (Cursor.count++ > 5)
{
Cursor.count=0;
char& k=Cursor.String[0];
if (k != Cursor.sym) k=Cursor.sym;
else k=' ';
Cursor.Erase();
Cursor.Draw();
if (need_invalidate)
{
m_richedit.InvalidateRect(NULL,false);
m_richedit.UpdateWindow();
}
}
CDialog::OnTimer(nIDEvent);
}
//к серверу присоединяется клиент
void CECHO_TCP_IPDlg::OnClientAccept(int err)
{
CConnectedUserInfo info;
info.socket_connect=new CClientSocket;
SOCKADDR sockaddr;
sockaddr.sa_family=AF_INET;
int addrlen=sizeof(sockaddr);
ServerSocket->Accept(*info.socket_connect, &sockaddr, &addrlen);
// ServerSocket->Accept(*info.socket_connect);
SOCKADDR_IN *saddr=(SOCKADDR_IN*)&sockaddr;
BYTE b1=saddr->sin_addr.S_un.S_un_b.s_b1;
BYTE b2=saddr->sin_addr.S_un.S_un_b.s_b2;
BYTE b3=saddr->sin_addr.S_un.S_un_b.s_b3;
BYTE b4=saddr->sin_addr.S_un.S_un_b.s_b4;
info.ip.Format("%i.%i.%i.%i"+ENDL,b1,b2,b3,b4);
ChatWindowAddStringUID("Подключился пользователь с IP:"+info.ip,SYSTEM_UID);
//теперь следует ожидать от пользователя управляющего
//пакета. Если разрешены подключения от Telneta -
//установить соотв. флаги (Echo для этого пользователя
//конвертацию OEM и др.)
//если приходит пакет с ESC==2 (старая верся chat)
//проинформировать пользователя, что версия поменялась
//и ему следует обновить программное обеспечение
//если приходит новый формат пакет с ESC==3, далее два байта
//размер пакета, и байт версии. проверяем на размер. Если совпадает, значит
//версия и размер - значит версии идентчиный, принмаем
//от пользователя его инфу (Ник,Цвет щрифт) и рассылаем эту инфу
//остальным подключенным пользователям а вновь подлюченному
//отсылаем информацию о сервере, и остальных подключенных пользователей.
//время на получения информации ограничено TimeOut'ом
//если по истечении тайм аута информация от пользователя не поступило-
//сбрасываем данное подключения и не отсылаем остальным параметры
//данного пользователя
/*сервер присваивает подключенному пользователю уникальный
идентификатор uid, который сохраняется на протяжении всего подключения
клиенты, получая информацию о других пользователях, получают их uid
клиенту может придти пакет на удаления пользователя с заданным
uid
*/
//сервер назначает клиенту UID
//for(int i=0; i<UserInfo.size(); i++)
//{
// if (UserInfo
//}
info.RemoteSettings.uid=GetTickCount();
info.startime=GetTickCount();
strcpy(info.RemoteSettings.NickName,"Ожидаю инфу...");
info.RemoteSettings.cf=SystemSettings.cf;
info.RemoteSettings.size=sizeof(info.RemoteSettings);
UserInfo.push_back(info);
RefreshUserList();
}
/////// установка соединения с сервером
int CECHO_TCP_IPDlg::OnConnect()
{
LocalSettings=SettingBox.GetUserSettings();
CString Caption="В Н И М А Н И Е . . .";
if (ServerSocket)
{
MessageBox("Соединиться с сервером невозможно, \r\nпоскольку в данным момент вы сами являетесь сервером!",Caption, MB_ICONINFORMATION);
return false;
}
if (UserInfo.size())
{
MessageBox("Соединение с сервером уже установлено!\r\n",Caption,MB_ICONINFORMATION);
return false;
}
if (AllSpace(SettingBox.m_nick_name))
{
MessageBox("Задайте в настройках свой ник.\r\nПустой ник недопустим!","Внимание!");
return false;
}
SettingBox.TryConnect=true;
//CConnectedUserInfo info;
CClientSocket * socket = new CClientSocket;
socket->Create();
socket -> Connect(SettingBox.m_cremote_ip, SettingBox.m_port);
// info.RemoteSettings.uid=0; //это сервер
// strcpy(info.RemoteSettings.NickName, "РОЖА");
// UserInfo.push_back(info);
CString k;
ChatWindowAddStringUID("Попытка установить соединение c "+SettingBox.m_cremote_ip+":"+
itos(SettingBox.m_port)+ENDL,SYSTEM_UID);
// RefreshUserList();
SynchroMenuButtons();
return true;
}
void CECHO_TCP_IPDlg::OnOK()
{
//WriteLogFile();
CDialog::OnOK();
// MessageBox("OK");
}
//посылка сервером своей информацией остальным пользователям-клиентам
void CECHO_TCP_IPDlg::InfoExchange()
{
if (ServerSocket)
for(int i=0; i<UserInfo.size(); i++)
{
UserInfo.SendInfo(LocalSettings);
//ChatWindowAddStringUID("InfoExchange - Server"+ENDL,SYSTEM_UID);
}
else if (UserInfo.size()>0)
{
UserInfo[0].SendInfo(LocalSettings);
//ChatWindowAddStringUID("InfoExchange - Client"+ENDL,SYSTEM_UID);
}
}
//посылка информацией другим пользователям ользователям
//source - номер пользователя, чья информацию будем передана остальным
void CECHO_TCP_IPDlg::InfoSend(int source)
{
for(int i=0; i<UserInfo.size(); i++)
{
if (i==source) continue;
UserInfo[i].SendInfo(UserInfo[source].RemoteSettings);
//ChatWindowAddStringUID("InfoSend"+ENDL,SYSTEM_UID);
}
}
void CECHO_TCP_IPDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
WriteLogFile();
ShowWindow(SW_HIDE);
/*if (UserInfo.size() !=0)
{
if (MessageBox("Установлено соединение с другим компьютером!\r\nПодтверждаете выход?", "Внимание!", MB_OKCANCEL) == IDOK )
{
for (int i=0; i<UserInfo.size(); i++)
OnRemoteClose(0, (DWORD)UserInfo[i].socket_connect);
WriteLogFile();
CDialog::OnClose();
}
}
else
{
WriteLogFile();
CDialog::OnClose();
}*/
AddIcon();
}
void CECHO_TCP_IPDlg::RefreshUserList()
{
CString us;
int nick_size=250;
m_user_list.ResetContent();
for(int i=0; i<UserInfo.size(); i++)
{
CString m=_S+UserInfo[i].RemoteSettings.NickName;
//itos(DWORD(UserInfo[i].socket_connect))+" "+
//" ("+ itos(UserInfo[i].RemoteSettings.uid)+")";
//CHARFORMAT f=UserInfo[i].RemoteSettings.cf;
//f.yHeight=30;
CHARFORMATA cf=UserInfo[i].RemoteSettings.cf;
cf.yHeight=nick_size;
//WizSelectionCharFormat(m_user_list, cf);
//WizSelectionCharFormat(m_user_list, UserInfo[i].RemoteSettings.cf);
//m_user_list.ReplaceSel(m+ENDL);
m_user_list.AddString(m);
int n=m_user_list.GetCount();
m_user_list.SetItemData(n-1,(ULONG) (&UserInfo[i].RemoteSettings) );
}
if (UserInfo.size()!=0)
{
CHARFORMATA cf=LocalSettings.cf;
cf.yHeight=nick_size;
//WizSelectionCharFormat(m_user_list, cf);
//m_user_list.ReplaceSel(LocalSettings.NickName+ENDL);
m_user_list.AddString(LocalSettings.NickName);
int n=m_user_list.GetCount();
m_user_list.SetItemData(n-1,(ULONG) (&LocalSettings));
}
SetTitle();
}
//вызывается при получения информации об удаленном пользователе
void CECHO_TCP_IPDlg::OnRemoteInfoReceive(int sender,
CUserSettings IncomingRemote)
{
//если это сервер
if (ServerSocket)
{
//если это первая информация - это информация о пользователе
if ( ++ (UserInfo[sender].CountInfoReceive) == 1)
{
CMenu *menu=GetMenu();
CMenu *sub=menu->GetSubMenu(2);
//добавляем в меню строчку с информацией о том, кого следует отключить
sub->AppendMenu(MF_STRING, (DWORD)UserInfo[sender].socket_connect,_S+"отключить "+
UserInfo[sender].RemoteSettings.NickName+"("+itos(UserInfo[sender].RemoteSettings.uid)+")");
CString c;
//посылаем инфо присоеденившемуся клиенту об остальных клиентах если мы сервер
//и о себе
CString message;
message=_S+"В чат вошел пользователь: "+ UserInfo[sender].RemoteSettings.NickName+ENDL;
Sound(SOUND_NEWUSER,STOP_SOUND);
ChatWindowAddStringUID(message,SYSTEM_UID);
UserInfo[sender].SendInfo(LocalSettings);
for(int i=0; i<UserInfo.size(); i++)
{
if (i!=sender)
{
UserInfo[sender].SendInfo(UserInfo[i].RemoteSettings);
UserInfo[i].socket_connect->SendStringWithUID(message,SYSTEM_UID);
}
}
//посылаем последние 20 строк
int max=m_richedit.GetLineCount();
for(int k=max-20; k<max; k++)
{
char buf[4096];
int c=m_richedit.GetLine(k,buf);
if (c==0) continue;
buf[c]=0;
UserInfo[sender].socket_connect->SendStringWithUID(_S+buf,HISTORY_UID);
}
CString z="Сейчас в чате:";
z+=LocalSettings.NickName;
int size=UserInfo.size();
for(i=0; i<size; i++)
{
z+=", ";
z+=UserInfo[i].RemoteSettings.NickName;
}
z+=ENDL;
UserInfo[sender].socket_connect->SendStringWithUID(z,SYSTEM_UID);
//если есть приветствие
if (!AllSpace(SettingBox.m_greeting))
{
CString k;
k+=dialog->SettingBox.m_greeting+ENDL;
//посылаем свое приветствие присоединившемуся клиенту
UserInfo[sender].socket_connect->SendStringWithUID(k,0);
//свое приветствие отображаем в своем окне
ChatWindowAddStringUID(_S+LocalSettings.NickName+">"+SettingBox.m_greeting,UnID,true);
}
}
}
//если не сервер - добавляем в список нового пользователя или обновляем
if (!ServerSocket)
{
bool found=false;
//если пользователь уже есть в списке
for(int i=0; i<UserInfo.size(); i++)
{
// uid в имеющемся списке совпал с uid пришедшей инф
if (UserInfo[i].RemoteSettings.uid == IncomingRemote.uid)
{
//обновляем информацию о пользователе
UserInfo[i].RemoteSettings=IncomingRemote;
found=true;
break;
}
}
//если в списке не нашлось uid переданной инфы, значит инфа о новом пользователе
if (!found)
{
CConnectedUserInfo info;
info.RemoteSettings=IncomingRemote;
//добавляем в список нового пользователя
UserInfo.push_back(info);
/*if (!AllSpace(SettingBox.m_greeting))
{
CString k;
k+=dialog->SettingBox.m_greeting+ENDL;
//посылаем свое приветствие присоединившемуся клиенту
UserInfo[UserInfo.size()-1].socket_connect->SendStringWithUID(k,0);
}*/
}
}
CString result;
CString _R="получена инфа от ";
if (ServerSocket)
result+=_R+UserInfo[sender].RemoteSettings.NickName + "("+itos(UserInfo[sender].RemoteSettings.uid)+")";
else
result+=_R+IncomingRemote.NickName + "("+itos(IncomingRemote.uid)+")";
result+=ENDL;
if (ShowSendRecvInfo) ChatWindowAddStringUID(result, SYSTEM_UID);
RefreshUserList();
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::EnableClientServerButtons(bool enable)
{
CMenu *m=GetMenu();
int k;
enable == true ? k=MF_ENABLED :k=MF_GRAYED;
m->EnableMenuItem(ID_MENU_RUN_SERVER, k);
m->EnableMenuItem(ID_MENU_CONNECT, k);
}
//////////////////////////////////////////////////////////////////////////
//извещение приходит после попытки соединения с сервером
void CECHO_TCP_IPDlg::OnToServerConnect(int err, DWORD sock)
{
int active;
//ошибка
if (err)
{
ChatWindowAddStringUID("Не удалось установить соединение! (err="+itos(err)+")"+ENDL,SYSTEM_UID);
active=GetUserIndex(sock);
if (active!=-1)
UserInfo.erase(&UserInfo[active]); //вызывает expection
SettingBox.TryConnect=false;
SynchroMenuButtons();
return;
}
CConnectedUserInfo info;
info.socket_connect=(CClientSocket*)sock;
info.RemoteSettings.uid=0;
UserInfo.push_back(info);
ChatWindowAddStringUID("Установлено соединение!"+ENDL,SYSTEM_UID);
Sound(SOUND_NEWUSER,SOUND_STOP);
InfoExchange();
active=GetUserIndex(sock);
/* //еперь нужно послать информацию от всех сокетов к подключенному
for(int i=0; i<UserInfo.size(); i++)
{
if (i!=active)
UserInfo[active].SendInfo(UserInfo[i].RemoteSettings);
}
*/
// send_all(_S+LocalSettings.NickName+" >> "+SettingBox.m_greeting+ENDL);
if (!AllSpace(SettingBox.m_greeting))
{
send_all(_S+SettingBox.m_greeting+ENDL);
ChatWindowAddStringUID(_S+LocalSettings.NickName+">"+SettingBox.m_greeting+ENDL,UnID,true);
}
SetTitle();
}
//////////////////////////////////////////////////////////////////////////
//функция считывает count байт по адресу ad
//возврашает true - блок успешно считался
//false - блок не смог считаться
bool ReceiveBlock(CClientSocket* socket, void *ad, int count)
{
BYTE * addr=(BYTE*) ad;
int n=0;
do
{
//!!!!!!!!!!!!!!!!!!!!ПРОБЛЕМНЫЙ КОД!!!!!!!!!!!!!!!!!!!
//попытка чтения из сокета count байт
n=socket->Receive(addr,count);
int err=GetLastError();
//если считали столько, сколько было затребовано сразу выходим
if (n==count) return true;
//было закрыто соединение
if (n==0)
{
CString error="Во время чтения данных из сокета "+
itos(DWORD(socket))+" разорвалось соединение";
dialog->ChatWindowAddStringUID(
error,SYSTEM_UID);
socket->OnClose(err);
send_all(error);
return false;
}
//WSAECONNABORTED
//если произошла ошибка при чтении из сокета
if (n==SOCKET_ERROR)
{
CString error="Ошибка при чтении данных из сокета "+itos(DWORD(socket))+
", (err= "+itos(err)+")";
dialog->ChatWindowAddStringUID(error
,SYSTEM_UID);
socket->OnClose(err);
send_all(error);
return false;
}
addr+=n;
count-=n;
Sleep(1);
}
while (count!=0);
return true;
}
//что-то пришло с удаленного компьютера
void CECHO_TCP_IPDlg::OnReceive(int err, DWORD sock)
{
CUserSettings IncomingRemote;
char a='\v';
//ищем, если в списке пользователей пользователь, у которого
//номер сокета совпадает с номером сокета пользователя, от которого
//в данный момент приходят данные
for(int sender=0; sender<UserInfo.size(); sender++)
if ( DWORD(UserInfo[sender].socket_connect) == sock) break;
//если не нашли от кого пришла инфа
if (sender==UserInfo.size())
{
//спорный момент
sender=0;
}
char buf;
static int userinfo;
CClientSocket * socket=(CClientSocket*)sock;
Cursor.Show();
if (!ReceiveBlock(socket,&buf,1))
{
return;
}
//принялу команду на удаление пользователя
if (buf==ESC_USER_EXIT)
{
DWORD uid;
//если не смогли принять ID пользователя
if (!ReceiveBlock(socket, &uid,4))
{
ChatWindowAddStringUID(_S+"не смогли принять ID пользователя который в данный момент отключается (код ESC_ посылал "+UserInfo[sender].RemoteSettings.NickName +")",SYSTEM_UID);
return;
}
for(int i=0; i<UserInfo.size(); i++)
{
if (UserInfo[i].RemoteSettings.uid==uid)
{
ChatWindowAddStringUID(_S+"удалили пользователя "+UserInfo[i].RemoteSettings.NickName,SYSTEM_UID);
UserInfo.erase(&UserInfo[i]);
RefreshUserList();
return;
}
}
if (i==UserInfo.size())
{
ChatWindowAddStringUID(_S+"принятый ID пользователя на удаление не найден в списке (код послал пользователь "+UserInfo[sender].RemoteSettings.NickName +")",SYSTEM_UID);
return;
}
}
//послали целую строку с указанием источника
if (buf==ESC_SEND_UID_STRING)
{
WORD size;
DWORD uid;
//считываем размер строки
if (!ReceiveBlock(socket,&size,2))
{
/// ошибка
ChatWindowAddStringUID(_S+"ошибка чтения длины строки от пользователя "+UserInfo[sender].RemoteSettings.NickName ,SYSTEM_UID);
return;
}
//считываем uid
if (!ReceiveBlock(socket,&uid,4))
{
//ошибка
ChatWindowAddStringUID(_S+"ошибка чтения ID пользователя от пользователя "+UserInfo[sender].RemoteSettings.NickName ,SYSTEM_UID);
return;
}
//если размер строки корректен
if (size>=1 && size<=MAX_MESSAGE_LEN)
{
BYTE * recvstr=new BYTE[size+1];
if (!ReceiveBlock(socket,recvstr,size))
{
ChatWindowAddStringUID(_S+"ошибка принятия строки текста от пользователя "+UserInfo[sender].RemoteSettings.NickName ,SYSTEM_UID);
return;
}
recvstr[size]=0;
CString nick;
for(int src=0; src<UserInfo.size(); src++)
{
CUserSettings &ui=UserInfo[src].RemoteSettings;
if (ui.uid==uid) nick=_S+ui.NickName+"> ";
}
//если приняли только один символ
if (size==1)
ChatWindowAddStringUID(recvstr, uid, NO_NEW_LINE);
else
ChatWindowAddStringUID(nick+recvstr, uid, NEW_LINE);
if (SettingBox.m_auto_chat_show)
{
m_hide=false;
ShowWindow(SW_NORMAL);
//ShowWindow(SW_RESTORE);
}
//если мы сервер, рассылаем всем остальным пользователям принятую строку
if (ServerSocket)
{
for(int i=0; i<UserInfo.size(); i++)
{
//эта проверка нужна для того, чтобы не посылать сообщение пользователю
//от которого пришло данное сообщение
//как вариант можно изменить алгоритм, чтобы при посылке сообщения
//у клиента, в его окне сообщения отображалось не мгновенно,
//а после принятия от сервера. Но это увеличит траффик.
if (UserInfo[i].RemoteSettings.uid!=uid)
{
UserInfo[i].socket_connect->SendStringWithUID(recvstr, uid);
}
}
}
delete recvstr;
return;
}
//иначе разрываем соединение с таким клиентом из-за
//нарушения протокола (слишком длинное сообщение)
else
{
socket->OnClose(0);
return;
}
}
if (buf== ESCAPE_CODE)
{
//чтение информации о пользователях
CUserSettings usr;
if (!ReceiveBlock(socket,&usr,sizeof(usr)))
{
//ошибка
ChatWindowAddStringUID(_S+"Произошла ошибка при считывании информации о пользователе "+UserInfo[sender].RemoteSettings.NickName,SYSTEM_UID);
return;
}
//если мы сервер
if (ServerSocket)
{
//считываем информацию о пользователе в соответтвующий ему слот
UserInfo[sender].RemoteSettings=usr;
}
else
//если мы клиент
{
//считываем информацию о пользователе в одну наперед заданную
//структурупеременную
IncomingRemote = usr;
}
//получили информацию, отдаем ее функции OnRemoteInfoReceive
OnRemoteInfoReceive(sender,IncomingRemote);
//если сервер - рассылаем изменившуюся информацию об одном пользователе
//всем остальным пользователям
if (ServerSocket)
{
InfoSend(sender);
}
//изменяем заголовок окна
SetTitle();
return;
}
if (buf== OLD_ESC_CODE)
{
CString k="Используйте более новую версию чата. Используемая Вами версия не совместима с версией сервера!";
socket->SendData(k+ENDL,sizeof(k)+sizeof(ENDL));
ChatWindowAddStringUID("Клиент использует старую версию чата! Произведено отключение"+ENDL,SYSTEM_UID);
Sleep(500);
socket->Close();
delete socket;//->Close();
UserInfo.erase(&UserInfo[sender]);
RefreshUserList();
return;
}
CString s=buf;
OnReceive(s, sock);
//если сервер - делаем эхо остальным пользователям
/* if (ServerSocket)
{
for(int i=0; i<UserInfo.size(); i++)
//тому кто прислал не отсылаем
if (i!=sender)
{
UserInfo[i].socket_connect->SendData(&buf,1);
}
}
*/
}
//////////////////////////////////////////////////////////////////////////
//закрывается удаленный пользователь
void CECHO_TCP_IPDlg::OnRemoteClose(int err, DWORD sock)
{
//если мы сервер
if (ServerSocket)
{
int active=GetUserIndex(sock);
if (active==-1)
{
ChatWindowAddStringUID("ОШИБКА: отключился незарегистрированный пользователь!",SYSTEM_UID);
return;
}
DWORD del_uid=UserInfo[active].RemoteSettings.uid;
CString tmp=_S+UserInfo[active].RemoteSettings.NickName+"("+itos(del_uid)+") отключился"+ENDL;
Sound(SOUND_DISCONNECT);
ChatWindowAddStringUID(tmp,SYSTEM_UID);
//удаляем из меню строку "отключить того-то.."
CMenu *sub=GetMenu()->GetSubMenu(2);
sub->DeleteMenu(sock,MF_BYCOMMAND);
delete UserInfo[active].socket_connect;
UserInfo.erase(&UserInfo[active]);
BYTE packet[5];
packet[0]=ESC_USER_EXIT;
LPBYTE puid=LPBYTE(&del_uid);
packet[1]=puid[0];
packet[2]=puid[1];
packet[3]=puid[2];
packet[4]=puid[3];
//посылаем остальным сообщение об отключении
for(int i=0; i<UserInfo.size(); i++)
{
UserInfo[i].socket_connect->SendData(&packet,5);
UserInfo[i].socket_connect->SendStringWithUID(tmp, SYSTEM_UID);
}
}
//если мы клиент - значит отключилсь от сервера
else
{
//очищаем список пользователей
UserInfo.clear();
ChatWindowAddStringUID("Сервер разорвал соединение"+ENDL,SYSTEM_UID);
SettingBox.TryConnect=false;
}
SynchroMenuButtons();
RefreshUserList();
//EnableClientServerButtons(true);
}
void CECHO_TCP_IPDlg::OnLButtonDown(UINT nFlags, CPoint point )
{
m_input_box.SetFocus();
CDialog::OnLButtonDown(nFlags, point);
}
//////////////////////////////////////////////////////////////////////////
#include "piano_plugin\pianores.h"
void CECHO_TCP_IPDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
OnMenuSettingBox();
// CDTFM_GeneratorDlg piano;
// piano.DoModal();
CDialog::OnRButtonDown(nFlags, point);
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::SetTitle()
{
if (UserInfo.size()==0) SetWindowText("TCP/IP Chat - Нет подключенных пользователей!");
else
{
CString m=_S+LocalSettings.NickName+ " говорит с ";
for(int i=0; i<UserInfo.size(); i++)
{
m+=UserInfo[i].RemoteSettings.NickName;
if (i<UserInfo.size()-1)
m+=", ";
}
SetWindowText(m);
}
//OnAbout();
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
if (m_richedit.m_hWnd)
{
CRect r, inp;
GetClientRect(&r);
m_input.GetWindowRect(&inp);
int len2=100;
int
len1=r.Width()-len2,
hei=r.Height()-inp.Height();
m_richedit.MoveWindow(0,0, len1, hei);
m_input. MoveWindow(0,hei, r.Width(), inp.Height());
m_user_list.MoveWindow(len1,0, len2, hei);
}
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::OnMenuConnect()
{
OnConnect();
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::OnMenuRunServer()
{
OnRunServer();
SynchroMenuButtons();
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::OnMenuSettingBox()
{
SettingBox.DoModal( ServerSocket ? false : true);
LocalSettings=SettingBox.GetUserSettings();
CHARFORMAT cf=LocalSettings.cf;
cf.yHeight=INPUT_HEI;
m_input.SetSel(0,-1);
WizSelectionCharFormat(m_input, cf);
m_input.SetSel(0,0);
InfoExchange();
SetTitle();
ShowSendRecvInfo=SettingBox.m_system_message;
RefreshUserList();
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::WriteLogFile()
{
//если нет разрещения на запись лога не пишем логи
if (SettingBox.m_enable_write_log_file == 0 ) return;
//MessageBox("WRITE LOG FILE!");
CreateDirectory("Logs",NULL);
CFile file;
if (file.Open(PathTextLog,file.modeWrite|file.modeCreate))
{
//CString txt;
//m_richedit.GetWindowText(txt);
GetData;
//file.Write(txt.GetBuffer(0),txt.GetLength());
file.Write(m_richtext.GetBuffer(0),m_richtext.GetLength());
file.Close();
}
RtfFile.Open(PathRtfLog, CFile::modeCreate|CFile::modeWrite);
EDITSTREAM es;
es.dwCookie=(DWORD) &RtfFile;
es.pfnCallback=MyStreamOutCallback;
m_richedit.StreamOut(SF_RTF,es);
RtfFile.Close();
}
void CECHO_TCP_IPDlg::OnFileExit()
{
if (ServerSocket)
{
OnMenuStopServer();
if (ServerSocket) return;
}
if (UserInfo.size() !=0)
{
if (MessageBox("В настоящей момент установлено подключение к чат-серверу.\r\n"
"Вы действительно желаете выйти из чата ?"," Внимание ! ", MB_OKCANCEL) == IDCANCEL)
return;
}
OnOK();
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::OnSetfocusInput(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
*pResult = 0;
}
void CECHO_TCP_IPDlg::OnClickInput(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
// Cursor.Hide();
// OnRichTest("\b ");
// *pResult = 0;
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::OnKillfocusInputBox()
{
//нужно спрятать курсор в RichEdit
// Cursor.Hide();
// Cursor.ReDraw();
}
void CECHO_TCP_IPDlg::OnSetfocusInputBox()
{
// TODO: Add your control notification handler code here
// Cursor.Show();
// Cursor.ReDraw();
}
void CECHO_TCP_IPDlg::OnReturnInput(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
//OnSend();
*pResult = 0;
}
void CECHO_TCP_IPDlg::OnMenuStopServer()
{
if (!ServerSocket) return;
//если есть активные соединения - закрываем соединения
if (UserInfo.size())
{
CString z="Установлено соединение с пользователями: ";
for(int i=0; i<UserInfo.size(); i++)
{
z+=UserInfo[i].RemoteSettings.NickName;
if (i<UserInfo.size()-1) z+=",";
}
z+="\r\nОстановка сервера повлечет за собой также разрыв активных соединений. Продолжить?";
if ( MessageBox(z, "Остановка сервера", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
{
CMenu *sub=GetMenu()->GetSubMenu(2);
for(int i=0; i<UserInfo.size(); i++)
{
sub->DeleteMenu(DWORD(UserInfo[i].socket_connect),MF_BYCOMMAND);
UserInfo[i].socket_connect->SendStringWithUID("Cервер останавливается"+ENDL,SYSTEM_UID);
delete UserInfo[i].socket_connect;
}
delete ServerSocket;
ServerSocket=NULL;
UserInfo.clear();
ChatWindowAddStringUID("Сервер остановлен, все соединения разорваны"+ENDL,SYSTEM_UID);
UserInfo.clear();
RefreshUserList();
}
}
//иначе закрываем сервер-сокет
else
{
delete ServerSocket;
ServerSocket=NULL;
ChatWindowAddStringUID("Сервер остановлен"+ENDL,SYSTEM_UID);
res:
UnID=1+rand();
if (UnID==0) goto res;
}
SynchroMenuButtons();
}
//синхронизирую состояние меню и кнопок
void CECHO_TCP_IPDlg::SynchroMenuButtons()
{
#define mfe MF_ENABLED
#define mfd MF_GRAYED
CMenu *m=GetMenu();
int k;
bool Server=false;
bool ActiveConnections=false;
if (ServerSocket) Server=true;
if (UserInfo.size()) ActiveConnections=true;
ActiveConnections || Server || SettingBox.TryConnect ? k=mfd: k=mfe;
m->EnableMenuItem(ID_MENU_RUN_SERVER, k);
if (SettingBox.m_hWnd) SettingBox.InitButtons(ServerSocket!=NULL, UserInfo.size() !=0);
//сервер з
m->EnableMenuItem(ID_MENU_STOP_SERVER, Server ? mfe : mfd);
if (Server)
{
m->EnableMenuItem(IDC_DISCONNECT, mfd);
m->EnableMenuItem(IDC_CONNECT, mfd);
}
else
{
if (ActiveConnections)
{
m->EnableMenuItem(IDC_DISCONNECT, mfe);
m->EnableMenuItem(IDC_CONNECT, mfd);
}
else
{
m->EnableMenuItem(IDC_DISCONNECT, mfd);
if (SettingBox.TryConnect==true)
m->EnableMenuItem(IDC_CONNECT, mfd);
else
m->EnableMenuItem(IDC_CONNECT, mfe);
}
}
}
BOOL CECHO_TCP_IPDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
return CDialog::OnMouseWheel(nFlags, zDelta, pt);
}
void CECHO_TCP_IPDlg::OnAbout()
{
AboutBox about;
about.DoModal();
// ChatWindowAddStringUID("x",SYSTEM_UID);
}
void CECHO_TCP_IPDlg::ScrollRich()
{
if (!SettingBox.m_no_autoscroll)
{
int cnt=m_richedit.GetLineCount();
for(int i=0; i<cnt; i++)
m_richedit.LineScroll(1);
}
}
BOOL CECHO_TCP_IPDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
WORD wNotifyCode = HIWORD(wParam);
WORD wID = LOWORD(wParam);
DWORD code = lParam;
if (wID==ID_POPUP_SHOW)
{
m_hide=false;
ShowWindow(SW_NORMAL);
BringWindowToTop();
return true;
}
if (wID==ID_POPUP_EXIT)
{
ShowWindow(SW_NORMAL);
OnFileExit();
return true;
}
if (wID == ID_SHELL_MESSAGE)
{
if (code==WM_LBUTTONDOWN)
{
if (m_hide==true)
{
m_hide=false;
ShowWindow(SW_NORMAL);
BringWindowToTop();
}
else
{
m_hide=true;
ShowWindow(SW_HIDE);
}
return true;
}
if (code==WM_RBUTTONDOWN)
{
CMenu menu;
menu.CreatePopupMenu();
menu.AppendMenu(0,ID_POPUP_SHOW,"Показать");
menu.AppendMenu(MF_SEPARATOR);
menu.AppendMenu(0,ID_POPUP_EXIT,"Выйти");
POINT p;
GetCursorPos(&p);
menu.TrackPopupMenu(TPM_RIGHTBUTTON|TPM_CENTERALIGN,p.x,p.y,this);
}
return 0;
}
return CDialog::OnCommand(wParam, lParam);
}
void CECHO_TCP_IPDlg::SavePlacement()
{
SettingBox.WriteSettings();
CRegKeyAdv reg;
CRect r;
GetWindowRect(&r);
reg.SetValue( r.left, "PosX");
reg.SetValue( r.top, "PosY");
reg.SetValue( r.Width(), "WinCX");
reg.SetValue( r.Height(), "WinCY");
reg.Close();
}
void CECHO_TCP_IPDlg::AddIcon()
{
NOTIFYICONDATA ni= {0};
ni.cbSize=sizeof(ni);
ni.hWnd=this->m_hWnd;
ni.uID=ID_SHELL_MESSAGE;
ni.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;
ni.uCallbackMessage=WM_COMMAND;
strcpy(ni.szTip,"TCP/IP чат");
ni.hIcon=hIcon;
Shell_NotifyIcon(NIM_ADD, &ni);//) MessageBox("ошибка Shell_NotifyIcon ");
}
void CECHO_TCP_IPDlg::DeleteIcon()
{
NOTIFYICONDATA ni= {0};
ni.cbSize=sizeof(ni);
ni.hWnd=this->m_hWnd;
ni.uID=ID_SHELL_MESSAGE;
ni.uFlags=NIF_MESSAGE;
ni.uCallbackMessage=WM_COMMAND;
Shell_NotifyIcon(NIM_DELETE, &ni);//) MessageBox("ошибка Shell_NotifyIcon ");
}
void CECHO_TCP_IPDlg::OnDestroy()
{
DeleteIcon();
SavePlacement();
WriteLogFile();
CDialog::OnDestroy();
}
void CECHO_TCP_IPDlg::OnFileSend()
{
MessageBox("Извините, данная функция находится в стадии разработки ...");
}
CECHO_TCP_IPDlg::~CECHO_TCP_IPDlg()
{
delete ServerSocket;
}
//
#include "stdafx.h"
#include <shellapi.h>
#include <Afxsock.h>
#include <atlbase.h>
#include <vector>
#include <mmsystem.h>
#include "ECHO_TCP_IP.h"
#include "ECHO_TCP_IPDlg.h"
#include "RegKeyAdv.h"
#include "sockets.h"
#include "aboutbox.h"
#include "statusdialog.h"
CString ENDL="\r\n";
CString PathTextLog,PathRtfLog;
CFile RtfFile;
CString _S="";
int ShowSendRecvInfo=false;
const int LIST_ITEM_HEIGHT=30;
const UINT MAX_MESSAGE_LEN=1024;
int INPUT_HEI=300;
const BYTE RING_SYMBOL='Ё'; //символ, по принятии которого звучит "вызов"
const BYTE RING_SYMBOL2='Й'; //символ, по принятии которого звучит "вызов"
char __MAIN__DATE__[]=__DATE__;
char __MAIN__TIME__[]=__TIME__;
const CString CopyRightString="TCP/IP Chat. (c) 2005 - 2010 Евгений Лапшин";
#define ID_POPUP_SHOW 0xF001
#define ID_POPUP_EXIT 0xF002
//COLORREF BackGroundColor=RGB(255,255,255);
COLORREF BackGroundColor=RGB(20,20,20);
CUserSettings
LocalSettings, //наши настройки
SystemSettings, //системные настройки
HistorySettings;//настройки для показа истории
DWORD UnID=0;
/*
typedef struct _charformat2 {
UINT cbSize;
DWORD dwMask;
DWORD dwEffects;
LONG yHeight;
LONG yOffset;
COLORREF crTextColor;
BYTE bCharSet;
BYTE bPitchAndFamily;
TCHAR szFaceName[LF_FACESIZE];
WORD wWeight;
SHORT sSpacing;
COLORREF crBackColor;
LCID lcid;
DWORD dwReserved;
SHORT sStyle;
WORD wKerning;
BYTE bUnderlineType;
BYTE bAnimation;
BYTE bRevAuthor;
BYTE bReserved1;
} CHARFORMAT2;
typedef struct _charformat {
UINT cbSize;
DWORD dwMask;
DWORD dwEffects;
LONG yHeight;
LONG yOffset;
COLORREF crTextColor;
BYTE bCharSet;
BYTE bPitchAndFamily;
TCHAR szFaceName[LF_FACESIZE];
} CHARFORMAT;
*/
void WizSelectionCharFormat(CRichEditCtrl & rich, CHARFORMAT & charformat)
{
CHARFORMAT ch=charformat;
CHARFORMAT2 ch2;
ch2.cbSize=0;
ch2.dwMask=
CFM_COLOR |
CFM_SIZE |
CFM_FACE |
CFM_CHARSET;
ch2.dwEffects=0;
ch2.yHeight=0;
ch2.yOffset=0;
ch2.crTextColor=0;
ch2.bCharSet=0;
ch2.bPitchAndFamily=0;
//TCHAR szFaceName[LF_FACESIZE];
ch2.wWeight=0;
ch2.sSpacing=0;
ch2.crBackColor=0;
ch2.lcid=0;
ch2.dwReserved=0;
ch2.sStyle=0;
ch2.wKerning=0;
ch2.bUnderlineType=0;
ch2.bAnimation=0;
ch2.bRevAuthor=0;
// ch2.bReserved1=0;
ch2.cbSize=sizeof(ch2);
//ch2.dwMask=ch.dwMask;
ch2.dwEffects=ch.dwEffects;
ch2.yHeight=ch.yHeight;
ch2.yOffset=ch.yOffset;
ch2.crTextColor=ch.crTextColor;
ch2.bCharSet=DEFAULT_CHARSET;
ch2.bPitchAndFamily=ch.bPitchAndFamily;
strcpy(ch2.szFaceName, ch.szFaceName);
ch2.crBackColor=RGB(0,255,0);
LOGFONT lf= {0};
lf.lfCharSet=ch.bCharSet;
lf.lfHeight=LIST_ITEM_HEIGHT;
lf.lfWidth=10;
lf.lfPitchAndFamily=ch.bPitchAndFamily;
lf.lfCharSet=DEFAULT_CHARSET;
rich.SetSelectionCharFormat(ch2);
}
//переводит число в CString
CString itos(int n)
{
CString m;
m.Format("%i",n);
return m;
}
static DWORD CALLBACK
MyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
CFile* pFile = (CFile*) dwCookie;
pFile->Write(pbBuff, cb);
*pcb = cb;
return 0;
}
//возвращает истину если все символы строки пробельные
bool AllSpace(CString &s)
{
for(int i=0; i<s.GetLength(); i++)
{
if (s!=' ') return false;
}
return true;
}
//bool need_show_cursor=true;
bool need_invalidate=false;
CString RegistryBase="Software\\TcpIpChat\\";
#define NO_NEW_LINE false
#define NEW_LINE true
#define PutData UpdateData(false)
#define GetData UpdateData(true)
CECHO_TCP_IPDlg* dialog=NULL;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CStatusDialog * StatusDialog;
#define STOP_SOUND 1
#define SOUND_STOP 1
CString GetLocalTimeString()
{
SYSTEMTIME t;
GetLocalTime(&t);
CString c;
//c.Format("{%02i:%02i:%02i.%03i} ", t.wHour, t.wMinute, t.wSecond,t.wMilliseconds);
c.Format("{%02i.%02i.%02i} [%02i:%02i.%02i] ", t.wDay, t.wMonth, t.wYear,
t.wHour, t.wMinute, t.wSecond);
return c;
}
struct CURSORINFO
{
CRichEditCtrl* rich;
char String[2];
char sym; //символ, используемый в качестве курсора
int count;
CURSORINFO()
{
sym='_';
String[0]=sym;
String[1]=0;
count=0;
}
void Show()
{
String[0]=sym;
count=0;
}
void Hide()
{
String[0]=' ';
count=0;
}
void LinkRichEdit(CRichEditCtrl * r)
{
rich=r;
}
//стираем курсор
void Erase()
{
//стираем последний символ в RichEdit'оре
//rich->SendMessage(WM_KEYDOWN, VK_BACK,0);
}
//отрисовка курсора
void Draw() {}
/* {
CHARFORMAT a={0};
//настраиваем системные настройки
a.cbSize=sizeof(CHARFORMAT);
a.yHeight=LocalSettings.cf.yHeight;
a.crTextColor=RGB(255,255,255);
//strcpy(a.szFaceName,"Terminal");
a.dwMask=
CFM_COLOR |
CFM_SIZE |
CFM_FACE
;
a.bPitchAndFamily=FIXED_PITCH;
a.bCharSet=DEFAULT_CHARSET;
rich->ReplaceSel(Cursor.String);
}
*/
} Cursor;
CServerSocket* ServerSocket=NULL;
const DWORD InfoTimeOut=4000; //время на получение информации от пользователя
//информация о присоединеных пользователях
struct CConnectedUserInfo
{
CConnectedUserInfo() : CountInfoReceive(0), socket_connect(NULL) {}
CClientSocket* socket_connect; //сокет удаленного пользователя
CString ip; //ip адрес
CString domainaddr; //доменное имя
DWORD unicalid;
DWORD startime; //время подключения
CUserSettings RemoteSettings; //настройка удаленного пользователя
void SendInfo(CUserSettings &info)
{
BYTE buf=ESCAPE_CODE;
int size=1+sizeof(info);
BYTE *bufer=new BYTE[size];
bufer[0]=ESCAPE_CODE;
CopyMemory(bufer+1,&info,sizeof(info));
socket_connect->SendData(bufer,size);
delete bufer;
if (ShowSendRecvInfo)
{
CString m;
m.Format("Send info для sock=%i ",DWORD(socket_connect));
m+=_S+RemoteSettings.NickName+"("+itos(RemoteSettings.uid)+")";
m+=_S+" о "+info.NickName+"("+itos(info.uid)+")"+ENDL;
dialog->ChatWindowAddStringUID(m,SYSTEM_UID);
}
}
int CountInfoReceive;
CString RecvString; //принимаемые текстовые данные
bool EchoToClient;//=false;
bool ConvertOemToAnsi;//=false;
};
std::vector<CConnectedUserInfo> UserInfo;
enum
{
SOUND_BLA,
SOUND_MLA,
SOUND_CLICK,
SOUND_RING1,
SOUND_RING2,
SOUND_MESSAGE1,
SOUND_MESSAGE2,
SOUND_LOL1,
SOUND_LOL2,
SOUND_NEWUSER,
SOUND_DISCONNECT,
SOUND_SOUND1,
SOUND_SOUND2,
SOUND_SOUND3,
SOUND_SOUND4,
SOUND_SOUND5,
SOUND_SOUND6
};
void CECHO_TCP_IPDlg::Sound(int type, int stop=false)
{
if (!SettingBox.m_sound_enable) return;
char *fname=NULL;
switch (type)
{
case SOUND_BLA:
{
fname="bla.wav";
break;
}
case SOUND_CLICK:
{
fname="click.wav";
break;
}
case SOUND_RING1:
{
fname="ring1.wav";
break;
}
case SOUND_RING2:
{
fname="ring2.wav";
break;
}
case SOUND_MESSAGE1:
{
fname="message.wav";
break;
}
case SOUND_MESSAGE2:
{
fname="message.wav";
break;
}
case SOUND_LOL1:
{
fname="lol1.wav";
break;
}
case SOUND_LOL2:
{
fname="lol2.wav";
break;
}
case SOUND_NEWUSER:
{
fname="newuser.wav";
break;
}
case SOUND_DISCONNECT:
{
fname="disconnect.wav";
break;
}
case SOUND_SOUND1:
{
fname="sound1.wav";
break;
}
case SOUND_SOUND2:
{
fname="sound2.wav";
break;
}
case SOUND_SOUND3:
{
fname="sound3.wav";
break;
}
case SOUND_SOUND4:
{
fname="sound4.wav";
break;
}
case SOUND_SOUND5:
{
fname="sound5.wav";
break;
}
case SOUND_SOUND6:
{
fname="sound6.wav";
break;
}
}
if (fname)
{
if (stop==1) sndPlaySound(NULL,SND_ASYNC);
sndPlaySound(_S+"Sound\\"+fname,SND_ASYNC | SND_NOSTOP);
}
}
int GetUserIndex(DWORD sock)
{
for(int i=0; i<UserInfo.size(); i++)
if ( DWORD(UserInfo.socket_connect) ==sock) return i;
//if (i== UserInfo.size())
//potencial bug
return -1;
}
//посылает строку всем пользователям
void send_all(const CString& m)
{
if (UserInfo.size()==0) return;
//если мы сервер
if (ServerSocket)
{
//поочереди посылаем строку каждому пользователю из списка
for(int i=0; i<UserInfo.size(); i++)
{
UserInfo.socket_connect->SendStringWithUID(m,0);
}
}
//иначе мы клиент и посылаем строку серверу
else
{
UserInfo[0].socket_connect->SendStringWithUID(m,UnID);
}
}
//CClientSocket* ConnectedSocket=NULL;
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
public:
virtual BOOL DestroyWindow();
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
afx_msg void OnMenuLoadLog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
ON_COMMAND(ID_MENU_LOAD_LOG, OnMenuLoadLog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CECHO_TCP_IPDlg dialog
CECHO_TCP_IPDlg::CECHO_TCP_IPDlg(CWnd* pParent /*=NULL*/)
: CDialog(CECHO_TCP_IPDlg::IDD, pParent)
{
dialog=this;
//{{AFX_DATA_INIT(CECHO_TCP_IPDlg)
m_richtext = _T(" ");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_hide=false;
CHARFORMAT &a=SystemSettings.cf;
//настраиваем системные настройки
a.yHeight=200;
a.crTextColor=RGB(50,255,100);
a.cbSize=sizeof(CHARFORMAT);
strcpy(a.szFaceName,"System");
//strcpy(a.szFaceName,"");
a.dwMask=
CFM_COLOR |
CFM_SIZE |
CFM_FACE |
CFM_CHARSET
;
a.bPitchAndFamily=VARIABLE_PITCH;
//a.bCharSet=RUSSIAN_CHARSET;
a.bCharSet=DEFAULT_CHARSET;
strcpy(SystemSettings.NickName, "System");
CHARFORMAT b=SystemSettings.cf;
b.crTextColor=RGB(240,200,250);
HistorySettings.cf=b;
}
void CECHO_TCP_IPDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CECHO_TCP_IPDlg)
DDX_Control(pDX, IDC_USER_LIST, m_user_list);
DDX_Control(pDX, IDC_INPUT, m_input);
DDX_Control(pDX, IDC_INPUT_BOX, m_input_box);
DDX_Control(pDX, IDC_RICHEDIT, m_richedit);
DDX_Text(pDX, IDC_RICHEDIT, m_richtext);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CECHO_TCP_IPDlg, CDialog)
//{{AFX_MSG_MAP(CECHO_TCP_IPDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_SEND, OnSend)
ON_WM_TIMER()
ON_WM_LBUTTONDOWN()
ON_WM_CLOSE()
ON_WM_RBUTTONDOWN()
ON_WM_SIZE()
ON_COMMAND(ID_MENU_CONNECT, OnMenuConnect)
ON_COMMAND(ID_MENU_RUN_SERVER, OnMenuRunServer)
ON_COMMAND(ID_MENU_SETTING_BOX, OnMenuSettingBox)
ON_COMMAND(ID_FILE_EXIT, OnFileExit)
ON_NOTIFY(EN_SETFOCUS, IDC_INPUT, OnSetfocusInput)
ON_NOTIFY(NM_CLICK, IDC_INPUT, OnClickInput)
ON_EN_KILLFOCUS(IDC_INPUT_BOX, OnKillfocusInputBox)
ON_EN_SETFOCUS(IDC_INPUT_BOX, OnSetfocusInputBox)
ON_NOTIFY(NM_RETURN, IDC_INPUT, OnReturnInput)
ON_COMMAND(ID_MENU_STOP_SERVER, OnMenuStopServer)
ON_WM_MOUSEWHEEL()
ON_COMMAND(ID_ABOUT, OnAbout)
ON_WM_DESTROY()
ON_COMMAND(ID_FILE_SEND, OnFileSend)
ON_COMMAND(IDC_CLEAR_LOG, OnClearLog)
ON_COMMAND(IDC_CRASH, OnCrash)
ON_COMMAND(IDC_DISCONNECT, OnDisconnect)
ON_NOTIFY(NM_CLICK, IDC_RICHEDIT, OnClickRichedit)
ON_NOTIFY(NM_RCLICK, IDC_RICHEDIT, OnRclickRichedit)
ON_NOTIFY(NM_DBLCLK, IDC_RICHEDIT, OnDblclkRichedit)
ON_NOTIFY(NM_RDBLCLK, IDC_RICHEDIT, OnRdblclkRichedit)
ON_LBN_SELCHANGE(IDC_USER_LIST, OnSelchangeUserList)
ON_WM_DRAWITEM()
ON_COMMAND(ID_MENU_LOAD_LOG, OnMenuLoadLog)
ON_WM_MEASUREITEM()
ON_WM_CTLCOLOR()
ON_BN_CLICKED(IDC_CONNECT, OnConnect)
ON_WM_CHAR()
ON_BN_CLICKED(IDC_RUN_SERVER, OnRunServer)
// ON_COMMAND(ID_CRASH_SERVER, OnCrashServer)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CECHO_TCP_IPDlg message handlers
BOOL CECHO_TCP_IPDlg::OnInitDialog()
{
CDialog::OnInitDialog();
LoadLibrary("riched32.dll");
SYSTEMTIME time;
GetLocalTime(&time);
PathTextLog.Format("logs\\%02i-%02i-%i_[%02i_%02i_%02i].log",time.wDay,time.wMonth,time.wYear,time.wHour,time.wMinute,time.wSecond);
PathRtfLog.Format("logs\\%02i-%02i-%i_[%02i_%02i_%02i].rtf",time.wDay,time.wMonth,time.wYear,time.wHour,time.wMinute,time.wSecond);
// m_richedit.SetFocus();
//генерируем сами себе свой идентификатор
rest:
srand(GetTickCount());
UnID=1+rand();
//это возможно в случае если rand()+1 станет равным нулю
if (UnID==0) goto rest;
//делаем системный шрифт "Tahoma"
strcpy(SystemSettings.cf.szFaceName,"Tahoma");
char buf[1024];
//получаем командную строку
char *command=GetCommandLine();
CString Cscom=command;
//если имеется ключевое слово HIDE
if (strstr(command,"hide")==NULL)
{
CRegKey reg;
reg.Create(HKEY_CURRENT_USER,
"Software\\Microsoft\\Windows\\CurrentVersion\\Run");
//получаем текушую директорию
GetCurrentDirectory(1024,buf);
//добавляем название приложения
strcat(buf,"\\echo_tcp_ip.exe hide");
reg.SetValue(buf,"TCP_IP_CHAT");
reg.Close();
GetCurrentDirectory(1024,buf);
reg.Create(HKEY_CURRENT_USER,"Software\\ECHO_TCP_IP");
reg.SetValue(buf,"CurDir");
reg.Close();
}
//запускаем скрыто
else
{
CRegKey reg;
reg.Create(HKEY_CURRENT_USER,"Software\\ECHO_TCP_IP");
DWORD count=1024;
//получаем текущий путь
reg.QueryValue(buf,"CurDir",&count);
reg.Close();
SetCurrentDirectory(buf);
}
AddIcon();
Cursor.LinkRichEdit(&m_richedit);
SetTimer(1, 100,NULL);
SettingBox.LoadSettings();
LocalSettings=SettingBox.GetUserSettings();
ShowSendRecvInfo=SettingBox.m_system_message;
m_richedit.SetBackgroundColor(false, BackGroundColor);
// m_user_list.SetBackgroundColor(false, RGB(10,10,10));
{
CHARFORMAT cf= {0};
cf=LocalSettings.cf;
cf.yHeight=INPUT_HEI;
m_input.SetBackgroundColor(false,BackGroundColor);
WizSelectionCharFormat(m_input, cf);
//m_input.SetEventMask()
}
ChatWindowAddStringUID("Ok"+ENDL,SYSTEM_UID);
CRect r;
GetWindowRect(&r);
CRegKeyAdv reg;
DWORD x,y,cx,cy;
reg.QueryValue( x, "PosX");
reg.QueryValue( y, "PosY");
reg.QueryValue( cx, "WinCX");
reg.QueryValue( cy, "WinCY");
if (!cx && !cy) cx=r.Width(), cy=r.Height();
MoveWindow(x,y, cx,cy);
PutData;
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
m_input_box.SetFocus();
if (SettingBox.m_connect_on_start) OnConnect();
else if (SettingBox.m_run_server_on_start) OnRunServer();
SynchroMenuButtons();
SetTitle();
return FALSE; // return TRUE unless you set the focus to a control
}
void CECHO_TCP_IPDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
void CECHO_TCP_IPDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CECHO_TCP_IPDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CECHO_TCP_IPDlg::OnRunServer()
{
ServerSocket=new CServerSocket;
UnID=0;
if (!ServerSocket->Create(SettingBox.m_port, SOCK_STREAM, FD_WRITE
| FD_READ | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
{
delete ServerSocket;
ServerSocket=NULL;
MessageBox("Не удается создать сервер");
return;
}
CString mes;
mes.Format("Запуск сервера(порт %i). Ожидаются подключения..."+ENDL, SettingBox.m_port);
ChatWindowAddStringUID(mes,SYSTEM_UID);
ServerSocket->Listen(1);
SynchroMenuButtons();
m_input_box.SetFocus();
LocalSettings.uid=0; //признак сервера
}
void CECHO_TCP_IPDlg::OnReceive(const CString &str, DWORD sock)
{
CString z=str;
BYTE k=str[0];
if (k!=RING_SYMBOL) Sound(SOUND_CLICK);
else Sound(SOUND_RING2);
ScrollRich();
//это применимо только к серверу
ChatWindowAddStringUID(z, UserInfo[GetUserIndex(sock)].RemoteSettings.uid);
if (SettingBox.m_auto_chat_show) ShowWindow(SW_SHOWNORMAL);
}
//послать целую строку
void CECHO_TCP_IPDlg::OnSend()
{
CString tmp,src;
m_input.GetWindowText(src);
if (src.GetLength()==0) return;
if (src.GetLength()>MAX_MESSAGE_LEN)
{
MessageBox("Посылаемое ваше сообщение слишком велико!\r\nУменьшите размер сообщение и повторите попытку", "Внимание!");
return;
}
if (AllSpace(src)) return;
if (src.GetLength() == 2)
{
if (
(src[0]==13 && src[1]==10)
||
( src[0]==10 && src[1]==13)
)
return;
}
CString z;
m_richedit.GetWindowText(z);
char k=z.Right(2)[0];
//if (k!='\r' && k!='\n') tmp+=ENDL;
GetData;
CString ss=src+ENDL;
send_all(ss);
ChatWindowAddStringUID(_S+LocalSettings.NickName+"> "+ss,UnID);
m_input.SetWindowText("");
}
BOOL CECHO_TCP_IPDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if (m_hide==true) ShowWindow(SW_HIDE);//,m_hide=false;
// if (pMsg->message== WM_QUIT)
// {
// MessageBox("WM_QUIT");
// }
if (pMsg->message == WM_RBUTTONDOWN)
{
OnMenuSettingBox();
return true;
}
if (pMsg->message == WM_COMMAND)
{
for(int i=0; i<UserInfo.size(); i++)
if (DWORD(UserInfo.socket_connect) == pMsg->wParam)
//удаляем пользователя
{
//DisconnectUser()
//UserInfo.socket_connect->Close();
OnRemoteClose(0, (DWORD)UserInfo.socket_connect);
//delete UserInfo.socket_connect;
//UserInfo.erase(&UserInfo);
//MessageBox("DISCONNECT ? ARE YOU SURE ?");
}
}
if (pMsg->message == WM_KEYDOWN)
{
//if (GetFocus() != GetDlgItem(IDC_INPUT)) return true;
BYTE key=pMsg->wParam;
if (key==17) return true;
if (key==27) return true;
//ChatWindowAddStringUID("?", UnID, NO_NEW_LINE);
//MessageBeep(MB_OK);
//CString m;
//m_input.GetWindowText(m);
//m_input.SetWindowText(m+itos(key)+" ");
switch (key)
{
case 13:
{
if (GetFocus() == GetDlgItem(IDC_INPUT_BOX))
{
/* Cursor.Show();
ChatWindowAddStringUID(ENDL,SYSTEM_UID);
send_all(ENDL);
*/
}
//else
if (GetFocus() == GetDlgItem(IDC_INPUT))
{
OnSend();
}
return true;
}
case VK_UP:
m_richedit.LineScroll(-1);
return 0;
case VK_DOWN:
m_richedit.LineScroll(1);
return 0;
}
}
/* if ( pMsg->message == WM_CHAR)
{
ScrollRich();
BYTE m=pMsg->wParam;
if (m==13) return true;
if (GetFocus() != GetDlgItem(IDC_INPUT_BOX)) return false;
if (m!=RING_SYMBOL) Sound(SOUND_CLICK);
else Sound(SOUND_RING);
if (m<32 && m!=8) return true;
Cursor.Show();
ChatWindowAddStringUID(m, UnID, NO_NEW_LINE);
//if (!ServerSocket) return false;
//если нет подключения к клиенту/серверу - не вводим ничего
if (UserInfo.size()==0) return true;
CString buf;
buf+=m;
//if (ConvertOemToAnsi) CharToOem(buf,buf);
send_all(buf);
return true;
}
*/
return CDialog::PreTranslateMessage(pMsg);
}
void CECHO_TCP_IPDlg::OnTimer(UINT nIDEvent)
{
SynchroMenuButtons();
//if (GetFocus() != GetDlgItem(IDC_INPUT_BOX)) return;
if (Cursor.count++ > 5)
{
Cursor.count=0;
char& k=Cursor.String[0];
if (k != Cursor.sym) k=Cursor.sym;
else k=' ';
Cursor.Erase();
Cursor.Draw();
if (need_invalidate)
{
m_richedit.InvalidateRect(NULL,false);
m_richedit.UpdateWindow();
}
}
CDialog::OnTimer(nIDEvent);
}
//к серверу присоединяется клиент
void CECHO_TCP_IPDlg::OnClientAccept(int err)
{
CConnectedUserInfo info;
info.socket_connect=new CClientSocket;
SOCKADDR sockaddr;
sockaddr.sa_family=AF_INET;
int addrlen=sizeof(sockaddr);
ServerSocket->Accept(*info.socket_connect, &sockaddr, &addrlen);
// ServerSocket->Accept(*info.socket_connect);
SOCKADDR_IN *saddr=(SOCKADDR_IN*)&sockaddr;
BYTE b1=saddr->sin_addr.S_un.S_un_b.s_b1;
BYTE b2=saddr->sin_addr.S_un.S_un_b.s_b2;
BYTE b3=saddr->sin_addr.S_un.S_un_b.s_b3;
BYTE b4=saddr->sin_addr.S_un.S_un_b.s_b4;
info.ip.Format("%i.%i.%i.%i"+ENDL,b1,b2,b3,b4);
ChatWindowAddStringUID("Подключился пользователь с IP:"+info.ip,SYSTEM_UID);
//теперь следует ожидать от пользователя управляющего
//пакета. Если разрешены подключения от Telneta -
//установить соотв. флаги (Echo для этого пользователя
//конвертацию OEM и др.)
//если приходит пакет с ESC==2 (старая верся chat)
//проинформировать пользователя, что версия поменялась
//и ему следует обновить программное обеспечение
//если приходит новый формат пакет с ESC==3, далее два байта
//размер пакета, и байт версии. проверяем на размер. Если совпадает, значит
//версия и размер - значит версии идентчиный, принмаем
//от пользователя его инфу (Ник,Цвет щрифт) и рассылаем эту инфу
//остальным подключенным пользователям а вновь подлюченному
//отсылаем информацию о сервере, и остальных подключенных пользователей.
//время на получения информации ограничено TimeOut'ом
//если по истечении тайм аута информация от пользователя не поступило-
//сбрасываем данное подключения и не отсылаем остальным параметры
//данного пользователя
/*сервер присваивает подключенному пользователю уникальный
идентификатор uid, который сохраняется на протяжении всего подключения
клиенты, получая информацию о других пользователях, получают их uid
клиенту может придти пакет на удаления пользователя с заданным
uid
*/
//сервер назначает клиенту UID
//for(int i=0; i<UserInfo.size(); i++)
//{
// if (UserInfo
//}
info.RemoteSettings.uid=GetTickCount();
info.startime=GetTickCount();
strcpy(info.RemoteSettings.NickName,"Ожидаю инфу...");
info.RemoteSettings.cf=SystemSettings.cf;
info.RemoteSettings.size=sizeof(info.RemoteSettings);
UserInfo.push_back(info);
RefreshUserList();
}
/////// установка соединения с сервером
int CECHO_TCP_IPDlg::OnConnect()
{
LocalSettings=SettingBox.GetUserSettings();
CString Caption="В Н И М А Н И Е . . .";
if (ServerSocket)
{
MessageBox("Соединиться с сервером невозможно, \r\nпоскольку в данным момент вы сами являетесь сервером!",Caption, MB_ICONINFORMATION);
return false;
}
if (UserInfo.size())
{
MessageBox("Соединение с сервером уже установлено!\r\n",Caption,MB_ICONINFORMATION);
return false;
}
if (AllSpace(SettingBox.m_nick_name))
{
MessageBox("Задайте в настройках свой ник.\r\nПустой ник недопустим!","Внимание!");
return false;
}
SettingBox.TryConnect=true;
//CConnectedUserInfo info;
CClientSocket * socket = new CClientSocket;
socket->Create();
socket -> Connect(SettingBox.m_cremote_ip, SettingBox.m_port);
// info.RemoteSettings.uid=0; //это сервер
// strcpy(info.RemoteSettings.NickName, "РОЖА");
// UserInfo.push_back(info);
CString k;
ChatWindowAddStringUID("Попытка установить соединение c "+SettingBox.m_cremote_ip+":"+
itos(SettingBox.m_port)+ENDL,SYSTEM_UID);
// RefreshUserList();
SynchroMenuButtons();
return true;
}
void CECHO_TCP_IPDlg::OnOK()
{
//WriteLogFile();
CDialog::OnOK();
// MessageBox("OK");
}
//посылка сервером своей информацией остальным пользователям-клиентам
void CECHO_TCP_IPDlg::InfoExchange()
{
if (ServerSocket)
for(int i=0; i<UserInfo.size(); i++)
{
UserInfo.SendInfo(LocalSettings);
//ChatWindowAddStringUID("InfoExchange - Server"+ENDL,SYSTEM_UID);
}
else if (UserInfo.size()>0)
{
UserInfo[0].SendInfo(LocalSettings);
//ChatWindowAddStringUID("InfoExchange - Client"+ENDL,SYSTEM_UID);
}
}
//посылка информацией другим пользователям ользователям
//source - номер пользователя, чья информацию будем передана остальным
void CECHO_TCP_IPDlg::InfoSend(int source)
{
for(int i=0; i<UserInfo.size(); i++)
{
if (i==source) continue;
UserInfo[i].SendInfo(UserInfo[source].RemoteSettings);
//ChatWindowAddStringUID("InfoSend"+ENDL,SYSTEM_UID);
}
}
void CECHO_TCP_IPDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
WriteLogFile();
ShowWindow(SW_HIDE);
/*if (UserInfo.size() !=0)
{
if (MessageBox("Установлено соединение с другим компьютером!\r\nПодтверждаете выход?", "Внимание!", MB_OKCANCEL) == IDOK )
{
for (int i=0; i<UserInfo.size(); i++)
OnRemoteClose(0, (DWORD)UserInfo[i].socket_connect);
WriteLogFile();
CDialog::OnClose();
}
}
else
{
WriteLogFile();
CDialog::OnClose();
}*/
AddIcon();
}
void CECHO_TCP_IPDlg::RefreshUserList()
{
CString us;
int nick_size=250;
m_user_list.ResetContent();
for(int i=0; i<UserInfo.size(); i++)
{
CString m=_S+UserInfo[i].RemoteSettings.NickName;
//itos(DWORD(UserInfo[i].socket_connect))+" "+
//" ("+ itos(UserInfo[i].RemoteSettings.uid)+")";
//CHARFORMAT f=UserInfo[i].RemoteSettings.cf;
//f.yHeight=30;
CHARFORMATA cf=UserInfo[i].RemoteSettings.cf;
cf.yHeight=nick_size;
//WizSelectionCharFormat(m_user_list, cf);
//WizSelectionCharFormat(m_user_list, UserInfo[i].RemoteSettings.cf);
//m_user_list.ReplaceSel(m+ENDL);
m_user_list.AddString(m);
int n=m_user_list.GetCount();
m_user_list.SetItemData(n-1,(ULONG) (&UserInfo[i].RemoteSettings) );
}
if (UserInfo.size()!=0)
{
CHARFORMATA cf=LocalSettings.cf;
cf.yHeight=nick_size;
//WizSelectionCharFormat(m_user_list, cf);
//m_user_list.ReplaceSel(LocalSettings.NickName+ENDL);
m_user_list.AddString(LocalSettings.NickName);
int n=m_user_list.GetCount();
m_user_list.SetItemData(n-1,(ULONG) (&LocalSettings));
}
SetTitle();
}
//вызывается при получения информации об удаленном пользователе
void CECHO_TCP_IPDlg::OnRemoteInfoReceive(int sender,
CUserSettings IncomingRemote)
{
//если это сервер
if (ServerSocket)
{
//если это первая информация - это информация о пользователе
if ( ++ (UserInfo[sender].CountInfoReceive) == 1)
{
CMenu *menu=GetMenu();
CMenu *sub=menu->GetSubMenu(2);
//добавляем в меню строчку с информацией о том, кого следует отключить
sub->AppendMenu(MF_STRING, (DWORD)UserInfo[sender].socket_connect,_S+"отключить "+
UserInfo[sender].RemoteSettings.NickName+"("+itos(UserInfo[sender].RemoteSettings.uid)+")");
CString c;
//посылаем инфо присоеденившемуся клиенту об остальных клиентах если мы сервер
//и о себе
CString message;
message=_S+"В чат вошел пользователь: "+ UserInfo[sender].RemoteSettings.NickName+ENDL;
Sound(SOUND_NEWUSER,STOP_SOUND);
ChatWindowAddStringUID(message,SYSTEM_UID);
UserInfo[sender].SendInfo(LocalSettings);
for(int i=0; i<UserInfo.size(); i++)
{
if (i!=sender)
{
UserInfo[sender].SendInfo(UserInfo[i].RemoteSettings);
UserInfo[i].socket_connect->SendStringWithUID(message,SYSTEM_UID);
}
}
//посылаем последние 20 строк
int max=m_richedit.GetLineCount();
for(int k=max-20; k<max; k++)
{
char buf[4096];
int c=m_richedit.GetLine(k,buf);
if (c==0) continue;
buf[c]=0;
UserInfo[sender].socket_connect->SendStringWithUID(_S+buf,HISTORY_UID);
}
CString z="Сейчас в чате:";
z+=LocalSettings.NickName;
int size=UserInfo.size();
for(i=0; i<size; i++)
{
z+=", ";
z+=UserInfo[i].RemoteSettings.NickName;
}
z+=ENDL;
UserInfo[sender].socket_connect->SendStringWithUID(z,SYSTEM_UID);
//если есть приветствие
if (!AllSpace(SettingBox.m_greeting))
{
CString k;
k+=dialog->SettingBox.m_greeting+ENDL;
//посылаем свое приветствие присоединившемуся клиенту
UserInfo[sender].socket_connect->SendStringWithUID(k,0);
//свое приветствие отображаем в своем окне
ChatWindowAddStringUID(_S+LocalSettings.NickName+">"+SettingBox.m_greeting,UnID,true);
}
}
}
//если не сервер - добавляем в список нового пользователя или обновляем
if (!ServerSocket)
{
bool found=false;
//если пользователь уже есть в списке
for(int i=0; i<UserInfo.size(); i++)
{
// uid в имеющемся списке совпал с uid пришедшей инф
if (UserInfo[i].RemoteSettings.uid == IncomingRemote.uid)
{
//обновляем информацию о пользователе
UserInfo[i].RemoteSettings=IncomingRemote;
found=true;
break;
}
}
//если в списке не нашлось uid переданной инфы, значит инфа о новом пользователе
if (!found)
{
CConnectedUserInfo info;
info.RemoteSettings=IncomingRemote;
//добавляем в список нового пользователя
UserInfo.push_back(info);
/*if (!AllSpace(SettingBox.m_greeting))
{
CString k;
k+=dialog->SettingBox.m_greeting+ENDL;
//посылаем свое приветствие присоединившемуся клиенту
UserInfo[UserInfo.size()-1].socket_connect->SendStringWithUID(k,0);
}*/
}
}
CString result;
CString _R="получена инфа от ";
if (ServerSocket)
result+=_R+UserInfo[sender].RemoteSettings.NickName + "("+itos(UserInfo[sender].RemoteSettings.uid)+")";
else
result+=_R+IncomingRemote.NickName + "("+itos(IncomingRemote.uid)+")";
result+=ENDL;
if (ShowSendRecvInfo) ChatWindowAddStringUID(result, SYSTEM_UID);
RefreshUserList();
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::EnableClientServerButtons(bool enable)
{
CMenu *m=GetMenu();
int k;
enable == true ? k=MF_ENABLED :k=MF_GRAYED;
m->EnableMenuItem(ID_MENU_RUN_SERVER, k);
m->EnableMenuItem(ID_MENU_CONNECT, k);
}
//////////////////////////////////////////////////////////////////////////
//извещение приходит после попытки соединения с сервером
void CECHO_TCP_IPDlg::OnToServerConnect(int err, DWORD sock)
{
int active;
//ошибка
if (err)
{
ChatWindowAddStringUID("Не удалось установить соединение! (err="+itos(err)+")"+ENDL,SYSTEM_UID);
active=GetUserIndex(sock);
if (active!=-1)
UserInfo.erase(&UserInfo[active]); //вызывает expection
SettingBox.TryConnect=false;
SynchroMenuButtons();
return;
}
CConnectedUserInfo info;
info.socket_connect=(CClientSocket*)sock;
info.RemoteSettings.uid=0;
UserInfo.push_back(info);
ChatWindowAddStringUID("Установлено соединение!"+ENDL,SYSTEM_UID);
Sound(SOUND_NEWUSER,SOUND_STOP);
InfoExchange();
active=GetUserIndex(sock);
/* //еперь нужно послать информацию от всех сокетов к подключенному
for(int i=0; i<UserInfo.size(); i++)
{
if (i!=active)
UserInfo[active].SendInfo(UserInfo[i].RemoteSettings);
}
*/
// send_all(_S+LocalSettings.NickName+" >> "+SettingBox.m_greeting+ENDL);
if (!AllSpace(SettingBox.m_greeting))
{
send_all(_S+SettingBox.m_greeting+ENDL);
ChatWindowAddStringUID(_S+LocalSettings.NickName+">"+SettingBox.m_greeting+ENDL,UnID,true);
}
SetTitle();
}
//////////////////////////////////////////////////////////////////////////
//функция считывает count байт по адресу ad
//возврашает true - блок успешно считался
//false - блок не смог считаться
bool ReceiveBlock(CClientSocket* socket, void *ad, int count)
{
BYTE * addr=(BYTE*) ad;
int n=0;
do
{
//!!!!!!!!!!!!!!!!!!!!ПРОБЛЕМНЫЙ КОД!!!!!!!!!!!!!!!!!!!
//попытка чтения из сокета count байт
n=socket->Receive(addr,count);
int err=GetLastError();
//если считали столько, сколько было затребовано сразу выходим
if (n==count) return true;
//было закрыто соединение
if (n==0)
{
CString error="Во время чтения данных из сокета "+
itos(DWORD(socket))+" разорвалось соединение";
dialog->ChatWindowAddStringUID(
error,SYSTEM_UID);
socket->OnClose(err);
send_all(error);
return false;
}
//WSAECONNABORTED
//если произошла ошибка при чтении из сокета
if (n==SOCKET_ERROR)
{
CString error="Ошибка при чтении данных из сокета "+itos(DWORD(socket))+
", (err= "+itos(err)+")";
dialog->ChatWindowAddStringUID(error
,SYSTEM_UID);
socket->OnClose(err);
send_all(error);
return false;
}
addr+=n;
count-=n;
Sleep(1);
}
while (count!=0);
return true;
}
//что-то пришло с удаленного компьютера
void CECHO_TCP_IPDlg::OnReceive(int err, DWORD sock)
{
CUserSettings IncomingRemote;
char a='\v';
//ищем, если в списке пользователей пользователь, у которого
//номер сокета совпадает с номером сокета пользователя, от которого
//в данный момент приходят данные
for(int sender=0; sender<UserInfo.size(); sender++)
if ( DWORD(UserInfo[sender].socket_connect) == sock) break;
//если не нашли от кого пришла инфа
if (sender==UserInfo.size())
{
//спорный момент
sender=0;
}
char buf;
static int userinfo;
CClientSocket * socket=(CClientSocket*)sock;
Cursor.Show();
if (!ReceiveBlock(socket,&buf,1))
{
return;
}
//принялу команду на удаление пользователя
if (buf==ESC_USER_EXIT)
{
DWORD uid;
//если не смогли принять ID пользователя
if (!ReceiveBlock(socket, &uid,4))
{
ChatWindowAddStringUID(_S+"не смогли принять ID пользователя который в данный момент отключается (код ESC_ посылал "+UserInfo[sender].RemoteSettings.NickName +")",SYSTEM_UID);
return;
}
for(int i=0; i<UserInfo.size(); i++)
{
if (UserInfo[i].RemoteSettings.uid==uid)
{
ChatWindowAddStringUID(_S+"удалили пользователя "+UserInfo[i].RemoteSettings.NickName,SYSTEM_UID);
UserInfo.erase(&UserInfo[i]);
RefreshUserList();
return;
}
}
if (i==UserInfo.size())
{
ChatWindowAddStringUID(_S+"принятый ID пользователя на удаление не найден в списке (код послал пользователь "+UserInfo[sender].RemoteSettings.NickName +")",SYSTEM_UID);
return;
}
}
//послали целую строку с указанием источника
if (buf==ESC_SEND_UID_STRING)
{
WORD size;
DWORD uid;
//считываем размер строки
if (!ReceiveBlock(socket,&size,2))
{
/// ошибка
ChatWindowAddStringUID(_S+"ошибка чтения длины строки от пользователя "+UserInfo[sender].RemoteSettings.NickName ,SYSTEM_UID);
return;
}
//считываем uid
if (!ReceiveBlock(socket,&uid,4))
{
//ошибка
ChatWindowAddStringUID(_S+"ошибка чтения ID пользователя от пользователя "+UserInfo[sender].RemoteSettings.NickName ,SYSTEM_UID);
return;
}
//если размер строки корректен
if (size>=1 && size<=MAX_MESSAGE_LEN)
{
BYTE * recvstr=new BYTE[size+1];
if (!ReceiveBlock(socket,recvstr,size))
{
ChatWindowAddStringUID(_S+"ошибка принятия строки текста от пользователя "+UserInfo[sender].RemoteSettings.NickName ,SYSTEM_UID);
return;
}
recvstr[size]=0;
CString nick;
for(int src=0; src<UserInfo.size(); src++)
{
CUserSettings &ui=UserInfo[src].RemoteSettings;
if (ui.uid==uid) nick=_S+ui.NickName+"> ";
}
//если приняли только один символ
if (size==1)
ChatWindowAddStringUID(recvstr, uid, NO_NEW_LINE);
else
ChatWindowAddStringUID(nick+recvstr, uid, NEW_LINE);
if (SettingBox.m_auto_chat_show)
{
m_hide=false;
ShowWindow(SW_NORMAL);
//ShowWindow(SW_RESTORE);
}
//если мы сервер, рассылаем всем остальным пользователям принятую строку
if (ServerSocket)
{
for(int i=0; i<UserInfo.size(); i++)
{
//эта проверка нужна для того, чтобы не посылать сообщение пользователю
//от которого пришло данное сообщение
//как вариант можно изменить алгоритм, чтобы при посылке сообщения
//у клиента, в его окне сообщения отображалось не мгновенно,
//а после принятия от сервера. Но это увеличит траффик.
if (UserInfo[i].RemoteSettings.uid!=uid)
{
UserInfo[i].socket_connect->SendStringWithUID(recvstr, uid);
}
}
}
delete recvstr;
return;
}
//иначе разрываем соединение с таким клиентом из-за
//нарушения протокола (слишком длинное сообщение)
else
{
socket->OnClose(0);
return;
}
}
if (buf== ESCAPE_CODE)
{
//чтение информации о пользователях
CUserSettings usr;
if (!ReceiveBlock(socket,&usr,sizeof(usr)))
{
//ошибка
ChatWindowAddStringUID(_S+"Произошла ошибка при считывании информации о пользователе "+UserInfo[sender].RemoteSettings.NickName,SYSTEM_UID);
return;
}
//если мы сервер
if (ServerSocket)
{
//считываем информацию о пользователе в соответтвующий ему слот
UserInfo[sender].RemoteSettings=usr;
}
else
//если мы клиент
{
//считываем информацию о пользователе в одну наперед заданную
//структурупеременную
IncomingRemote = usr;
}
//получили информацию, отдаем ее функции OnRemoteInfoReceive
OnRemoteInfoReceive(sender,IncomingRemote);
//если сервер - рассылаем изменившуюся информацию об одном пользователе
//всем остальным пользователям
if (ServerSocket)
{
InfoSend(sender);
}
//изменяем заголовок окна
SetTitle();
return;
}
if (buf== OLD_ESC_CODE)
{
CString k="Используйте более новую версию чата. Используемая Вами версия не совместима с версией сервера!";
socket->SendData(k+ENDL,sizeof(k)+sizeof(ENDL));
ChatWindowAddStringUID("Клиент использует старую версию чата! Произведено отключение"+ENDL,SYSTEM_UID);
Sleep(500);
socket->Close();
delete socket;//->Close();
UserInfo.erase(&UserInfo[sender]);
RefreshUserList();
return;
}
CString s=buf;
OnReceive(s, sock);
//если сервер - делаем эхо остальным пользователям
/* if (ServerSocket)
{
for(int i=0; i<UserInfo.size(); i++)
//тому кто прислал не отсылаем
if (i!=sender)
{
UserInfo[i].socket_connect->SendData(&buf,1);
}
}
*/
}
//////////////////////////////////////////////////////////////////////////
//закрывается удаленный пользователь
void CECHO_TCP_IPDlg::OnRemoteClose(int err, DWORD sock)
{
//если мы сервер
if (ServerSocket)
{
int active=GetUserIndex(sock);
if (active==-1)
{
ChatWindowAddStringUID("ОШИБКА: отключился незарегистрированный пользователь!",SYSTEM_UID);
return;
}
DWORD del_uid=UserInfo[active].RemoteSettings.uid;
CString tmp=_S+UserInfo[active].RemoteSettings.NickName+"("+itos(del_uid)+") отключился"+ENDL;
Sound(SOUND_DISCONNECT);
ChatWindowAddStringUID(tmp,SYSTEM_UID);
//удаляем из меню строку "отключить того-то.."
CMenu *sub=GetMenu()->GetSubMenu(2);
sub->DeleteMenu(sock,MF_BYCOMMAND);
delete UserInfo[active].socket_connect;
UserInfo.erase(&UserInfo[active]);
BYTE packet[5];
packet[0]=ESC_USER_EXIT;
LPBYTE puid=LPBYTE(&del_uid);
packet[1]=puid[0];
packet[2]=puid[1];
packet[3]=puid[2];
packet[4]=puid[3];
//посылаем остальным сообщение об отключении
for(int i=0; i<UserInfo.size(); i++)
{
UserInfo[i].socket_connect->SendData(&packet,5);
UserInfo[i].socket_connect->SendStringWithUID(tmp, SYSTEM_UID);
}
}
//если мы клиент - значит отключилсь от сервера
else
{
//очищаем список пользователей
UserInfo.clear();
ChatWindowAddStringUID("Сервер разорвал соединение"+ENDL,SYSTEM_UID);
SettingBox.TryConnect=false;
}
SynchroMenuButtons();
RefreshUserList();
//EnableClientServerButtons(true);
}
void CECHO_TCP_IPDlg::OnLButtonDown(UINT nFlags, CPoint point )
{
m_input_box.SetFocus();
CDialog::OnLButtonDown(nFlags, point);
}
//////////////////////////////////////////////////////////////////////////
#include "piano_plugin\pianores.h"
void CECHO_TCP_IPDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
OnMenuSettingBox();
// CDTFM_GeneratorDlg piano;
// piano.DoModal();
CDialog::OnRButtonDown(nFlags, point);
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::SetTitle()
{
if (UserInfo.size()==0) SetWindowText("TCP/IP Chat - Нет подключенных пользователей!");
else
{
CString m=_S+LocalSettings.NickName+ " говорит с ";
for(int i=0; i<UserInfo.size(); i++)
{
m+=UserInfo[i].RemoteSettings.NickName;
if (i<UserInfo.size()-1)
m+=", ";
}
SetWindowText(m);
}
//OnAbout();
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
if (m_richedit.m_hWnd)
{
CRect r, inp;
GetClientRect(&r);
m_input.GetWindowRect(&inp);
int len2=100;
int
len1=r.Width()-len2,
hei=r.Height()-inp.Height();
m_richedit.MoveWindow(0,0, len1, hei);
m_input. MoveWindow(0,hei, r.Width(), inp.Height());
m_user_list.MoveWindow(len1,0, len2, hei);
}
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::OnMenuConnect()
{
OnConnect();
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::OnMenuRunServer()
{
OnRunServer();
SynchroMenuButtons();
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::OnMenuSettingBox()
{
SettingBox.DoModal( ServerSocket ? false : true);
LocalSettings=SettingBox.GetUserSettings();
CHARFORMAT cf=LocalSettings.cf;
cf.yHeight=INPUT_HEI;
m_input.SetSel(0,-1);
WizSelectionCharFormat(m_input, cf);
m_input.SetSel(0,0);
InfoExchange();
SetTitle();
ShowSendRecvInfo=SettingBox.m_system_message;
RefreshUserList();
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::WriteLogFile()
{
//если нет разрещения на запись лога не пишем логи
if (SettingBox.m_enable_write_log_file == 0 ) return;
//MessageBox("WRITE LOG FILE!");
CreateDirectory("Logs",NULL);
CFile file;
if (file.Open(PathTextLog,file.modeWrite|file.modeCreate))
{
//CString txt;
//m_richedit.GetWindowText(txt);
GetData;
//file.Write(txt.GetBuffer(0),txt.GetLength());
file.Write(m_richtext.GetBuffer(0),m_richtext.GetLength());
file.Close();
}
RtfFile.Open(PathRtfLog, CFile::modeCreate|CFile::modeWrite);
EDITSTREAM es;
es.dwCookie=(DWORD) &RtfFile;
es.pfnCallback=MyStreamOutCallback;
m_richedit.StreamOut(SF_RTF,es);
RtfFile.Close();
}
void CECHO_TCP_IPDlg::OnFileExit()
{
if (ServerSocket)
{
OnMenuStopServer();
if (ServerSocket) return;
}
if (UserInfo.size() !=0)
{
if (MessageBox("В настоящей момент установлено подключение к чат-серверу.\r\n"
"Вы действительно желаете выйти из чата ?"," Внимание ! ", MB_OKCANCEL) == IDCANCEL)
return;
}
OnOK();
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::OnSetfocusInput(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
*pResult = 0;
}
void CECHO_TCP_IPDlg::OnClickInput(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
// Cursor.Hide();
// OnRichTest("\b ");
// *pResult = 0;
}
//////////////////////////////////////////////////////////////////////////
void CECHO_TCP_IPDlg::OnKillfocusInputBox()
{
//нужно спрятать курсор в RichEdit
// Cursor.Hide();
// Cursor.ReDraw();
}
void CECHO_TCP_IPDlg::OnSetfocusInputBox()
{
// TODO: Add your control notification handler code here
// Cursor.Show();
// Cursor.ReDraw();
}
void CECHO_TCP_IPDlg::OnReturnInput(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
//OnSend();
*pResult = 0;
}
void CECHO_TCP_IPDlg::OnMenuStopServer()
{
if (!ServerSocket) return;
//если есть активные соединения - закрываем соединения
if (UserInfo.size())
{
CString z="Установлено соединение с пользователями: ";
for(int i=0; i<UserInfo.size(); i++)
{
z+=UserInfo[i].RemoteSettings.NickName;
if (i<UserInfo.size()-1) z+=",";
}
z+="\r\nОстановка сервера повлечет за собой также разрыв активных соединений. Продолжить?";
if ( MessageBox(z, "Остановка сервера", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
{
CMenu *sub=GetMenu()->GetSubMenu(2);
for(int i=0; i<UserInfo.size(); i++)
{
sub->DeleteMenu(DWORD(UserInfo[i].socket_connect),MF_BYCOMMAND);
UserInfo[i].socket_connect->SendStringWithUID("Cервер останавливается"+ENDL,SYSTEM_UID);
delete UserInfo[i].socket_connect;
}
delete ServerSocket;
ServerSocket=NULL;
UserInfo.clear();
ChatWindowAddStringUID("Сервер остановлен, все соединения разорваны"+ENDL,SYSTEM_UID);
UserInfo.clear();
RefreshUserList();
}
}
//иначе закрываем сервер-сокет
else
{
delete ServerSocket;
ServerSocket=NULL;
ChatWindowAddStringUID("Сервер остановлен"+ENDL,SYSTEM_UID);
res:
UnID=1+rand();
if (UnID==0) goto res;
}
SynchroMenuButtons();
}
//синхронизирую состояние меню и кнопок
void CECHO_TCP_IPDlg::SynchroMenuButtons()
{
#define mfe MF_ENABLED
#define mfd MF_GRAYED
CMenu *m=GetMenu();
int k;
bool Server=false;
bool ActiveConnections=false;
if (ServerSocket) Server=true;
if (UserInfo.size()) ActiveConnections=true;
ActiveConnections || Server || SettingBox.TryConnect ? k=mfd: k=mfe;
m->EnableMenuItem(ID_MENU_RUN_SERVER, k);
if (SettingBox.m_hWnd) SettingBox.InitButtons(ServerSocket!=NULL, UserInfo.size() !=0);
//сервер з
m->EnableMenuItem(ID_MENU_STOP_SERVER, Server ? mfe : mfd);
if (Server)
{
m->EnableMenuItem(IDC_DISCONNECT, mfd);
m->EnableMenuItem(IDC_CONNECT, mfd);
}
else
{
if (ActiveConnections)
{
m->EnableMenuItem(IDC_DISCONNECT, mfe);
m->EnableMenuItem(IDC_CONNECT, mfd);
}
else
{
m->EnableMenuItem(IDC_DISCONNECT, mfd);
if (SettingBox.TryConnect==true)
m->EnableMenuItem(IDC_CONNECT, mfd);
else
m->EnableMenuItem(IDC_CONNECT, mfe);
}
}
}
BOOL CECHO_TCP_IPDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
return CDialog::OnMouseWheel(nFlags, zDelta, pt);
}
void CECHO_TCP_IPDlg::OnAbout()
{
AboutBox about;
about.DoModal();
// ChatWindowAddStringUID("x",SYSTEM_UID);
}
void CECHO_TCP_IPDlg::ScrollRich()
{
if (!SettingBox.m_no_autoscroll)
{
int cnt=m_richedit.GetLineCount();
for(int i=0; i<cnt; i++)
m_richedit.LineScroll(1);
}
}
BOOL CECHO_TCP_IPDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
WORD wNotifyCode = HIWORD(wParam);
WORD wID = LOWORD(wParam);
DWORD code = lParam;
if (wID==ID_POPUP_SHOW)
{
m_hide=false;
ShowWindow(SW_NORMAL);
BringWindowToTop();
return true;
}
if (wID==ID_POPUP_EXIT)
{
ShowWindow(SW_NORMAL);
OnFileExit();
return true;
}
if (wID == ID_SHELL_MESSAGE)
{
if (code==WM_LBUTTONDOWN)
{
if (m_hide==true)
{
m_hide=false;
ShowWindow(SW_NORMAL);
BringWindowToTop();
}
else
{
m_hide=true;
ShowWindow(SW_HIDE);
}
return true;
}
if (code==WM_RBUTTONDOWN)
{
CMenu menu;
menu.CreatePopupMenu();
menu.AppendMenu(0,ID_POPUP_SHOW,"Показать");
menu.AppendMenu(MF_SEPARATOR);
menu.AppendMenu(0,ID_POPUP_EXIT,"Выйти");
POINT p;
GetCursorPos(&p);
menu.TrackPopupMenu(TPM_RIGHTBUTTON|TPM_CENTERALIGN,p.x,p.y,this);
}
return 0;
}
return CDialog::OnCommand(wParam, lParam);
}
void CECHO_TCP_IPDlg::SavePlacement()
{
SettingBox.WriteSettings();
CRegKeyAdv reg;
CRect r;
GetWindowRect(&r);
reg.SetValue( r.left, "PosX");
reg.SetValue( r.top, "PosY");
reg.SetValue( r.Width(), "WinCX");
reg.SetValue( r.Height(), "WinCY");
reg.Close();
}
void CECHO_TCP_IPDlg::AddIcon()
{
NOTIFYICONDATA ni= {0};
ni.cbSize=sizeof(ni);
ni.hWnd=this->m_hWnd;
ni.uID=ID_SHELL_MESSAGE;
ni.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;
ni.uCallbackMessage=WM_COMMAND;
strcpy(ni.szTip,"TCP/IP чат");
ni.hIcon=hIcon;
Shell_NotifyIcon(NIM_ADD, &ni);//) MessageBox("ошибка Shell_NotifyIcon ");
}
void CECHO_TCP_IPDlg::DeleteIcon()
{
NOTIFYICONDATA ni= {0};
ni.cbSize=sizeof(ni);
ni.hWnd=this->m_hWnd;
ni.uID=ID_SHELL_MESSAGE;
ni.uFlags=NIF_MESSAGE;
ni.uCallbackMessage=WM_COMMAND;
Shell_NotifyIcon(NIM_DELETE, &ni);//) MessageBox("ошибка Shell_NotifyIcon ");
}
void CECHO_TCP_IPDlg::OnDestroy()
{
DeleteIcon();
SavePlacement();
WriteLogFile();
CDialog::OnDestroy();
}
void CECHO_TCP_IPDlg::OnFileSend()
{
MessageBox("Извините, данная функция находится в стадии разработки ...");
}
CECHO_TCP_IPDlg::~CECHO_TCP_IPDlg()
{
delete ServerSocket;
}
У вас нет необходимых прав для просмотра вложений в этом сообщении.
12073, Господи, не могу найти ошибку в программе! Помоги! В итоге, вчера в сессии не удалось даже установить элементарного подключения к серверу.
12076, что Ты, Господи, пишешь. Слишком сложную программу ты написал. Теперь, чтобы найти ошибку, тебе нужно нанимать специалиста, а это большие деньги.
Схема, Господи, говоришь...
Давай про себя уже. Хватит сам с собой на форуме разговаривать.
12079: operator_123:
> Хватит сам с собой на форуме разговаривать
да ладно б если б еще что полезное сам с собой обсуждал, а то пургу гонит беспросветную же. Совершенно не пользуется своей щизофренией
> Хватит сам с собой на форуме разговаривать
да ладно б если б еще что полезное сам с собой обсуждал, а то пургу гонит беспросветную же. Совершенно не пользуется своей щизофренией
12080: Manfred:
Ща, напостит говновидева какого-нить.
Лучше ничего придумать не может. (
Ща, напостит говновидева какого-нить.
Лучше ничего придумать не может. (
12081: Cpt.Heidegger:
притом все вместе придумать не могут
притом все вместе придумать не могут
12082: Manfred:
Писал бы рассказы какие-нить, например.
Борис Виан и Мамлеев ему в помощь.
Там шизо больше, чем во всей этой теме.
Я бы читал, с удовольствием.
Писал бы рассказы какие-нить, например.
Борис Виан и Мамлеев ему в помощь.
Там шизо больше, чем во всей этой теме.
Я бы читал, с удовольствием.
12083: Cpt.Heidegger:
таки согласен с тобой. Визу вообще давно все кому не лень советовали творчеством заняться, но нет, скулить на форуме ему куда интересней и молиться мутному бородатому чуваку
таки согласен с тобой. Визу вообще давно все кому не лень советовали творчеством заняться, но нет, скулить на форуме ему куда интересней и молиться мутному бородатому чуваку
12084: Manfred пишет:
> тВизу вообще давно все кому не лень советовали творчеством заняться,
Судя по тем музыкальным видео, которые редко, но встречаются у него - с творческими ориентирами у него полнейшая беда.
Не выйдет художника. Пелевина поди не читал, даже и про Бьорк не в курсе. А это, вроде, его тема - если в разрезе диагноза говорить.
На фотографиях - в шахматы играл. "Защиту Лужина" помнишь книгу? Во.
> тВизу вообще давно все кому не лень советовали творчеством заняться,
Судя по тем музыкальным видео, которые редко, но встречаются у него - с творческими ориентирами у него полнейшая беда.
Не выйдет художника. Пелевина поди не читал, даже и про Бьорк не в курсе. А это, вроде, его тема - если в разрезе диагноза говорить.
На фотографиях - в шахматы играл. "Защиту Лужина" помнишь книгу? Во.
-
Демиург
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость