PROgrammist, №18

Page 1


«Содержание выпуска»

Редакция: Сергей Бадло, Василий Мединцев, Utkin, Виталий Желтяков, Алексей Шишкин, Егор Горохов, Алексей Шульга Дизайн и верстка: Василий Мединцев Контакты: Вопросы и предложения для редакции, а также авторские статьи направляйте на Email: reddatacentr @ gmail . com info @ procoder . info

VIP ПЕРСОНА Интервью с Мигелем де Икаса „03” ЗАЩИТНОЕ ПРОГРАММИРОВАНИЕ Реализация современных криптоалгоритмов в проприетарных программах, ошибки и пути их решения на основе открытых технологий „05”

Информационная поддержка: Международная Академия Информатизации (МАИН) РК http://academy.kz Журнал «Радиолюбитель» http://radioliga.com АСУТП и интеллектуальная начинка приборов http://raxp.radioliga.com Некоммерческая сеть AirNet-Berdyansk http://airnet.zp.ua Электронная электротехническая библиотека http://electrolibrary.info Примечание: Издание некоммерческое. Все материалы, товарные знаки, торговые марки и л оготипы, упомянутые в ж урнале, принадлежат их владельцам. Статьи, поступающие в редакцию, рецензируются. Мнение авторов не всегда совпадает с мнением редакции. Перепечатка материалов журнала и использование их в любой форме, в том числе в электронных СМИ, возможны только с разрешения редакции, при обязательном указании ссылки на сайт журнала http://procoder.info.

МУЛЬТИМЕДИА И ИГРЫ Как я написал 3D игру в консоли „08” Основы компиляции исходного кода MTA „12” ОБЩИЕ ВОПРОСЫ Визуализируем данные в приложении LightSwitch „15” ЛАБОРАТОРИЯ Пишем HTML-приложение для мониторинга ресурсов „21” Платформа FireMonkey в Delphi XE2 „24” Гаджеты. Взгляд со стороны „26” Управление программой (устройствами) через браузер „29” ВНИМАНИЕ КОНКУРС ! „37”

Большая просьба к авторам присылать вместе со статьей свое фото или желаемый аватар, т.к. по текущему формату журнала фото автора будет обязательно отображено перед текстом его статьи в журнале, и после статьи на сайте, с именем, ником, либо другими контактами которые будут представлены. При отсутствии или нежелании автора будет отображен стандартный аватар журнала. Идея создания журнала: Алексей Шульга

Выходит с марта 2010 года

„02” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

www.procoder.info


«Интервью с Мигелем де Икаса»

Мигель де Икаса (Miguel de Icaza), основатель GNOME, Midnight Commander и Gnumeric, в настоящее время занимающийся развитием проекта Mono и адаптацией Moonlight (свободная реализация Silverlight) для мобильных платформ в собственной компании Xamarin, а ранее в Novell, любезно согласился дать интервью нашему журналу. К большому сожалению, полностью ответить на все интересующие вопросы Мигель не смог из-за недостатка времени и занятости, но разрешение на публикацию сокращенной версии дал. Представляем вашему вниманию перевод нашего общения в электронном режиме. Редакция: Добрый день, Мигель. Российскому читателю мало, что о Вас известно. Расскажите о себе.

Мигель: Мы открыли ресурс для людей, которые хотят помочь проекту Mono, но те же принципы применимы к почти любому проекту с открытым кодом: www.mono-project.com/Contributing

Мигель: Я родился в Мексике, я счастливо женат, и я отец красивого м а л е н ь к о го р е б е н к а . Занимаюсь открытым исходным кодом и развитием Linux, начиная с 1992-го или около того. Можно сказать, любимое занятие на каждую секунду. В эти дни, в основном, я сосредоточился на разработке программного обеспечения с акцентом на новые мобильные пространства.

Редакция: Могут ли российские компании получать прибыль, используя в своей деятельности Mono? И если да, то, как Вы это представляете? Мигель: Они могли-бы использовать Mono в своей деятельности для получения прибыли. На самом деле, есть много компаний, которые ищут коммерческое приложение для Mono. Они могли-бы обеспечивать техподдержку, например.

Редакция: Зачем вообще .Net нужна на линукссистемах?

Редакция: Может ли пользователь Gnome в случае обнаружения ошибки и/или неточности в документации обратиться к Вам?

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

Мигель: Это был бы отличный способ для кого-то из России внести свой вклад. Редакция: Есть ли у Вас какое-либо отношение к проекту MonoXNA?

Редакция: Среди российской молодежи есть люди желающие помочь бесплатно с целью получения опыта программирования, работы в команде и т.д., но просто не знающих куда обратиться. Как связаться с разработчиками Gnome и Mono? Многие видят себя программистами, бета-тестерами, переводчиками документации и дизайнерами. Кто еще требуется проектам?

Мигель: Этот проект был переименован в MonoGame. Мне приходиться довольно часто общаться с его разработчиками, но я не принимал непосредственного участия в нем.

„03” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Интервью с Мигелем де Икаса»

Редакция: Как вы попали в программирование, есть ли у вас специальные «ритуалы» при написании кода?

контроля версий? Какие самые лучшие, с вашей точки зрения для команды разработчиков и почему?

Мигель: Как то я хотел поиграть в одну игру, но в то время мы не могли позволить себе приобрести диск для моего компьютера, так что я не мог играть в любые коммерческие игры. Все, что я мог сделать, это научиться писать собственные небольшие игры. Причем, для того, чтобы поиграть , мне приходилось делать это каждый раз при включении компьютера. Год спустя отец купил мне кассету, чтобы записать мою игру, но к тому времени я уже стал думать о других интересных задачах.

Мигель: Я не очень религиозен, когда дело доходит до этого. Я использую то, что выбрали другие люди для своего проекта. Для Gnome и Mono мы используем Git. Как правило, мы всегда его используем. И я обожаю GitHub, так что он стал частью нашего инструмента изо дня в день.

Редакция: Какие средства разработки используете? Что мешает работе, что помогает? Мигель: В эти дни, так как я связан с различными проектами, использую много различных инструментов. Emacs является моим основным текстовым редактором, но я регулярно использую также и VI. Иногда я использую IDE: MonoDevelop или Visual Studio. Большинство моих разработок проводится на базе либо Linux, либо MacOS. Во время работы с другими людьми много времени уходит на создание документов, в эти дни я использую Google Docs.

Редакция: Как правильно хранить резервные копии? Мигель: Я практически не использую резервных копий. Редакция: Были интересные случаи в вашей работе? Мигель: Да, были всевозможные инциденты, например http://abock.org/2010/08/06/real-american-heroestoilet-trouble или http://tirania.org/blog/archive/2008/Jun-17.html Прошу прощения, мне уже нужно идти домой, так что я не смогу завершить полностью наше интервью.

Редакция: Используете такие вещи, как системы

Удачи Вам, Мигель

контроля версий? Какие самые лучшие, с вашей точки зрения для команды разработчиков и почему?

„04” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Реализация современных криптоалгоритмов в проприетарных программах, ошибки и пути их решения на основе открытых технологий»

Семен Савинов (Fetxp Inc.) info@fetxp.com

Современная криптография является одновременно наукой и искусством защиты информации. И в наше время старая истина о том, что кто владеет информацией, тот владеет миром, становится все более актуальной. Проблема ограничения доступа к информации, сохранения её целостности и конфиденциальности, на сегодняшний день является практически одной из самых ключевых во всех сферах современного мира. Это и экономика и медицина и безопасность целого государства. Предприниматель желает защитить свою финансовую информацию от посторонних глаз и вмешательства, примерный муж думает о том, куда бы ему запрятать телефоны любовниц на своем компьютере подальше от глаз жены. Все, от мала до велика испытывают потребность в средствах защиты информации. И рынок предлагает эти средства. На сегодняшний день их выбор достаточно велик. Есть программы стоимостью от нескольких десятков тысяч долларов, до совсем бесплатных. Что же выбрать и кому доверить свое самое сокровенное? Об этом задумываются все, от министра обороны, до простого школьника. При выборе системы безопасности, одним из основных решающих факторов должен быть принцип целесообразности и адекватности. Если вы являетесь носителем весьма ценной информации, то помимо криптографических средств защиты, вы должны позаботиться так же и о собственной безопасности (нанять телохранителей, купить бронированную машину и т.д. в зависимости от ценности самой информации). Мощные, грамотно построенные криптографические системы способны на многое, но нельзя считать их панацеей от всех бед. Здесь будет уместно привести цитату Б. Шнайера: «Пользователи, уделяющие слишком много внимания алгоритмам шифрования в ущерб другим методам обеспечения безопасности, похожи на людей, которые вместо того, чтобы обнести свои владения высоким забором, перегораживают дорогу массивными воротами, нисколько не задумываясь о том, что злоумышленникам не составит труда сделать шаг в сторону, и обойти сей "неприступный бастион".» Говоря проще, метод нагретого Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

Peter Gutmann (Digital Data Security, University of Auckland) pgut001@cs.auckland.ac.nz

утюга ещё никто не отменял, и с его помощью, зачастую, можно получить доступ к информации, зашифрованной самым стойким алгоритмом всего за несколько минут. Но есть и обратная сторона медали. Когда вы приобрели программу или скачали бесплатно ее из сети Интернет, и вдруг узнали (в лучшем случае), что заявленные возможности и характеристики данной программы не соответствуют действительности. Основная неприятность, связанная с плохой системой защиты, в том, что она выглядит точно так же, как и хорошая система защиты. Невозможно обнаружить разницу по их внешнему виду. Обе системы дают одни и те же обещания по надежности защиты, обе имеют одинаковые функции, даже могут использовать одинаковые алгоритмы, например RC6 или RSA. Тем не менее, одна система защищает вашу информацию, а другая – нет. Нельзя сказать, что на рынке нет хороших криптографических средств. Они есть. Есть производители, которые пытаются создать хорошие средства и давать честную рекламу, но есть и такие, кто просто хочет подзаработать, и совершенно не беспокоится о том, достаточно ли хороши и надежны их средства защиты. Время от времени наша группа разработчиков скачивает программы из сети Интернет, и проводит их исследования с различных сторон. Это делается для того, что бы узнать какие возможности и сервисы предлагают современные программы, как в них реализованы те или иные функции, ну и конечно же, соответствуют ли в них заявленные возможности действительности. Мы не пытаемся тем самым скомпрометировать правообладателя исследуемой программы, таким образом мы исследуем ошибки в реализации различных криптоалгоритмов и построении самих программ (декомпиляция проводится лишь в тех случаях, где это допустимо). И конечно же, если обнаруживается ошибка, то в известность в первую очередь ставится ее автор. Некоторые авторы программ относятся к

К оглавлению

„05” www.procoder.info


«Реализация современных криптоалгоритмов в проприетарных программах, ошибки и пути их решения на основе открытых технологий» этому с пониманием и с удовольствием принимают конструктивную критику, другие же наоборот, обращаются в суд и прочие инстанции. В особенности, последнее, можно отнести к зарубежным авторам и компаниям. Первое, что должно натолкнуть на сомнение в выборе криптосредства – это само описание программы, либо ее техническое описание. Приведу несколько наиболее ярких примеров. Реальные названия программ и авторов я опущу. Итак, небольшая выдержка из описания одной программы: «В основе нашего алгоритма находится виртуальная матрица, матрица двоичных значений, размер которой теоретически бесконечен, и таким образом она не имеет избыточности. Шифруемые данные сравниваются с данными в виртуальной матрице. Как только обнаруживается совпадение, создается набор указателей, показывающих, как найти это место в виртуальной матрице. Этот набор указателей затем зашифровывается множеством различных алгоритмов на различных стадиях для достижения лавинного эффекта…» далее цитировать нет смысла, поскольку смысл теряется после прочтения первого абзаца даже для экспертов. И в заключении не могу привести ещё одну цитату, которая просто поражает глубиной заложенного в неё смысла: «…Так как длина ключа и ключевая структура изменяются, и так как механизм шифрования не использует никаких математических алгоритмов, восстановление исходных данных невозможно, и подбор так же невозможен». Однажды исследовав одну из программ, в описании которой было заявлено, что она в качестве алгоритма шифрования использует 128-битный DES, было установлено, что в данной программе используется обычный XOR, который применялся с числом 128. По всей видимости это и был тот самый 128-битный ключ. Некоторые полагают, что чем длиннее ключ, тем лучше. Это утверждение справедливо только до некоторого момента, при наступлении которого дальнейшее увеличение ключа просто теряет смысл. AES поддерживает ключи длиной 128, 192 и 256 бит. Это гораздо больше, чем может потребоваться в обозримом будущем. По правде говоря, сложно даже представить себе мир, в котором возможен полный перебор всех ключей длиной 256 бит. Если кто-то из вас знаком с проектом проводимым компаниями RSA Lab. и Distributed.net, (нечто похожее на seti@home), . Это потребует каких-то фундаментальных открытий в физике или создании нанокомпьютеров. Но потребует каких-то фундаментальных открытий в физике или создаИздание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

нии нанокомпьютеров.Но большинство людей не имеют достаточно времени, терпения и знаний, чтобы самостоятельно провести анализ, необходимый для того, чтобы сделать обоснованный выбор. Единственное, что может сделать здравомыслящий пользователь – обращать внимание на эти или аналогичные предупреждающие знаки. Криптографическая система не может быть надежнее использованных в ней отдельных алгоритмов шифрования. Иными словами, для того чтобы преодолеть систему защиты, достаточно взломать любой из ее компонентов. Использование хороших строительных материалов еще не является гарантией прочности здания. Так и криптографическая система, построенная на основе мощных алгоритмов и протоколов, тоже может оказаться слабой. Какие же наиболее частые ошибки совершают создатели современных криптографических средств. џСамыми распространенными ошибками (вообще-то это сложно назвать ошибкой) являются несоответствие программ их техническому описанию. То есть, говоря иными словами, в программе применяется не описанный RC6, а банальный XOR в собственной интерпретации; џНе выполняется проверка допустимости значений входных переменных; џМногократное использование якобы случайных параметров, что недопустимо; џИспользование некачественных, либо стандартных генераторов случайных чисел. Разработать хороший генератор случайных чисел непросто, поскольку он часто зависит от особенностей аппаратного и программного обеспечения. Сама система шифрования может быть выполнена на высоком уровне, но если генератор случайных чисел выдает легко угадываемые ключи, то все оставшиеся барьеры преодолеваются без особого труда. В ряде продуктов используются генераторы случайных чисел, вырабатывающие ключи, в которых прослеживается определенная закономерность. Так же стоит отметить, что использование одного и того же генератора в некоторых областях обеспечивает требуемую степень безопасности, а в других – нет; џНе стертая до конца секретная, или так называемая промежуточная информация; џСохранение пароля в буфере окна после его закрытия;

К оглавлению

„06” www.procoder.info


«Реализация современных криптоалгоритмов в проприетарных программах, ошибки и пути их решения на основе открытых технологий» џНенадежная система обнаружения и восстановления после ошибок или системных сбоев; џИспользование файла подкачки; џИспользование собственных супер алгоритмов шифрования. Как правило, вскрыть известные алгоритмы шифрования удается лишь в исключительных случаях. Если же разработчик делает ставку на собственные методы, шансы взломщиков повышаются многократно. Незнание секрета алгоритма не является особым препятствием. Квалифицированному специалисту достаточно пары дней, чтобы по объектному коду восстановить исходный алгоритм шифрования; џОптимизация системы защиты до такого примитивного уровня, которая рушится от малейшего колебания; џХранение пользовательских паролей или их хэшей в файлах ключей либо в зашифрованных файлах; џХранение паролей в открытом виде.

Функциональность и высокое качество не являются синонимами, и даже бесконечное тестирование не позволяет устранить всех брешей в системе защиты. Нужно хорошо разбираться в тонкостях терминологии: даже продукты, обладающие абсолютно надежными средствами шифрования, зачастую не могут гарантировать пользователям полной безопасности. Каким же образом можно построить надежную и адекватную систему защиты информации? Есть 2 пути. 1-й – изобрести велосипед, и 2-й использовать уже готовые средства. Нет, я отнюдь не отвергаю создание собственных решений, иначе без них бы ничего не было, как известно, «опыт, сын ошибок трудный». Рассмотрим же, однако, 2-й вариант. Можно приобрести у какой-либо софтверной компании библиотеки разработчика и на их основе строить свою систему безопасности, или же, использовать открытые решения. Использование открытых средств и библиотек имеет ряд преимуществ, и дело вовсе не в цене, особенно когда это касается безопасности. Во первых, это вызывает доверие самого разработчика, т.к. основа на которой он будет строить свою систему полностью прозрачна и он может проследить работу всех ее частей и убедится в отсутствии «потайных ходов». Во вторых, открытость системы, дает возможность изучать, дополнять и исправлять последнюю, тем самым, улучшая ее качественные характеристики и повышая надежность. Возьмем к примеру открытую библиотеку CryptLib автором которой является Петер Гутманн. Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

Данная библиотека представляет собой мощный набор инструментов, который позволяет даже неопытным программистам легко добавлять шифрование и механизмы идентификации к существующему или создаваемому проекту. Интерфейс высокого уровня предоставляет возможность любому программисту добавить достаточно серьезные криптографические функции в свою программу затратив на это, не более получаса времени. Например, для создания защищенной SSL сессии требуется всего 4 строчки кода: CRYPT_SESSION cryptSession; /* Создание сессии */ cryptCreateSession(&cryptSession, cryptUser, CRYPT_SESSION_SSL ); /* Имя сервера и активация сесии */ cryptSetAttributeString( cryptSession, CRYPT_SESSINFO_SERVER_NAME, serverName, serverNameLength ); cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, 1 );

Эта библиотека поддерживает целый ряд современных стандартов и технологий и позволяет с легкостью их использовать. Например такие как шифрование, использование цифровой подписи и управление сертификатами. Ещё одна из замечательных особенностей этой библиотеки это ее межплатформенность. Решения на ее основе могут быть построены для большинства операционных систем. Как раз таким свойством могут похвастать в основном решения на базе открытых исходных кодов. Библиотека предоставляет доступ к различным криптоустройствам, смарт-картам и аппаратным крипто-устройствам. Для создания решений на базе этой библиотеки могут использоваться основные и наиболее распространенные средства разработки и языки программирования. С уважением, Петер Гутманн и Савинов Семён

К оглавлению

„07” www.procoder.info


«Как я написал 3D игру в консоли»

Дивитаев Ришат

Введение

вертящегося куба ничего запрограммировать не сумею). Совсем недолго помучавшись с функциями Glaux/OpenGL, оторвав последний пучок волос на голове, и изрядно понегодовав, я бросил это дело, и все же решил писать игру в той «среде», в которою я так яростно влюбился – в консоли.

Я, начинающий программист. Начал программировать около года назад на С++, хотя, как оказалось, тяготил ко всему компьютерному с тех самых лет, как в первый раз сел за маленький пухлый ЭЛТ (монитор в детстве). При дальнейшем изучении ЭВМ меня все больше затягивал этот логический порядок. И то, что я начну управлять этой логикой – было лишь вопросом времени. Итак, я создал свой первый Pacman в консоли, и вдруг я понял, что я достаточно неровно отношусь к консоли. Мне кажется, что дело в ее простоте и открытости, тогда как создание GUI – приложения таит в себе очень много скрытого и таинственного. Я создавал все больше и больше игр, модифицировал старые проекты, и все это я совершал в текстовом окне консоли, но однажды я захотел большего...

Все началось с того, как у меня в голове возникла идея сотворить трехмерный шутер от первого лица. Все бы ничего, но вот не знал я тогда ни OpenGL, ни DirectX (хотя я и сейчас сложнее текстурированного вертящегося куба ничего запрограммировать не сумею). Совсем недолго помучавшись с функциями Glaux/OpenGL, оторвав последний пучок волос на голове, и изрядно понегодовав, я бросил это дело, и все же решил писать игру в той «среде», в которою я так яростно влюбился – в консоли.

Генеральная идея или «Паранойя mode on»

Начало начал или «Неужели все так просто?»

Все началось с того, как у меня в голове возникла идея сотворить трехмерный шутер от первого лица. Все бы ничего, но вот не знал я тогда ни OpenGL, ни DirectX (хотя я и сейчас сложнее текстурированного

Итак, я решил сотворить собственную 3D игру, да еще и в текстовой среде.

Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

Генеральная идея или «Паранойя mode on»

К оглавлению

„08” www.procoder.info


«Как я написал 3D игру в консоли»

Недолго думая, за пару минут было решено не отвлекать мои мысли настоящим «Труъ-Тры-Дэ» в текстовом виде, а нагло обмануть игрока псевдотрехмерными изображениями (как это умели делать умельцы из id Software). Эта задумка решала достаточный объем проблем, чтобы начать творить, не задумываясь о негативных последствиях на мозг игрока. Взаимодействие с миром игры сделать было проще пошаговым. Это так же решало кучу проблем, в ряды которых включалась медленная отрисовка изображения на консольный экран, с последующим предотвращением мелькания экрана. Так же было задумано перемещаться не «попиксельно», как принято в нормальных играх, а «поблочно», т. е. при каждом шаге игрок двигался на определенное кол-во пикселей. Это давало преимущество при отрисовке окружающего пространства (про которое я расскажу позже).

эти проблемы решались лишь моей искренней любовью к pixel-art'у, моей достаточно извращенной фантазией, и немереным количеством свободного времени, которое я потратил на рисование всех предметов в игре (которые к тому же приходилось «дублировать» при инверсии тех же стен и проходов для другой стороны, или при создании одного и того же предмета разных размеров для иллюзии перспективы). Сама графика игры была спрятана в отдельный файл с «текстурами». Такой подход давал множество преимуществ, среди которых была легкая отладка и переформировка изображений (хотя кому это интересно?!). Двухмерность в трехмерности или «Давайте поиграем в Doom»:

Графика или «Почему я вижу текст?» Во-первых, первой и самой главной проблемой в графике – это было, есть, и будет именно то, что консоль не предназначалась для рисования в принципе. Именно это и подталкивало меня на то, чтобы продолжать над игрой работу в последующем... Во-вторых, окно было достаточно маленькое: 80х25 символов, что и стало первой стеной между моими фантазиями и реальностью, хотя эта проблема решалась довольно просто – меньше деталей, больше смысла в изображениях. В-третьих, количество цветов для «разукрашивания» и так не понятной с первого взгляда графики было достаточно мало: 8 основных цветов и их более яркая вариация, что только добавляло во мне энтузиазма, словно масло в карбюратор. Но, так или иначе, жаловаться на то, что «квадрат (Один из кусков стены) с л и ш к о м у гл о в ат ы й »

(0: пустота, 1: стена, 2: игрок, 3: враги)

Для создания иллюзии 3D решено было создать двухмерную матрицу, состоящую из стен (цифра 1) и пустот (цифра 0), и проецировать ее на экран как трехмерное пространство, считывая из карты только то, что должен был видеть игрок. Сам же алгоритм расчета рисуемых (не рисуемых) участков карты выглядела не совсем удобно, или лучше - не комфортно, как для понимания, так и для модифицирования, но именно на нем построена вся графическая часть игры, что довольно прискорбно... Также игра не поддерживает карты с открытыми площадками (2х2 клетки) из-за особенностей считывания объектов на карте. При вышеописан-

„09” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Как я написал 3D игру в консоли»

(на миникарте открытая площадка (левый нижний угол), а на экране две стены(!!!))

ном раскладе будут рисоваться неправильные, пугающие еще больше, чем сама графика игры, изображения на экране. Движение и повороты или «Хардкор начинается...» Итак, создав то, что издалека было похоже на трехмерное пространство, можно было достаточно уверенно вручить игроку выбор направления и скорость передвижения, чем я и занялся. Если при движении игрока прямо не возникало проблем, то когда я столкнулся с поворотами, все мое негодование прибавило силу вдвое! Что же выбрать? Скорость, или простоту исполнения? Этот выбор был не легким, но все же я остановился на простоте исполнения (да простят меня владельцы спектрумов). Все же я расскажу про каждый алгоритм. Первый, сложный вариант, было бы достаточно сложно запрограммировать ввиду огромного количества скрытых нюансов. Суть алгоритма состояла в том, что движение игрока должна была определять переменная, которая бы указывала, в какую сторону идет игрок, и куда он смотрит. Несостоятельность этого алгоритма была в огромном количестве условий, которые бы изменяли порядок считывания информации с карты. Не уверен, что я достиг понимания читателя, поэтому расскажу про простой вариант. Простой вариант был воистину простым, ибо содержал всего одну функцию: поворот карты на 90

Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

содержал всего одну функцию: поворот карты на 90 градусов. Это было слегка затратно со стороны ресурсов компьютера, но выглядело это очень удобно. Но матрица карты поворачивалась только в одну сторону. Поэтому поворот в противоположную сторону я сделал еще проще: поворачивал карту три раза, не создавая нового алгоритма поворота. Кстати, поворот налево происходит в три раза дольше поворота направо. Это связано с тем, что карта всегда поворачивалась направо, и для поворота налево я использовал тройной поворот направо. Экшн или «Давайте убьем зомби!» Теперь игрок способен перемещаться по лабиринту, хотя это совсем бессмысленно, разве что, не дать игроку выход на следующий уровень. Но интересно ли бегать по одинаковым лабиринтам в бессмысленной истерике нахождения выхода? Я думаю, нет... Нужен экшн, нужен драйв, нужен враг! Так какой же будет враг? Это однозначно будет зомби, ведь я так неравнодушен к ним... О, да! Зомби, псевдографика, и дробовик! Чего еще желать? =)

К оглавлению

„10” www.procoder.info


«Как я написал 3D игру в консоли»

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

5, если игрок смотрит на зомби, и от 0 до 3, если игрок стоит к зомби спиной (но все же не стоит поворачиваться к зомби спиной, это опасно...). В заключении

Интересный факт: зомби видит лучше, чем игрок. Это связано с тем, что зомби начинает реагировать на игрока при расстоянии между ними в 7 клеток, тогда как игрок может видеть только то, что находится на расстоянии в 5 клетках от него. Зомби очень подвижны, ведь при виде игрока они перемещаются на случайное количество клеток, от 0 до 2, при этом всегда догоняют игрока. При попытке переместиться на клетку игрока, зомби не двигается, нанося при этом урон. Урон может быть от 1 до

Итак, в конце концов, получилась довольно несерьезная игрушка на пять минут, чертовски недоработанная, тормозная и непроходимая. «Но главное не то, что мы видим, а то, что мы чувствуем к увиденному.» В статье я пропустил большинство неинтересных подробностей, заставляющих скучать и совсем не радоваться жизни.

„11” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Основы компиляции исходного кода MTA»

Виталий Иванов vintprog@gmail.com

{

Итак, дорогие читатели, я решил написать русскую статью о том как можно скомпилировать исходный код MTA. Исторический сложилось, что проект делался на 2008 студии, возможно со временем, разработчики перепишут весь исходный код по Microsoft Visual Studio 2010. Поскольку стандарт программирования поменялся - это будет не так просто переписать для компилятора MSVC 2010.

Итак, приступим. Для начала скачаем Microsoft Visual Studio 2008 professional edition отсюда: http://www.microsoft.com/download/en/details.aspx?i d=3713%20 - тут вы скачаете 90 дневную пробную версию, затем когда пройдет 90 дней, ее можно просто переустановить и пользоваться вновь. После того как скачаете установите ее себе. Следующий этап это установка компонентов не необходимых для компиляции исходного кода MTA. Первым делом возьмем и скачаем обновление под именем Microsoft Visual Studio 2008 Service Pack 1 (Installer) для нашей студии: http://www.microsoft.com/download/en/details.aspx? displaylang=en&id=10986. Дальше еще нужно скачать SDK для DirectX отсюда http://www.microsoft.com/download/en/details.aspx? displaylang=en&id=10084%20. DirectX SDK не обходим, на нем завязывается вся графика и GUI проекта MTA. Теперь надо скачать еще один компонент под названием Microsoft ® Windows Server® 2003 R2 Platform SDK Web Install. качаем его отсюда: http://www.microsoft.com/download/en/details.aspx? displaylang=en&id=22668. Теперь только можно приступить к выкачиванию исходных кодов MTA. Опять таки чтобы руками не выдирать исходный код, есть программа TortoiseSVN http://tortoisesvn.net/downloads.html, скачав ее и установив, можно начать выдирать исходный код MTA. Для этого создадим папку и назовем ее MTA_SourceCode, к примеру, кликнув по ней правой кнопкой мыши и мы увидим {РИС. 1} Теперь нажмем там export... и введем ссылку на исходный код: http://mtasa-blue.googlecode.com/svn/trunk как показано на {РИС. 2}

{РИС. 1}

{РИС. 2}

„12” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Основы компиляции исходного кода MTA»

"Фухх", почти все позади: студию поставили, компоненты и SDK тоже, и выдрали исходный код. Теперь остается скачать мелочи:

Приступаем к компиляции

the latest nightly и это: MTASA 1.1 data files

Зайдите в нашу папку где мы скачали исходный код MTA и найдите следующею директорию под названием "Shared", вот тут лежит проект студии под названием "Core 2008", его мы и запускаем {РИС. 3}

после установки, они будут лежать примерно тут: C:\Program Files\MTA San Andreas 1.2, в зависимости от имени вашего жесткого диска.

Это так сказать и есть вся группа проектов, которая собрана в кучу, что существенно упрощает работу программисту.

примечание: MSVC 2010 - сокращеное слово Microsoft Visual Studio 2010.

Теперь вы сами решаете компилировать частями или все проекты. Нажмем Build Solution, компиляция начнется и может занять от 2-х до 7-ми минут, все зависит от вашей мощности компьютера.

{РИС. 3}

„13” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Основы компиляции исходного кода MTA»

{РИС. 4} После завершения компиляции внизу будет указано, сколько у вас проектов откомпилировалось, в случае неудачи будут написаны ошибки, такое могло произойти из-за неустановленных компонентов... Теперь о скомпилированных проектах. "Куда-же они компилируются?", - спросите вы. Изначально они были настроены на то, чтобы при компиляции файлы были в каталоге: "C:\Program Files\MTA San Andreas 1.2". Это значит все, что вы откомпилируете, будет лежать там. И не забываем компилировать в режиме release.

Ресурсы џссылка на оригинал статьи:

http://forum.mtasa.com/viewtopic.php?f=12 3&t=37177 џhttp://www.microsoft.com/download/en/details.a spx?id=3713%20 џhttp://www.microsoft.com/download/en/details.a spx?displaylang=en&id=10986 џhttp://www.microsoft.com/download/en/details.a spx?displaylang=en&id=10084%20 џhttp://www.microsoft.com/download/en/details.a spx?displaylang=en&id=22668 џhttp://tortoisesvn.net/downloads.html џthe latest nightly: http://nightly.mtasa.com/?mtasa-1.2unstable-latest џMTASA 1.1 data files: http://code.google.com/p/mtasablue/downloads/detail?name=mtasa-1.1data-r3333.exe&can=2&q=label%3AData

„14” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Визуализируем данные в приложении LightSwitch»

Анатолий Демидович http://da440dil.narod.ru

{

У топ-менеджеров, как правило, нет ни времени, ни желания работать с данными. Да и не царское это дело. Им необходима информация - то, что они способны понять. Разумеется, в объеме их понимания поставленных задач. В этой статье я попробую превратить данные в информацию путем создания интерактивной диаграммы в приложении LightSwitch используя SilverLight 4 Toolkit. Изложение подробное, в картинках. Вопрос нетривиален.

/ Ladies and gentlemen, let's get ready to rumble / Запускаем Visual Studio 2010, создаем проект LightSwitch, назовем его MyChart. В качестве источника данных используем всем известную базу данных Northwind. Открываем обозреватель решений, добавляем источник данных.

В свойствах подключения выбираем имя сервера. Я использовал MS SQL SERVER 2008 Express. Проверяем подключение и выбираем из списка базу данных Northwind.

Выбираем "База данных".

В списке объектов выберем таблицу Products.

„15” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Визуализируем данные в приложении LightSwitch» Назовем запрос Top10Products и добавим фильтр.

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

Добавляем экран поиска данных на основе нашего запроса.

Создание экрана поиска данных завершено. Назовем его SearchTop10Products.

„16” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Визуализируем данные в приложении LightSwitch» System.Windows.Controls.Toolkit.dll, которая находится в каталоге установки SilverLight 4 Toolkit. В панели элементов должны появиться новые элементы управления. Нас интересуют Chart и PieSeries. Разместим на форме PieChartControl.xaml элемент Chart. Удалим свойства макета диаграммы и ColumnSeries, созданные по умолчанию. Изменим заголовок контейнера Chart и добавим в коллекцию Series элемент PieSeries.

Добавим в наше решение новый проект - библиотеку классов SilverLight и назовем ее PieChart. Удалим созданный по умолчанию файл Class1.vb, добавим пользовательский элемент управления SilverLight и назовем его PieChartControl.

Свойства элемента PieSeries в XAML-коде: џItemsSource - привязывает элемент управления к коллекции сущностей экрана џIndependentValueBinding - свойство сущности, отраженное в диаграмме по оси X џDependentValueBinding - свойство сущности, отраженное в диаграмме по оси Y Компилируем библиотеку. Открываем конструктор экрана SearchTop10Products и создаем пользовательский элемент управления. Добавим ссылку на проект PieChart.

Далее необходимо добавить ссылку на библиотеку

Выберем PieChartControl и добавим его на экран.

„17” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Визуализируем данные в приложении LightSwitch» Начинаем отладку...

<UserControl x:Class="PieChart.PieChartCcntrol" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentati on" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expressicn/blend/2008" xmlns:mc=”http://schemas.openxmlformats.org/markupccmpatibility/2006" me:Ignorable="d" d:DesignHeight="300” d:DesignWidth="400" xmlns:toolkit="http://schemas.microsoft.com" <Grid x:Name="LayoutRoot" Background=”White"> <toolkit:Chart Name="Chartl" Title="Top 10 Products" Height="400" Width=”600" <toolkit:Chart.Series> <toolkit:PieSeries Name="PieSeriesl" DataContext="{Binding}" ItemsSource="{Binding Screen.Topl0Products}" IndependentValueBinding="{Binding ProductName}" DependentValueBinding="{Binding UnitPrice}" IsSelectionEnabled="True" SelectionChanged="PieSeriesl_SelectionChanged" /> </toolkit:Chart.Series> </toolkit:Chart> </Grid> </UserControl>

Открываем обозреватель решений и для проекта MyChart выбираем вид "Представление файлов". Добавим в проект Common каталог UserCode, в который, в свою очередь, добавим класс и назовем его UserInterface. Менеджерам подобная картинка сможет донести гораздо больше информации, чем таблицы. Правда до заявленного выше интерактива нам еще далеко. Спустя некоторое время у пользователя непременно возникнет желание манипулировать данными, отраженными в диаграмме, и мы с вами подготовимся к такому повороту событий :). Для примера реализуем редактирование элемента списка в диалоговом окне. Открываем PieChartControl.xaml, изменяем размер элемента Chart (на мой взгляд наш пирог выглядит слишком скромно). Добавим еще пару свойств элементу PieSeries: џIsSelectionEnabled="True" - разрешает выбор элемента џSelectionChanged="PieSeries1_SelectionCha nged" - добавляет обработку события выбора элемента В итоге наш XAML-код выглядит следующим образом:

„18” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Визуализируем данные в приложении LightSwitch» Пишем нехитрый код интерфейса. Imports System Namespace LightSwitchApplication.UserCode Public Interface Iuserlnterface 'метод класса SearchTopl0Products Sub EditSelectedProduct() End Interface End Namespace

Перейдем к конструктору MyChart и добавим код для экрана SearchTop10Products.

В коде экрана реализуем созданный в проекте Common интерфейс IUserInterface. Namespace LightSwitchApplication Public Class SearchToplGProducts Implements LightSwitchApplication.UserCcde.IUserlnterface Private Sub EditSelectedPrcduct() Implements UserCcde.IUserlnterface.EditSelectedProduct Me.ToplGPrcducts.EditSelected() End Sub End Class End Namespace

Вернемся к обозревателю решений и добавим в проект PieChart ссылки на библиотеки: Microsoft.LightSwitch.dll и Microsoft.LightSwitch.Client.dll, которые находятся в каталоге установки Visual Studio LightSwitch, а также на проект Common.

„19” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Визуализируем данные в приложении LightSwitch» Наконец, переходим к PieChartControl.xaml, выбираем элемент PieSeries. В окне свойств выберем вкладку "События", после чего перейдем к коду обработчика события PieSeries1_SelectionChanged.

Топы довольны, внушительная премия, Рио де Жанейро, белые парусиновые штаны, креолки и мулатки... :) Заключение

Partial Public Class PieChartControl Inherits UserControl Public Sub New InitializeCcmponent() End Sub Private Sub PieSeriesl_SelectionChanged(sender As System.Object, _ e As System.Windows.Controls.SelectionChangedEventArgs)

Пожалуйста, Ваши замечания по содержанию статьи отправляйте на e-mail: da440dil @ ya.ru

’выбираем в таблице выбранную в диаграмме сущность Me.DataContext.Screen().ToplGProducts.Selectedltem = e.AddedItems(0) 'берем экран контекста данных: DataContext=”{Binding}" ItemsSource="{Binding Screen.ToplGProducts}" Dim scr As Microsoft.LightSwitch.Client.IScreenObject = Me.DataContext.Screen 'приводим экран LightSwitch к созданному в проекте ‘Common интерфейсу Dim IUserlnterface As LightSwitchApplication.UserCcde.IUserlnterface = scr 'вызываем метод экрана LifgtSwitch scr.Details.Dispatcher.BeginInvoke(Sub() IUserlnterface.EditSelectedPrcduct() End Sub) End Sub End Class

Запускаем, щелкаем мышью в область диаграммы...

„20” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«ResMon. Пишем HTML-приложение для мониторинга ресурсов Windows»

Анатолий Демидович http://da440dil.narod.ru

{

Однажды, в студеную зимнюю... заинтересовал меня вопрос мониторинга ресурсов Windows, а конкретно (хочется добавить "чисто" конкретно) мониторинга объема свободной памяти (физической и виртуальной), процента использования файла подкачки и загрузки процессоров. Казалось бы ничего особенного, для этого существуют соответствующие классы WMI. Однако заинтересовал меня этот вопрос потому, что необходимо было реализовать "игру цветом", т.е. в случае уменьшения объема ресурса цвет индикатора должен был измениться на "более красный". Итак. В этой статье я предлагаю Вам отправиться в увлекательное путешествие по изменению цвета окна .

Поехали? Открываем блокнот. Я использую Notepad++. Пишем простенький код, пишем HTA: <head> <title>ResMon</title> <HTA:APPLICATION ID = "ResMon" APPLICATIONNAME="ResMon" SINGLEINSTANCE="yes" MAXIMIZEBUTTON = "no" SCROLL="no" ShowInTaskbar ="no" BORDER="none" Version = "1.0"> </HTA:APPLICATION> </head> <script language="VBScript"> Sub Window_OnLoad() window.setTimeout "SetColor "& 0 & "," & 0 & "," & 255,1, "vbscript" End Sub 'переводим число из RGB в Hex для HTML Function GetStrHex(i) If i < 16 Then GetStrHex = "0" & Hex(i) Else GetStrHex = Hex(i) End If End Function 'рекурсивная процедура изменения цвета Sub SetColor(x,y,z) window.document.body.style.background = "#" & GetStrHex(x) & GetStrHex(y) & GetStrHex(z) x=x+1 z=z-1 If z <> 0 Then window.setTimeout _ "SetColor " & x & "," & y & "," & z,5, "vbscript" End Sub </script> <body></body> </html>

Сохраняем, запускаем... Правда красиво? Кажется наше путешествие заканчивается, не успев начаться , а чтобы сделать его "увлекательным", я опишу алгоритм. При загрузке окна мы запускаем рекурсивную процедуру изменения цвета SetColor, которая и выставляет цвет окна : window.document.body.style.background используя функцию перевода RGB в Hex GetStrHex. Начинаем с 0,0,255 - "радикально синего" цвета . Далее, в процессе рекурсии, каждые 5 миллисекунд процедура SetColor добаляет "красного" - x = x + 1, и убавляет "синего" - z = z - 1, до тех пор, пока цвет окна не станет "радикально красным" - If z <> 0 Then. А теперь давайте попробуем изменить палитру начать с зеленого. Для этого достаточно изменить пару строчек: window.setTimeout "SetColor "& 0 & "," & 255 & "," & 0,1, "vbscript" - чтобы начать с зеленого цвета, и y = y - 1 вместо z = z - 1 - чтобы убавлять "зеленый". Теперь, когда у нас есть алгоритм изменения цвета мы можем приступить к реализации алгоритма мониторинга целевых ресурсов. Для мониторинга процента загрузки процессоров используем WMIкласс Win32_Processor, файла подкачки Win32_PageFileUsage, свободной физической и виртуальной памяти - Win32_OperatingSystem, объема физической памяти : Win32_PhysicalMemory. Открываем блокнот, пишем не более сложный чем прежде код:

„21” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«ResMon. Пишем HTML-приложение для мониторинга ресурсов Windows»

<html> <head> <title>ResMon</title> <HTA:APPLICATION ID = "ResMon" APPLICATIONNAME="ResMon" SINGLEINSTANCE="yes" MAXIMIZEBUTTON = "no" SCROLL="no" ShowInTaskbar ="no" BORDER="none" SELECTION="no" Version = "1.0"> </HTA:APPLICATION> </head> <style type="text/css"> html, body{ margin:1px; text-align: center; font:bold 12 sans-serif; border-style: outset; color: #ffffff; } #menu{ background-color: #800000; } #closebtn{ position: absolute; top: 1px; right: 1px; } /* Цвета по умолчанию */ #pRAM,#swap{ background-color: #0000ff; } #vRAM,#proc{ background-color: #00ff00; } </style> <script language="VBScript"> Option Explicit Const strHash = "#" '----- WMI-запросы ----Const strOSQ = "Select FreePhysicalMemory, FreeVirtualMemory, TotalVirtualMemorySize From Win32_OperatingSystem" Const strPMQ = "Select Capacity From Win32_PhysicalMemory" Const strPFUQ = "Select AllocatedBaseSize, CurrentUsage From Win32_PageFileUsage" Const strPQ = "Select LoadPercentage From Win32_Processor" Const intPSF = 48 'флаг полусинхронности '----------------------Dim objItem Dim intTotal, intFreePart, intFreePartV, intFreePartP, intProcRate, intFreePartProc Dim intOSInfoArr(2), intOSInfo Dim intPFUInfoArr(1), intPFUInfo Dim i Dim objWMI, wshShell Set objWMI = GetObject("winmgmts:\\.\root\cimv2") Set wshShell = CreateObject("WScript.Shell") Sub Window_OnLoad() 'устанавливаем размер о позицию приложения window.resizeTo 245,80 window.moveTo screen.availWidth-255, screen.availHeight-90 'устанавливаем обработку событий окна SetUpEventHandler() 'устанавливаем заголовок приложения header.Innertext = ResMon.APPLICATIONNAME 'запускаем процедуру обновления информации window.setTimeout "UpdateInfo", 1, "vbscript" End Sub

'----- Обработка событий окна приложения ----Sub SetUpEventHandler() Dim ClosebtnOnclick, MouseOverClose, MouseOutClose 'закрываем окно Set ClosebtnOnclick = GetRef("OnClickCloseSub") closebtn.attachEvent "onclick", ClosebtnOnclick Set MouseOverClose = GetRef("MouseOverCloseSub") closebtn.attachEvent "onmouseover", MouseOverClose Set MouseOutClose = GetRef("MouseOutCloseSub") closebtn.attachEvent "onmouseout", MouseOutClose End Sub '--------------------------------------------'----- Закрыть ----Sub OnClickCloseSub() Window_OnUnload End Sub Sub MouseOverCloseSub() closebtn.Style.Cursor = "hand" closebtn.style.backgroundColor = "#ff8c00" End Sub Sub MouseOutCloseSub() closebtn.style.backgroundColor = "#800000" End Sub '-------------------Sub Window_OnUnload() Set wshShell = Nothing Set objWMI = Nothing window.close End Sub Sub UpdateInfo() 'информация из Win32_OperatingSystem: свободная физическая память, 'свободная виртуальная память, полный объем виртуальной памяти intOSInfo = GetOSInfo() intTotal = GetTotalMemorySize() 'полный объем физической памяти intPFUInfo = GetPFUInfo() 'информация о файле подкачки intProcRate = GetProcRate() 'процент свободного времени процессоров 'процент свободных ресурсов в масштабе изменения RGB intFreePart = Int(intOSInfo(0)/intTotal*255) 'физической intFreePartV = Int(intOSInfo(1)/intOSInfo(2)*255) 'виртуальной intFreePartP = Int(intPFUInfo(0)/intPFUInfo(1)*255) 'подкачки intFreePartProc = Int(intProcRate*2.55) 'процессоры 'выводим количество ресурсов fpRAM.Innertext = intOSInfo(0) tpRAM.Innertext = intTotal fvRAM.Innertext = intOSInfo(1) tvRAM.Innertext = intOSInfo(2) fswap.Innertext = intPFUInfo(0) tswap.Innertext = intPFUInfo(1) procrate.Innertext = intProcRate 'выставляем цвет окна: "#" + R + G + B, вариант от синего к красному pRAM.style.backgroundColor = strHash & _ GetStrHex(255-intFreePart) & GetStrHex(0) & GetStrHex(intFreePart) 'вариант от зеленого к красному, прочие варианты - по аналогии vRAM.style.backgroundColor = strHash & _ GetStrHex(255-intFreePartV) & GetStrHex(intFreePartV) & GetStrHex(0) 'снова от синего - подкачка swap.style.backgroundColor = strHash & _

„22” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«ResMon. Пишем HTML-приложение для мониторинга ресурсов Windows»

GetStrHex(255-intFreePartP) & GetStrHex(0) & GetStrHex(intFreePartP) 'снова от зеленого - процессор proc.style.backgroundColor = strHash & _ GetStrHex(255-intFreePartProc) & GetStrHex(intFreePartProc) & GetStrHex(0) 'курим 1 секунду и вызываем сами себя :) window.SetTimeout "UpdateInfo()", 1000, "vbscript" End Sub 'получаем объем свободной памяти Function GetOSInfo() Dim colOS Set colOS = objWMI.ExecQuery(strOSQ,,intPSF) For Each objItem In colOS With objItem intOSInfoArr(0) = Int(.FreePhysicalMemory/1024) intOSInfoArr(1) = Int(.FreeVirtualMemory/1024) intOSInfoArr(2) = Int(.TotalVirtualMemorySize/1024) End With Next Set colOS = Nothing GetOSInfo = intOSInfoArr End Function 'получаем объем физической памяти Function GetTotalMemorySize() Dim colPM Set colPM = objWMI.ExecQuery(strPMQ,,intPSF) For Each objItem In colPM GetTotalMemorySize = GetTotalMemorySize + Int(objItem.Capacity/1024/1024) Next Set colPM = Nothing End Function 'получаем объем файла подкачки Function GetPFUInfo() Dim colPFL Set colPFL = objWMI.ExecQuery(strPFUQ,,intPSF) For Each objItem In colPFL With objItem 'свободно = объем - использовано intPFUInfoArr(0) = .AllocatedBaseSize - .CurrentUsage intPFUInfoArr(1) = .AllocatedBaseSize 'объем End With Next Set colPFL = Nothing GetPFUInfo = intPFUInfoArr End Function 'получаем процент загрузки процессоров Function GetProcRate() Dim colP Set colP = objWMI.ExecQuery(strPQ,,intPSF) i=0 For Each objItem In colP i=i+1 GetProcRate = GetProcRate + objItem.LoadPercentage Next 'вычисляем среднее арифметическое на случай, если процессоров несколько GetProcRate = 100-(GetProcRate/i) Set colP = Nothing End Function 'переводим число из RGB в Hex для HTML Function GetStrHex(i) If i < 16 Then GetStrHex = "0" & Hex(i) Else GetStrHex = Hex(i) End If End Function

</script> <body> <div id="menu"> <span id="header"></span><span id="closebtn">X</span> </div> <div id="pRAM"> Физическая память:&nbsp <span id="fpRAM"></span>&nbsp из&nbsp <span id="tpRAM"></span>&nbsp MB </div> <div id="vRAM"> Виртуальная память:&nbsp <span id="fvRAM"></span>&nbsp из&nbsp <span id="tvRAM"></span>&nbsp MB </div> <div id="swap"> Файл подкачки:&nbsp <span id="fswap"></span>&nbsp из&nbsp <span id="tswap"></span>&nbsp MB </div> <div id="proc"> Процессоры:&nbsp <span id="procrate"></span>&nbsp из 100% </div> </body> </html>

При загрузке приложение принимает необходимый размер, выставляется в нужную позицию, устанавливает обработку события нажатия на кнопку закрытия окна и запускает рекурсивную процедуру обновления информации о целевых ресурсах UpdateInfo, которая, в свою очередь, раз в секунду выполняет WMI-запросы к заявленным выше WMIклассам и обновляет информацию окна HTA. Сохраняем, запускаем... Вуа-ля. В развитие разработки, с помощью библиотеки DAHTACOM можно установить позицию окна приложения "поверх всех", закинуть иконку приложения в область уведомлений, использовать PNGизображение с альфа-каналом в качестве "корпуса" окна HTA... Но, это уже совсем другая история... В завершение нашего "путешествия", хочу обратить Ваше внимание на то, что для запуска полученного в результате приложения для подключения к службе WMI необходимо обладать правами администратора. Заключение Пожалуйста, Ваши замечания по содержанию статьи отправляйте на e-mail: da440dil @ ya.ru

„23” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«FireMonkey 3D. Возможность быстрого построения 3D приложений в Delphi XE2»

Шагров Александр ericblack @ mail.ru

С выпуском Delphi XE2 в конце лета 2011 года Embarcadero добавило новую библиотеку – FireMonkey. Как написано на сайте Embarcadero FireMonkey - это платформа которая позволяет создавать визуально привлекательные приложения, используя возможности графического процессора как для настольных, так и мобильных систем. Поддерживаются Mac OS X, Win32, Win64. Фактически – аналог WPF. Поддерживается 2D и 3D графика, причем в 2D проекте (FireMonkey HD Application) также могут использоваться 3D компоненты благодаря контейнеру TViewPort3D. Модули FireMonkey находятся в пространстве имен FMX. Для рендеринга объектов в системах на платформе Windows в HD приложениях, где доступно, используется Direct2D, там где он недоступен, как на Windows XP используется GDI+. Для 3D приложений используется Direct 3D. На платформе Apple вся отрисовка выполняется с помощью OpenGL. Для нас FireMonkey 3D представляет интерес в первую очередь тем, что позволяет достаточно быстро и просто, без глубоких познаний в области 3D графики, создавать простые 3D приложения пример разработки, которого и приведен ниже. Итак, мы поставили Delphi XE2 (30 дневный trial можно взять на https://downloads.embarcadero.com/free/delphi ), насладились sizeOf(pointer) = 8 и, вспомнив старые опыты с OpenGL, решили попробовать сделать 3D приложение. Если же вы никогда не работали с 3D графикой, то для краткого ознакомления с основными понятиями, такими как камера, источник света и до того уровня который вас заинтересует, рекомендовал бы посмотреть известную книгу Михаила Краснова: «OpenGL. Графика в проектах Delphi». Для первого опыта попробуем создать маленькую модель солнечной системы. Создаем проект FireMonkey 3D и видим несколько отличную от VCL форму и другой набор компонентов. Что будем делать? Начнем с Солнца. Поместим на форму сферу. Дальше тянем ее во все стороны, пока не добьемся

Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

приемлемого размера и вида или задаем размер по осям в инспекторе объектов. Раскрываем свойство Material и выбираем цвет. Добавляем вторую сферу и делаем ее размером поменьше – Земля. Теперь заставим Землю вращаться вокруг Солнца. Для этого добавим таймер, и в таймере будем задавать координаты Земли в каждый момент времени. Координаты в FireMonkey 3D вещественные. Начало координат – в центре экрана. Ось Х направлена вправо, Y – вниз, Z – от экрана. Отсчет углов осуществляется по часовой стрелке в радианах. Нулевой угол совпадает с осью Х. Для простоты расчета координат запустим Землю по кругу. Обработчик таймера будет выглядеть так: procedure TForm1.Timer1Timer(Sender: TObject); begin if corner < - 2* pi then corner := 0; Sphere2.Position.X := r*cos(corner); Sphere2.Position.Y := r*sin(corner); Sphere2.Position.Z := corner; corner := corner - 0.001; end;

После запуска приложения Земля должна побежать вокруг Солнца. Масштабирование изображения при изменении размеров формы выполняется автоматически. Теперь сделаем Землю похожей на Землю. Возьмем файл с развернутой картой земли и подгрузим его в свойство Texture. Текстура будет сохранена в файле формы (*.fmx). Сфера оказалась покрыта текстурой и похожа на Землю. Далее позиционируем ее, выставляя наклоны по углам – значения свойства Rotation Angle. Затем заставим планету вращаться вокруг своей оси, изменяя значение свойства Rotation Angle в таймере, добавив следующий код:

К оглавлению

„24” www.procoder.info


«FireMonkey 3D. Возможность быстрого построения 3D приложений в Delphi XE2»

Form1.Sphere2.RotationAngle.Z := Form1.Sphere2.RotationAngle.Z + 1; Form1.Sphere2.RotationAngle.Y := Form1.Sphere2.RotationAngle.Y + 0.11; Form1.Sphere2.RotationAngle.X:= Form1.Sphere2.RotationAngle.X + 0.01;

Теперь самое время обратиться к источникам света, что бы на Земле появилась смена времени суток. Добавляем на форму компонент TLight. Выставляем для него свойство LightType в значение ltPoint и помещаем внутрь Солнца (Sphere1) перетягивая в окне Structure. А теперь попробуем посмотреть на то, что у нас получилось с разных сторон. Сейчас мы пользовались камерой по умолчанию – свойство формы use design camera выставлено в true. Для того чтобы иметь возможность рассмотреть изображение с разных сторон добавим еще несколько камер и сделаем переключение между ними. Здесь мы столкнемся с проблемой – отсутствие у формы в инспекторе объектов привычных обработчиков событий мыши и нажатий клавиш. Ок. Идем смотреть исхдники формы и находим обработчики запрятанными в классе предке TCommonCustomForm. Они объявлены как virtual, поэтому мы можем их переопределить и сделать управление приложением с клавиатуры и мыши как в VCL. Я не знаю почему в Embarcadero не опубликовали обработку этих событий, но переопределенные события корректно обрабатываются как в Win 32, так и в Win64. На Mac OS возможности проверить работу у меня, к сожалению, нет. Далее, меняя положение камеры, мы можем создать иллюзию подлета к Земле из космоса. Для этого переопределим события обработчика колесика мыши, в которых будем изменять координату Z текущей камеры. Координаты дефолтной камеры изменять нельзя. Мы должны получить следующие обработчики событий:

end; 37:if Form1.Camera <> nil then Form1.Camera.Position.X := Form1.Camera.Position.X - 1; 38:if Form1.Camera <> nil then Form1.Camera.Position.Y := Form1.Camera.Position.Y + 1; 39:if Form1.Camera <> nil then Form1.Camera.Position.X := Form1.Camera.Position.X + 1; 40:if Form1.Camera <> nil then Form1.Camera.Position.Y := Form1.Camera.Position.Y - 1; end; end; procedure TForm1.MouseWheel(Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean); begin if Form1.Camera <> nil then if WheelDelta > 0 then Form1.Camera.Position.Z := Form1.Camera.Position.Z + 1 else Form1.Camera.Position.Z := Form1.Camera.Position.Z - 1; end;

Для переключения камер используются клавиши 0, 1, 2. Для изменения положения текущей камеры по осям X и Y – клавиши управления курсором. По оси Z – колесико мыши. К сожалению, платформа еще очень сырая и недоработана. Даже, после установки Update 3, если просто накидать на форму компонентов, без единой строчки кода, в run-time возможны падения с различными ошибками, в том числе и division by zero. Нет очевидного способа создания компонентов реализующих такие объекты как тор, полусфера, додекаэдр и т.д. Документация зачастую включает в себя только сигнатуры методов, поэтому приходится в основном изучать исходники. В интернете информации еще очень мало. Хромает скорость и плавность отрисовки окон. Но библиотека обеспечивает очень низкий порог вхождения в разработку 3D приложений, так что хочется пожелать ей удачной и долгой жизни.

procedure TForm1.KeyDown(var Key: Word; var KeyChar: System.WideChar; Shift: TShiftState); begin inherited; case Key of 48:Form1.UsingDesignCamera := true; 49:begin Form1.UsingDesignCamera := false; Form1.Camera := Self.Camera1; end; 50:begin Form1.UsingDesignCamera := false; Form1.Camera := Self.Camera2;

Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

„25” К оглавлению

www.procoder.info


«Гаджеты в Windows. Взгляд со стороны»

Виталий Крячко lord_ru @ mail.ru

{

Например, гаджет погоды отображает информацию о погодных условиях, а гаджет записки обеспечивает простейший функционал для создания ежедневных записей. Гаджеты обычно имеют привлекательный вид и выполняют одну конкретную задачу. Чаще всего они располагаются на боковой панели Windows (Sidebar), справа рабочего стола. Гаджеты не плохо работают и в Windows XP, надо только скачать и установить файл Windows Sidebar.exe.

Всю эту информацию я почерпнул из Интернета, и там же взял первые уроки по созданию этих приложений. Но постоянные эксперименты занимали много времени на рутину по подготовке, а инструмента, который каким либо образом облегчил и ускорил создание гаджетов, я не нашел. В итоге я решил посвятить этому ближайшие выходные и вот что получилось. Теоретически простейший гаджет состоит из 2-х файлов: 1.html файл (gadget.html) – в этом файле описан внешний вид гаджета и его функциональность. 2.xml файл (gadget.xml) – конфигурационный файл или еще его называют файл манифеста, который включает в себя всю информацию о гаджете и его настройках. Практически еще нужны файлы ресурсов, различные изображения - файл иконки, файл фона и т.п. Далее все эти файлы собираются в одну папку и ей дается имя NameGadget.Gadget Эту папку можно поместить в специальную папку на системном диске С:\Program Files\Windows Sidebar\ если гаджет для общего пользования или C:\Users\User\AppData\Local\Microsoft\Windows Sidebar\Gadgets\ для конкретного пользователя. Все – при выборе нового гаджета он автоматически появится в списке гаджетов. Но существует установщик ( дистрибутив) гаджетов, запустив который Windows автоматически установит и запустит гаджет – это ZIP архив этой самой папки NameGadget.Gadget с именем ( внимание!) NameGadget.Gadget. Да именно так, и папка и архив – установщик имеют одно имя. И это серьезное препятствие – их невозможно хранить в одном месте, возникает конфликт имен. Теперь к практике!

Переходим к практике... Я набросал простенькую программу, которая делает всю черновую работу. Вам остается только творческий процесс – написать код HTML со скриптами или без, как умеете. Что приятно – скрипты можно писать как на Java ( js) , так и на Basic ( vbs), работает и то и другое одинаково.Вся работа разбита на два действия. На первом экране мы заполняем форму из которой в последствии будет сгенерирован xml файл (gadget.xml) – конфигурационный файл и простой html файл (gadget.html). Манифест мы больше не увидим, а по этому заполняем все пункты со звездочками тщательно. Название программы пишем на латинице, имена и копирайты можно на кириллице – все будет преобразовано в utf-8, так надо по стандарту. Я писал гаджет, который при помощи Google осуществляет поиск по форуму ПРОфорум.Изображения для общего фона и иконки скопированы прямо с главной страницы. ( все ресурсы прилагаются к программе). Вот изображение первого экрана на финальной стадии выбора цвета текста.( в этом гаджете цвет текста не пригодился, и он не является обязательным элементом).

„26” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Гаджеты в Windows. Взгляд со стороны»

После того, как все поля заполнены жмем кнопку «Продолжить» и переходим на следующий экран. Это редактор HTML c простейшими функциями. В редакторе уже есть элементарный код и мы запускаем его на выполнение кнопкой «Просмотр», дабы убедиться, что все идет правильно:

Все нормально, в принципе гаджет уже готов и если сейчас нажать кнопку «Закончить», то будет создан вполне рабочий экземпляр, правда без функциональности. Приступаем к написанию функционального кода. Код можно писать прямо тут, можно скопировать из более продвинутого редактора – как угодно. Главное, чтобы он был рабочим. Для нашего кода не хватает еще одного рисунка – иконки поиска ( увеличительное стекло, лупа). Нажимаем «Добавить ресурсы», выбираем, убеждаемся, что он там есть и вставляем в нужное место в коде. Я не очень крутой программист HTML, большую часть кода списал, вот что у меня получилось:

width: 70px; height: 20px; } body { background-color: #666666; } .searchBox { background-color: #FFFFFF; border: 1px solid #cccccc; } --> </style> </head> <script> function clickClass(id) { id.className = "boxHover"; } function googsh() { var url = "http://www.google.ru/search?q=site%3Ahttp%3A%2F%2Fforum. procoder.info%2F + "+ document.getElementById("srchBox").value; alert(url); window.open(url,"youGadget"); } </script> </head> <body> <img src="images/favicon1.png" width="16" height="16" align="left" />  <input name="srchBox" type="text" class="searchBox" id="srchBox" onclick="clickClass(this)" /> <input name="srchBtn" type="submit" class="searchBtn" id="srchBtn" value="Go" onclick="googsh()" /> </body> </html>

Запускаем на выполнение, убеждаемся, что все работает как надо:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" <html > <head> <title>Search Document</title> <style type="text/css"> <!-body { height: 91px; width: 322px; background-image: url(images/bg.png); background-repeat: no-repeat; padding-top: 50px; padding-left: 50px; .searchBox { background-color: #FFFFFF; border: 1px solid #cccccc; } .searchBtn { background-color: #FFFFFF; border: 1px solid #333333;

Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

„27” К оглавлению

www.procoder.info


«Гаджеты в Windows. Взгляд со стороны»

Заключительный этап – нажимаем кнопку «Закончить». Программа создает папку ProForumSearsh.Gadget в текущей папке и запрашивает папку, куда поместить дистрибутив нашего гаджета ( мы помним, что в папку с программой его поместить не получится!). После удачного размещения мы можем просто запустить дистрибутив на выполнение, и наш гаджет окажется на рабочем столе!

Ресурсы http://ru.wikipedia.org/wiki/ Анаглиф џПоляков А.Ю. Третье измерение фотографии. Часть 1, 2 http://3dmasterkit.ru/articles/article_1 џВикипедия. Анаглиф

Ну вот и все! Ресурсы этого гаджета в комплекте с программой в папке sourse + еще один исходник для запуска блокнота.

С уважением Виталий Крячко ( kvitaliy)

„28” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Управление программой (устройствами) через браузер»

Сергей Бадло http://raxp.radioliga.com

{

Доброго времени суток, маньяки компьютерной индустрии. Сегодня вы узнаете не только как управлять своей программой через браузер, но и как управлять устройствами через сеть Интернет. Для повторения материала потребуются базовые знания электроники и сетей.

Итак, все делаем на основе WEB-сервера из статьи [1]. Поэтому за подробностями принципа работы сервера и отработки им команд, идем туда и читаем внимательно или... вкуриваем :). Сам гаджет USB.HID термометра был разработан с целью измерить температуру, получить команды с пульта, помигать парой выходов (светодиодов) и на этом казалось бы все (см. рисунок 1):

Рис. 2. Схема электрическая принципиальная модификации Дабы не терять времени зазря, паяльник "извлечен из ножен" и на макетнице, частично навесным монтажом, был собран гаджет (см. рисунок 3):

Рис. 1. Сердце разработки. USB.HID термометр

Конечно, в продолжении цикла были добавлены – голосовая озвучка данных, автопостинг в Twitter, трансляция показаний на сайт, предсказание заморозков и прочие "вкусности". Однако, хотелось и иметь возможность поуправлять как минимум еще восемью дискретными выходами (приводами той же WEB-камеры и прочими мелочами), а в реализованном железе уже не хватало свободных портов, да и сам конструктив висит за окном и несет "боевое дежурство". Поэтому было решено собрать новый девайс, благо ATMeg-и в запасе, и как нельзя кстати, подвернулся под руку материал Петра Высочанского с его uniUSB эмуляцией на ATMega8 (Радио, 2011, №2, с.26). Сама схема была модифицирована в виде "хотелки" (см. рисунок 2):

Рис. 3. Макетная плата гаджета

„29” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Управление программой (устройствами) через браузер»

Так как схема простейшая, плату не разрабатывал, распаяно за пару часов. Особенности прошивки Фьюзы в среде CVAVR следующие* (см. рисунок

При этом, код управления битами простейший: function SetBit(AWord: longword; ABit: byte; AState: boolean = true): longword; begin if AState then Result:= AWord or (1 shl ABit) else Result:= AWord and (not (1 shl ABit)) end; procedure Tform1.set_leds_; var written: cardinal; begin if dout = nil then exit; leds:= SetBit(leds,0,CheckBox1.Checked); leds:= SetBit(leds,1,CheckBox2.Checked); leds:= SetBit(leds,2,CheckBox3.Checked); leds:= SetBit(leds,3,CheckBox4.Checked); leds:= SetBit(leds,4,CheckBox5.Checked); leds:= SetBit(leds,5,CheckBox6.Checked); leds:= SetBit(leds,6,CheckBox7.Checked); leds:= SetBit(leds,7,CheckBox8.Checked); fillchar(Raw,length(RAW),0); Raw[0]:= $0; // ReportID Raw[1]:= LEDs; // any data ... dout.WriteFile(raw, 2, Written); end;

Компилируем, проверяем работоспособность uniUSB. Ок? Теперь вернемся к нашему WEB-серверу. Точнее второму, первый сервер оставим на 500-м порту и пусть он отрабатывает запросы к термометру. Второй повесим на 501-й порт. Почему собственно решил отделить "погоду" от "управления"? По причине разного подхода к формированию HTMLстраниц: для погоды – страничка самообновляется, а для управления это не нужно (обновление только после передачи управляющих сигналов) ...хотя, конечно можно и фреймами или на AJAX, но решил не заморачиваться (реализуем просто двухпоточный сервер). Поскольку на шине будет висеть уже два USB-девайса, для их различения добавим селекцию по VID и PID:

Рис. 4. Установка фьюз в среде CodeVision-AVR В известной PonyProg будут аналогичные, SPIEN поумолчанию всегда включен / Комментарий автора.

В качестве программатора может быть использован USB программатор AVR910М или программатор "5-проводков", или любой другой под AVR. Для тестов сваяем тестовую утилитку управления с удержанием и автосбросом битов (см. рисунок 5, исходники в ресурсах к журналу):

function hidc.hidEnumerate(HidDev: TJvHidDevice; const Idx: Integer): Boolean; begin // это термометр if (HidDev.Attributes.VendorID = $0) and (HidDev.Attributes.ProductID = $3) then begin status1:= 'датчик активен'; Dev:= HidDev; Dev.CheckOut end; // это управление дискретными выходами if (HidDev.Attributes.VendorID = $0207) and (HidDev.Attributes.ProductID = $2010) then begin status2:= 'uniUSB активен'; dout:= HidDev; dout.CheckOut end; Result:= True end;

Рис. 5. Тестовая утилита

Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

„30” К оглавлению

www.procoder.info


«Управление программой (устройствами) через браузер»

Управление матрицей состояний и сигналов реализовано следующим образом (в комментариях не нуждается): var Dev, dout: TJvHidDevice; // объекты HID устройств Raw: array[0..128] of byte; // массив репорта LEDs : Byte; // параметр зажигания tick : integer; // глобальный счетчик на секунду check : array[0..1, 0..7] of boolean; // массив управления en_reset : boolean; // флаг разрешения сброса порта // УПРАВЛЕНИЕ ---------------------------------------------------------------function SetBit(AWord: word; ABit: byte; AState: boolean = true): word; begin if AState then Result:= AWord or (1 shl ABit) else Result:= AWord and (not (1 shl ABit)) end; procedure set_leds_; var written: cardinal; begin if dout = nil then exit; // считываем матрицу сигналов и // устанавливаем нужный бит в порт // дискретных выходов leds:= SetBit(leds, 0, check[0, 0]); leds:= SetBit(leds, 1, check[0, 1]); leds:= SetBit(leds, 2, check[0, 2]); leds:= SetBit(leds, 3, check[0, 3]); leds:= SetBit(leds, 4, check[0, 4]); leds:= SetBit(leds, 5, check[0, 5]); leds:= SetBit(leds, 6, check[0, 6]); leds:= SetBit(leds, 7, check[0, 7]); fillchar(Raw,length(RAW),0); Raw[0]:= $0; //ReportID Raw[1]:= LEDs; //any data ... dout.WriteFile(raw, 2, Written); end; procedure set_leds; begin set_leds_; // запускаем сброс порта в таймере en_reset:= true end; //--procedure Ontmr2(uTimerID, uMessage: uint;dwUser, dw1, dw2: dword) stdcall; var tp: integer; s : string; begin // таймер на 100 мс// управление сбросом порта if en_reset then begin // проверяем матрицу управляющих сигналов и // устанавливаем состояние матрицы сигналов if not check[1, 0] then check[0, 0]:= false; if not check[1, 1] then check[0, 1]:= false; if not check[1, 2] then check[0, 2]:= false; if not check[1, 3] then check[0, 3]:= false; if not check[1, 4] then check[0, 4]:= false;

if not check[1, 5] then check[0, 5]:= false; if not check[1, 6] then check[0, 6]:= false; if not check[1, 7] then check[0, 7]:= false; // set_leds_; en_reset:= false end; ... ... end;

Получение контента сервером, выборка, селекция управляющих сигналов и формирование клиентской странички реализуем на основе сокетов (обертка TClientSocket): procedure html3(s, ms:string; Socket:TCustomWinSocket); function getcheck(stolb, stroka: integer; par: boolean): string; begin result:=''; // if ((par)and(not check[stolb,stroka]))or ((not par)and(check[stolb,stroka])) then result:= ' checked' end; var temp: string; ens : boolean; i : integer; begin // проверяем есть ли смысл работать с матрицей if pos('h=',s)>0 then ens:= true; if (ens) then begin // сканируем запросы на предмет наличия // ch0=1&ch1=0&ch2=0&ch3=0&ch4=0&ch5=0&ch6=0&ch7=0&sh 1=1&sh2=1&sh0=0&sh3=0&sh4=0&sh5=0&sh6=0&sh7=0 for i := 0 to 7 do begin if pos('ch'+inttostr(i)+'=1',s)>0 then check[0,i]:= true; if pos('ch'+inttostr(i)+'=0',s)>0 then check[0,i]:= false; if pos('sh'+inttostr(i)+'=1',s)>0 then check[1,i]:= true; if pos('sh'+inttostr(i)+'=0',s)>0 then check[1,i]:= false; end; set_leds end; // контент try if pos('mode=1',s)>0 then p:= false; if pos('mode=2',s)>0 then p:= true; if (p) then temp:= format('%.1f',[gl_temp*1.8 + 32]) // °F else temp:= format('%.1d',[gl_temp]); // °C Socket.SendText('HTTP/1.0 200 OK'+#$0D+#$0A); Socket.SendText('Server: USB-TERM'+#$0A); Socket.SendText(#$0D+#$0A); //формирование Socket.SendText('<html><head><title>USB-термометр | Украина, г.Запорожье, пески (р-н маг.Сильпо)</title>' + '<STYLE TYPE="text/css"><!--BODY {backgroundcolor: black; font-family: Verdana; color: white;'+ ' font-size: 9px} --> </STYLE>' + '<style>a{color:#668791;text-decoration: none; font:10px verdana} a:hover {color:lime}</style>' + '<meta http-equiv="Content-Type" content="text/html;

„31” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Управление программой (устройствами) через браузер»

'<meta http-equiv="Content-Type" content="text/html; Charset=windows-1251">' + '<META HTTP-EQUIV="Refresh" CONTENT="9;URL=">' + '<script type="text/javascript">function toggleview(itm) {var itmx = document.getElementById(itm);'+ 'if (itmx.style.display == "none"){itmx.style.display = "block";} else {itmx.style.display = "none";}}</script>' + '</head><body>' + '<b>Показания термометра USB:</b>' + status +'<h1>' + temp + '°</h1>'+ '<b href="#" onclick="toggleview(''q1'')">' + get_moroz + '</b>'+ '<div id=''q1'' style="display:none"><hr width=145 align=left><table border=0 width=145><tr><td>'+ '<font size=1>Методика основана на эмпирических таблицах профессора Броунова.'+ ' Измерение производится в 13 и 21 час дня.</font></td></tr></table></div>' + '<hr width=145 align=left><FORM ACTION="">'); if (p) then Socket.SendText('<input type="radio" name="mode" value="1"> цельсия' + '<input type="radio" name="mode" value="2" checked> фаренгейта') else Socket.SendText('<input type="radio" name="mode" value="1" checked> цельсия' + '<input type="radio" name="mode" value="2"> фаренгейта'); Socket.SendText('<P><INPUT TYPE=SUBMIT VALUE="применить настройки"></FORM>' + '<p>' + formatdatetime('hh:nn:ss',time) + '<a href=http://raxp.radioliga.com>Разработка АСУТП © 2011</a></p>' + '<DIV style="position:absolute;left:180px;top:8px;"><b> Управле ние'+ ' положением WEB- камеры:</b> <img src="" width=220 height=55 border=1>'+ '</img><FORM ACTION="">' + // нужно вывести чекнутый radiobutton в зависимости от check[0,i] '<input type="radio" name="ch0" value="1"' + getcheck(0,0, false) + '>0' + '<input type="radio" name="ch1" value="1"' + getcheck(0,1, false) + '>1' + '<input type="radio" name="ch2" value="1"' + getcheck(0,2, false) + '>2' + '<input type="radio" name="ch3" value="1"' + getcheck(0,3, false) + '>3' + '<input type="radio" name="ch4" value="1"' + getcheck(0,4, false) + '>4' + '<input type="radio" name="ch5" value="1"' + getcheck(0,5, false) + '>5' + '<input type="radio" name="ch6" value="1"' + getcheck(0,6, false) + '>6' + '<input type="radio" name="ch7" value="1"' + getcheck(0,7, false) + '>7' + '<input type="radio" name="ch0" value="0"' + getcheck(0,0, true) + '>0' + '<input type="radio" name="ch1" value="0"' + getcheck(0,1, true) + '>0' + '<input type="radio" name="ch2" value="0"' + getcheck(0,2, true) + '>0' + '<input type="radio" name="ch3" value="0"' + getcheck(0,3, true) + '>0' +

Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

'<input type="radio" name="ch4" value="0"' + getcheck(0,4, true) + '>0' + '<input type="radio" name="ch5" value="0"' + getcheck(0,5, true) + '>0' + '<input type="radio" name="ch6" value="0"' + getcheck(0,6, true) + '>0' + '<input type="radio" name="ch7" value="0"' + getcheck(0,7, true) + '>0' + ' удерживать состояние:' + // нужно вывести чекнутый radiobutton в зависимости от check[1,i] '<input type="radio" name="sh0" value="1"' + getcheck(1,0, false) + '>0' + '<input type="radio" name="sh1" value="1"' + getcheck(1,1, false) + '>1' + '<input type="radio" name="sh2" value="1"' + getcheck(1,2, false) + '>2' + '<input type="radio" name="sh3" value="1"' + getcheck(1,3, false) + '>3' + '<input type="radio" name="sh4" value="1"' + getcheck(1,4, false) + '>4' + '<input type="radio" name="sh5" value="1"' + getcheck(1,5, false) + '>5' + '<input type="radio" name="sh6" value="1"' + getcheck(1,6, false) + '>6' + '<input type="radio" name="sh7" value="1"' + getcheck(1,7, false) + '>7' + '<input type="radio" name="sh0" value="0"' + getcheck(1,0, true) + '>0' + '<input type="radio" name="sh1" value="0"' + getcheck(1,1, true) + '>0' + '<input type="radio" name="sh2" value="0"' + getcheck(1,2, true) + '>0' + '<input type="radio" name="sh3" value="0"' + getcheck(1,3, true) + '>0' + '<input type="radio" name="sh4" value="0"' + getcheck(1,4, true) + '>0' + '<input type="radio" name="sh5" value="0"' + getcheck(1,5, true) + '>0' + '<input type="radio" name="sh6" value="0"' + getcheck(1,6, true) + '>0' + '<input type="radio" name="sh7" value="0"' + getcheck(1,7, true) + '>0' + ' <INPUT TYPE=SUBMIT VALUE="установить данные в S- матрице">'+ '</FORM></div>' + '</body></html>'); socket.Close; except end end; procedure hidc.srv_read(Sender: TObject; Socket: TCustomWinSocket); var s: string; begin s:= Socket.ReceiveText; html3(s, '500', Socket) end;

„32” К оглавлению

www.procoder.info


«Управление программой (устройствами) через браузер»

Компилируем по F9 и тестируем сервер, а также управление выходами uniUSB через браузеры (см. рисунок 6 и 7):

Рис. 7. Тест в браузере Opera

Рис. 6. Тест в браузере FireFox

„33” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Управление программой (устройствами) через браузер»

В качестве движков удалось наковырять с CD-ROM низковольтные RF-300-CA-09550 c рабочим напряжением от 1 до 6 В (см. рисунок 8):

Рис. 8 Характеристики движков RF-300CA По табличке, ток казалось-бы и небольшой, до 60 мА. Однако, экспериментальным путем протестировал, что движки RF-300CA-09550 без нагрузки тянут 9.6 мА, под нагрузкой менее 22 мА при запитке 5-ю вольтами, что укладывается в паспортные данные и позволяет "подрубить" питание драйвера к USB-порту, при двух движках. Еще попался FF-0505SK-09250 c механизма позиционирования блока лазера, у него ток на ХХ поболе, менее 23мА, а под нагрузкой до 30 мА. Впрочем, что тоже приемлемо. При желании, для управления движками ничего нового выдумывать не стоит – ведь имеется стандартный драйвер L293D. Логика его работы следующая (см. рисунок 9):

Описание API библиотеки HIDOUT.dll Для упрощения работы с USB.HID гаджетом из своих проектов вне зависимости от языка была создана универ-

сальная библиотека, далее DLL. Вы можете работать через нее хоть из EXCEL. Вы спросите: «...а за счет чего достигается универсальность применения DLL и почему DLL?». Обычно, если заранее неизвестно какой язык программирования будет использовать предполагаемый пользователь, будь то разработчик или программист, то реализуют механизм взаимодействия (называемый API разработчика) с предыдущей разработкой на основе: сообщений, файлами, сокетами-заглушками (через сеть), в виде библиотеки (DLL**) или в виде COM объекта (тот же ActiveX). Разумеется, если языки программирования совпадают, то конечному разработчику останется лишь скорректировать сам исходный проект. Мы будем реализовывать механизм взаимодействия через DLL, как самый универсальный и предоставим API для этого обмена. Принцип такой же как у разработчиков таких популярных приложений как WinAMP, VLC, Skype, Beholder и т.п. Они реализуют свой продукт и предоставляют доступ к нему через свое API, а уже сторонние разработчики каждый на своем языке получают универсальный доступ к этому API, согласно правилам своего языка, без привязки к языку разработчика, будь то Си, С# [2], Delphi или VBA. По сути, система плагинов. Вот так просто.

** DLL (dynamic-link library) – динамическая библиотека, позволяющая многократное использование различными программными приложениями. K DLL относятся также элементы управления ActiveX и драйверы. В мире UNIX аналогичные функции выполняют так называемые общие объекты (англ. shared objects). Рис. 9 Логика работы драйвера L293

„34” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Управление программой (устройствами) через браузер»

Данная DLL, для работы с USB.HID (VID=$0207, PID=$2010) через SetupAPI [3] в ОС NT/2000/2003/XP, предоставляет универсальный доступ для других приложений вне зависимости от языка в среде Win32. Для использования DLL в своих проектах соблюдайте соглашение об stdcall-вызовах. Тип соглашения о вызове объявляется после прототипа функции, будь то объявление функционального типа или же объявление функции. Каждый бит входного параметра экспортируемой функции setleds() (библиотеки HIDOUT.DLL) размерностью byte отвечает за управление состоянием пинов МК (см. таблицу):

setleds:= LinkProc('setleds'); end; { пример вызова } begin setleds(leds) ...

Порядок использования следующий: // допустим нужно зажечь нулевой бит (установить в "1"), что соответствует порту PB0 (выв.14 МК) // тогда пользуемся функцией SetBit() и передадим значение байта в функцию setleds() leds:= SetBit(leds, 0, true) setleds(leds) ...

// допустим нужно погасить нулевой бит (установить в "0"), что соответствует порту PB0 (выв.14 МК) // тогда пользуемся функцией SetBit() и передадим значение байта в функцию setleds() leds:= SetBit(leds, 0, false) setleds(leds) ...

// допустим нужно зажечь первый бит (установить в "1"), что соответствует порту PB1 (выв.15 МК) // тогда пользуемся функцией SetBit() и передадим значение байта в функцию setleds() leds:= SetBit(leds, 1, true) setleds(leds) ...

// допустим нужно погасить первый бит (установить в "0"), что соответствует порту PB1 (выв.15 МК) // тогда пользуемся функцией SetBit() и передадим значение байта в функцию setleds() leds:= SetBit(leds, 1, false) setleds(leds) ...

Таблица. Распиновка портов гаджета

Рассмотрим пример динамического подключения в среде Delphi 6/7/2006/2009/2010/TDL: var leds: byte; // значение байта данных на МК setleds:function(leds: byte):pchar; stdcall; LibHandle: THandle; { установка любого бита в байте } function SetBit(AWord: longword; ABit: byte; AState: boolean = true): longword; begin if AState then Result:= AWord or (1 shl ABit) else Result:= AWord and (not (1 shl ABit)) end; function LinkProc(ProcName: string):Pointer; begin try result:= GetProcAddress(LibHandle,PChar(ProcName)); Win32Check(Assigned(Result)) except end end; { инициализация } begin LibHandle:= LoadLibrary('hidout.dll'); Win32Check(LibHandle<>0);

Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

// допустим нужно зажечь седьмой бит (установить в "1"), что соответствует порту PС1 (выв.24 МК) // тогда пользуемся функцией SetBit() и передадим значение байта в функцию setleds() leds:= SetBit(leds, 7, true) setleds(leds) ...

// допустим нужно погасить седьмой бит (установить в "0"), что соответствует порту PС1 (выв.24 МК) // тогда пользуемся функцией SetBit() и передадим значение байта в функцию setleds() leds:= SetBit(leds, 7, false) setleds(leds) ...

// допустим нужно зажечь одновременно нулевой и первый бит (установить в "1"), // что соответствует порту PB0, PB1 (выв.14, 15 МК) // тогда пользуемся функцией SetBit() и передадим значение байта в функцию setleds() leds:= SetBit(leds, 0, true) leds:= SetBit(leds, 1, true) setleds(leds) ...

// допустим нужно погасить одновременно нулевой и первый бит (установить в "0"), // что соответствует порту PB0, PB1 (выв.14, 15 МК) // тогда пользуемся функцией SetBit() и передадим значение байта в функцию setleds() leds:= SetBit(leds, 0, false) leds:= SetBit(leds, 1, false) setleds(leds)

„35” К оглавлению

www.procoder.info


«Управление программой (устройствами) через браузер»

Ресурсы

Ниже показан пример вызова под С:

џ Е.Бадло. С.Бадло. USB термометр и дистанци-

function TestDLL() { // определяем новый тип DLL setledsdll = DLL.DefineDLL("MyDLL");

онка в одном флаконе. Часть 4. Интерактивный WEB сервер. – Радиолюбитель, Минск, 2010, №2, с.52-56 џ Marshaling Delegates as Function Pointers http://msdn.microsoft.com/enus/library/ms172513.aspx џ Setup API (Windows) http://msdn.microsoft.com/enus/library/cc185682(v=vs.85).aspx

// описываем вызываемую функцию // последний параметр - возвращаемое значение, должен быть указан обязательно proc = setledsdll.DefineProc("setleds", *char); // загружаем DLL в память, связывая имя DLL-файла с созданным ранее типом DLL lib = DLL.Load("hidout.dll", "MyDLL");

Удачи!

// вызываем функцию lib.setleds(byte leds); }

Ниже показан пример вызова под С#: using System.Runtime.InteropServices; ... unsafe static class hidout { [DllImport("hidout.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.char)] static extern char setleds ( [In] byte leds ); public static int setleds_ ( byte leds ) { setleds(leds); return 0; } } { пример вызова } hidout.setleds_(byte leds);

Видео работы гаджета и исходники тестового WEBсервера управления вы найдете в ресурсах к 18 выпуску нашего журнала. По всем вопросам обращайтесь на ящик редакции: reddatacentr @ gmail . com

„36” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


«Конкурс статей. Лучшая статья 2012» Требования к материалам:

Уважаемые читатели и авторы. Журнал «ПРОграммист» объявляет конкурс на лучшую статью 2012 года. В конкурсе участвуют все присланные на адрес reddatacentr @ gmail . com, опубликованные журнале и размещенные на сайте http://procoder.info статьи за 2012 год. Конкурс начинается 30 мая и заканчивается 1 декабря 2012 г. Присланная вами статья не должна ранее где-либо публиковаться и должна быть авторской. Темы статей: теоретические и/или практические статьи, обучающие материалы, описание какихлибо новых современных технологий и практических решений с их применением на стыке программирования и любой другой области человеческой деятельности, будь то автоматизация производства, биология, медицина и электроника, астрономия или химия и т.д..

џстатья должна иметь четко выраженную

структуру и содержать название статьи, сведения об авторах, экскурс, информацию о средствах разработки, теоретическую и/или практическую часть, заключение и ресурсы к статье; џтекст статьи в формате OpenOffice, MS Word, VK WordPad или обычным текстовым файлом, шрифт Arial; џвсе рисунки, таблицы должны быть подписаны и иметь упоминание в тексте статьи; џрисунки к статье должны прилагаться в виде отдельных файлов в формате PNG; џразделы статьи отделять двумя <ENTER>. По присланным материалам автор получает рецензию и корректирует статью согласно замечаниям. Текущий список статей-участников можно посмотреть на сайте журнала.

Выбор победителя: победитель будет выбираться при помощи жюри. Будут оцениваться такие факторы статьи как: актуальность, техническая грамотность, полнота изложения материала, оформление и объем материала. Допускается от одного автора несколько статей или цикл статей, в этом случае шансы на победу увеличиваются.

Приз-первое место: StarterKit плата USB V850ES/Jx3 от RENESAS c датчиком влажности и температуры на борту.

Приз-второе место: 1000 рублей на счет мобильного или по системе Web-Money.

„37” Издание некоммерческое. Формат А4. Тираж неограничен. Перепечатка материалов журнала с разрешения редакции.

К оглавлению

www.procoder.info


Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.