Ну, вот и свершился час релиза очередного выпуска электронного журнала VR-Online. На его создание ушло практически 2 месяца. Что мы так долго делали? Ответ предельно прост - верстали и собирали материал. Причем на верстку и сведение ушло рекордное количество времени. По факту целый месяц. Т.е. номер был практически готов к концу сентября (за исключением нескольких статей), а вот верстка затянулась на весь октябрь. Причина этому - моя сильная занятость, которая в последнее время чересчур увеличилась. Времени элементарно не хватает на форум и подкаст. Надеюсь, все образуется и войдет в привычное русло, а пока приходиться крутиться как белка в колесе. Ладно, поплакался и хватит. Теперь несколько слов о новом номере. Это номер мы постарались сделать интересней, чем предыдущий. Статей по программированию реально больше и надеюсь, они тебе понравятся. Другой изюминкой этого выпуска является интервью с Dr.Bob. Ты наверняка в курсе кто это такой. Побеседовать с доком реально у нас не было возможности, поэтому мы отыскали один забугорный журнал и перевели опубликованное в нем интервью. Оно получилось небольшим, но достаточно интересным. В будущем мы обязательно попробуем повторить этот трюк и забабахать перевод еще какого-нибудь интервью. Главное, чтобы тебе понравилось начало. Приятного чтения! P.S. Выражаю огромную благодарность всем тем, кто подготовил статьи и графику (Редькин Дмитрий, Soffrick, Magistral) для этого номера. Без вашего неоценимого вклада журнала бы однозначно не было. Еще раз спасибо! Игорь Антонов
Над номером работали: Редактор: Игорь Антонов Графика: Soffrick (Рубрикаторы, кроме Psycho), Дмитрий Редькин (Обложка), Magistral (Рубрикатор «Психо») Верстка: Игорь Антонов Состав VR-Team: Fritooll, Egoiste, Lord_of_fear, Soffrick, Gensei (aka KeyWarez), Spider_NET
НОВОСТИ IT
Начались продажи Windows 7 Новейшая версия ОС Microsoft Windows 7 официально запущена в продажу. От ее успеха будет зависеть будущее крупнейшего в мире производителя программного обеспечения. Критики уже, который год предрекают конец монополии Microsoft. Однако, на основе Windows работает 90% всех компьютеров в мире. По подсчетам самой компании, этой операционной системой пользуется более миллиарда человек. Microsoft рассчитывает, что успех новой версии поможет преодолеть последствия неудачи с предыдущей - Vista.
Ubuntu 9.10 final stable release Хорошие новости для убунтологов. Один день (прим. редактора – уже вышла!) остался до выхода Ubuntu 9.10 Karmic Koala. Релиз построен на базе GNOME 2.28 с включенной в него службой Instant Messenger для Linux - Empathy. Среди особенностей релиза разработчики отмечают уменьшение времени загрузки ОС, сервис доступа к файлам Ubuntu One, использование GRUB 2, и другие особенности. Тестеры, поработавшие с предварительными модификациями платформы, отмечают, что при определенных условиях и наличии в компьютере твердотельного диска на основе флеш-памяти загрузка операционной системы занимает около пяти секунд. Антивирус от Microsoft обновляется через раз Выпущенный недавно компанией Microsoft антивирус Security Essentials (MSE) в ряде случаев на протяжении нескольких дней не загружает последние обновления антивирусных баз, несмотря на то, что они уже имеются на сервере обновлений. Этот срок может длиться аж до недели. Пронаблюдать такое можно, к примеру, если регулярно переводить ноутбук в спящий режим, закрывая его крышку. После возобновления работы и часового нахождения в сети антивирус по-прежнему уверяет пользователя, что все
необходимые сигнатуры установлены, и что пользователь ПК находится под защитой. Тесты показывают, что антивирусное ПО с базами двухнедельной давности выявляет лишь от 30 до 50 процентов новых угроз. Когда специалисты AV-Test.org попробовали запустить 20 образцов вредоносных программ, для которых у MSE не имелось сигнатур, антивирус не поднял тревогу ни разу, позволив всем 20 вирусам заразить систему. Подходите с большой серьёзностью к выбору антивирусного ПО… или переходите на Linux. Правда, второй вариант ну никак не подходит для новичков.
Линус Торвальдс доволен выходом Windows 7 ? Windows 7, продажи, которой начались в конце прошлой недели, оказалась настолько классной операционной системой, что произвела впечатление даже на Линуса Торвальдса. Не исключено, что к такому мнению могут прийти линуксоиды, знающие Торвальдса в лицо, если им на глаза попадётся фотография, выложенная недавно на фотохостинге Picasa. Мнение это, конечно же, будет ошибочным. На снимке действительно запечатлён отецоснователь "Линукса", но он всего лишь прикалывается. В действительности в день начала продаж новой системы Microsoft в Японии как раз проходил симпозиум Linux. Рядом с местом проведения симпозиума оказался большой киоск по продаже Windows 7, и шутникилинуксоиды уболтали Торвальдса сняться на фоне многочисленных коробок с "семёркой". Продавец-японец наверняка остался в недоумении, когда после того как "вылетела птичка", этот довольный блондинистый варвар почему-то так и не купил ни одной из этих зелёненьких коробочек.
Новый стандарт для домашних сетей обеспечит скорость 1 Гбс Международный Телекоммуникационный Союз(ITU) ратифицировал свой новый стандарт G.hn. ITU рассчитывают, что новый стандарт окажет большое влияние на новые технологии, вроде, телемедицины. Если обратиться к технической составляющей, то G.hnсовместимые устройства будут способны обрабатывать медиа-контент на скорости до 1 Гбс. При этом будет задействована комбинация из проводных и беспроводных технологий. Более того, стандарт способен работать с устройствами линии электропередач используя технологию IEEE P1901. В дальнейшем в G.hn ITU планируют добавить поддержку технологии
SmartGrid. Ожидается, что первые устройства поддерживающие стандарт G.hn станут доступны в начале следующего года.
Written by Костенко Роман aka lord of fear E-mail: lord_of_fear@list.ru
Железные НОВОСТИ
AMD начнёт поставлять 32 нм процессоры через год Последнее знакомство с планами AMD создавало впечатление о готовности компании начать поставки 32 нм процессоров не ранее 2011 года, включая и первые гибридные процессоры Llano со встроенным графическим ядром. Однако, квартальный отчёт AMD на этой неделе принёс новые откровения руководителей компании, которые заставляют нас пересмотреть прогнозы по срокам появления первых 32 нм процессоров AMD. Как сообщает сайт CNet со ссылкой на заявления Дирка Мейера, главы AMD, компания планирует начать поставки 32 нм гибридных процессоров во второй половине 2010 года. Господин Мейер не уточняет, однако, какой характер будут носить эти поставки. Известно, например, что Intel уже начала коммерческие поставки своих 32 нм процессоров, но в продаже они появятся только 3 января.
Сколько стоит освоить 22 нм техпроцесс? Если расходы на научно-исследовательские работы при освоении 90 нм и 65 нм техпроцесса измерялись суммами около $310-400 млн., то в случае с 45/32 нм техпроцессом суммы возрастают до $600-900 млн., а в случае с 22/12 нм техпроцессом достигают $1,3 млрд. Оснащение фабрики по производству полупроводниковых чипов обходится в следующие суммы: 90/65 нм -> $2,5 - 3,5 млрд.; 45/32 нм -> $3,5 - 4 млрд.; 22/12 нм -> $4,5 - 6 млрд. Соответственно, осваивать новые техпроцессы смогут позволить себе только очень крупные компании, располагающие достаточными бюджетами.
General Electric удалось создать терабайтные Blu-ray диски Компании General Electric удалось разработать технологию голографических дисков, которые смогут хранить терабайт данных, при этом, считать информацию можно будет с помощью несколько доработанного привода Blu-ray. Сам принцип записи на голографические диски технологически не так уж сложен. Луч лазера разделяется на два потока, один из которых становится "опорным", а второй "сигнальным", с помощью которого и происходит запись-считывание информации. Ранее, при записи на голографический диск, "страница" с данными имела
объём в 1 миллион бит, а в ходе экспериментов учёным из General Electric удалось установить, что "микространица" объёмом всего в 1 бит и созданные диски на основе таких страниц, при равной плотности записи, будут иметь скорость чтения значительно выше. Причём верхний слой данных можно считывать уже сейчас при мощи обычных Blu-ray приводов, а чтобы считать все слои, необходимы некоторые доработки данного устройства чтения. Скорость чтения голографических дисков примерно в 5 раз выше скорости DVD, а время доступа сокращено всего до 3 миллисекунд. Вывод на массовый рынок стоит ожидать через 2-3 года, к тому времени будут доступны и новые приводы.
Microsoft предложит владельцам нетбуков средство установки Windows 7 с USB-носителей Эра нетбуков породила многомиллионную армию мобильных компьютеров, которые лишены привода для чтения оптических дисков. Пользователям приходится рассчитывать либо на внешний оптический привод с интерфейсом USB, либо на флэшку или другой твёрдотельный носитель, а также варианты установки программного обеспечения по сети. Перед началом процедуры Microsoft рекомендует провести оценку аппаратной конфигурации нетбука с точки зрения совместимости с Windows 7 при помощи онлайнового сервиса, а также найти USB-накопитель с 4 Гб свободного места. Если учесть, что большинство нетбуков использует Windows XP, желающих самостоятельно перейти на Windows 7 среди их владельцев будет достаточно. Приятно, что Microsoft попыталась облегчить этот процесс.
Утверждён стандарт универсальных зарядных устройств для телефонов Разговоры о необходимости унификации зарядных устройств для мобильных телефонов ходили давно, но только на этой неделе Международный союз электросвязи, являющийся подразделением ООН, утвердил стандарт, описывающий универсальное зарядное устройство. По замыслу разработчиков, все мобильные телефоны в будущем смогут использовать одно и то же зарядное устройство. Универсальное зарядное устройство будет использовать разъём типа Micro-USB (на фото слева). Предложенный разработчиками стандарт не является обязательным к использованию, но некоторые производители мобильных телефонов уже согласились перейти на универсальные зарядные устройства. Компания Sony Ericsson
планирует начать оснащать ими свои телефоны с первой половины следующего года.
Written by Костенко Роман aka lord of fear E-mail: lord_of_fear@list.ru
VrIP Person
Интервью с Dr.Bob Сегодня у нас не совсем обычное интервью. Впервые на страницах нашего журнала заграничный гость – Dr. Bob. Кто такой Dr.Bob? Это известный (в кругах Delphiразработчиков) человек. Он написал огромное количество статей, факов, книг по практическому применению Delphi. Те, кто программируют на Delphi не первый год, уже наверняка натыкались на его труды. Мы решили, что тебе было бы интересно узнать мнение дока по некоторым около дельфячим вопросам, поэтому мы подобрали достаточно интересное интервью, которое он давал для одного западного журнала, а lord of fear любезно сделал перевод. Надеемся, интервью тебе понравится, приятного чтения!
Немного о Dr.Bob Боб Сворт (или Dr. Bob — www.drbob42.com) в настоящее время работает старшим научным консультантом по использованию Delphi, C++Builder и JBuilder (а также Kylix) в компании TAS Advanced Technologies (www.tas-at.com), Бест, Нидерланды (Best, The Netherlands). Боб также публикует свои статьи в журналах The Delphi Magazine, Delphi Developer, UK-BUG NewsLetter и SDGN Magazine. Он соавтор книг The Revolutionary Guide to Delphi 2, Delphi 4 Unleashed и C++Builder 4 Unleashed. Помимо писательской карьеры, Bob часто выступает на конференциях Embarcadero, которые проводятся по всему миру. Вопрос: Годами я сталкивался с большим количеством замечательных имен и ников, связанных с Вами. Например: Dr.Bob, eBob, eBob42, и так далее. С чем связано появление такого большего количества псевдонимов? Я уверен, это интересная история! Ответ: Когда я был ребенком, то точно я знал, что стану программистом. Почему? Дело в том, что мой отец был программистом. В 1983 году я начал обучение в Университете Амстердама. Двумя годами позже, я написал свою первую программу. Я продолжал обучаться в том же университете и параллельно работал с моим племянником Тако Баккером (Tako Bakker). В то время мы программировали на Turbo Pascal II. Кстати, я им пользуюсь до сих пор. Что касается статей, то я начал их писать в 1992 для журналов Blaise, DOS/Win Special и The Pascal Magazine (последние два журнала ныне не существуют). Нник 'Dr.Bob' произошел от названия моей статьи 'Dr.Bob on Bugs, Reports and Fixes', продолжение которой я сначала назвал 'Dr.Bob's Delphi Clinic' (в журнале The Delphi Magazine), а затем 'The Delphi Clinic'. В 1994, компания Borland (так компания стала называться уже позже) предложила мне испытать новую версию Pascal. Годом позже он был выпущен под названием Delphi. Мой сын родился годом ранее, и мы назвали его Эриком Марком Паскалем (Erik Mark Pascal). Моя дочь Наташа Луиза Делфин (Natasha Louise Delphine) родилась спустя год после релиза первой версии Delphi. Примерно в тоже время стал набирать популярность мой сайт - Dr.Bob's Delphi Clinic . В 1999 Марко Канту (Marco Cantu) и я, совместно получили награду Spirit of Delphi от Borland, которую тогда ещё называли Inprise. В 2002 году, я основал свою собственную
компанию Bob Swart Training & Consultancy. Помимо обучения и консультаций, я писал статьи, был вебмастером и разработчиком программного обеспечения (проекты среднего и малого масштаба). Спустя несколько лет я начал заниматься IT поддержкой различных компаний. Сегодня я почетный член общества Delphi/Pascal и председатель секции Delphi, группы разработки программного обеспечения (Software Development Group). Помимо этого, я модератор телеконференции британской Группы Разработчиков (UK Developer Group). Вопрос: Ваш рассказ даёт ответы на многие вопросы. Теперь я хотел бы задать некоторые вопросы о последнем продукте дельфячего мира - Delphi Prism. Это отличное название с хорошей эмблемой, но что оно означает для пользователей Delphi? Что вы думаете об этом продукте? Ответ: Разработчики должны были с самого начала взять направление в сторону создания продукта подобного Delphi Prism. Одна из косвенных целей .NET версии состояла в том, чтобы позволить выжить максимальный объем существующего кода. Из-за этого, разработчики приняли решение создать реализацию VCL для .NET. По сути, упор был сделан правильно, но не совсем корректно выбран подход к действию. В итоге, ждать стабильного релиза пришлось бы очень долго. Мне жаль людей, которые сразу перешли на .NET версию Delphi. Я был прав, всё зайдёт в тупик. Не верите? Взгляните на .NET версию UltraWEB (основан на VCL для .NET). Как бы не было печально, но продукт не выжил на рынке. Да, разработчики UltraWEB не хотят мириться с положением дел и уверяют, что их продукт для Win32 все еще жив. Лично я сочувствую тем, кто начал использовать Delphi 8, 2005, 2006 и 2007 для разработки .NET приложений. К сожалению, теперь им придется переписывать весь код. Delphi Prism – более естественный и удачный продукт. По сути, это собственная Visual Studio Development Environment от Microsoft. Язык очень похож на Delphi, но включает расширения от команды RemObjects. По некоторым параметра, этот язык иногда даже лучше, чем C#. Преимущество проявляется как в плане «синтаксической красоты», так и красивости всего того, что можно найти в .NET Framework.
Выбирая Delphi Prism вы получаете, технологию работы с СУБД от CodeGear – dbExpress (или DBX4 ныне). На мой взгляд, Delphi Prism – идеальная среда разработки. Я был вовлечен в достаточно много проектов ASP .NET и очень рад приобретенному опыту. Вопрос: Станет ли Delphi Prism предметом рассмотрения вашей следующей книги? Ответ: У меня есть в планах выпуск книги по Delphi Prism. К сожалению, из-за большой занятости я до сих пор не смог уделить ей должного времени. Вопрос: Я так понимаю, Embarcadero продолжит развивать Delphi Prism. Как повашему, они позволят ребятам из RemObjects продолжить разработку, несмотря на из то, что последние создали компилятор Oxygen? Ответ: Embarcadero продолжат делать компонент dbExpress максимально совместимым с .Net, и конечно же они продолжат развивать обычный Delphi. И само собой, они не должны ничего делать с компилятором. За прошлые пять лет, начиная с Chrome (предыдущей версии Oxygen), RemObjects показали, что они имеют достаточно опыта и сил для завершения разработки компилятора. Я использовал Chrome и Oxygen даже прежде, чем этот компилятор был доступен. Тогда он был альтернативой Delphi для .Net. Получилось так сказать, два лагеря: люди, которые оставались верными CodeGear/.Net, и люди, которые приняли сторону RemObjects. Последних было очень немного. Вопрос: Как обстоят дела с компонентами для коммуникации? Я слышал, что для мобильной коммуникации ничего не предвидься.
Ответ: В Delphi для мобильных телефонов однозначно ничего не будет. Да и .NET Compact Framework, увы, ничего не может предложить. Пока решения есть лишь в C# и VB. Данные компонент не пользуются популярность. Я не думаю, что разработчики обеспечат Delphi поддержкой мобильной коммуникации в виде стандартных компонент. Это задача сторонних компонент. Конечно, реализовать это возможно, но у меня очень мало опыта в этом.
Примечания Игоря Антонова Это наш первый опыт в переводе и публикации интервью из зарубежных источников. Нам очень интересно твое мнение по этому поводу. Тебе понравилось? Обязательно потрать 10 минут своего драгоценного времени и напиши мне (antonov.igor.khv@gmail.com) свое мнение. Если соберется достаточное количество положительных отзывов, то таких интервью будет больше. Жду твоего письма!
Оригинал опубликован в Blaise Pascal 6/88 Автор перевода: Костенко Роман aka Lord Of Fear E-Mail: lord_of_fear@list.ru WWW: http://vr-online.ru
Без рамки
Билайн кидалово? Или как нас дурят… Как вы догадались из названия статьи, пиара Билайну здесь не будет. Что же тогда будет вместо этого? А будет рассказ о том, как Моська лает на слона. Но давайте все по порядку. Ты помнишь, как все начиналось Все началось с забавной рекламы про usb-модем от Билайна. Красивая многообещающая реклама про высокоскоростное соединение с сетью Интернет. Речь шла о 2-3 Мб\с. Мне же, нужен был высокоскоростной безлимитный интернет, поэтому я решил выбрать именно Билайн. В то время для меня Билайн был вполне серьезной компанией, которая дорожит своими абонентами и своей репутацией. Сказано – сделано: я приобрел usbмодем. При этом я знал, что в нашем городе Омске все еще нет сети 3G, но в Интернет просочилась информация о тестировании сети 3G в ряде городов Сибири. Это было как раз, когда зима только вступила в свои права и начала исполнять обязанности по замораживанию города. Словом - заканчивался 2008 год. Первое знакомство с технической поддержкой Билайн С отсутствием 3G я мирился и путешествовал по Интернету с помощью старого и проверенного EDGE зная, что и на нашей улице будет свадьба. Скорость, как вы понимаете, у этой технологии не высока и составляла 90-100 кбит\с. Между тем, 2008 год закончился, ровно как и закончился февраль месяц. Я решил написать письмо на электронную почту Билайну и разузнать, как продвигаются дела с 3G. На что мне ответили, что в моем городе уже работает шесть базовых станций, которые поддерживают технологию 3G. Пришлось снова брать в руки клавиатуру и строчить еще одно письмо. Для начала мне прочитали лекцию про технологию EDGE, и на каких скоростях она работает. Было весьма познавательно разговаривать с роботом. Затем пришлось писать еще одно письмо и объяснить роботам, что в нашем городе сеть 3G замечена не была. Техподдержка попросила меня предоставить свои данные: ФИО, номер телефона и т.п. Через пару дней в своем электронном ящике я обнаружил долгожданное письмо. В нем говорилось о том, что данная проблема с сетью 3G будет решаться, а мое письмо передано в соответствующее подразделение моего города. Это радует, когда хоть кто-то работает. Шло время Прошло три дня. Я как обычно бродил по бездонному Интернету. Стоит отметить, что безлимитный тариф был только ночной с 0:00 до 8:00. Но мне этого хватало. Так вот, открывая страницу за страницей, я сидел и ждал их полной загрузки. И о чудо: соединение разорвалось, и usb-модем радостно замигал зеленой лампочкой. Забыл сказать, что на usbмодеме есть индикатор сети. Когда соединяешься с EDGE, то модем загорается, синим цветом, а если повезло и у тебя есть 3G, то горит зеленый цвет. Делать было нечего, и я снова подключился, но на этот раз уже к 3G. Вот думаю, выкачаю сейчас весь Интернет. Но скорость была немного выше EDGE и составляла уже 130-150 кбит\с. Это было начало действия новой сети в городе Омске. Иногда мне кажется, что, не написав то письмо, в нашем городе до сих пор не было бы сети 3G. Так как сеть 3G появилась на третий день после моего письма, то я считаю, что благодаря мне она наконец-то была запущенна в нашем городе. Ладно, минута слабости прошла где я чутьчуть похвастался, но надо продолжать далее.
Скорость росла Буквально каждый месяц скорость росла и была уже 300-400 кбит\с. Платил я за такое удовольствие около 300 рублей в месяц. Однажды мне пришло СМС-сообщение, в котором говорилось об изменении тарифов. Это сообщение было первой ласточкой дальнейших проблем. И вот опять тех. поддержка Про постоянные сбои в сети и обнулением баланса можно говорить много, но ограничимся несколькими предложениями. Наверное, в каждом из нас есть капля сисадмина и мы каждый раз смотрим баланс своего телефона. Я так же всегда контролировал свой баланс и заметил, что он обнулился. До этого на счету оставалась некая сумма. Все бы ничего, но ведь я не выходил в Интернет в дневное время, а пользовался им строго в промежуток между 0:00 и 8:00. Поэтому мой баланс должен быть положительным. Нужно было снова писать письмо в тех. поддержку, что я и сделал. Я подробно описал, когда заметил обнуление баланса, и в какой промежуток времени я пользовался Интернетом. Но служба поддержки настаивала на том, что я выходил в Интернет именно в дневное время. Пришлось написать им, что я еще умею различать день и ночь. Разговор двух непонимающих друг друга людей продолжался и насчитывал семь писем. В итоге, я добился своего - мне вернули деньги, которые были ошибочно сняты с моего счета. Моська слона укусила так, что ему пришлось извиниться перед ней. Случаев с ошибочным обнулением баланса на данный момент уже пять. За несколько дней до написания этой статьи обнуление произошло в пятый раз. После долгой переписки, баланс восстанавливали до состояния на момент сбоя. Usb-модемы успешно продавались, и компания «полосатых» решила сделать ограничение в скорости закачки. Кстати, небольшое отступление. Наверняка вы обращали на логотип Билайна. Он черно-желтый. Раньше была пририсована еще и пчела. Вот только не пойму, почему именно пчела. Ведь пчелы не желто-черные, а серенькие, но никак не желтые. Желтые осы, а если присмотреться, то черно-желтые. Что же получается? Пчела – трудолюбивое насекомое и нет такого дня, когда она сидела бы сложа руки. Оса же, в свою очередь, не такая трудолюбивая и, так как в мире насекомых нет законов, она иногда любит заниматься грабежом. Именно грабежом или разбоем, как вам удобнее. Оса частенько ворует мед у пчел. И это не мое предположение. Это на самом деле так. Спросите у любого пчеловода и он вам скажет то же самое. Выводы из этого краткого
отступления делать не буду и, как любит выражаться Эдуард Петров: «Выводы делать только вам». Мы остановились на ограничении в скорости загрузки файлов. Продолжим. Оказывается, чтобы хоть как-то снизить нагрузку на сеть, Билайн решила эту проблему ограничением скорости. Скорость теперь при загрузке свыше 2 Гигабайт будет составлять 56 Кб\с. Это на usb-модеме с поддержкой 3G? Да, именно так. А в рекламе нам обещали, что мы будем летать на скоростях 2-3 Мб\с. Все бы ничего, но в компании Билайн путают кбит и Кб и меня наградили 56 кбит\с. Выше этой отметки скорость не поднималась. Все мои попытки разъяснить технической поддержке Билайн, что кбит и Кб – это совершенно разные величины, не увенчались успехом. В это время наступило лето, и я уехал в деревню к родителям. Соответственно, там 3G и в помине нет, поэтому я сменил свой «Ночной безлимит» на «Пакет 50». Это означало 50 мегабайт включенного трафика за ежемесячную абонентскую плату в 100 рублей. Свыше 50 мегабайт тарифицировалось уже по 2 рубля за мегабайт. А скорость опять упала Лето пролетело незаметно и, когда я снова приехал в город Омск, то сразу же перешел на тариф «Ночной безлимит». Скорость закачки приятно порадовала: 700-750 кбит\с. Я был счастлив и закачал «Пароль Рыба-меч». На следующий день я поставил на закачку Visual Studio и тут меня обломали. Скорость то теперь уже была не 56 кбит\с, а 32 кбит\с. Можно было бы, конечно, подождать полгода пока закачается Visual Studio, но я не люблю ждать и написал очередное письмо в Билайн.
Ответ пришел немного погодя. Это письмо подтверждало мои предположения об очередном ограничении по скорости загрузки файлов. Вот только опять они перепутали кбит\с с КБ\с. Чтобы не быть голословным, приведу текст переписки с службой поддержки: Здравствуйте. Мой федеральный номер usb-модема 8-962-ХХХ-ХХХХ Меня интересует такой вопрос: Я слышал, что после скачивания более 2 Гигабайт в месяц, ставится ограничение по скорости в 56Кб/с. Но дело в том, что у меня после превышения лимита в 2 Гб скорость ограничивается 35 кбит/с. Это гораздо меньше Кб/с. Для подтверждения моих слов я прикрепил снимок программы "Билайн Интернет Дома".
Большая просьба: измените, пожалуйста, порог загрузки. Просто если качать битами, а не байтами - это проще не пользоваться Интернетом. Я согласен на ограничение в 56 Кб/с, но не на 56 кбит/с. И еще вопрос: можно ли каким-то образом с сим-карты модема дозвониться в службу поддержки Билайн? Кроме почты, я никак с вами не могу связаться в таком случае.
Прямо на снимке пришлось написать небольшую памятку. Вы наверно не совсем поняли, почему я пишу именно письма, а не просто позвонил Билайну по телефону? Дело в тот, что на сим-картах, которые идут с usb-модемом, голосовые вызовы запрещены. Вот поэтому я все писал на клавиатуре. Ответ пришел на следующий день: Уважаемый ХХХХХХХ! Благодарим Вас за обращение. Чтобы ответить на интересующий Вас вопрос, нам необходимо уточнить следующую информацию: - номер Вашего телефона; - контактный номер телефона; - точное время, место (улица, дом) возникновения и подробное описание ситуации; - номера телефонов, звонки на которые и с которых совершались в условиях данного ограничения, время звонков; - модель Вашего телефонного аппарата; - уровень приема сигнала сети.
Пожалуйста, обратитесь к нам повторно по электронной почте с уточненными данными или позвоните в Центр поддержки клиентов по телефону 0611 (с мобильного телефона). Будем рады ответить на Ваши вопросы. Желаем приятного общения! Ваш "Билайн". Причем тут мой телефон? Я, вообще-то, про ограничение скорости веду речь. Пришлось писать им следующее: Здравствуйте Я пользуюсь usb-модемом Билайн. Мой номер модема 8-962-ХХХ-ХХХХ На данный момент проживаю в г.Омске, улица ХХХХХХХХХХ. Сеть 3G в этом районе есть, хотя и уровень сигнала слабый, но когда не было ограничения - я мог скачивать файлы на скорости 56 Kb\s У вас на сайте в разделе usb-модемов говорится об ограничении, но у меня это ограничение еще больше. Буду рад за скорейшее разрешение проблемы. Далее я буду опускать всякие приставки, которые обычно пишутся в письме, а оставлю только само письмо. Итак, в ответ на мое письмо мне прочитали лекцию: Позвольте предоставить общую информацию о работе услуг на базе GPRS. Работа и скорость передачи данных в сети GPRS зависит от множества факторов, влияющих на ситуацию в каждый конкретный момент: а) наличия свободных ресурсов на базовой станции, которая обслуживает телефон (самый значительный фактор!). Если на ней или нет свободных каналов, или свободные каналы делятся между несколькими абонентами, параллельно пользующимися услугами на основе GPRS, то возможно возникновение задержек, на время, пока освободится канал связи. Кроме того, если число выделяемых каналов невелико, то и скорость будет не очень высокой. В другое время в этом же месте ситуация может быть иной, и скорость будет предельной высокой для данной модели телефона. б) производительности сервера, с которого получается информация. Если сервер или недостаточно производителен, или в данный период времени сильно перегружен, то и время обработки запроса будет увеличиваться. в) маршрутизации пакетов в Интернете и загрузки каналов связи в Интернете. В неудачном случае пакеты ходят кружным путем или теряются при перегрузке промежуточных узлов. Пункты б) и в) могут и не зависеть от сети "Билайн", но заметно влиять на скорость получения информации. К сожалению, в описанном Вами случае, наиболее вероятна ситуация описанная в пункте а).Ситуация с загрузкой БС (голосовых и GPRS каналов) решается путем увеличения ее емкости, т.е. способности обслуживать большее количество Абонентов одновременно в определенный момент времени. Работы по увеличению емкости сети "Билайн" ведутся непрерывно.
Единственный вывод, который я извлек из общения с сотрудниками Билайн – это то, что там сидят роботы, которые отвечают заученными фразами и нередко невпопад. Им все равно, то, что они могут потерять репутацию. В моих глазах они уже ее потеряли. Должен сказать, что проблема со скоростью как была, так и остается. Не понимаю, зачем крутить рекламу о высоких скоростях, но в то же время ставить такие жесткие ограничения в 32 кбит\с. Это же просто издевательство. Попробуйте скачать что-либо на скорости 32 кбит\с и посчитайте количество матов вами произнесенных. Где же безлимит? Я исправно плачу абонентскую плату, но получаю кукиш в ответ. И это все обещанная 3G скорость? Все печально В данной статье я постарался более полно описать все причины, по которым не стоит покупать usb-модем от Билайна. И это вполне обоснованно, а также без вранья и прочей клеветы. Я могу только догадываться, какое ограничение по скорости будет месяца так через два. И, поверьте мне, оно будет ниже отметки в 32 кбит\с. Примерно 15 кбит\с. Ваш телефон через GPRS будет летать по сравнению с usb-модемом от Билайна. Так что я повторюсь: не введитесь на красивую рекламу от Билайна и ни в коем случае не покупаете этот утиль от Билайна. Ежели, вы его купите, то у вас будет одна проблема: кому его продать или где его уничтожить под гусеницами бульдозера.
В случае с обнулением баланса, Моська всегда рвала слона, но ей пока не удалось порвать его в ограничении по скорости загрузки файлов. Так что будьте внимательны: наступает новая эра разводов. Вирусы и прочий спам видимо уйдут в прошлое, а миром будет править лохотрон от Билайна. И все снова будут сидеть в пещерах, и смотреть на костер, представляя его монитором любимого компьютера, и есть искусственный мед.
Written by Алексей aka wenfri E-mail: wenfri@yandex.ru
Перехват и блокировка Skype: правда и вымысел Прослушивание Skype возможно, или всё-таки нет? И если да, то кто его может осуществить? Можно ли блокировать разговоры по Skype в организации? И стоит ли это делать? Давайте попробуем разобраться вместе. Защищённость Skype
Skype не случайно считается одним из самых хорошо защищённых от прослушивания каналов коммуникации. Его создатели, имевшие уже опыт организации пиринговой сети Kazaa, создали сервис IP-телефонии, работающий по принципу P2P-сети, и активно использующий многоуровневое шифрование трафика. Несмотря на большой интерес к Skype со стороны, как злоумышленников, так и спецслужб, протокол держится довольно стойки, и не выдаёт своих секретов посторонним. Как известно, недавно Российский союз промышленников и предпринимателей (РСПП) предложил «законодательно урегулировать» Skype, ссылаясь, в том числе, на то, что разговоры по Skype недоступны для прослушивания спецслужбам. Между тем, ещё летом 2008-го появилась информация о том, что в Skype имеется бэкдор, который позволяет осуществлять прослушивание Skype, что подтвердили чиновники австрийского министерства внутренних дел. Что касается Skype, то касательно всех слухов о взломе и прослушивании протокола в компании всегда отвечают одинаково: «Skype не комментирует слухи. Никаких комментариев». Тем не менее, официальных сообщений о том, что Skype удалось взломать и успешно прослушать, пока ни от кого не поступало. Но правоохранительные органы могут спать спокойно, потому что руководство Skype подчёркивает, что готово сотрудничать с правоохранительными органами «везде, где это возможно с правовой и технологической точки зрения». А простые пользователи? Очевидно, если они не занимаются ничем противоправным, и их больше беспокоит защита от злоумышленников, чем от правоохранительных органов, то и они могут не волноваться. Шифрования трафика с помощью AES-256, для передачи ключа которого, в свою очередь, используется 1024битный ключ RSA, достаточно для самых требовательных к соблюдению конфиденциальности информации участников личных и деловых переговоров.
Блокировка Skype Прослушать Skype в разы сложнее, чем перехватить электронную почту, которой многие пользуются, не прибегая ни к каким средствам защиты передаваемой по ней данным. Тем не менее, несмотря на хорошую защищённость протокола, многие компании предпочитают блокировать доступ сотрудников к Skype. Делается это по разным причинам: и для того, чтобы сотрудник не отвлекался в рабочее время, если общение по Skype не входит в список его непосредственных обязанностей; и для того, чтобы избежать возможных утечек конфиденциальной информации; и просто чтобы сэкономить на трафике, который Skype потребляет с весьма неплохим аппетитом. Тем не менее, в силу ряда особенностей протокола Skype даже блокировать его не так уж и просто. Дело в том, что для обхода блокировки с помощью «файрволов» разработчики Skype немало поработали ещё на этапе создания распределённой архитектуры своего протокола. Оказывается, Skype может пользоваться как протоколом UDP, так и TCP, а благодаря шифрованию пакетов распознать их в общем трафике тоже довольно непросто. С помощью Google можно найти немало форумов, где системные администраторы дружно пытаются с переменным успехом найти рецепт блокировки Skype с помощью iptables. Разработчики Skype отслеживают попытки, как администраторов, так и производителей «файрволов» заблокировать их продукт, и наиболее удачные из них нейтрализуют выпуском новый версии клиента, которая уже успешно обходит новые способы блокировки Skype-трафика. Тем не менее, есть ряд продуктов, вполне пригодных для того, чтобы блокировать использование Skype в одной отдельно взятой конторе. Наиболее успешны «железные» решения – например, Unified Security Gateway компании Facetime или Cisco IOS Flexible Packet Matching. С их помощью вы можете или совсем заблокировать Skype-трафик, или, по крайней мере, несколько умерить аппетит Skype-клиента, выставив фиксированную ширину канала, отведённого для него. Что касается чисто программных «файрволов», то по отзывам, среди них неплохо зарекомендовал себя TeleMate NetSpective. Большинство же широко используемых «файрволов» (не будем показывать пальцем, чтобы не обидеть их производителей) в вопросах блокировки Skype-трафика, увы, находятся не на высоте. Тем не менее, ещё раз повторюсь, большинство администраторов, которые на практике сталкивались с задачей запрета использования Skype, сходятся во мнении, что наиболее эффективной (и при этом, пожалуй, самой дешёвой для компании) мерой является удаление клиента Skype с пользовательских рабочих станций. А также постоянный контроль за тем, чтобы он там снова не мог появиться. И всё-таки, прослушивание Тем не менее, Skype, оказывается, прослушивать можно. Не перехватывая и расшифровывая трафик, отправляемый Skype-клиентом, а перехватывая тот поток данных, который ещё не подвергся шифрованию и пересылке. Конечно, для этого требуется иметь доступ к компьютеру того человека, чьи переговоры по Skype хотят
прослушивать злоумышленники. Впрочем, не только они – ведь и руководство может предпочесть не блокировать Skype, особенно если он нужен для каких-то деловых коммуникаций, а устанавливать наблюдение за переговорами, ведущимися с его помощью. Это можно реализовать как с помощью программ, осуществляющих перехват всей информации со звуковой карты и клавиатуры (ведь в Skype есть и чат, и за ним тоже хочется наблюдать), так и специализированных решений, «заточенных» специально под Skype. Первый вариант реализуется вообще малой кровью – достаточно в том же стандартном Sound Recorder'е выбрать в качестве входного канала Stereo Mixer (в зависимости от звуковой карты, он может называться иначе – например, «What you hear»). Плюс какой-нибудь бесплатный кейлоггер, который можно за пять минут найти с помощью Google, и у вас есть готовая система слежения за сотрудниками. Но у неё есть минусы: вместе с разговором по Skype будет записываться и музыка, которую пользователь слушает в перерывах между ними. То же касается и клавиатурного ввода – вам придётся вручную отделять «зёрна от плевел», то есть сообщения, переданные через Skype, от набранных в Word'е документов. Что касается специализированных инструментов, то Google показал, что их на самом деле мало. Мне, честно говоря, удалось отыскать только один - SearchInform SkypeSniffer. Как заявляют разработчики, программа умеет самостоятельно выделять голосовой и клавиатурный ввод Skype из общего потока, а также обладает мощными поисковыми возможностями по базе собранных пользовательских сообщений. К сожалению, на сайте её разработчиков пробную версию скачать было ещё нельзя, так как она была только недавно анонсирована. Резюме Если вы не международный террорист, то за перехват своих Skype-переговоров можете не волноваться – обычным людям, пусть даже очень хорошо подкованным технически, это пока что не по силам. Блокировать Skype-трафик при желании можно, но гораздо проще запретить установку самого клиента Skype. Прослушать же разговоры по Skype, установив, перехватчики на пользовательском компьютере, несложно – если, конечно, есть такая необходимость.
Written by Р. Идов E-mail: r-idov@mail.ru
Удаленное Решение Современный ритм жизни все время требует нас обрабатывать все больше и больше информации, современный деловой человек без интернета и без сотового телефона оказывается за бортом и безнадежно отстает…. Мудрость гласит «Кто владеет информацией, тот владеет миром». Раньше об удаленном доступе к своему компьютеру можно было мечтать, теперь, когда практически у каждого есть домашний компьютер (а у некоторых и больше одного) удаленный доступ к себе домой или в организацию, в которой ты работаешь не мечта и не сказка, а будничная необходимость.
Зачем Забыл, отчет на флешке, а она дома, поедешь домой? Заболел и необходимо поработать дома, ты выйдешь больной доделать отчет? Я уверен так могут поступить многие, но не ты, потому что ты читаешь VR-Online! Определимся что нам нужно: чтобы настроить удаленный доступ нам нужен компьютер с рабочей ОС (в нашем случаем Windows XP),обязательно статистический внешний IP адрес, по которому мы будем обращаться к своему компьютеру.
Вездесущая теория Для начала немного теории. Доступ к компьютеру происходит так: первое - устройство должно находиться в сети Интернет и иметь внешний адрес. При обращении к внешнему адресу по определенному порту программа, которая работает на нем будет обрабатывать входящие и исходящие соединения (к примеру, Radmin по умолчанию работает на 4899 порту). Дальше либо сама система должна иметь на одном из сетевых интерфейсов внешний адрес либо должен осуществляться проброс с внешнего ip (wan) на локальный (lan) адрес. Достичь этого можно двумя путями: Авторизацией в интернете методом Bridge т.е созданием высокоскоростного подключения с использованием логина и пароля (при данном методе авторизации обычно используется xDSL модем, он должен быть настроен в режиме моста “bridge”) . При такой схеме у нас при успешной авторизации сетевой карте присвоиться ip адрес выданный нам провайдером (в нашем случае он будет статистический и внешний) Далее показана окно подключения такого подключения и собственно присвоенный внешний адрес на сетевой карте.
Первый метод настройки у нас есть теперь нам необходимо настроить модем в режиме router’a для этого зайдем в веб-интерфейс модема и в разделе настройки найдем пункт меню port forwarding (проброс порта) Default Server (для модемов ZyXEL) или DMZ (для модемов D-link) и там укажем свой локальный ip адрес. Если все прошло успешно, то переходим к уровню приложений… Для получения доступа можно воспользоваться несколькими простыми способами все зависит от степени Вашей готовности и фантазии. Мы рассмотрим два очень простых примера, а точней две программы: Remote Administrator ,и встроенная утилита Windows «Подключение к удаленному рабочему столу». Предполагается, что лицензия на использование Radmina у Вас имеется, а раз так, то посмотрим, что можно тут настроить. Зайдем в настройки и увидим следующее окно Первый пункт это IP фильтр, думаю назначение его понятно, он фильтрует внешние адреса и допустит пользователя к авторизации, только если его адрес находиться в этом списке. Далее идет указание порта по стандарту программа работает на 4899 порту при желании можно указать свой, но нужно быть осторожным, чтобы не указать порт другой программы, потому что это может привести к сбоям в работе приложений. Некоторые другие опции, такие как ведение статистики событий, скрытие иконки, и разрешение на вход нас мало интересуют, поэтому мы на них останавливаться не будем. Далее можно попробовать с другого компьютера осуществить вход через radmin’a на наш внешний адрес. Поздравляю, теперь вы должны успешно зайти на удаленный компьютер!!! А теперь я расскажу маленький трюк:
допустим, есть какой, то удаленный офис там находиться 5 машин на каждом стоит radmin проброс настроен на адрес 192.168.1.2, которая выступает главной машиной, как получить доступ к машине 192.168.1.38? Если вы создадите соединение 192.168.1.3, то вы будете обращаться к локальному адресу, а нам нужно попасть в сеть, которая стоит за внешним адресом. Для этого есть одна очень нужная функция зайдем в нового свойства соединения и укажем, что нам нужно подключаться к адресу 192.168.1.68 через промежуточный сервер, и указываем его 87.117.6.29.
Вот и все На этом собственно все. Конечно, этими двумя способами удаленный доступ не ограничивается, есть еще несколько способов получить доступ к компьютеру через интернет. Но это совершенно другая история…
Written by Аветисов Артур E-mail: man-from-it@ya.ru
Обзор компонент FastReport VCL Год выпуска: 2009 Версия: 4.8 Разработчик: Fast Reports Inc Официальный сайт: http://www.fast-report.com/ Платформа: Delphi 4 - BDS 2010 Системные требования: Windows 2k - Vista Описание: FastReport - это набор инструментов, позволяющих Вашей программе быстро и качественно создавать отчёты. Studio предоставляет весь набор инструментов для разработки отчётов. В этот набор входят: визуальный дизайнер отчётов и диалоговых форм, средства предварительного просмотра, средства доступа к данным и четыре встроенных интерпретатора языков Pascal, C, Basic и Java. Интерпретаторы обладают встроенными средствами пошаговой отладки. Помимо этого, Студия предоставляет широкий набор классов и методов, определенных в библиотеке VCL, что позволяет создавать динамические отчёты с неограниченными возможностями.
EurekaLog v6.0.21 Год выпуска: 2009 Версия: 6.0.21 Разработчик: Fabio Dell'Aria and the EurekaLog team Официальный сайт: http://www.eurekalog.com/ Платформа: Delphi 5 - BDS 2010 Системные требования: Windows 2k - Vista Описание: EurekaLog представляет собой полный набор инструментов резолюции ошибок для Delphi, C + + Builder, C #, VB.NET и Delphi Prism, которая дает разработчикам приложений отлавливать каждое исключение и утечку памяти, генерируя подробный журнал стек-вызовов.
Автор: Савельев Андрей aka dron-s Сайт: http://www.reportingfor.info/ru/ e-mail: dron-s@yandex.ru
KOL’ная диета для делфийца Самый часто обсуждаемый минус среды разработки Delphi – огромный размер ее скомпилированного проекта. Причем, чем старше версия Delphi, тем тяжелее exe. Например, моя 10 Lite версия создает пустой VCL проект весом в 347 Кб, а версия 2010 аж 797 Кб. И это без единой строчки кода! Думаю, многие знают, что такой большой размер готовой программы связан с использованием VCL (Visual Component Library). А как же без него? Тогда ведь придется все создавать самому средствами WinAPI! Ну, тут есть отличное решение, разработанное, кстати говоря, русским программистом - Кладовым Владимиром. Называется оно KOL - Key Objects Library - библиотека объектов для программирования в среде Delphi без VCL. Немного о KOL Распространяется она бесплатно и с исходными текстами. На данный момент поддерживаются версии Delphi2, Delph3, Delphi4, Delphi5, Delphi6, Delphi7, BDS 20052009, Kylix а так же Free Pascal Compiler 1.0.5 и выше. Для 2010 версии пока нету, к сожалению, а использовать в ней последнюю версию – 2.82 датируемую, сентябрем 2008 года – нельзя, поскольку типы данных теперь отличаются (прим. редактора – скорей всего, на D2009 работать тоже не будет, т.к. в нем вместо string используется WideString), особенно string (теперь это все WideString) и компилятор будет ругаться. Но пока и так сойдет. Что я планирую Цикл статей, который я собираюсь написать, будет полностью посвящен разработке программ малого размера на Delphi с использованием KOL и иногда с использованием сторонних модулей и компонентов. Я хочу показать и доказать, что на дельфях абсолютно реально написать маленькое, но полнофункциональное приложение.
Давайте сразу поглядим на реальный пример. Вот сколько, на Ваш взгляд, весит программка, имеющая такое окошко (рисунок 1)?
Рисунок 1 (Окно тестовой программы) Кнопочки, диалог выбора файла, картинка, чекбокс, Edit и Label’ы + код самой программы. При использовании VCL это все бы весело…, ща проверю на своей 10 версии,
423 Кб. А с KOL я достиг размера в 42 Кб! Нехилая разница, не так ли? Размер программы уменьшился в десять раз. Кстати хочу заметить, что создавать оконные программы с помощью KOL очень даже просто. И не надо думать, что там код будет в 300 строчек. Ничего подобного! Ну, в общем, обо всем по порядку. Начнем с основ. Начинаем Попробуем создать наше первое приложение с использованием данной библиотеки. Разумеется, перед тем как начать, ее надо скачать (http://kolmck.net/kol.zip). Скачали, распаковали, открыли IDE и создали новый проект. Как я ранее говорил, мы не юзаем VCL, поэтому производим удаление всех ненужных вещей вроде нашей формы. Далее в Project Manager вызываем контекстное меню для “Project1.exe” и кликаем “View source”. У Вас должно быть примерно следующее: program Project1; uses Forms; {$R *.res} begin Application.Initialize; Application.Run; end. Убираем все, что связанно с Application и модуль Forms. Теперь жмякаем “Project” – “Add to project...” и выбираем ранее закачанный файл Kol.pas. После, не забудьте добавить к проекту модуль Windows. Без него никак :). Почему мы не убрали строку “{$R *.res}”? Ну ведь, иконку красивую хочется для приложения, не так ли?? Вот и оставляем эту директиву, чтобы далее можно было менять иконку. Теперь к кодингу. Для создания главного окна приложения можно пойти двумя путями: 1. Создать форму средствами WinAPI. 2. Создать форму средствами KOL Я буду рассматривать второй способ. Первый так же не нагружает приложение, но строк кода у нас будет гораздо больше. Для создания формы средствами нашей библиотеки используется функция NewForm: function NewForm( AParent: PControl; const Caption: String ): PControl; В первом параметре указывается объект, который является визуальным контролом. Чаще его называют Applet и создать его можно с помощью функции NewApplet, в параметрах которой указывается только заголовок окна. А второй параметр функции NewForm я думаю, понятен всем. Поэтому приступим непосредственно к написанию кода:
program Project1; uses Windows, KOL; {$R *.RES} var Form:PControl; begin Form:=NewForm(Applet,'Программа на KOL'); Form.Width:=400; Form.Height:=250; Run(Form); end. Функция Run, как вы догадались, производит запуск программы и цикла обработки сообщений. NewForm создает форму, в параметрах ей передается апплет и заголовок формы. Перед запуском производится настройка будущего окна, поэтому предлагаю рассмотреть некоторые основные свойства объекта PControl: Width – ну тут понятно, ширина окна Height – аналогично, только высота окна Handle – хэндл окна Style – стиль окна Top и Left – расположение на экране Caption – заголовок окна Cursor – курсор для окошка Ну, собственно, остальное большинство свойств этого объекта соответствует его аналогу – TForm. Если очень интересно, то их можно посмотреть в самом модуле Kol. Компилируем нашу программу и получаем такое окошко:
Смотрим размер файла Project1.exe – 28 Кб, из них 4 Кб – файл ресурсов. Теперь попробуем добавить на приложение какие-нибудь контролы. Начнем с простейших TButton и TEdit. Для этого объявим новую переменную типа PControl и назовем ее Button. Теперь напишем следующий код: var Form:PControl; Button: PControl; Begin ... Button:=NewButton(Form, 'Пример кнопки'); Button.Width:= 130; Button.Left:= (Form.Width div 2) - 65; Button.Top:= 90; Edit:= NewEditBox(Form, []); Edit.Width:= 160; Edit.Left:= (Form.Width div 2) - 80; Edit.Top:= 60; Edit.Color:= clWhite; ... end. Замечу, что создание всех компонентов и их настройка должна производиться до вызова функции Run. Рассмотрим функции NewButton и NewEditBox: function NewButton(AParent: PControl; const Caption: KOLString ): PControl;
function NewEditbox(AParent: PControl; Options: TEditOptions ) : PControl; У двух функций первый параметр одинаковый (в принципе, как и у всех функций), предназначенных для создания моделей компонентов. Второй параметр функции создания кнопки понятен, поэтому перейдем ко второй функции. В качестве параметра Options передается набор настроек для Edit, таких как: TEditOption = (eoNoHScroll, eoNoVScroll, eoLowercase, eoMultiline, eoNoHideSel, eoOemConvert, eoPassword, eoReadonly, eoUpperCase, eoWantReturn, eoWantTab, eoNumber );
Думаю понятно, что они выступают за стиль отображения и редактирования текста. Например, eoPassword закрывает символы звездочками, eoReadonly не позволяет редактировать содержимое компонента, eoUpperCase переводит все символы в верхний регистр и так далее. Все, пробуем запустить наш проект и видим такое окошко:
Размер готового приложения изменился лишь на один Кб. Вот мы и добавили некоторые компоненты на нашу форму. Это уже Вам не “Hello world!” ;) Заключение На этом хочу закончить статью и посоветовать вам - самостоятельно разобраться с функциями NewPanel, NewCheckbox, NewRadiobox и NewGroupBox. Из названия уже понятно, что они так же создают компоненты. И это будет домашнее задание. Если кто не может по каким-то причинам понять принцип использования данных функций – я всегда готов помочь как на форуме, так и по e-mail. А на следующем уроке мы рассмотрим принцип создания обработчиков событий, изменить шрифт текста у контролов, попробуем написать более-менее функциональную программу. Всем респект и удачи
Исходники примера находятся в папке KOL1 Written by Никита Булай aka Bulka E-mail: bulka@sa-sec.org WWW: http://bulaj.ru
KOL’ная диета для дельфийца. Часть 2 В прошлой статье мы рассмотрели принцип создания простейшего однооконного приложения с помощью KOL. Научились размещать на нем некоторые объекты вроде кнопок и полей ввода текста. Но что же это за приложение, если оно ничего не делает, кроме как показывает форму с кучей контролов на ней? Надо ведь выполнять какие-то действия при клике на кнопки и прочие компоненты! В рамках этой статьи я постараюсь рассмотреть алгоритмы создания обработчиков событий, создания главного меню приложения, способы настройки шрифта интерфейса и некоторые другие полезности. Чтобы закрепить все полученные знания из предыдущей и этой статьи, мы попробуем написать болееменее функциональное приложение. Ну это в конце, а пока рассмотрим одну из наиболее важных частей KOL программирования – создание и использование обработчиков событий.
Ах, эти события (Events) Принцип создания обработчиков событий для KOL объектов такой же, как и в VCL. К определенному действию над объектом присваивают процедуры, которые и совершают требуемые действия. Привязывание идет через свойства, названия которых начинаются на OnXXXXX: OnClick,OnResize,OnMouseDblClk. Как видите, пока всё, как и при визуальном кодинге. Однако есть и отличие. Оно заключается в том, что через эти самые свойства мы должны создать указатель с помощью функции MakeMethod на процедуру или функцию, которые будут обрабатывать событие. В параметрах у процедур должны быть определенные данные, которые зависят от типа события. Ниже я приведу список некоторых заголовков (шаблонов) событий: TOnEvent TOnEventAccept TOnMouse TOnKey TOnMenuItem TOnMessage
Procedure NameProc ( Dummy : Pointer; Sender : PControl ); Procedure NameProc ( Sender: PObj; var Accept: Boolean ); Procedure NameProc( Sender: PControl; var Mouse: TMouseEventData ); Procedure NameProc( Sender: PControl; var Key: Longint; Shift: DWORD ); Procedure NameProc( Sender : PMenu; Item : Integer ); Function NameFunc( var Msg: TMsg; var Rslt: Integer ): Boolean;
Попробуем описать простейший обработчик нажатия на кнопку. Создадим новый проект (как подготовить проект для KOL программирования описано в первой статье), добавим некоторые глобальные переменные и создадим простую форму с одной кнопкой: var MainForm, Button: PControl; ... begin MainForm:=NewForm(Applet,'Обработка событий').SetSize(300,200); Button:= NewButton(MainForm,'Пример').SetSize(70,25); Button.Left:=60; Button.Top:= 50; ...
При создании формы и кнопки мы воспользовались функцией SetSize, которая позволяет
сразу при создании задать размеры нашего будущего компонента. Теперь опишем процедуру-обработчик и присвоим ее нашей кнопке. После этого выполним функцию Run: procedure SayHello; begin ShowMessage('Hello World!'); end;
… Button.OnClick := TOnEvent(MakeMethod(nil,@SayHello)); Run(MainForm);
... Классический пример, который выводит сообщение «Hello World!». Кстати для вывода сообщения функцией ShowMessage не требуется указывать в используемых юнитах модуль Dialogs – данная функция доступна в KOL библиотеке. Как видно из листинга, мы присваиваем свойству OnClick компонента Button указатель функцией MakeMethod, в параметрах которой мы передаем процедуру SayHello. Именно она и выполняет требуемые действия, в нашем случае это вывод сообщения. Таким же образом создаются и другие обработчики. Поэтому я не буду на них останавливаться, а продолжу нашу статью и расскажу о создании и использовании меню. А где меню? Какая нормальная программа не имеет своего меню? Ну, только та, что консольная или относится к разряду вредоносных . Именно поэтому я решил в рамках второй статьи рассмотреть принципы создания главного меню. Как Вам уже известно, мы не создаем нашу программу визуально. И справедливо задать вопрос: как же будет создаваться меню с использованием KOL и будет ли это удобно? Что ж, обо всем по порядку. Создавать меню с помощью KOL довольно таки легко и удобно. Делается оно на объектах типа PMenu функцией NewMenu: function NewMenu(AParent: PControl; FirstCmd: Integer; const Template: array of PChar; aOnMenuItem: TOnMenuItem ): PMenu;
В качестве AParent указывается контрол, которому будет принадлежать меню. Чаще всего это просто наша форма. Template - это массив, состоящий из пунктов и подпунктов меню. В них могут встречаться специальные символы, которые служат для обозначения начала и конца подменю (это символы “(“ и “)” соответственно), создания разделителя (символ “-”), создания подчеркивания (символ “&”) и так далее. Через OnMenuItem указывается процедура, которая будет обрабатывать выбранный пункт меню. Тип параметра TOnMenuItem, который Вы можете увидеть выше в шаблонах обработчиков событий. Во втором параметре данной процедуры указывается номер пункта меню, к которому будет привязано определенное действие. Попробуем создать простейшее приложение со своим меню. Пусть в нем будет присутствовать пункты «Файл», «Новый», «Выход» и «О программе». Для начала объявим переменные для нашей формы и меню: var MainForm: PControl;
MainMenu: PMenu;
Далее напишем основной код программы, где создадим новую форму и меню: MainForm := NewForm(Applet,'Тест меню').SetSize(595,650);
//Создадим меню для приложения mainMenu := NewMenu(MainForm,0,
// Заполним пункты [ '&Файл', '(', '&Новый', '-', '&Выход', ')', '&Помощь', '(', 'О программе', ')' ], //Обработчик нажатия пунктов меню TOnMenuItem( MakeMethod(nil, @ProcessMenu )));
Рассмотрим код подробнее. Создаем новую форму функцией NewForm и сразу присваиваем ей размер – SetSize. Далее производим создание главного меню функцией NewMenu, в параметрах которой передаем как родителя нашу форму – MainForm, массив из пунктов меню и обработчик событий (ProcessMenu). Теперь надо написать этот самый обработчик: procedure ProcessMenu(P: Pointer; Sender: PMenu; Item:Integer); begin case Item of 1: ShowMessage('Menu test – New clicked'); 3: Applet.Close; 5: ShowMessage('Menu test 0.1'+#13#13+'2009 Bulaj Nikita'); end; end;
Процедура проверяет номер пункта, который был нажат, после чего выполняет ассоциированное с ним действие. Для первого («Новый») происходит отображение мессаги, для третьего («Выход») выполняется завершение работы программы процедурой Close объекта Applet, для пятого («О программе») отображается сообщение с информацией о программе. Запустим наше приложение на выполнение и увидим такую вот картинку:
Хочется заметить одну особенность: многие начинающие программеры часто путаются с номерами пунктов меню. Это происходит часто из-за того, что они считают скобки (символы “(” и ”)” в передаваемом массиве Template) за отдельный пункт меню. Их, в отличие от символа разделителя, учитывать не надо! Это путает, и многие ошибаются при настройке обработки для отдельных пунктов меню. Так что будьте внимательны при подсчете элементов. Ну вот с основами мы разобрались, настало время закрепить наши знания и потренироваться в написании полнофункционального приложения. И сегодня мы будем кодить не что иное, как блокнот . Приступим. А теперь Coding Назовем наше приложение «Мега-блокнот 0.1». Для начал создадим новый проект и объявим в нем глобальные переменные: var MainForm, AboutForm, ToolPanel, ClearBtn, CopyBtn, RichEdit, NewBtn, PasteBtn, OpenBtn, CutBtn, SaveBtn: PControl; mainMenu:pMenu; Dialog: POpenSaveDialog;
Поясню. MainForm – наша форма, AboutForm – форма с информацией о программе. ToolPanel – панель инструментов; RichEdit – поле редактирования текста; ClearBtn... SaveBtn – кнопки на панели инструментов. mainMenu будет отвечать за главное меню, а Dialog за диалоги открытия и сохранения файлов. О нем я поговорю чуть позже. А пока я бы хотел разделить всю нашу работу по написанию приложения на несколько этапов: 1. Создание формы 2. Создание панели инструментов
3. Настройка интерфейса 4. Создание меню 5. Создание обработчиков событий Так нам проще будет вникнуть в суть. Начнем с первого и второго этапа: … function GetScreenCenter(fWidth, fHeight: Integer): TPoint; var W,H: Integer; begin W:=GetSystemMetrics(SM_CXSCREEN); // Ширина экрана H:=GetSystemMetrics(SM_CYSCREEN); // Высота экрана Result.X:= (W div 2) - (fWidth div 2); // Центр X Result.Y:= (H div 2) - (fHeight div 2); // Центр Y end; … begin // Новая и главная форма MainForm:=NewForm(Applet,'Мега блокнот 0.1').SetSize(595,650); MainForm.StatusText[0]:=''; // Выведем форму в центре экрана MainForm.Position:=GetScreenCenter(MainForm.Width, MainForm.Height); // Создадим "Панель инструментов" ToolPanel := NewPanel(MainForm,esRaised).SetAlign(caTop); ToolPanel.Height := 35 ; RichEdit := NewRichEdit(MainForm,[eoNoHScroll]).SetAlign(caClient); // Панель инструментов NewBtn:= NewButton(ToolPanel,'Новый').SetSize(70,25).PlaceRight; // Настроим шрифт NewBtn.Font.FontName:='Tahoma'; NewBtn.Font.FontHeight:=14; OpenBtn:= NewButton(ToolPanel,'Открыть').SetSize(70,25).PlaceRight; SaveBtn:= NewButton(ToolPanel,'Сохранить').SetSize(80,25).PlaceRight; CutBtn:= NewButton(ToolPanel,'Вырезать').SetSize(90,25).PlaceRight; CopyBtn:= NewButton(ToolPanel,'Копировать').SetSize(90,25).PlaceRight; PasteBtn:= NewButton(ToolPanel,'Вставить').SetSize(90,25).PlaceRight; ClearBtn:= NewButton(ToolPanel,'Очистить').SetSize(70,25).PlaceRight; // Диалог открытия и сохранения файла Dialog:=NewOpenSaveDialog('','',[OSOverwritePrompt]); // Настроим типы файлов Dialog.Filter:='Txt Files|*.txt|All files|*.*'; …
Рассмотрим некоторые вещи по порядку: 1. StatusText – данное свойство объекта MainForm позволяет автоматически создавать нашему приложению строку состояния (Status Bar), что очень удобно. 2. GetScreenCenter – данная функция получает размеры экрана и вычисляет центральную точку. Она передается свойству Position нашей формы для того, чтобы она появилась в центре экрана. 3. NewPanel создает новый объект, аналогом которого в VCL является TPanel. Функцией SetAlign мы настраиваем расположение панели на форме. 4. NewRichEdit создает поле редактирования текстовой информации, аналог из VCL – TRichEdit. Во втором параметре я передаю ей eoNoHScroll, что убирает горизонтальную полосу прокрутки у этого контрола. Можно и предать некоторые
другие, почитать о них можно в модуле Kol.pas 5. NewButton создает новую кнопку, а функция PlaceRight, вызываемая при ее создании, помещает объект справа от уже существующего контрола. Очень удобно, поскольку мы не имеем возможности визуального программирования и нам не придется вычислять расстояние между компонентами. 6. Свойство Font у каждого из контролов думаю понятно всем – оно отвечает за шрифт. Поскольку по стандарту шрифт у KOL приложений не совсем стандартный, нам придется самим все настраивать. 7. Функция NewOpenSaveDialog создает новый диалог сохранения/открытия файла. В качестве второго параметра я передал ей OSOverwritePrompt, что делает запрос на перезапись файла. Теперь приступим к настройке интерфейса нашего приложения. В рамках этой статьи я не буду рассматривать графический интерфейса, вроде иконок и картиночек – об это поговорим позже. Сейчас мы поговорим о смене стандартного шрифта. Поскольку мы уже настроили шрифт для кнопки NewBtn, нам осталось только присвоить такие же настройки и остальным контролам: // Для всех кнопок шрифт одинаков ClearBtn.Font.Assign(NewBtn.Font); OpenBtn.Font.Assign(NewBtn.Font); PasteBtn.Font.Assign(NewBtn.Font); SaveBtn.Font.Assign(NewBtn.Font); RichEdit.Font.Assign(NewBtn.Font); CopyBtn.Font.Assign(NewBtn.Font); CutBtn.Font.Assign(NewBtn.Font); Вот так вот просто. Конечно, если нужен разный шрифт, то код надо будет немного подкорректировать, но это не должно составить особой проблемы. Поэтому можно приступить к четвертому пункту нашего поэтапного программирования, а точнее к созданию меню. В данном примере оно будет иметь довольно приличное кол-во пунктов: … // Создадим меню для приложения mainMenu := NewMenu(MainForm,0, // Заполним пункты [ '&Файл', '(', '&Новый', 'Открыть', 'Сохранить как..', '-', '&Выход', ')', 'П&равка', '(', 'Отмена', 'Повтор', '-', 'Вырезать', 'Копировать', 'Вставить', '-', 'Очистить', ')', '&Помощь', '(',
'О проге', ')' ], // Обработчик нажатия пунктов меню TOnMenuItem(MakeMethod(nil, @ProcessMenu ))); …
Ну вот и остался последний этап – создание обработчиков событий. Добавьте к используемым модулям ShellAPI, он пригодится для открытия ссылок. Каждому компоненту на нашей форме мы присвоим свою процедуру: procedure OpenSite; begin ShellExecute(MainForm.Handle,'open', 'http://mysite.ru',nil, nil, SW_SHOW); end; procedure ShowAbout; var InfoLabel, SiteLabel: PControl; begin // Новая форма с информацией о версии и авторе проги AboutForm:= NewForm(MainForm,'О программе').SetSize(250,110); AboutForm.Position:=GetScreenCenter(AboutForm.Width, AboutForm.Height); AboutForm.Style:=WS_DLGFRAME or WS_SYSMENU; InfoLabel:= NewLabel(AboutForm,'Мега блокнот 0.1').SetPosition(10,10); InfoLabel.Width:= 200; InfoLabel:= NewLabel(AboutForm,'© 2009 Булай Никита').SetPosition(10,30); InfoLabel.Width:= 200; SiteLabel:= NewLabel(AboutForm,'http://mysite.ru').SetPosition(10,50); SiteLabel.Width:= 200; SiteLabel.Font.Color:= clNavy; SiteLabel.OnClick:= TOnEvent(MakeMethod(nil, @OpenSite)); AboutForm.Show; end; procedure ProcessButtons(P: Pointer; Sender: PControl ); begin if (sender = ClearBtn) or (sender = NewBtn) then begin RichEdit.Clear; Exit; end else if sender = PasteBtn then begin RichEdit.ReplaceSelection(Clipboard2Text, true ); Exit; end else if sender = CopyBtn then begin Text2Clipboard(Copy(RichEdit.Text,RichEdit.SelStart+1, RichEdit.SelLength)); Exit; end else if sender = CutBtn then begin Text2Clipboard(Copy(RichEdit.Text,RichEdit.SelStart+1, RichEdit.SelLength)); RichEdit.ReplaceSelection('', true ); Exit;
end else if sender= OpenBtn then begin Dialog.title := 'Открыть'; Dialog.OpenDialog := true; RichEdit.Clear; end else begin Dialog.title := 'Сохранить как...'; Dialog.OpenDialog:= false; end; if Dialog.Execute then if sender= OpenBtn then RichEdit.RE_LoadFromFile(Dialog.Filename,reText,false) else RichEdit.RE_SaveToFile(Dialog.Filename,reText,false); MainForm.StatusText[0]:=PChar(Dialog.Filename); end; procedure ProcessMenu(P: Pointer; Sender:PMenu; Item:Integer); begin case Item of 1:begin RichEdit.Clear; MainForm.StatusText[0]:=''; end; 2: ProcessButtons(nil,OpenBtn); 3: ProcessButtons(nil,SaveBtn); 5: Applet.Close; 7: RichEdit.Undo; 8: RichEdit.RE_Redo; 10: ProcessButtons(nil,CutBtn); 11: ProcessButtons(nil,CopyBtn); 12: ProcessButtons(nil,PasteBtn); 14: ProcessButtons(nil,ClearBtn); 16: ShowAbout; end; end; … begin ... // Обработчкик для кнопок с панели инструментов NewBtn.OnClick := TOnEvent(MakeMethod(nil,@ProcessButtons)); OpenBtn.OnClick := TOnEvent(MakeMethod(nil,@ProcessButtons)); SaveBtn.OnClick := TOnEvent(MakeMethod(nil,@ProcessButtons)); ClearBtn.OnClick := TOnEvent(MakeMethod(nil,@ProcessButtons)); CutBtn.OnClick := TOnEvent(MakeMethod(nil,@ProcessButtons)); CopyBtn.OnClick := TOnEvent(MakeMethod(nil,@ProcessButtons)); PasteBtn.OnClick := TOnEvent(MakeMethod(nil,@ProcessButtons)); // Выполним программу Run(MainForm);
Ну что ж, опять все по порядочку: 1. Процедура OpenSite отвечает за открытие сайта нашей программы. 2. Процедура ShowAbout создает и показывает форму с информацией о программе, на которой весит название программы, версия, автор и ссылка на сайт. Вся текстовая информация находится в объектах, которые создаются функцией NewLabel и в
3.
4.
5.
6. 7. 8.
VCL имеют аналоги TLabel. Процедура ProcessButtons отвечает за обработку нажатий кнопок на панели инструментов. В качестве второго параметра ей указывается, каким объектом была вызвана процедура и в зависимости от этого выполняется определенное действие. Функции Clipboard2Text и Text2Clipboard производят получение и помещение текстовой информации из/в буфер обмена соответственно. В нашем примере они используются для функций вырезания, копирования и вставки текста в RichEdit контрол. Кстати для этого используется функция ReplaceSelection. Если ей передать пустым первый параметр, то текст будет вырезан (предварительно скопировав его), а если с текстом – то вставлен. Объекту Dialog в зависимости от нажатой кнопки присваивается true или false для свойства OpenDialog. Если true – компонент при вызове функции Execute отображает диалог открытия файлов, при false – сохранения. Функции RE_LoadFromFile и RE_SaveToFile загружают текст из выбранного файла и сохраняют его в файл соответственно. Процедура ProcessMenu занимается обработкой нажатия пунктов главного меню. Для всех кнопок на форме создаем обработчик функций MakeMethod, которой присваивается процедура ProcessButtons. Она и будет выполнять заданные действия для каждой кнопочки.
Вот так вот. Наш блокнот наконец-таки написан. Осталось откомпилировать его и проверить в действии. Заключение После удачной компиляции и запуска нашего первого серьезного проекта мы видим его основное окошко:
Ничем не отличается от своего VCL аналога, разве что размер готовой программы равен
38 Кб взамен как минимум 450 Кб. И это без упаковки каким-нибудь UPX или ASPack. Все прелести KOL налицо! На это я закончу статью, ждите продолжения с следующем номере, тренируйтесь писать программки с уже полученными знаниями. Если кто-то не понял что-либо, то Вам поможет исходник, который прилагается к статье или наш всеми любимый форум. До встреч ;)
Written by Никита Булай aka Bulka Email: bulka@sa-sec.org www: http://bulaj.ru
Работа с датой в C# У многих наверно возникала проблема с отображением даты в формате, к примеру, 10 июня 2009 года. Visual Studio C# предоставляет большие возможности по работе с Датой и Временем… На старт! Конечно, можно было бы использовать следующий вариант для преобразования месяца в прописной вид public static string NameMonthPropis(int month) { return new DateTime(2000, month, 1).ToString("MMMM"); }
Что результатом будет для даты 21.09.2009 -> Сентябрь, т.е. если представить дату 21.09.2009 с прописным месяцем, то получится не очень красиво. public static string NameMonthPropis(DateTime date) { string month; month = new DateTime(2000, date.Month, 1).ToString("MMMM"); return Convert.ToString(date.Day) + " " + month + " " + Convert.ToString(date.Year) + " года"; }
Результат: 21 Сентябрь 2009 года Мдя, не очень то и красиво смотрится . Как же быть и как привести к нормальному виду? Очень просто: для того чтобы решить задачу и привести к нормально читабельному виду, я сделаю следующее: создам массив из перечисляемых месяцев и буду выбирать из массива тот месяц который мне необходим для текущего месяца DataTime.Today.Month. public static string NameMonthPropis(DateTime date) { string[] d = new string[]// объявляем текстовый массив и перечисляем месяца { "Января", "Февраля", "Марта", "Апреля", "Мая", "Июня", "Июля", "Августа", "Сентября", "Октября", "Ноября", "Декабря" }; return Convert.ToString(date.Day) + " " + d[Convert.ToUInt32(date.Month-1)] + " " + Convert.ToString(date.Year) + " года"; }
В итоге получим на выходе: 01 Сентября 2009 года, именно тот результат что нам и был нужен .. Так как DateTime.Today.Month идёт в интервале от 1 до 12, а в массиве данные идут от 0, то мы минусуем -1.
Аналогично можно поступить и с Днями недели: public static string DaysOfWeekPropis(DateTime date) { int FCount; //определяем переменную для количества значений в массиве FCount = 7; string[] d = new string[FCount]; d[0] = "Воскресенье"; //заполняем массив d[1] = "Понедельник"; d[2] = "Вторник"; d[3] = "Среда"; d[4] = "Четверг"; d[5] = "Пятница"; d[6] = "Суббота"; return d[Convert.ToUInt32(date.DayOfWeek)]; }
Но можно воспользоваться и стандартными возможностями: public static string DayOfWeekPropis(DateTime date) { return date.ToString("dddd"); }
Результат будет одним: понедельник (только в первом случае название месяца будет с большой буквы). Если же поиграться с форматом DayOfWeekPropis и вместо 4-х d (“dddd”) поставить 3-d, то выходное значение будет представлять в сокращённом виде, т.е. Пн, Вт, Ср и т.д., этого же результат можно добиться и через первый вариант. В C# предоставляются многочисленные возможности по работе с датой. Перечислю некоторые из них и приведу примеры их использования: AddDays – прибаляет указанное число к текущему дню. Пример: текщий день – 21.09.2009 DateTime.Today.Date.AddDays(2) Результат - 23.09.2009
DaysInMonth – возращает количество в указанном месяце Пример: Текущая дата: 21.09.2009 DateTime.DaysInMonth(2009,9) //необходимо указать год и месяц Результат: 30 //30 дней в месяце сентябрь
AddMonths - прибаляет указанное число к текущему месяцу Пример: Текущий день – 21.09.2009 DateTime.Today.AddMonths(2) Результат - 21.11.2009 //получится Ноябрь месяц
AddYears – прибавляет указанное число лет к текущему году Пример: Текщий день – 21.09.2009
DateTime.Today.AddYears(2) Результат - 21.11.2011
Ну вот в принципе и всё. Если что то не понятно из этого материала, то обязательно загляни в MSDN. Там есть все . Удачи!
Автор: Савельев Андрей aka dron-s Сайт: http://www.reportingfor.info/ru/ e-mail: dron-s@yandex.ru
Файловый менеджер своими руками. Часть 2 Итак, выходит в свет вторая часть статьи, в которой я рассказываю о функциях по работе с файловой системой на примере написания файлового менеджера. Первая часть статьи вышла в предыдущем номере. В принципе, они никак не связаны по смыслу. Так что для понимания материала не обязательно читать первую часть.
Типичные функции файлового менеджера Создаем папку Для того, чтобы создать папку нужно воспользоваться функцией: BOOL WINAPI CreateDirectory( LPCTSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Ей нужно передать полный путь к создаваемой папке, а также опционально указатель на структуру типа SECURITY_ATTRIBUTES. Я передаю NULL, и папке присваивается стандартный дескриптор безопасности. Подробнее о втором параметре можешь прочесть в msdn. Если папка создана, то функция вернет TRUE в противном случае FALSE. Как видишь, ничего сложного нет. Один диалог на все случаи жизни Чтобы пользователю было удобно вводить имя создаваемой папки, и многое другое (об этом речь пойдет дальше) я решил создать диалоговое окно. Но так как операций будет 3, то пришлось бы создавать 3 диалоговых окна, потому что для каждой команды они немного отличаются. Я решил, что 3 форму это чересчур и решил обойтись одной. Сейчас я расскажу, как я это сделал. Для начала обычным образом я создал форму. Поместил на нее 2 кнопки, 2 label и 1 textbox. В файле Form1.h я добавил строку: #include "DialogForm.h".
По умолчанию С++ снабжает все компоненты в классе формы спецификаторами private, то есть их можно изменять только из функция класса и функций-друзей класса. А мне надо чтобы я мог управлять компонентами на диалоговой форме из главного окна. Поэтому первым делом я изменил private на public. Затем я добавил второй конструктор, в котором передаю строку для заголовка формы. Вот его код. DialogForm(System::String^ title) { InitializeComponent(); this->Text=title; }
Ничего сложного просто меняем заголовок формы на текст переданный конструктору. Теперь дошли до самого интересного. Как же управлять нашим «чудо-диалогом»? Для создания нашей формы нужно написать следующую строку:
FileCommander::DialogForm ^newDlg = gcnew FileCommander::DialogForm("Создаем папку");
Создаем переменную и вызываем, конструктор с параметром "Создаем папку". В данном случае мы будем делать диалог, в котором будет запрос на создание папки. Далее все очень просто. Чтобы изменять текст кнопок и всего остального нужно обращаться к ним, как будто они находятся на главной форме. newDlg->button1->Text = "Создать"; newDlg->button1->DialogResult= System::Windows::Forms::DialogResult::OK; newDlg->button2->Text = "Отмена"; newDlg->button2->DialogResult= System::Windows::Forms::DialogResult::Cancel;
Так как форма представляет из себя диалоговую, то мы должны указать DialogResult для каждой кнопки. По нему мы сможем узнать, какая кнопка была нажата пользователем. Стоит учитывать, что показывать такую форму нужно не функций Show(), а ShowDialog(). Результатом выполнения которой будет DialogResult нажатой кнопки. Обрати на это внимание. System::Windows::Forms::DialogResult dr; dr=newDlg->ShowDialog(); //Далее с ним очень просто работать: if (dr==System::Windows::Forms::DialogResult::OK) //Если пользователь нажал кнопку с положительным ответом, то то-то делаем.
Продолжаем обзор функций Итак, мы уже научились создавать папки. Теперь пора бы научится их удалять. Тут нам придется столкнуться с досадным ограничением. В WinAPI есть функция: BOOL WINAPI RemoveDirectory (LPCTSTR lpPathName) Но она удаляет только пустую папку. Надеюсь, что назначения ее параметра тебе понятно. Так что если папка не пуста, придется ее сначала очистить от файлов и всех вложенных папок. Для этого существует функция BOOL WINAPI DeleteFile (LPCTSTR lpFileName) Она принимает полный путь к файлу и пытается его удалить. Если ей это удалось, то она вернет не 0, а если не удалось то 0. Проницательные читатели моей статьи уже знают, для того чтобы удалить папку нужно для начала по ней пробежаться и удалить все файлы, и папки если таковые имеются (естественно рекурсивно). О том, как искать файлы в папках, было написано в первой части статьи, которую можно прочитать в предыдущем номере. На очереди у нас копирование файла. Чтобы произвести эту не хитрую операцию нужно вызвать функцию: BOOL WINAPI CopyFile (LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName,
BOOL bFailIfExists) Назначение первых двух параметров должно быть понятно, это путь к копируемому файлу, и новый полный путь включая имя файла (это к вопросу о создании копии в том же каталоге). Поэтому поподробнее остановимся на третьем параметре. Если он равен TRUE и файл определенный в lpNewFileName уже существует, то ничего скопировано не будет и функция завершится с ошибкой, то есть вернет 0. Если же bFailIfExists равен FALSE, а «новый» файл существует, то он будет перезаписан и функция выполнится успешно – вернет не 0. Наряду с операцией копирования есть операция перемещения файлов. Надеюсь, что разница между ними известна всем. Естественно перемещение можно было бы реализовать путем копирования и удаления, но тут программисты из Microsoft о нас позаботились и написали функцию, которая называется BOOL WINAPI MoveFile(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName)
Эта функция может перемещать не только файлы, но и папки. Единственный нюанс в том, что папки должны находиться на одном логическом диске иначе ничего не выйдет. Заключение На этом я заканчиваю свой рассказ о функциях по работе с файловой системой. Естественно он был не полным, он этого запаса вполне хватит для написания простенького файлового менеджера. Хочешь узнать больше? Читай msdn. Будут вопросы, пиши мне на почту.
Written by Крылов Егор E-mail: krilov-egor@yandex.ru
Windows 7: Программирование SuperBar Новая панель задач, носящая гордое название "SuperBar" - не просто симпатичная панелька в стиле Mac OS. Это абсолютно новый компонент системы, способный выполнять кучу полезных функций (в рамках приложений). Если ты планируешь в серьез заняться разработкой софта под новую ОС и хочешь, чтобы твои программы не выглядели среди остальных белыми воронами, то ты просто обязан разобраться и реализовать в них полную поддержку всех новых фишек таск бара. Тем более, все эти новые штучки делают работу с приложением более комфортной и удобной. Что нам потребуется Для знакомства с возможностями нового таск бара, тебе понадобиться Visual Studio и библиотека .NET Interop Sample Library http://code.msdn.microsoft.com/Windows7Taskbar/Release/ProjectReleases.aspx?ReleaseId=22. В эту либу входит уже известная Vista-разработчикам библиотека - Vista Bridge и многочисленные примеры, демонстрирующие использование некоторых новых технологий Windows 7 (SuperBar, Librarys, Sensor and Location Platform и т.д). В сегодняшней статье, мы затронем лишь SuperBar, но если захочешь узнать нюансы о перечисленных технологиях, то намыль письмецо редактору рубрики и возможно в одном из ближайших номеров нашего журнала появиться соответствующая статья . ProgressBar на панели задач Начинать наше знакомство с программированием SuperBar мы будем с самого простого – с создания элегантного ProgressBar. Ты, наверное, уже смог заметить, что некоторые приложения (такие как, IE8, Проводник) могут отображать ход выполнения какой-либо операции прямо на панели задач (смотри рисунок 1). Такой подход очень удобен и позволяет лишний раз не дергаться и не разворачивать окно приложения с целью посмотреть, а не скопировался/закачался ли очередной файл или нет. К тому же, одним отображением процесса выполнения операции, дело не ограничивается. Например, ты без особого труда можешь проинформировать пользователя о неудачи выполнения задачи, приостановки ее выполнения или вовсе, утвердительно намекнуть, на неизвестное количество времени, необходимого для завершения операции. Все это реализуется, путем изменения состояния ProgressBar (рисунок 2). В общем, вариантов применения этой возможности SuperBar можно найти огромное множество, а сейчас мы рассмотрим, как реализовать все эти штуки на практике.
Рисунок 1 (Типичный пример ProgressBar на панели задач)
Вид иконки
Тип состояния Normal
Paused
Indeterminate
Error
Создавай в Visual Studio новый проект и подключи к нему скачанную библиотеку и добавь ссылки на компоненты интеграции с рабочим столом. На этом подготовительные работы окончены. Теперь можно приступить непосредственно к рассмотрению примера. Для решения этой задачи, нам потребуется воспользоваться услугами класса WindowsFormExtensions. А если быть еще точнее, то нас интересуют всего, лишь два метода: SetTaskbarProgress() - метод позволяет указать процент SetTaskbarProgressState() - метод отвечает за установку
выполнения операции. состояния ProgressBar.
Кинь на форму своего проекта две кнопки, одну надпись и один компонент типа ComboBox. Для первой кнопки в свойстве Text укажи "+", а для второй "-". Как не трудно догадаться, по нажатию первой пимпы мы будем сознательно увеличивать процент выполнение операции, а по нажатию второй наоборот, уменьшать. Компонент ComboBox мы будем использовать для хранения списка возможных состояний: - Normal - Indeterminate - Error - Pause - NoProgress
Рисунок 2 (Форма примера демонстрирующего ProgressBar)
Пример моей формы ты можешь узреть на рисунке 2. Теперь, создавай обработчик события Clicked для первой кнопки (та которая "+") и пиши в нем две незамысловатые строчки кода: WindowsFormsExtensions.SetTaskbarProgress(this, totalProgress); totalProgress = totalProgress + 10;
Аналогичным образом создавай обработчик события нажатия для второй кнопки и напиши в нем точно такие же строчки как и в первом случае, только плюс поменяй на минус. Все. Вот так, с помощью всего лишь одной строчки кода мы добились отображения ProgressBar для нашего приложения на SuperBar. Чтобы программа успешно запустилось, не забудь добавить namespace Windows7.DesktopIntegration, Windows7.DesktopIntegration.WindowsForms и объявить приватную переменную totalProgress. Попробуй запустить приложение и поиграться с кнопками, а я тем временем приступлю к рассмотрению статусов ProgressBar. Как ты помнишь, возможные типы статусов мы забили в ComboBox. Теперь вдохнем жизнь в наш список выбора. Создавай для него обработчик события SelectedIndexChanged и напиши в него код из листинга 1. Листинг 1 (Изменение статуса ProgressBar) int result = comboBox1.SelectedIndex; switch (result) { case 0: WindowsFormsExtensions.SetTaskbarProgressState(this, Windows7Taskbar.ThumbnailProgressState.Normal); break; case 1: WindowsFormsExtensions.SetTaskbarProgressState(this, Windows7Taskbar.ThumbnailProgressState.Indeterminate); break; ... }
Код для установки состояния ProgressBar затруднений вызвать не должен. По сути, весь листинг (я его привел не полностью) это сплошной case и вызов метода SetTaskbarProgressState(). В качестве параметров, я передаю методу хэндл формы и
значение из перечисления Windows7Taskbar.ThumbnailProgressState, соответствующее определенному статусу. Результат работы моего примера ты можешь увидеть на рисунке 3.
Рисунок 3 (Пример демонстрации ProgressBar в действии)
Списки переходов на практике (JumpList) Другой очень заметной новинкой SuperBar стали так называемые списки переходов. Они позволяют хранить список задач (функций), ассоциированных с приложением, ссылки на недавно открытые файлы и т.д. Если ты юзаешь Windows 7 в первый раз, то чтобы познакомиться с функцией JumpList, кликни правой клавишей мыши по какому-нибудь значку на таск баре (например, по IE8). В появившемся контекстном меню будут содержаться ссылки на основные функции программы - "Создать новое окно", "Приватный режим" (Рисунок 4) и т.д. Плюсы такой "менюшки" очевидны. Сужу сам по себе. Поюзав, эту фичу с недельку, я к ней чертовски привык, и теперь во всех своих будущих проектах буду обязательно делать поддержку JL.
Рисунок 4 (Демонстрация JumpList у IE8)
Перед тем как писать код, проговорим теоретические нюансы. Для того чтобы встроить в свое приложение поддержку списков перехода, нам необходимо создать экземпляр объекта JumpListManager. Нюанс в этой казалось бы простой операции всего один инициализировать объект нужно в момент создания кнопки приложения на SuperBar. Как это сделать? Достаточно всего лишь переопределить метод WndProc. В нашем случае, метод должен обрабатывать сообщение TaskbarButtonCreatedMessage. При его возникновении, от нас требуется воспользоваться методом CreateJumpListManager класса WindowsFormExtensions. Создав свой JumpListManager можно начинать пить шампанское, т.к. по сути, первая часть работы выполнена. Ой, что-то я отвлекся. Далее следует "оформить" подписку на событие UserRemovedItems и приступать к созданию самих ссылок. Я тебе уже говорил, что ссылки могут быть нескольких типов недавние документы, просто ссылки на программы и т.д. В своем примере я создаю так называемые задачи (делаю ссылку на программу "калькулятор"). За добавление очередной такой задачи отвечает метод AddUserTask объекта типа JumpListManager. В качестве одного единственного параметра, методу требуется передать новый объект типа ShellLink с заполненными полями: - Path. Путь к приложению/файла. - Title - заголовок пункта в списке перехода. - Category - группа. Все ссылки в JL могут быть разделены по группам - IconLocation - путь к иконке. - IconIndex - индекс иконки в файле.
На этом рассмотрение процесса создания задач в списке переходов можно считать оконченным. Переписывай содержимое листинга 2 и запускай приложение для теста. Обрати внимание, если ты создашь для своей программы иконку на таск баре, то JL будет появляется всегда, независимо от того запущено ли твое приложение или нет. Вполне возможно, что рано или поздно тебе захочется в JL создать список недавно открытых в твоей программе файлов. Не переживай, сложности не добавятся. Принцип остается тот же за исключением используемого метода. Вместо AddUserTask, применяется AddToRecent.
Листинг 2 (Создание задачи для JumpList) protected JumpListManager myJumpListManager; protected override void WndProc(ref Message m) { if (m.Msg == Windows7Taskbar.TaskbarButtonCreatedMessage) { myJumpListManager = WindowsFormsExtensions.CreateJumpListManager(this); myJumpListManager.UserRemovedItems += (o, e) => { e.CancelCurrentOperation = false; };
myJumpListManager.AddUserTask(new ShellLink { Path = Path.Combine(Environment.GetFolderPath
(Environment.SpecialFolder.System), "calc.exe"), Title = "Calculator", Category = "Application", IconLocation = Path.Combine(Environment.GetFolderPath (Environment.SpecialFolder.System), "calc.exe"), IconIndex = 0 }); myJumpListManager.Refresh(); } base.WndProc(ref m); }
Ах эти оверлейные иконки Microsoft в последней версии своей ОС пытается все делать так, чтобы пользователю жилось уютно и комфортно. Взять хотя бы еще одну фишку SuperBar - OverlayIcons (оверлейные иконки). Пользователю, эта функция предоставляет возможность узнать о состоянии приложения. Уверен, что к выходу семерки в свет, производители программ месенджеров возьмут эту функцию на заметку, т.к. с ее помощью можно красиво отображать текущий статус (отошел, занят) прямо на панели задач. Чтобы лучше понять, то о чем я говорю, не поленись и запусти стандартного MSN Messanger, попробуй подключиться к серверу, и выстави какой-нибудь статус. Как проделаешь это не хитрое действие - глянь на панель задач. Прямо на иконке месенджера, увидишь иконку, соответствующую текущему статусу.
Благодаря классам, реализованным в библиотеке .NET Interop Sample Library, встроить в свое приложение поддержку оверлейных иконок становиться совсем не трудно и скоро ты в этом убедишься. Итак, разберем весь процесс по шагам. Нам необходимо:
1. Подготовить иконки. Можешь создать для этого отдельный файл ресурсов или просто воспользоваться компонентом ImageList. 2. Воспользоваться методом SetTaskbarOverlayIcon. В качестве параметров он принимает: - handle формы - Объект Icon - Текст подсказки. 3. Лицезреть готовый результат. На основании выше сказанного, создаем новый проект. Кидаем на форму компонент Button и определяем для кнопки обработчик события Clicked. В его тело пишем: WindowsFormsExtensions.SetTaskbarOverlayIcon(this, this.Icon, "My OverlayIcon");
Так, создавать иконки типа научились. Поглядим сразу на обратный процесс - удаление созданной иконки. Бросай на форму еще одну кнопку и по ее нажатию пиши: WindowsFormsExtensions.SetTaskbarOverlayIcon(this, null, String.Empty);
На этом все. Можешь запускать приложение и потестить его. Мой результат показан на рисунке 5. Перед тем как приступить к описанию следующей функции TaskBar, хочу подкинуть тебе одну идейку по практическому использованию оверлейных иконок. Если немножко включить соображалку, то реально написать несколько строчек тухлого кода и описать метод для динамического создания иконок. Что нам это дает? А дает нам это, возможность создавать красивые иконки с цифрами (или буквами). Например, ты кодишь приложение, которое работает с сетью и принимает/отправляет файлы. Как можно сделать отображение процента выполнения загрузки в то время, когда главное окно свернуто? Да, ты можешь сделать, как я говорил в самом начале статьи (сделать ProgressBar), ну куда прикольней (и симпатичней) решить эту задачу с помощью динамического генерирования иконок. Говоря проще, на каждый процент ты должен создавать иконку, в которой в качестве изображение будет нужная цифра. Код в рамках статьи я приводить не буду. Если сам не справишься, то загляни в исходники моего проекта в папке с журналом. ThumbButtons - What is??? Наведи курсор грызуна на запущенный (и свернутый) проигрыватель Windows Media Player и ты увидишь маленькое окошко с кнопками, позволяющими управлять состоянием проигрывания мультимидийного контента. У Media Plaeyr, в этом окне доступны три кнопки (рисунок 6) - Play, Next, Previous. В своем приложении ты можешь не придерживаться таких ограничений и создать до 7 кнопок. Больше создать увы, не получится, т.к. это ограничение могучей Windows. Нельзя так нельзя. Не будем расстраиваться по пустякам, а лучше попробуем создать приложение, демонстрирующего эту возможность.
Рисунок 6 (Загадочные ThumbButtons) Как и следует ожидать, главным нашим помощником будет опять, уже полюбившаяся библиотека. Создавай новый проект и вновь подключай к нему vistabridge, а также Windows 7 DesktopIntegration. Для этого примера нам не потребуются никакие элементы управления, поэтому смело переходи в редактор кода и потихонечку начинай перебивать содержимое третьего листинга. Листинг 3 (Создание ThumbButton) private ThumbButton myThumbButton; private ThumbButtonManager myThumbButtonManager; protected override void WndProc(ref Message m) { if (m.Msg == Windows7Taskbar.TaskbarButtonCreatedMessage) { if (myThumbButtonManager == null) { myThumbButtonManager = WindowsFormsExtensions.CreateThumbButtonManager(this);
} myThumbButton = myThumbButtonManager.CreateThumbButton(1, this.Icon, "Test"); myThumbButton.Clicked += delegate { MessageBox.Show("Test button"); }; myThumbButtonManager. AddThumbButtons(myThumbButton); } if (myThumbButtonManager != null) { myThumbButtonManager.DispatchMessage(ref m); }
base.WndProc(ref m); } }
Все кнопки такого вида (ThumbButtons) создаются при помощи объекта-контейнера ThumbButtonManager и объекта ThumbButton. Именно поэтому в самом начале третьего листинга я описываю два приватных поля - myThumbButton и myThumbButtonManager. Дальше от нас требуется переопределить метод WndProc (вспомни, мы уже проделывали такой трюк) и сделать в нем проверку на сравнение очередного сообщения с Windows7Taskbar.TaskbarButtonCreatedMessage. Если результат истина, то нужно выполнить проверку на созданность экземпляра объекта ThumbButtonManager. Далее действуем в зависимости от ситуации. В случае уже проведенной инициализации переменной myThumbButtonManager пропускаем вызов метода CreateThumbButtonManager() и переходим сразу к создание кнопки. Каждая новая кнопка создается вызовом метода CreateThumbButton(), объекта типа ThumbButtonManager. Для успешной отработки, методу требуется передать три параметра:
1. Id - Числовой идентификатор кнопки. Я не заморачиваюсь и передаю 1. 2. Icon - Иконка для кнопки. В этом параметре я указываю this.Icon, т.е. по сути устанавливаю в качестве иконки, основную иконку нашего приложения. 3. ToolTip - Текст подсказки. Толку от безжизненной кнопки немного, а раз так, то неплохо было бы забиндить обработчик события Clicked. Для этого описываем делегат. В своем примере я просто вызываю метод Show класса MessageBox. Т.е. говоря другими словами, при каждом нажатии на кнопку у меня будет появляется окно с текстом "Test button". После описание действие кнопки ее необходимо добавить в наш ThumbButtonManager. Эта процедура выполняется посредством вызова метода AddThumbButtons. Из параметров ему нужно передать объект типа ThumbButton. Можно считать, что пример полностью готов. Все что остается - так это утвердительно намекнуть ThumbButtonManager, что обрабатывать сообщения теперь его прямая
обязанность. Именно это я и делаю, вызывав метод DispatchMessage. На этом третий листинг подошел к концу и пора переходить к разбору полетов. Попробуй запустить созданное приложение и подвести к его иконке курсор мыши. Если ты не допустил ошибок, то увидишь примерно такую же картинку как на рисунке 7.
Рисунок 7 (ThumbButton во всей своей красе)
Shutdown Обычно принято ругать Microsoft за кривизну их продуктов и ухахатываться над допущенными ими "детскими" ошибками, но я хотел бы их наоборот похвалить, за то что еще до выхода финального релиза Windows 7, у нас с тобой имеется возможность поюзать все новые фишки системы и реализовать их поддержку в своих программах. Библиотека, которую мы с тобой сегодня использовали - лишние тому подтверждение. Кроме того, есть еще и SDK, который содержит кучу примеров и все, что только может потребоваться Windows разработчику. Это реально круто и я надеюсь, что в будущем компания будет придерживаться такого пути. Тебе приятель, я хочу пожелать удачи в программировании и не в коем случае не теряй времени и не отставай от прогресса. Уже сейчас начинай готовить версию своих мега проектов для Windows 7. Тем более для этого у тебя есть все необходимое. Если с чем-то не разберешься, то пиши мне. С удовольствием постараюсь помочь.
Врезка № 1: Полезные ресурсы
http://code.msdn.microsoft.com/WindowsAPICodePack - Альфа версия библиотеки Windows API CodePack http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=6db1f17f-5f1e4e54-a331-c32285cdde0c - Отсюда можешь стянуть официальный образ Windows 7 RC SDK. В нем ты найдешь документацию, а также кучу примеров на неуправляемом коде. Очень рекомендую для изучения. http://www.techdays.ru/ - на сайте собрано огромное количество официального видео по продуктам от MS. По Windows 7, есть достаточно большое количество роликов. Причем, ролики несут в себе реальную пользу, а не пиар :) http://habrahabr.ru - здесь всегда появляется новая и актуальная информация о всем, что связано с IT. Windows 7 не стала исключением. Есть как обзоры системы, так и посты касательно разработки приложений под новую ОС. http://blogs.microsoft.co.il/blogs/sasha/ - хороший блог по технологиям MS. Очень много постов касательно программига на C# и под Windows 7 в частности. Настроение портится лишь от того, что все посты на английском.
http://www.gumpi.com/Blog/2009/01/20/Alpha1OfWindows7ControlsForDelphi.aspx - набор компонент с помощью которого ты сможешь реализовать описанные в статье приемы, используя в качестве среды разработки старый добрый Delphi.
Врезка № 2: А как же Delphi?
Вполне возможно, что ты из банды бывших дельфийцев, вынужденных через силу перейти на Visual Studio от корпорации зла. А что если у тебя есть проекты, требующие поддержки новой ОС и ее новых функций? Если твой ответ «да», то значит эта врезка для тебя. Специально для любителей старого доброго Delphi, Daniel Wischnewski создал пакет компонент под названием «Windows 7 Controls for Delphi». С помощью компонент входящих в набор ты с легкостью сможешь встроить в свое приложение поддержку следующих функций: 1. 2. 3. 4.
JumpList Overlay Icons ProgressBar Indication TaskBar Thumbnails
Неплохо? Если учесть, что все это бесплатно и безглючно работает на Delphi 7-2009, то это просто замечательно!!! Обязательно скачай и опробуй этот набор компонент на практике. Кстати, по практике использования этого наборчика есть статья в июльском номере электронного журнала VR-Online. Сами компоненты можешь слить по ссылке приведенной в первой врезке.
Written by Игорь Антонов aka Spider_NET E-mail: antonov.igor.khv@gmail.com
Менеджер отчетов Общий смысл написания этой статьи состоит в том, чтобы показать, как можно легко управлять большим количеством отчётов в своей программе для определённой категории. Сама идея такой реализации использовании отчётов родилась давно, но реализовать её пришлось только недавно на своём проекте АРМ: Торговля и склад. Немного нюансов Сам проект, конечно, предоставлять не буду, так он коммерческий, а во-вторых "увесистый". Но суть самого проекта, да и идеи создания менеджера отчётов распишу вкратце. Суть самого проекта заключается в реализации программного обеспечения для работы как на складе, так и на кассе (в торговом зале). Раз есть модуль склад, то он в себе подразумевает группу документов: приходные документы, расходные документы, списание товара, возврат товара, продажи по кассе и т.д. И к каждой группе документов соответствуют свои отчёты. Например, к приходным и расходным документам относятся такие отчёты как "Приходная и расходная накладная", "Печать ценников на оприходованный товар", к списанию товара или передачи в другой отдел соответствуют такие отчёты как "Акт на списание", "Накладная на списание"; к документам Продажи по кассе соответствуют "Список чеков на дату", "Справка отчёт кассира – операциониста" и т.д. Как видно из перечисляемых отчётов, их просто большое количество, а как для определённого документа выполнить тот или иной отчёт? Для этого и сделан менеджер отчётов. Ну в общем случае, картину действий я описал, теперь приступим к реализации задуманного. Структура БД Для этого первоначально необходимо определить структуру таблички, в которой будут храниться как физические названия, так и описание отчётов. В моём случае табличка называется RPT_LIST и имеет следующую структуру: -
ID_RPT //нумерация позиций отчётов NAME_RPT //название отчёта COMMENT_RPT //комментарий для отчёта VALUE_RPT //значение, которому будет соответствовать тип операции NAME_RPT_SHOT //физическое название отчёта
DDL таблицы CREATE TABLE RPT_LIST ( ID_RPT INTEGER NOT NULL, NAME_RPT VARCHAR(50) NOT NULL, COMMENT_RPT VARCHAR(255) NOT NULL, VALUE_RPT INTEGER NOT NULL, NAME_RPT_SHORT VARCHAR(50) NOT NULL );
Так со структурой разобрались, теперь перейдём к части проектирования проекта. Создадим новый проект, на форму бросим Panel, на панели разместим три кнопки и
назовём их btnPreview, btnPrint, btnExit. Также на форме разместим DBGrid и DBMemo. Выставим нужные Align у компонентов так, как это показано на рисунке 1.
Рисунок 1 Создадим DataMoule и бросим туда IBDataBase, IBTransaction, IBQuery, DataSources. Свяжем их, как обычно (подробно, смотрите в примере). Теперь дело осталось за малым: написать код и разобраться с алгоритмом действий. Алгоритм действий очень прост: при открытии формы, в DBGrid’е формируется список отчётов в зависимости от выбранного типа операции. В нашем случае за тип операций отвечают RatioButton’s и по умолчанию выбран тип "Приход". При выборе в гриде необходимого отчёта, в DBMemo отображается краткое описание для выбранного отчёта. Выбранный отчёт можно как просмотреть в предварительном просмотре, так и сразу вывести на печать. А теперь – код! С алгоритмом действий разобрались. Идём дальше... В написании кода вообще ничего военного нет, всё очень просто. Полный код проекта предоставлен ниже: Код модуля DataModule (назван в примере dm) Tdm.DataModuleCreate(Sender: TObject); begin // вызываем процедуру подключения БД frmMain.OpenBD; // Открываем DataSet для первичного формирования группы отчётов // для определённого типа операции IRep.Open; end;
Код главной формы frmMain //процедура, которая отвечает за динамическое подключение БД procedure TfrmMain.OpenBD; begin
//путь до БД dm.IBDatabase.DatabaseName := ExtractFilePath(Application.ExeName)+'\base.fdb'; with dm do begin try IBDatabase.Connected := True; IBTransaction.Active := True; except on E:Exception do begin Application.MessageBox(PChar('Не удалось подключиться к серверу!' + #10#13+#10#13 + e.Message),'Пример',MB_OK + MB_ICONERROR); Close; end; end; end; end; procedure TfrmMain.RadioButton1Click(Sender: TObject); begin with dm.IRep do begin close; sql.Clear; sql.Text := 'select * from rpt_list where value_rpt = ' + QuotedStr(IntToStr((Sender as TRadioButton).Tag)); Open; end; end; //кнопка просмотра procedure TfrmMain.btnPreviewClick(Sender: TObject); begin //Создаём объект Rep := TfrxReport.Create(self); //загружаем отчёт Rep.LoadFromFile(ExtractFilePath(Application.ExeName)+dm.IRep.FieldByName('n ame_rpt_short').AsString); //просмотр отчёта if rep.PrepareReport then rep.ShowPreparedReport; //освобождаем память rep.Free; end; procedure TfrmMain.btnExitClick(Sender: TObject); begin Close; end; // кнопка печати procedure TfrmMain.btnPrintClick(Sender: TObject); begin //Создаём объект Rep := TfrxReport.Create(self); //загружаем отчёт Rep.LoadFromFile(ExtractFilePath(Application.ExeName)+dm.IRep.FieldByName('n ame_rpt_short').AsString); //печать отчёта
if Rep.PrepareReport then Rep.Print; //освобождаем память Rep.Free; end;
Ну, вот в принципе и вся задумка по этому делу. Полный вид написанного выше примера выглядит как на рисунке 2
Рисунок 2
База данных создавалась на СУБД FireBird 1.5.4. Для работы примера, необходимо чтобы СУБД была установлена!!! Исходники примера ищи в папке с журналом
Автор: Савельев Андрей aka dron-s Сайт: http://www.reportingfor.info/ru/ e-mail: dron-s@yandex.ru
FastReport: пользовательские функции У многих разработчиков работающих с БД и проектировании отчётов в FastReport не раз возникал вопрос: как использовать свои функции в отчётах? Для этого в FastReport есть пользовательские функции. Как использовать и как добавить их в FastReport, попытаюсь рассказать в этой статье. Стандартный набор пользовательских функций выглядит как на рисунке ниже
Все функции в дизайнере FastReport распределены по категориям и делятся на: 1. математические 2. агрегатные 3. текстовые 4. конвертирование 5. прочие 6. дата и время 7. форматирование И так, приведу пример добавления пользовательской функции Округления до нескольких знаков после запятой. Полный аналог функции RoundTo из модуля Math.pas. В стандартной комплекте FastReport есть пользовательская функция Round – округление до целого числа, но не редко требуется вывести результат, чтобы он был округлён до определённого знака. Для этого я написал функцию MyRoundTo, выглядит она следующим образом function MyRoundTo(X:Extended; N: Integer): Extended; var i,i1: Integer; begin Result := X; i1 := 1; for i := 1 to N do
i1 := i1*10; result := Round(Result*i1)/i1; end;
Подключение функций производится через интерфейс скриптовой библиотеки FastScript, входящей в состав FastReport. Для добавления нашей функции в FastReport, необходимо отредактировать файл fs_isysrtti.pas, находящийся в ./FastReports/FastReport 4/FastScript. Именно в этом файле и описаны все пользовательские функции. Преступим к редактированию файла fs_isysrtti.pas. Откроем его с помощью любого текстового редактора (я использовал текстовый редактор Bred). После секции implementation вставим код нашей пользовательской функции, описанный выше.
Для того, чтобы наша функция появилась в списке доступных в дизайнере отчётов, необходимо её добавить в конструкцию constructor TfsSysFunctions.Create следующим образом AddMethod('function MyRoundTo(X:Extended; N: Integer): Extended', CallMethod6, FCatMath)
Далее, найдём поиском по документу функцию CallMethod6 и добавим следующий код
После всех сделанных изменений, сохраним файл. После чего необходимо перекомпилировать исходники скриптовой библиотеки FastScript. Для этого, запускаем ReCompile.exe из корневой папки FastReport, в пункте What you want to do, выбираем Recompile on packages и нажимаем кнопку Compile (при компиляции IDE должна быть закрыта).
После компиляции, откроем дизайнер FastReport, перейдём на вкладку Functions и увидим, что списке функций появилась наша функция
Попробуем использовать нашу функцию на простом примере. К примеру, необходимо округлить число -2.656654 до 3-х знаков после запятой, а число -5.75656324 до 5-ти знаков после запятой. Сделаем, как показано на рисунке ниже и нажмем на просмотр.
Видим, что всё работает как положено.
Автор: Савельев Андрей aka dron-s Сайт: http://www.reportingfor.info/ru/ e-mail: dron-s@yandex.ru
Делаем мобильную версию сайта В последнее время упрямо и неотвратимо наблюдается тенденция роста мобильных устройств. И это я сейчас имею в виду вовсе не звонковоэсэмэсные трубки, я говорю о смартфонах, коммуникаторах и даже КПК. Девайсы эти действительно мобильны, удобны и вполне юзабельны для сравнительно простых пользовательских задач (вот, например, эту самую статью я набираю на коммуникаторе, вольготно развалившись на диване), в том числе и для серфинга по вебу. И все было бы просто замечательно, если бы не одно "но" - размер дисплея у коммуникатора куда как меньше аналогичного параметра у более-менее современного десктопа.
Результат: на мобильных устройствах сайты выглядят достаточно искаженно, а уж если в оформлении веб-ресурса активно используется графика, тут и вовсе впору закрывать голову руками и давать себе зарок никогда не блуждать по вебу с таких девайсов. Особенно обидно, когда Ваше собственное творение переколбашивается на мобильных дисплеях, обидно стало и мне. Ну а поскольку сдаваться не в моих привычках, я и начал поиск другого решения. Все начинается с идеи Идеи и зацепки искать даже не пришлось - сразу было решено создать отдельную версию блога для мобильных устройств, по внешней аналогии с тем, как это сделано в сервисах того же Яндекса или Вконтакте (понятное дело, мне неизвестно, каким образом это у них организовано на уровне кода, я опирался лишь на внешнее оформление ресурсов и на структуру адресной строки). Перед тем, как начать описание этого действа, хочу уточнить, что я опирался на максимальную универсальность, от хостинга требуется лишь поддержка алиасов, ну и, само собой, PHP, поскольку блог мой написан именно на нем. Я ничуть не сомневаюсь, что существуют и другие варианты решения, но те, что я сумел раскопать, пока решал эту задачку, были более требовательны. Хоть я и не собираюсь пока переезжать со свого удобного хостинга, хочется все же быть наименее связанным в случае, если переезд все же понадобится. На сем прелюдия закончена, переходим к делу. Начинаем действовать Адрес был выбран интуитивно - pda.sitename (Хотя подумывал еще и о "mobile", признаться). Для начала решил не заморачиваться с поддоменами, несмотря на то, что адрес мобильной версии по всей логике должен быть таковым. Должен, да не обязан, потому я просто-напросто поковырялся в конфиге виртуального хоста и добавил строчку примерно такого вида (Вполне возможно, что Ваш хостер предусмотрел еще более дружественную к пользователю работу с алиасами, кстати, у моего хостера это предусмотрено, в конфигах я ковырялся в локальной сети): ServerAlias pda.sitename
Ковыряю настройки виртуального хоста
Порядок, теперь адрес для pda-версии успешно обрабатывается и выдает нужную и правильную страницу. Одна проблема - десктопную. Что ж, раз пошла такая пьянка, воспользуемся сессиями, что им почти без дела простаивать. Через несколько секунд в сессии появилась новая переменная $_SESSION['view_pda'], которая и стала хранить тот "переключатель видов страницы" таким вот образом (Кстати, аналогичного результата можно добиться и не используя сессионные переменные, я выбрал их лишь потому, что обычную переменную $view_pda можно изменить и не заметить, а потом долго копаться в коде, выискивая, где же случилась такая мерзопакость. А вот во время перезаписи сессионной переменной невольно задумаешься о том, что же в ней такого особенного хранится, что ей выпала честь попасть в $_SESSION[].): <?php session_start(); $_SESSION['view_pda'] = (strpos($_SERVER['HTTP_HOST'], 'pda.') !== false) ? true : false; ?>
Немного о том, почему используется “!==”, а не просто “!=”. Дело в том, что нам нужно проверить не только возвращаемое значение, но тип этого самого значения. Если написать “!=”, то вернется 0, который, по всей логике есть “false”, а значит, скрипт будет считать, что строка “pda.” не была найдена и успешно начнет выдавать нам десктопную версию сайта. А вот когда мы проверяем не только возвращаемое значение, но и его тип, то все будет отлично, в этом случае “0” и “false” являются совершенно разными значениями, что нам как раз и требуется.
Такой внешний вид получил раздел “Новости”
Собственно, на этом можно и закончить, остальное было уже делом техники: создать файл стилей для мобильной версии, упростить саму структуру страниц для нее же, нарисовать дополнительные картинки и все такое прочее. Здесь, я думаю, никаких белых пятен и темных областей для Вас, уважаемый мой читатель, не обнаружится. А значит, мне остается сказать свое "приятного чтения свежего номера VR-Online" и поставить финальную точку.
Written by ZeroXor WWW: http://zeroxor.ru/
Печать ценников Наверное, у многих при разработке программ, связанных с товарооборотом, возникает такая необходимость, как печать ценников по количеству товара. В этой статье, я покажу, как это можно сделать, используя FastReport. Куем базу данных Для того чтобы продемонстрировать наглядно печать ценников, создадим БД со следующей структурой: CREATE TABLE CENNIK ( ID_CENNIK INTEGER NOT NULL, NAME_TOVAR VARCHAR(100), PROIZVOD VARCHAR(30), DATA_CENNIK DATE, KOLVO_TOV INTEGER, ARTIKUL VARCHAR(7), CENA_TOV NUMERIC(15,2) ); Добавим к полю ID_CENNIK генератор и треггер: CREATE GENERATOR GEN_CENNIK_ID; SET TERM ^ ; CREATE OR ALTER TRIGGER CENNIK_BI FOR CENNIK ACTIVE BEFORE INSERT POSITION 0 AS BEGIN IF (NEW.ID_CENNIK IS NULL) THEN NEW.ID_CENNIK = GEN_ID(GEN_CENNIK_ID,1); END ^ SET TERM; ^
Заполним нашу таблицу следующими позициями INSERT INTO CENNIK (ID_CENNIK, NAME_TOVAR, PROIZVOD, DATA_CENNIK, KOLVO_TOV, ARTIKUL, CENA_TOV) VALUES (1, 'Юбка ', 'Москва', '2009-01-25', 5, '0000001', 1500); INSERT INTO CENNIK (ID_CENNIK, NAME_TOVAR, PROIZVOD, DATA_CENNIK, KOLVO_TOV, ARTIKUL, CENA_TOV) VALUES (2, 'Шорты', 'Турция', '2009-01-06', 10, '0000002', 100); INSERT INTO CENNIK (ID_CENNIK, NAME_TOVAR, PROIZVOD, DATA_CENNIK, KOLVO_TOV, ARTIKUL, CENA_TOV) VALUES (3, 'Топ', 'Германия', '2008-12-15', 2, '0000003', 230);
Обмозгуем алгоритм Для того, чтобы напечатать ценники по количеству товара, необходим некий алгоритм. Наш алгоритм будет таким - необходимо создать столько позиций на выходе, сколько есть
количество товара. На первый взгляд алгоритм непонятен. Не волнуемся и смотрим далее. Я реализовал этот алгоритм на хранимой процедуре и назвал её EOF_KOLVO. Выглядит она следующим образом CREATE PROCEDURE EOF_KOLVO ( in_kolvo integer) returns ( res integer) AS begin res = 0; while (in_kolvo > 0) do begin res = res + 1; in_kolvo = in_kolvo - 1; suspend; end end^
Что делает эта процедура? Она получает входной параметр, который равен количеству товара. Внутри процедуры выполняется цикл на уменьшение количества товара для каждого прохода. В итоге на выходе получаем количество позиций равное количеству товара одной позиции. Всё очень просто, как оказалось. А теперь сотворим отчет В принципе, задача уже решена на 70%. Далее необходимо построить сам отчёт. Для этого, запустим Delphi, бросим на форму frxReport, frxIBXComponents, IBDatabase, IBTransaction. Подключим БД к IBDatabase, у IBTransaction выберим DefaultDatabase равным IBDatabase. Откроем дизайнер отчётов кликнув дважды по frxReport. На вкладке Data дизайнера отчётов расположим frxIBXQuery и назовём его Tovar, дважды кликнем по нему и в редакторе SQL добавим следующий SQL запрос. SELECT c.name_tovar, c.proizvod, c.data_cennik, c.kolvo_tov, c.artikul, c.cena_tov FROM cennik c LEFT OUTER JOIN eof_kolvo(c.kolvo_tov) ON (0=0)
Этот запрос и сделает всё, что для нас необходимо используя хранимую процедуру EOF_KOLVO. Далее перейдём к моделированию отчёта. Для этого перейдём на вкладку Page1 дизайнера отчёта, положим на него бэнд MasterData1, подключим его к источнику данных Tovar. У ценников, есть определенный формат (размер). В моём случае размер ценников равен 5x4. Чтобы в одной строке было несколько ценников разделим MasterData1 на колонки, для этого выставим свойство Column равным 4. Общий вид отчёта получился, как показано ниже.
Для того чтобы просмотреть конечный результат, нажмём Предварительный просмотр на панели управления или функциональные клавиши Ctrl+P. У меня он выглядит следующим образом.
Итог сей сказки Если мы посмотрим заполненную таблицу CENNIK, то увидим, что у позиции Юбка количество товара равно 5 и цена её составляет 1500р, а на рисунке выше, мы видим что ценников для этой позиции именно 5. Поставленная задача выполнена. P.S. для работы БД необходим SQL сервер FireBird 1.5.4 Все необходимые файлы приложены к журналу
Автор: Савельев Андрей aka dron-s Сайт: http://www.reportingfor.info/ru/ e-mail: dron-s@yandex.ru
Что нового нам принес новый дельфин Смотрим и оцениваем новые фишки любимого Delphi Не так давно, компания Embarcadero презентовала новую версию RAD Studio. Я думаю, многие Delphi-программисты ждали этого события. Увы, за последние годы Delphi сдал свои позиции и серьезно пропустил вперед своего главного конкурента – C#. Причин тут много и в этой статье о них я говорить не стану. Куда важней для меня, рассказать тебе про те новинки, которые бросились в глаза и самое главное, смогли заинтересовать меня. Где взять обновленного Delphi’на Я понимаю, что наш журнал читает много новичков, и некоторые из них могут испытывать трудности, с получением новой версии RAD Studio. Если ты в курсе, о месте, где берут Delphi, то этот раздел можешь смело пропускать. Итак, ты решил поюзать на практике новый релиз, но не знаешь где его взять. Не буду читать долгих нотаций, а лучше сразу укажу пальцем в нужном направлении https://downloads.embarcadero.com/free/delphi. С этой страницы ты можешь стянуть либо Delphi 2010 Architect или же RAD Studio 2010 Architect. Не смущайся размеру представленных файлов. Delphi не смог похудеть до 16 мегабайт, а архиваторов, способных сжать бинарник до такого размера еще не придумали . Дело в том, что тебе дается возможность загрузить Download версию. После запуска загруженного инсталлятора, мастер установки предложит тебе отметить возможные пакеты для загрузки и после чего начнет их автоматически тянуть с инета. Общий размер зависит от количества пакетов, которые ты выберешь. Могу сказать, что в среднем придется раскошелиться на 100 метров входящего трафика. Отсюда вывод: gprs пользователи, будьте осторожны! Закачка может быть опасна для вашего баланса . Не стоит также забывать, что скачанный таким образом Delphi будет trial'ным и прослужит тебе верой и правдой лишь 30-ть дней и столько же ночей. После этого срока, наглый дельфин начнет клянчить не малые деньги за показ новых трюков . Если денег нет, а юзать хочется, то тогда твой путь – torrents.ru и множество других трекеров. Только учти, я не призываю тебя пользоваться пиратским софтом, т.к. это очень плохо . Установка Установка практически ничем не отличается от инсталляции других версий delphi. Все тот же мастер (если сравнивать с версией D2009), стандартные вопросы и до боли знакомые глазу кнопки – Next, Cancel, Finish. Могу лишь сказать, что на глаз процесс установки завершился быстрее, чем в случае с Delphi 2009. Мелочь, а приятно . Запуск Чтобы не говорили разработчики, а IDE легче не стала. Во всяком случае, на глаз это хорошо заметно. Само время загрузки осталось неизменным (по сравнению с Delphi 2009), а вот тормозов в работе стало явно меньше. Не стоит обольщаться и ждать сверх быстрого старта любимой среды. Медленный старт – не означает, что к финишу придешь последним.
А теперь о новинках Не буду больше ходить вокруг да около, а сразу приступлю к описанию всех замеченных мной фишечек. Заметить, это список далеко не полон. Все то, про что я забыл написать, ты сможешь прочесть в официальном reviewer guide. Будь осторожен, он на английском, не забудь приготовить словарик!
Рисунок 1 (Устанавливаем RAD Studio 2010) Новинка №1 – Классический интерфейс Не знаю как, но лично я начал работать с delphi еще с 5-версии. Эх, давненько это было и столько воды утекло с того славного времени. Тогда я с не поддельной радостью наслаждался расстановкой компонентов на форме и игрался с их свойствами. Сегодня меня этим не удовлетворишь, хочется куда более острых ощущений. Черт, я немного отвлекся и замечтался. Вернемся к теме. Проработав несколько лет с Delphi, я окончательно привык к его интерфейсу. Во всех версиях он был практически неизменным и после выхода версии 2005 я испытал первый дискомфорт. Те, кто прошел через все версии, наверное, догадались, о чем я говорю. Разработчики Delphi, решили начать подражать внешнему виду Visual Studio и интерфейс Delphi сделали в таком же стиле. Да, GUI студии мне по душе, но я мой мозг приходит в состоянии шока, когда видит его применительно к Delphi. Не подумай, что я придираюсь. Стиль VS очень хорош и удобен. Более того, сегодня я его считаю идеальным, но старый добрый Delphi мне больше по душе в классической шкурке.
Конечно же я смирился с новым видом (хотя с delphi, мне теперь приходится работать не часто), но вот тут я увидел, что в новой версии дельфина, разработчики приготовили приятный сюрприз – возможность выбирать стиль интерфейса. Ты не ошибся! Если тебе нравится Delphi 7 style, то ты запросто сможешь воспользоваться им в D2010. Посмотри на рисунок 2. На нем как раз показан вид Delphi после смены интерфейса на классический.
Рисунок 2 (Delphi в классическом костюме)
Переключиться к old-скульному виду, ты всегда можешь через меню View -> Desctops -> Classic Undocked. Чтобы вернуться на новомодный стиль, в этом же пункте меню выбери Default Layout. Новинка №2 – Обновленный поисковик по модулю Одной из неизменяемых возможностей Delphi всегда было окно поиска текста в модулях. В версии 2010 и это окошко коснулось изменений. Теперь оно выглядит как на рисунке 3 и скромненько располагается в нижней части окна рабочей области. Не могу сказать, что от этой новинки можно ахнуть, но пользоваться стало точно удобней, да и выглядит вполне хорошо. Делаю вывод – красиво, удобно, но не сильно нужно. Я бы смог прожить и со старым вариантом поиска.
Рисунок 3 (Обновленный поиск)
Новинка №3 – Функция поиска в окне выбора типа проекта При создании нового проекта, теперь стало возможным воспользоваться поиском и собственно говоря, найти нужный шаблон проекта (смотри рисунок 4). При вводе очередного символа, IDE будет пытаться найти шаблон, удовлетворяющий запросу. Например, я ввел слово Active и моему взору предстали проекты, связанные с разработкой ActiveX компонентов.
Рисунок 4 (Функция поиска) Опять же, не могу сказать, что эта фича очень полезная, но иногда она бывает очень кстати. Во всяком случае, пару секунд своего драгоценного времени, ты сможешь сэкономить . Новинка №4: Компилирование в фоне При выполнении компиляции больших проектов, всегда сталкиваешься с одним досадным ограничением. Пока происходит компилирование – IDE становиться недоступной. Нельзя писать код, выполнять необходимые действия и т.д. Все прям, как в песни: «Все здесь замерло до утра..». Было бы здорово, если IDE не блокировалась, а с удовольствием выполняла твои приказы. Какие приказы могут быть во время компиляции? Да самыми разными! Вот тебе несколько примеров: расстановка бряков (точек останова), банальное комментирование кода и т.д. Не могу сказать, что такие потребности возникают постоянно, но все же они бывают. В 2010 версии RAD разработчики решили эту проблему путем создания опции – «фоновая компиляция». Не трудно догадаться, что ее смысл заключается в запуске компилятора в отдельном потоке. Пока он будет трудиться, мы сможем заниматься полезными вещами.
По умолчанию, режим фоновой компиляции отключен. Для его активации сбегай в Options и в разделе Environment Options (рисунок 5) группы Compiling установи флажок – «Background Compilation». Здесь же ты можешь задать для него приоритет.
Рисунок 5 (Заюзаем фоновую компиляцию) Новинка №5: Держим на контроле сообщения компилятора По сути это мелочь, но крайне полезная. В меню View, появился новый пункт – Messages, позволяющий вывести окно, содержащее все сообщение компилятора в хорошо структурированном виде. Попробуй эту фичу в деле (рисунок 6).
Рисунок 6 (Окно Messages)
Новинка №6: IDE Insight Дословно название IDE Insight можно перевести как "Итуитивная IDE". Это одна из ключевых новинок Rad Studio. Данная штучка позволяет разработчикам (т.е. нам) быстренько найти нужную функцию среды разработки или компонент. Для вызова окна IDE Insight, нажми клавишу F6. В появившемся окне есть строка поиска. Попробуй в ней написать название какой-нибудь функции IDE. Я, например, написал Background (хотел найти опцию «Компиляция в фоне») и IDE Insight выдал мне ссылку на соответствующую настройку в меню Options. Выглядит это удобно и прикольно. Особенно фича пригодиться тем, кто постоянно играется с настройками. Я пока к ней отношусь скептически. Идея интересная, но мне она не шибко нужна, т.к. IDE я настраиваю один раз, а потом просто юзаю. Радует, что быстрым поиском настроек среды разработки, возможности IDE Insight не ограничены. Открой свой проект и выбери любую форму. Теперь вызови IDE Insight и напиши название любого-компонент. Сию секунду, будет выдана ссылка на соответствующий компонент в палитре компонент. Для примера я написал grid и IDE Insight выдал мне компоненты, в имени которых содержится введенное мной слово. Точно таким же образом ты можешь найти компонент на своей форме. Вот для этой цели, я скорей всего и буду юзать IDE Insight. Кстати, эту функцию можно выполнить не только посредством горячей клавиши F6. Точно такого же результат можно достичь путем одновременного нажатия кнопок CTRL + . (контрол + точка).
Рисунок 7 (IDE Insight во всей красе)
Новинка №7: Улучшения в редакторе кода
Редактор кода также претерпел приятные изменения. Я особо не копал, но вот следующие фишки особенно бросились мне в глаза: 1. Шаблоны кода. Постоянное написание операторов, которые требует закрывающих операторов (например, begin..end, try...finally) может довести до нервного приступа. Мне очень понравилось, что теперь появилась возможность самостоятельно создать шаблоны. После установки Rad Studio 2010 к твоим услугам будут шаблоны по умолчанию (которых кстати хватает). Войди в редактор кода и как пример напиши ключевое слово Try. После этого клацни на enter и увидишь работу шаблонов в действии. 2. Свертка кода. Во всех современных IDE уже давно есть такая фича как группировка кода, расположенного между закрывающими операторами. Типичным тому примером является блоки - If then и begin end. В Delphi 2010 эта фича также реализована. Пользуйся на здоровье. Однако жаль, что она не работает для циклов. Мне очень много приходится разрабатывать приложений на встроенном в 1С языке, и вот в тамошней IDE такая штука есть. Т.е. код, написанный, в цикле тоже может своравичиваться. Интересно, почему разработчики Delphi это не предусмотрели? 3. Правильные отступы. Меня всегда бесило, что при выделении какого-то куска кода и нажатия клавиши tab весь текст пропадал (в Delphi 7 точно было так). Хотя я ожидал, что он просто сдвинется вправо. Особенно это раздражало при нехватке времени. Бывало, выделишь быстро кусок кода, нажмешь tab, а затем резко Ctrl+s и все. Код пропал. Ctrl + Z уже не помогал. Так вот, в Delphi 2010, все работает, как должно быть. 4. Автоматическая отбивка отступов. Я программирую уже давно и привык писать хорошо структурированный код. Т.е. кода в стиле "все на одном уровне", в реальных проектах я ни в коем случае не делаю. Сам понимаешь, что хорошо оформленный код облегчает понимание и дает гарантии, что через месяц-другой ты сам же в нем не запутаешься. Увы, но многие посетители нашего сайта (те, кто являются начинающими программистами) еще не выработали в себе эту чувство и шлют свои исходники в совершенно неоформленном виде. Я всегда стараюсь всем помогать и по возможности найти в их кодах ошибки, но первое что я делаю с их исходниками - отбиваю отступы. В зависимости от размера кода, на это уходит много времени, а у меня из-за огромного количества работы его мало. Я рад, что с появлением Delphi 2010 мне не придется заниматься этим в ручную. Благодаря функции Format Source (доступна по нажатию Ctrl+D или через контекстное меню редактора кода), от меня лишь требуется выделить не отформатированный код. Все остальное, сделает IDE. Буквально несколько секунд и передо мной уже читабельный код. На мой взгляд, эта одна из самых полезных новинок новой версии Delphi. Новинка №8: Экранная клавиатура для touch/multitouch приложений Уже наверное все знают, что в Windows 7 есть все необходимо для поддержки touch/multitach экранов. Не нужно ходить к гадалке, чтобы узнать, о перспективах данной технология в ближайшее время будет. А раз так, то не в коем случае, нельзя остаться в стороне. Придется немножко поднапрячься и сделать в своем приложении какие-нибудь финтивлюшки, используя данную технологию. В палитре компонент Delphi 2010 появился новый контол - TTouchKeyboard, представляющий собой клавиатуру, которую можно использовать при создании multitouch
приложений. Контрол довольно-таки симпатично выглядит и поддерживает множество языков ввода, а также технологию touch/multitouch. Очень приятно, что он не заточен лишь под Windows 7. Им ты можешь воспользоваться при создании приложений, ориентированных на работу в Windows 2000/XP/Vista. Все будет работать прекрасно, за исключением лишь возможностей multitouch. Увы, мультитач будет доступен лишь пользователям Windows 7. Новинка №9: Мелкие полезняшки Мелких полезных штучек в Delphi 2010 более, чем предостаточно. Вот те, которые больше всего мне бросились в глаза: 1. Настраиваемое меню Reopen. Если ты привык пользоваться возможностью "последние открытые файлы", то тебя может заинтересовать фича, позволяющая выполнить его настройку. В меню File -> Reopen появился пункт Properties, выбрав который, перед тобой откроется окно для настройки. В окне настройке ты можешь задать количество проектов и файлов, которые будут сохраняться в списке недавних файлов. Кроме того, ты можешь очистить этот список или удалить отдельные записи. 2. Визуализация просматриваемой, через отладчик информации. Перед тем как рассказать о том, что это такое, сначала я хочу похвалить разработчиков за эту возможность. Она действительно полезна и удобна в использовании. Теперь немного подробностей. Благодаря этой фичи, ты можешь в удобном виде просматривать отладочную информацию. Словами очень тяжело объяснить, поэтому я рекомендую тебе создать тестовый проект и написать небольшой кусок кода: var stringList:TStringList; begin stringList := TStringList.Create; stringList.Clear(); stringList.Add('Это первая строка'); stringList.Add('А вот это вторая строка'); stringList.Add('Последняя строчка'); ShowMessage(stringList.Strings[0]); end;
Теперь установи точку останова на строке с вызовом ShowMessage() и запусти приложение. У меня этот код повешен на обработчике события OnClick единственной кнопки. Я кликаю по кнопке и сразу попадаю в отладчик. Теперь выдели переменную stringList, шмякни правой кнопкой и в появившемся контекстном меню выбери Debug -> Evaluate/Modify. Выполнив это действие, перед тобой появится окно Evaluate/Modify. В нем, в поле Expression будет пестреть stringList. Ничего не изменяй, а просто нажми кнопку Visualizers и в выпавшей менюшке выбери Show Strings. Опять перед тобой отобразиться новое окно, в котором будут показан список строк и их индексов, находящихся в stringList. Очень симпатичненько и удобно. Попробуй, наверняка тебе это понравиться. 3. Перемещение точек останова с помощью мышки. Установи бряк, а потом перемести курсор мыши на появившийся красный кружок. Зажми левую клавишу мышки и попробуй переместить точку вверх или вниз. Брякпоинт должен будет переместится за твоим курсором.
4. Сортировка файлов в Project Manager. Тут все должно быть ясно. 5. Появилась поддержка Windows Image Component. Эта новинка позволяет использовать в проекте всевозможные форматы изображений. Новинка №10 Новый класс для работы с файлами Это последняя новинка, о которой я хочу тебе рассказать. Итак, в Delphi 2010 появился новый модуль IOUtils.pas - OO FileSystem Access. В нем описано несколько классов, с помощью которых ты сможешь комфортно работать с файловой системой. Взгляни на небольшой пример: var path:string; begin if not TDirectory.Exists(Edit1.Text) then begin ShowMessage('Нет такой директории!!!'); Exit; end else begin Memo1.Lines.Clear; for path in TDirectory.GetFiles(Edit1.Text, '*.*') do Memo1.Lines.Add(Format('Name = %s', [Path])); end;
В этом коде я выполняю проверку существования директории введенной в компоненте Edit. Если она существует, то я запускаю цикл и при помощи метода GetFiles класса TDirectory получаю имена файлов, расположенных в ней. Во втором параметре метода GetFiles я задаю фильтр - обрабатывать абсолютно все файлы. Заметь, никаких рекурсий и подобных трюков. Все решается с помощью возможностей класса. Приведенный пример - лишь малая часть функционала, реализованного в IOUtils.pas. Поскольку статья носит обзорный характер, то сейчас я не буду углубляться и рассказывать подробности. Возможно, для нового выпуска журнала я напишу отдельную статью, в которой расскажу про все те полезняшки, которые получает разработчик сделавший выбор в пользу этого модуля. На этом все Заканчивая свой небольшой обзор, я хотел бы подвести кое-какие итоги. Во-первых, Delphi 2010 действительно лучше Delphi 2009. Разработчики не ковыряли в носу целый год, а действительно работали и придумывали новые фичи. Пускай их не сильно много и они не носят революционного характера, но они полезные и ими наверняка будут пользоваться, а значит можно надеяться, что программисты не оставят Delphi еще на какое-то время. Ну а раз так, то у Embarcadero есть чем заниматься в ближайшем году.
Written by Игорь Антонов aka Spider_NET E-mail: antonov.igor.khv@gmail.com
Бот для твиттера на php Прочитав эту небольшую статейку, ты познаешь священные знания и сможешь создать клон известного сервиса twitterfeed. Шутка! Спрячь слюни обратно! Мы рассмотрим лишь макет, простейший прототип, который не готов к реальному использованию. Скажу сразу, я не собираюсь открывать свой исходник полностью. Я лишь покажу тебе, как производить аутентификацию, работать с rss, парсить твиты, благодарить и фоловить пиплов, которые выполняют ретвит наших сообщений. Интересно? Тогда читай дальше! Клонируем twitterfeed посредством php В нашем сценарии мы попытаемся реализовать следующие функции: * Запуск в консоле, без HTTP доступа * Аутентификация и твиттинг с помощью OAuth * Получение RSS, парсинг, формирование твиттов ограниченных 140 символами, включающих постфикс (хэштэг или RT). * Отправка благодарности пользователям, сделавшим ретвит сообщения нашего бота * Фоловинг людей, сделавших ретвит Все это мы установим и настроим в linux. А затем будем запускать при помощи crond каждые 15 минут. Ты готов? Тогда приступим! Регистрируемся Если решил использовать OAuth (а мы точно решили), то необходимо выполнить регистрацию своего приложения. Базовую аутентификацию использовать не стоит, т.к. твиттер рано или поздно может закрыть соединение. К тому же мы создаем персонального бота, а значит строка «from» обязана присутствовать в твитте. Регистрацию выполнить очень легко. Достаточно лишь запустить свою бродилку и перейти на страницу Twitter OAuth Clients (http://twitter.com/oauth_clients). Если открыв страницу ты не увидел ничего полезного, то не пугайся. Выполни вход под своим аккаунтом и повтори открытие страницы. Сам процесс регистрации выглядит достаточно просто. Проверь только, а не забыл ли ты при регистрации в качестве прав доступа выбрать Read and Write (чтение и запись). Кроме того, проверь, что мы полностью исключили http доступ для управления ботом. Мы заюзаем PIN, основанный на OAuth, поэтому убедись, что в форме регистрации установлен Client Appliaction. По окончании регистрации, тебе будет предоставлен Consumer Key и Consumer. Не в коем случае не потеряй и не передавай эти секретные данные! Настраиваем окружение Что еще за окружение? Так, обо всем по порядку. В сегодняшем уроке нам придется воспользоваться следующими штуками: 1. Magpie RSS (http://magpierss.sourceforge.net). Это либой мы воспользуемся для разбора rss фидов.
2. Curl (http://ru2.php.net/curl) – для доступа к Twitter API; 3. Twitter OAuth Class (http://github.com/abraham/twitteroauth), написанный Abraham Williams. Проверь, что ты все установил и верно настроил – функции magpie и curl’a работают, а класс Twitter OAuth подключен. Чуть не забыл. Нам еще потребуется учетка для сервиса bit.ly (http://bit.ly/account/register). Можешь не ограничиваться bit.ly, а воспользоваться любым другим сервисом для сокращения URL, но в статье я буду ориентироваться именно bit.ly. Аутентификация: Хранение ключей доступа Весь наш проект мы разделим на две части. Первая будет автоматически стартовать раз в 15 минут, а вторая будет запускаться лишь раз - для аутентификации. Подготовительные действия завершены. Создавай новый файл сценария и назови его oauth.php (или как твоей душе угодно). Поразмышляй и определись с местом хранения consumer key и secret. Я предпочитаю держать такие вещи в файле config.php, который затем будет подключаться с помощью банального include/require к auth.php и robot.php
Сценарий oauth.php будет запускаться самостоятельно, и принимать параметры командной строки. Примерно так: php oauth.php register
Результатом работы этой команды будем выполнение запроса на этот линк: https://twitter.com/oauth/authorize?oauth_token=whatever. Или еще вот такой пример: php oauth.php validate 123456
После того как ты проверил OAuth сессию, ключи доступа будут храниться где-то на диске. Свои файлы я назвал access_token и access_token_secret. Если они присутствуют, тогда ёбот сможет отправлять твиты, в противном случае перейдет к регистрации. Надеюсь, что здесь все понятно. Читаем твит-ленту из RSS Нам с тобой необходимо научить нашего бота, различать команды, которые мы будем ему передавать. Не забудь, мы договорились, что все команды будут передаваться в виде параметров командной строки. Код обработки команд можешь реализовать любым способом. Мой вариант выглядит так: $action = $argv[1]; if ($action == "feed") { $feed_name = $argv[2]; // Read the feeds, tweet the feeds } elseif ($action == "rthx") { // Read the names, tweet the names! } elseif ($action == "reply") { // Read the names, umm.. Say something! }
Управлять ботом будем так: # php robot.php feed wordpress Чтение статей wordpress # php robot.php rthx Благодарность и фоловинг тех людей, которые сделали ретвит нашего сообщения # php robot.php reply Отправка сообщения
Хорошо, теперь представим, что мы находимся в rss фиде. Объявите ассоциированный массив, содержащий пути к rss лентам: $feeds = array( "wordpress" => array("url" => http://wordpress.org/development/feed/", "postfix" => "#wordpress"), "mashable" => array("url" => "http://feeds2.feedburner.com/Mashable", "postfix" => "via (@mashable)"), );
Двух фидов для начала хватит. Теперь сделаем так, что наш бот твитил #wordpress, читал и твитил последние новости через @mashable. Проверь, что код проверки для access_token и access_secret уже написан и не выдает сообщение об ошибке. Я предполагаю, что ключи сохранены в $access_token и $access_token_secret соответственно и выполнили инициализацию объекта $oauth:
$oauth = new TwitterOAuth($oauth_consumer_key, $oauth_consumer_secret, $access_token, $access_token_secret);
Второй параметр («wordpress», в примере выше) будет храниться в переменной $feed_name. Теперь перейдем к рассмотрению следующего кода: // Store the feed settings into $feed $feed = $feeds[$feed_name]; // Fetch the feed and store the prefix $rss = fetch_rss($feed["url"]); $postfix = $feed["postfix"]; // Loop through the feed items foreach ($rss->items as $item) { // All simple enough here $title = trim($item["title"]); $url = $item["link"]; // Let's make sure our feeds are in English, allow spaces and punctuation if (ereg('^[[:alnum:][:blank:][:punct:]]+$', $title)) { // Escape the URL for bit.ly shortening and then shorten the link // This is the place where you have to use your bit.ly login // And the API key $url_escaped = urlencode($url); $bitly_url = "http://api.bit.ly/shorten?version=2.0.1"; $bitly_url .= "&longUrl=$url_escaped"; $bitly_url .= "&login=$bitly_login&apiKey=$bitly_key"; $shortened_url = json_decode(file_get_contents($bitly_url)); // If everything went okay, go on if ($shortened_url->errorCode == 0) { // Retrieve the shortened url from the json object foreach ($shortened_url->results as $key => $value) $shorturl = $value->shortUrl; // Form a new message from the short URL and the postfix $message = " $shorturl $postfix"; $length = strlen($message); // We should trim down the title if it's too long // So that our tweets are 120 characters or less if (strlen($title) > 120-$length) $shorttitle = substr($title, 0, 117-$length) . "..."; else $shorttitle = $title; // Add the title to the message $message = $shorttitle.$message; // Post the message to Twitter $oauth>OAuthRequest('https://twitter.com/statuses/update.xml', array('status' => $message), 'POST'); // Wait a couple of mintes before the next tweet // Don't try and flood Twitter, remember, you have // Only 150 API calls per hour, use them wisely. sleep(rand(60,120)); } } }
Внимательно прочитай комментарии. По ним ты должен разобраться с кодом. Все, с RSS закончили. Теперь посмотрим на реализацию ретвитов. Фоловим и говорим спасибо Будь внимательным при создании этой части. Ты же не хочешь благодарить человека за ретвит несколько раз? Если ты со мной согласился, то тебе придется позаботиться о хранении идентификатора (id) последнего ретвита, за который уже была отправлена благодарность. Идентификатор будем в параметре $since_id. Этот алгоритм я оставлю на твою совесть, но вообще, у тебя должно получиться примерно так: // Read the since_id from a file $since_id = @file_get_contents("retweets_since_id"); if ($since_id > 0) { } else { $since_id = 1; } // Send the Twitter API request for the latest 50 mentions // That were posted after the since_id parameter we read earlier $mentions = $oauth->OAuthRequest("http://twitter.com/statuses/mentions.xml" , array("count" => 50, "since_id" => $since_id), "GET"); // Make the XML an object $mentions = simplexml_load_string($mentions); // Setup an array which will contain users to retweet and follow $users_to_rthx = array(); // Read the last tweet's id and store it into the retweets_since_id file $last_id = ($mentions->status[0]->id > $since_id) ? $mentions->status[0]->id : $since_id; file_put_contents("retweets_since_id", (string)$last_id); // Loop through the tweets foreach ($mentions->status as $status) { // Let's see if somebody retweeted you. // Err, remember to replace @yourname if (strpos(strtolower($status->text), "rt @yourname") || strpos(strtolower($status->text), "via @yourname")) { // Add the guy to the retweeters array $users_to_rthx[] = $status->user->screen_name; } } // Remove duplicates (we don't thank somebody twice in a tweet) $users_to_rthx = array_unique($users_to_rthx); // Setup the tweet prefix and initialize the mentions variable // The tweet_prefix is just in case ;) $tweet_prefix = "Thanks for the retweets! "; $tweet_mentions = ""; $tweet_prefix = ""; // Loop through the retweeters popping variables out of the array while ($mention_this_guy = array_pop($users_to_rthx)) { // If the popped guy fits into our brand new tweet, add him if (strlen($tweet_prefix . $tweet_mentions . $tweet_postfix . "@".$mention_this_guy) < 140) {
$tweet_mentions .= "@".$mention_this_guy . " "; // Send the friendhips create (follow) request to the API echo "Following: " . $mention_this_guy; $oauth->oAuthRequest("https://twitter.com/friendships/create/" . $mention_this_guy . ".xml", array(), "POST"); } // If he doesn't push him back into the variable, tweet and reset // The $tweet_mentions variable for the other retweeters else { array_push($users_to_rthx, $mention_this_guy); // Format the message and output to screen (for debugging) $message = $tweet_prefix . trim($tweet_mentions) . $tweet_postfix; echo "Tweeting: " . $message . " (" . strlen($message) . ") \n"; // Send the status update request to the Twitter API $oauth>OAuthRequest('https://twitter.com/statuses/update.xml', array('status' => $message), 'POST'); // Wait a few seconds before the next round sleep(rand(5,30)); // Reset $tweet_mentions = ""; } } // If we've got something left in the mentions, we need to tweet that if (strlen($tweet_mentions) > 0) { $message = $tweet_prefix . trim($tweet_mentions) . $tweet_postfix; echo "Tweeting: " . $message . " (" . strlen($message) . ") \n"; $oauth->OAuthRequest('https://twitter.com/statuses/update.xml', array('status' => $message), 'POST'); sleep(rand(5,30)); $tweet_mentions = ""; }
Генерим случайные ответы Эта самая забавная часть часть. Всякий раз, когда кто-то упоминает наше имя (и это не ретвит), наш бот будем отправлять ему необычное сообщение, не забывая при этом упомянуть свое имя. Код выглядит примерно также как и код, которым мы говорили спасибо за ретвит. Единственным исключением является поиск «rt @yourname» и «@yourname». Не забудь сохранить replies_since_id, т.к. нам не нужно, чтобы сообщение отправлялось пользователям несколько раз (бесконечное количество раз). Мы же не хотим, чтоб нас забанили? Мой код выглядет так: // The loop while ($mention_this_guy = array_pop($users_to_reply))
{ // Some random quotes ;) You can add your own $random_quotes = array( "Wha?", "Interesting ...", "Affirmative sir!", "Hmm, makes me think ..", "So you really think I'm not human? Well.. Umm.. *sigh*" ); // Format the message and tweet a random quote $message = "@".$mention_this_guy . " " . $random_quotes[array_rand($random_quotes)]; echo "Tweeting: " . $message . " (" . strlen($message) . ") \n"; $oauth->OAuthRequest('https://twitter.com/statuses/update.xml', array('status' => $message), 'POST'); // Wait a little sleep(rand(5,30)); }
Теперь настроим cron. Открой файл кронтаба и внеси несколько строчек:
# Feed mashable and wordpress tweets once every 15-16 minutes */15 * * * * php /home/youruser/twibots/robot.php feed wordpress */16 * * * * php /home/youruser/twibots/robot.php feed mashable # Thank and follow the retweeters once every half an hour */30 * * * * php /home/youruser/twibots/robot.php rthx # Reply to people hourly 01 * * * * php /home/youruser/twibots/robot.php reply
Выполните перезапуск демона cron и вуаля! Можно наслаждаться . Если ты используешь простой хостинг, то получить доступ к crontab (или выполнению cron-задач) посредством CPanel (панели управления хостингом). Не забывай указывать php перед нужной командой. Помни, в linux .php файлы не являются исполняемыми. disconnect Также хочу обратить твое внимание на следующий момент. Старайся не хранить свои сценарии в директориях, доступ к которым можно получить через Apache (т.е. обратившись из браузера к файлу). Думаю, не нужно объяснять, что из-за этого может случиться. Если ты все же решишь хранить их в публичных директориях, то позаботься о создании файла .htaccess с записью "deny from all". Ты же не хочешь, чтобы посторонние люди пользовались нашим новорожденным ботом?
Автор оригинала: Konstantin Kovshenin WWW автора: http://kovshenin.com Вольный пересказ от Игоря Антонова aka Spider_NET E-mail: antonov.igor.khv@gmail.com
Студенту в помощь Этот раздел будет полезен студентам. Предлагаем вашему вниманию решение математических задач на языке С++ от Булай Никиты aka Bulka.
Задача: Составить программу, которая бы по двум углам определяла тип треугольника в зависимости от вида его углов (прямоугольный (p), остроугольный (o), тупоугольный (t)) и в зависимости вида его сторон (равнобедренный (b), равносторонний (s)). Результатом работы программы должна быть строка, состоящая из указанных выше маленьких латинских символов p, o, t, b, s. Очевидно, что в ответе первые три типа могут сочетаться с двумя последними. Ваша программа должна контролировать правильность вводимых значений углов и, в случае неправильных входных данных, выдавать значение n.
Решение: #include <iostream> int main() { FILE *in, *out; in= fopen("input.txt","r"); out= fopen("output.txt","w"); if (in==NULL || out==NULL) return 0; int a,b,c; fscanf(in,"%d %d", &a,&b); c=180-(a+b);// Найдем 3 угол if ( ((a+b)>=180) || (b==0) || (a==0) ) { fprintf(out,"n"); // Не может быть такого fclose(out); } if ((c<90 && b<90 && a<90) && ((a+b)<180)) fprintf(out,"o"); // Остроугольный if ((c>90 || b>90 || a>90) && ((a+b)<180)) fprintf(out,"t"); // Тупоугольный if ((c==90 || b==90 || a==90) && ((a+b)<180)) fprintf(out,"p");// Прямоугольный if ((a==60) && (b==60)) { fprintf(out,"s"); // Равносторонний fclose(out); } if ((c==a || b==a || c==b) && ((a+b)<180)) fprintf(out,"b"); // Равнобедренный fclose(in); if (out==NULL ) fclose(out); return 0; }
Задача: Составить программу, определяющую значение функции у(х) в зависимости от введенного значения аргумента х. Функция определена следующим образом: | -x, при х < -10 y = -| x^2, при -10 <= х < 5 | 2*х, при х >= 5 Формат входного файла:
X - действительное число. Формат выходного файла: Y - вычисленное значение функции с точностью до двух знаков после запятой.
Решение: #include <iostream>
int main() { float x; FILE *in, *out; in= fopen("input.txt","r"); out= fopen("output.txt","w"); fscanf(in, "%f", &x);
if (x<-10) fprintf(out,"%f", -x); else if (x>=5) fprintf(out,"%f", x*2); else if (x>=-10 && x<5) fprintf(out,"%.2f", x*x); fclose(in); fclose(out); return 0; }
Задача: Составить программу, определяющую является ли введенный шестизначный номер "счастливым" (совпадает ли у него сумма трех начальных и трех конечных цифр). Для выделения отдельных цифр во введенном номере можно использовать операции mod и div. Формат входного файла: NNNNNN - запись номера, где каждое N - некоторая цифра. Ведущие нули в номере могут быть опущены (т.е. номер 002846 может быть записан как 2846). Формат выходного файла: Если номер «счастливый» - вывести 'YES', если нет – 'NO'.
Решение: #include <iostream>
long int DoDiv(long int a, long int b) { return a /= b; }
long int DoMod(long int a, long int b) { return a %= b; }
int main() { long int Ch, a,b, Tmp; FILE *in, *out; int i;
in= fopen("input.txt","r"); out= fopen("output.txt","w"); a=0; b=0; fscanf(in, "%d", &Ch); if (Ch==0) fprintf(out, "YES"); else if ((Ch>=1000) && (Ch<=999999)) { // BEGIN Tmp=DoMod(Ch, 1000); for (i=0; i<3; i++) { a=a+DoMod(Tmp, 10); Tmp=DoDiv(Tmp, 10); } } // END
if ((Ch>=100000) && (Ch<=999999)) { Tmp=DoDiv(Ch, 1000); for (i=0; i<3; i++) { b=b+DoMod(Tmp, 10); Tmp=DoDiv(Tmp, 10); } if (a==b) fprintf(out, "YES"); else fprintf(out, "NO"); } else
if ((Ch>=10000) && (Ch<=99999)) { Tmp=DoDiv(Ch, 1000); for (i=0; i<2; i++) { b=b+DoMod(Tmp, 10); Tmp=DoDiv(Tmp, 10); } if (a==b) fprintf(out, "YES"); else fprintf(out, "NO"); } else if ((Ch>=1000) && (Ch<=9999)) { Tmp=DoDiv(Ch, 1000); for (i=0; i<1; i++) { b=b+DoMod(Tmp, 10); Tmp=DoDiv(Tmp, 10); } if (a==b) fprintf(out, "YES"); else fprintf(out, "NO"); } else if ((Ch>=1) && (Ch<=999)) { fprintf(out, "NO"); } fclose(in); fclose(out); return 0; }
Задача: Составить программу, которая бы в зависимости от введенного возраста человека выводила бы на экран комментарий: если введено значение: от 1 до 6 - "baby", от 7 до 16 - "child", от 17 до 21 - "student" , от 22 до 35 – «programmer», от 36 до 60 – «boss», от 61 до 100 – «guru»
Предусмотреть реакцию на ввод неправильных данных – если введенный возраст не укладывается в указанные диапазоны – вывести слово «sorry».
Формат входного файла: Возраст вводится как целое положительное число. Формат выходного файла: Вывести одну из указанных строк.
Решение: #include <iostream> int main() { int a; FILE *in, *out; in= fopen("input.txt","r"); out= fopen("output.txt","w"); fscanf(in,"%d", &a); if (a>=1 && a<=6) fprintf(out,"baby"); else if (a>=7 && a<=16) fprintf(out,"child"); else if (a>=17 && a<=21) fprintf(out,"student"); else if (a>=22 && a<=35) fprintf(out,"programmer"); else if (a>=36 && a<=60) fprintf(out,"boss"); else if (a>=61 && a<=100) fprintf(out,"guru"); else fprintf(out,"sorry"); fclose(in); fclose(out); return 0; }
Задача: На отрезке [A;B] подсчитать количество чисел у которых количество делителей есть число простое (1<=A <= B <= 1000). Формат входного файла: Числа A и B, разделенные пробелом. Формат выходного файла: Количество указанных в условии чисел.
Решение: #include <iostream> #include <math.h> signed long int GDiv(signed long int a){ long int k=0; signed long int i; for (i=1; i<=a ;i++) { if (a%i==0) k++; } return k;
} bool isSimple(int a) { int i,k, flag; for(i = 2; i <= a;i++) { flag = 1; for(k = 2; k*k <= i;k++) { if(i % k == 0) { flag = 0; break; } } } if(flag == 1) return 1; return 0; } int main() { FILE *fin, *fout; fin=fopen("input.txt","r"); fout=fopen("output.txt","w"); int u=0, A,B, KOL=0; fscanf(fin,"%d %d",&A, &B); if (B<A) {u=A; A=B; B=u;} for (int i=A; i<=B; i++) { u=GDiv(i); if (isSimple(u)) KOL++; } fprintf(fout,"%d", KOL ); fclose(fin); fclose(fout); return 0; }
Задача: Составить программу, которая бы для введенного натурального числа N (N <= 1000 000 000) выводила количество его делителей. Формат входного файла: N - заданное число. Формат выходного файла: Количество делителей N.
Решение: #include <iostream> #include <math.h> main() { signed long int a,n,c,d, count=0; FILE *fin, *fout; fin=fopen("input.txt","r");
fout=fopen("output.txt","w"); fscanf(fin, "%d", &a); for (n=1; n <= sqrt(a); n++) { c=a % n; d=a / n; if (c == 0) { count++; if (n != d) count++; } } fprintf(fout, "%d",count); fclose(fin); fclose(fout); return 0; }
Задача: Числа Фибоначчи определяются как: F1=1, F2=1, F3 = F2+ F1, ... Fn = Fn-1 + Fn-2 при n>2. Вывести все числа Фибоначчи, кратные N и меньшие M (M < 1 000 000). В случае, если таковых не найдется вывести NO. Формат входного файла: MN Формат выходного файла: Список указанных чисел Фибоначчи в порядке возрастания по одному в строке либо NO.
Решение: #include <iostream> int main() { FILE *fin, *fout; signed long int M, N; bool exist=false; fin=fopen("input.txt","r"); fout=fopen("output.txt","w"); fscanf(fin, "%d %d", &M, &N); signed long int i; signed long int i1=1,i2=1; if (i1%N==0) { fprintf(fout, "1\n"); exist=true; } if (i2%N==0) { fprintf(fout, "1\n"); exist=true; } while(i2<M) { i=i1+i2; i1=i2; i2=i; if (i2<M && i2%N==0) { fprintf(fout, "%d\n", i2); exist=true; } } if (exist==false) fprintf(fout, "NO"); fclose(fin);
fclose(fout); return 0; }
Автор задач и решений: Булай Никита aka Bulka E-mail: delphilib@mail.ru
Не бойся! Разбираемся со страхом Страх — отрицательно окрашенная эмоция или чувство, связанное с ощущением опасности, реальной или воображаемой. Wikipedia (http://ru.wikipedia.ru)
Хочу тебя спросить, боишься ли ты страха? Большинство ответят, что мне не до этого, некоторые скажут, что я слишком занят, другие придумают еще что-то, но так и не дадут прямого ответа. Будь уверен, все боятся ощущения страха. Пришло время по-настоящему разобраться, что же собой представляет страх, рассмотреть природу страха, причины его возникновения. Поговорить о фобии, как об одном из самых распространенных видов страха, и узнать, как бороться со страхом и нужно ли бороться с ним вообще. Какой он страх? Страх многолик и разнообразен, и в этом легко убедиться, если покопаться в своих страхах – их у тебя вполне достаточно :). Каждый из нас на собственном опыте знает это переживание, и ощущал его воздействие, как на психику, так и физически: вялость, скованность движений, учащенное сердцебиение, сумбур в голове и т.д. Можно приводить десятки ощущений, но всегда ли страх плохо влияет на организм? Оказывается, что в нем есть и положительные стороны, к примеру, выброс адреналина в кровь приводит человека в состояние "боевой готовности" – крайняя точка возбуждения, делающая человека бесстрашным перед лицом опасности, стимулирует мозговую деятельность, т.к. в критических ситуациях кровь просто вскипает и начинает активно «бегать» по организму. Приход к состоянию, когда опасность уже не кажется чем-то угрожающим, в первую очередь зависит от оценки собственных сил (порой накаченность трицепсов мало, что изменяет), собственно если запаса сил много, то человек идет навстречу опасности, и не задумывается о последствиях, если сил мало, выбирай меньшее из зол - бегство. В этом случае смех неуместен, да-да, зазорного здесь ничего нет, ведь лучше быть целым и невредимым, чем быть «разобранным по частям», но имея при этом ненужную гордость. Как на нас влияет страх Страх влияет на нас с вами через ощущения, поэтому, как и любое другое ощущение, страх запоминаем. Ничего не поделаешь, но наш организм построен так, что на все неизвестное у него возникает ответная реакция (да и плохого в этом ничего нет), по сути это готовность к защите, ярчайшим признаком этого, является боль. Значит, с уверенностью можно сказать, что страх это защитный механизм на внешние и внутренние раздражители.
Интересно другое – может ли ощущение страха быть одинаковым на разные раздражители, к примеру, мы поздно ночью возвращаемся домой, идя по темному переулку в котором как назло не горят фонари или не успеваем сдать отчет, без которого нас не пустят к экзаменам или из-за экономического кризиса боимся потерять работу. Определенно нет, воздействие страха по-разному воспринимается флегматиком, холериком, пессимистом и оптимистом. Одни в мгновение ока впадают в такой страх, что про них говорят "душа в пятки ушла", а другим хоть бы хны, даже глазом не моргнули. Порой от строения тела зависит восприимчивость к страху, как выяснили ученые, худые люди чаще испытывают чувство тревоги, чем люди плотного телосложения (но не всегда в действительности это так). К примеру, эмоциональные люди сильно восприимчивы к неврозам, да все потому, что таким людям присущ особый склад личности, которая и заключается в поверхностности суждений, внушаемости, склонности к фантазированию, неустойчивости настроения и т.п. Поэтому склонность к неконтролируемому проявлению страха у каждого происходит по-разному, а вот трусость является признаком этой склонности. Человечество далеко вперед шагнуло в своем развитии, но с развитием цивилизации, порождается разнообразное количество форм страха, возьмем, к примеру, боязнь потерять работу, боязнь потратить деньги, боязнь идти в армию, практически похожие страхи есть у каждого, если не сказать, что у всех. Это страх в форме чрезвычайно многообразных и часто очень странных «фобий». Такая форма страха, как фобия, психически более связана и соединена с определенными объектами или ситуациями, а как мы узнали из предыдущих статей уважаемого Криса Касперски, сознание оперирует фигурами, цветами и т.д. Самое интересное, не в их содержании, сколько в их интенсивности, которая парой вынуждает совершать неординарные и безрассудные поступки. Пару слов о неврозе При нашей крайне неустойчивой социальной жизни, не редко появление у человека неврозов. Мы с головой погружены в повседневную рутинную работу, которая как кроме хлопот нам ничего хорошего не приносит, разве, что немного денег. Да и те кончаются быстро =(. Невроз, как правило, является ответной реакцией на продолжительный стресс, успех в исцелении зависит от уменьшения или полном устранении стрессовых обстоятельств и ситуаций – активный отдых на воздухе, чем не релакс. Иногда положительное воздействие оказывает перемена обстановки (достаточно просто убраться в комнате, помыть посуду, выкинуть мусор, прогуляться с друзьями), говоря простым языком в получении положительных эмоций, т.к. влияние эмоций на человека весьма ощутима. Это понимает каждый - хоть к гадалке не ходи :). Именно поэтому люди
начинают рано пристращаться к спиртному, в итоге зарабатывают себе болезни и начинается все сначала: стресс, бутылка, нехватка денег, опять стресс и т.д. Со всей своей многообразностью страх все же, принято разделять на категории, вернее на виды восприятия человеком. Страх, который был нам внушен и даже тот, которого мы не испытывали является сознательным. Предметы и события, пугающие и вызывающие чувство страха тоже относятся сознательному страху, т.к. такая боязнь происходит на основе неудачного опыта или полученных от кого-то знаний об этом. Чаще всего при усилении страха его высшая форма - ужас - сопровождается именно подавленным состоянием, депрессией. Психологические и физические ощущения в теле «верные» спутники страха: паника, неуверенность, напряжение, угнетение, бездействие, тревога, оцепенение, нерешительность и обида, а также холодный пот, сердцебиение (ощущение, что сердце вот-вот выпрыгнет из груди), сдавленность в груди, расстройство желудка, затрудненность дыхания. Бессознательный страх Бессознательный страх, это другая сторона карты (вернее страха). Здесь мы уже говорим, о том, что опыт ощущения страха отсутствует. Например, многие боятся пришествия Апокалипсиса, т.е. конца всему живому. Почему же так происходит? Мы не разу не испытывали это, не видели, не ощущали? Так почему же столь велик страх перед этим явлением. Ответ очень прост, наш мозг «вытаскивает» из своих глубин (под)сознания, картинки уже испытанных страхов и строит новую нафантазированную модель будущей ситуации. Происходит, как - бы сопоставление возможных событий с уже испытанными негативными событиями, происходит просмотр фильма, содержание которого нам четко известно. В итоге мы боимся неизвестного, которое сами себе придумали, потому что боимся плохого неизвестного. Лишь стоит нам только подумать о неизвестном событии, ум сразу показывает плохую картину/фильм, и возникает чувство тревоги на основе ранее испытанного страха. В данном случае, увы, опыт нам сослужил плохую службу. И тогда возникает тревога, по поводу будущих событий. Все слышали выражение «мысль – материальна», наш организм реагирует на ощущения и восприятия, если мы испытываем негативные ощущения, то возникает боль или расстройство, нередко приводящая к болезни. Стоит нам испытать радость, как ощущение плохого испаряется, словно его и не было, а остаются только неприятные ощущения – дискомфорт. Вывод напрашивается простой, чтобы не стать мишенью, для собственных страхов, нужно придерживаться строгого самоконтроля. Именно, контролю за собственными мыслями стоит уделять большее внимание.
Как мы уже выяснили, страх является врожденным качеством, предостерегающим человека от опасности. Без него человек становится мишенью, но в природе ничего не существует «просто так», поэтому страх позволяет выработать иммунитет к более сильным потрясениям. По мнению некоторых ученых, умеренный страх повышает интенсивность обменных процессов, улучшает питание мозга, усиливает сопротивляемость инфекциям и защищает от стрессов. Ведь почему-то есть среди нас те, кто любит смотреть страшилки и киношные ужастики и у каждого есть тяга к экстриму, пусть даже без участия в нем. Сам просмотр происходящего дает нам массу положительных эмоции, словно мы сами участвовали в этом событии. Человек получает волшебную таблетку (это ни те таблетки, что вы пьете на ночь), которая способна помощь от возможных, в будущем, жизненных неприятностей. Наш организм таит в себе столько интересных особенностей, одна из которых это является тяга к опасности. Мы не прочь иногда посмотреть фильмы ужасов, даже иногда смысл фильма бывает, неважен – лишь бы было больше острых ощущений. Ученые выяснили, что за поиск ощущений отвечает ген, который создает в мозгу особый фермент. Фермент «дофамин» является виновником, того, что люди бывают настолько изобретательны в поисках опасности, что их «подвиги» оказываются в книгах рекордов Гиннеса. Но не будем глубоко уходить в подробности, а поговорим лучше о способах использования страха. Страх – это манипулятор? Неправильным было бы не затронуть способы манипуляции человеком с помощью страха. По вашему, какой бизнес является одним из самых прибыльных? Если принять во внимание тему нашей статьи, то это страхование. Вспомните время, когда вы учились в школах, к вам часто приходили страховые агенты и говорили, что опасности предостерегают нас везде. Где бы мы не находились с вами может произойти нехорошая ситуация: играя в футбол сломал ногу и руку, катался на велосипеде – попал в аварию. И многие соглашаются на страхование, ведь тогда можно получить компенсацию причиненных убытков – покупка лекарств и т.д. Данная ситуация хорошо показывает прием манипуляции - мы готовы застраховаться от всех возможных напастей, пусть даже если большая часть из них никогда не произойдет. Другой пример: доблестные сотрудники милиции нередко прибегают к манипуляциям с помощью страха. Ведь страх сесть за решетку на «долгие года» никого не прельщает, а снизить срок можно, только если все подробно рассказать и показать, проще говоря, расколоться. Манипуляции, построенные на страхе, пришли из глубины веков и остаются по сей день. Ведь порой и начальство не редко использует эти невидимые нити скрытого управления, но и подчиненный может всегда поменяться местами с руководителем и уже выступать в роли манипулятора. Человек эмоциональное существо, поэтому постоянно нуждается в положительных эмоциях, которые заряжают организм энергией, бодростью и дают хорошее самочувствие.
Принято считать, что мужчин называют сильным полом и дело то, вовсе не в мышцах или строении тела, а в эмоциональной устойчивости. С рождения будущим мужчинам навязывают, что они должны быть сильными, что у них в жизни больше ответственности, чем у слабого пола. Говорят, что мужчина должен быть кормильцем в семье, а не наоборот. Это ярчайший пример социального развития – навязать свое, пусть даже если мы этого не хотим. Можно сказать, что страх одна из величайших сил в жизни человека, потому что он заставляет их учиться. Он не дает нам совершать глупости и опрометчивые поступки. Наша работа из-за страха не приносит радости, а дает только лишь ощущение бесцельно растрачиваемого времени жизни. Поэтому бессмысленно пытаться избавиться от страха. Можно лишь уменьшить интенсивность восприятия страха. Достигается это путем тренинга разработано множество методов, помогающих эффективно избавиться от этого в высшей степени неприятного чувства. Примеры можно найти в книгах по психологии или аутотренингу, я же объясню лишь некоторые. Подавление страха Главным заблуждением многих, является попытка подавления страха с помощью искусственного оптимизма. Увы, при сегодняшних реалиях это не возможно, но вот переформулировка своего страха, способно решить многое, например чаще оказывается, что эти страхи так ничтожны и не существенны. Поэтому определенно, нужно как можно чаще себя хвалить, эти маленькие радости дадут желаемый эффект. Порой бывает достаточно представить, что всё, чего вы боялись, уже случилось и впереди только светлое будущее. Помогай другим людям преодолевать страхи. К примеру, тем, кто окружает тебя, находи совместные, интересные занятия, общайся больше с жизнерадостными людьми, ищи впечатлительные моменты и ограждайся от плохих мыслей. Наш ум устроен так, что на хорошее впечатление он реагирует хорошим, и на плохое – плохим. Зная об этом, вы всегда сможете посмотреть со стороны на вашу хандру и плохое настроение, и отдавать себе отчет в том, что эти чувства не столь истинны и адекватны, как может вам показаться.
Есть еще один метод. Нужно составить список всех ваших прошлых побед над самыми различными страхами и опасениями. Выберите из него несколько наиболее значимых для вас ситуаций и попытайтесь заново пережить состояние бесстрашия и уверенности. Вспомните образы других людей, восхищавшие вас. Постарайтесь вжиться в их образ,
размышляйте о них, и через какое-то время почувствуете, что бесстрашие стало вашим естественным состоянием. Самое простое, это представить, что все, чего вы боялись, уже случилось и впереди лишь ясное и чистое будущее. Подводим черту Страх, как пес Цербер, охраняющий нас от внешних раздражителей, он всегда стоит на страже. И только вам решать будет ли он послушным щенком или опасным диким зверем.
Written by JimmyJonezz e-mail: jimmyjonezz@bk.ru
Какой язык программирования учить начинающему К данному размышлению меня подтолкнули постоянные вопросы продвинутых пользователей, желающих не только запускать программы, но и самостоятельно создавать их. Может быть, я и не стал, писать все это, если бы не одно наблюдение: вопрос, "какой язык программирования изучать в первую очередь" не только не теряет своей актуальности, а даже наоборот - становится все чаще встречающимся на просторах Сети. Ближе к теме Также не могу не вспомнить здесь фразу Конфуция: "Дай человеку рыбу - и завтра он снова будет голоден, научи ловить рыбу - и ты прокормишь его на всю жизнь". Понятное дело, что на форумах и прочих чатах программисты зачастую называют тот язык, на котором пишут они сами, ведь сообщение в форумы большей частью пишутся спонтанно и "между делом". А здесь, в этом посте, я хотел бы по рассуждать, логически обосновать все (сколько получится) "за" и "против" того или другого языка программирования. Только вот отталкиваться я буду не от конкретных языков и их возможностей, классификация будет совсем иная. Вспомним, что программ существует великое множество. Они разные по размерам, по функционалу, платформе, на которой они работают и многому другому - различий очень много. Общим, пожалуй, остается лишь одно - все они созданы, чтобы облегчить человеку выполнение какой-либо задачи, это всего лишь инструменты для выполнения пользовательских задач. Получается, что создавая какую-либо программу, имеет смысл подумать о том, для чего, кем и в каких условиях (на каком железе) эта программа будет запускаться. Это нужно для того, чтобы понять, каким инструментом (языком программирования) лучше всего воспользоваться, чтобы написать наиболее эффективное решение задачи (программу). И я как раз сейчас хочу разобраться с теми параметрами, по которым и можно выбирать язык программирования. Минимизация сроков разработки И сразу пример. Допустим, Вам нужно написать еще одну версию пасьянса "Косынка" (помнится, Spider_NET с wwwnet во втором подкасте VR-Online совместно собирались :)). Такая программа в любом случае не будет потреблять большого количества ресурсов на более-менее современной машине, а значит, нет никакого смысла вспоминать ассемблерные команды и вручную гонять байты из регистра в регистр. Естественно, такой пасьянс, написанный на ассемблере, а не на Delphi или C# будет работать в десятки (или даже сотни) раз быстрее, и места в оперативной памяти будет занимать гораздо меньше, но... На разработку такого пасьянса уйдет в те же сотни раз больше времени. А ведь конечный пользователь не заметит разницы в скорости, да и особого напряга с оперативной памятью
не испытает, а вот время, затраченное на разработку, будет потеряно. И времени этого будет много. Так что, если размер потребляемых машинных ресурсов не критичен, используйте высокоуровневые языки программирования - они помогут существенно уменьшить время разработки программы.
Базовая платформа До недавнего времени особого вопроса в выборе платформы и не было - операционная система Windows царила везде и повсеместно. Сейчас же и Apple отгрыз свои почти 10% рынка, и Linux поклевывает, FreeBSD - и тот вилами тычет Windows'у куда-то под коленку. И это только десктопы/ноутбуки. А если взять мобильные телефоны? Смартфоны? Коммуникаторы? КПК? Как видим, не Windows единой бывает базовая платформа. А значит, перед тем, как выбрать язык программирования, на котором будет разработана программа, нужно хорошо представлять себе, на какой платформе (платформах) она должна будет работать. В этом случае, выбирать лучше всего тот язык, для которого есть компилятор или интерпретатор на требуемых платформах. Наибольшую кроссплатформенность может показать Java, JavaScript, ActionScript (программирование во Flash), ну и, конечно, старые добрые C, C++, Pascal и иже с ними. Правда, в случае со "старыми добрыми" велика вероятность переписывания под каждую платформу той части кода, которая отвечает за графический интерфейс (за GUI, в общем), если, конечно, Вы не консольное приложение пишете. Популярность языка программирования Это, пожалуй, стоит учитывать любому программисту, пишущему "на продажу". Для начинающих популярный язык означает большое количество обучающего материала и, конечно, тематических форумов, где в проблемном случае можно спросить совета более опытных программистов. Для тех же, кто пишет программы "на продажу", популярность языка - это большее количество заказов, ведь специализированные языки программирования и применяются для решения специализированных задач, значит, заказчиков на такие услуги будет меньше, даже если разделить общее количество заказов на количество программистов, способных эту задачу решить и согласных взяться за ее решение. Ну и непосредственно для начинающих Развитие языков программирования все больше и больше стремится к переходу от машинного языка к человеческому. Может быть и стоит выучить тот же ассемблер или C, но, в большей части только для того, чтобы понимать, как "думает" компьютер. Для повседневной же разработки все чаще и все больше применяются языки, которые позволяют писать буквально нормальными и понятными каждому человеку предложениями. Именно для этого было создано то же объектно-ориентированное
программирование, которое позволяет писать довольно сложные программы, используя уже запрограммированные модели, максимально приближенные к объектам реального мира. Не нужно изобретать велосипед Современные средства разработки позволяют делать очень многое, не вникая в принципы работы компьютера вообще и операционной системы в частности. Стандартные библиотеки языков программирования позволяют делать очень многое, нужно только знать, что же может делать та или иная библиотека. Поэтому, перед тем, как начинать писать килобайты кода, поищите, может быть, Ваша проблема решается парой-тройкой строчек с использованием уже написанных и отлаженных функций языка. Не поленитесь изучить мануал той библиотеки, которую собираетесь использовать, особенно если собираетесь работать с ней более-менее постоянно, время, потраченное на изучение, с лихвой окупится при разработке программ. С какого языка начинать изучать программирование - зависит только от того, чего Вы хотите добиться, научившись писать программы. И только после того, как эта цель будет определена - выбирайте. Лично я бы посоветовал для начала C#, все-таки .NET становится все более распространенным, а Windows, несмотря ни на что, держит подавляющую долю рынка. Если же Вас интересует сайтостроительство, то для начала лучше ознакомиться с PHP, причем сразу с PHP5. Книг и статей по этим языкам сейчас более чем достаточно, уверен, ни для кого не составит труда найти обучающие материалы. P.S. Дописав этот материал, понял, что есть еще кое-что, о чем хочется рассказать тем, кто совсем недавно определился с выбором языка, тем, для кого Hello world уже позади, но впереди еще таинственный и темный лес под названием "программирование". Если комуто это может быть нужным, то я обязательно напишу еще одну заметку для начинающих программистов в следующий номер VR-Online.
Written by ZeroXor www: http://zeroxor.ru
FA Q
Вопрос: Создал пункты меню в ActionManager и поместил их на ActionToolBar. Появилась необходимость скрывать кнопки, расположенные на ActionToolBar. Но вот проблема - пункты этой панели разбиты на группы по три, разделенные сепараторами. Как скрыть и показать сепаратор программно в ран тайме? И как программно создать и поместить кнопку типа Action на ActionToolBar? Ответ: Сепараторы скрываются так: var i:integer; begin //Перебираем все элементы на первой панели инструментов (ActionBars[0]). //Если хочешь перебирать на всех тулбарах, то добавляй еще один цикл for i:=0 to ActionToolBar1.ActionManager.ActionBars[0].Items.Count - 1 do begin //Если в качестве заголовка "-", то значит это сепаратор if ActionToolBar1.ActionManager.ActionBars[0].Items[i].Caption = '-' then //Делаем его невидимым. ActionToolBar1.ActionManager.ActionBars[0].Items[i].Visible := false; End;
Кнопка создается таким образом: var NewAction:TAction; NewActionClient:TActionClientItem; begin //Сначала создадим новый action NewAction := TAction.Create(ActionManager1); //Текст кнопки NewAction.Caption := 'Пимпа'; //Обработчику события присваиваем вызов Action1Execute. //В теле процедуры Action1Execute просто комментарий. //Он нужен чтобы кнопка была активной NewAction.OnExecute := Action1Execute; //Добавляю кнопку на первую панель инструментов NewActionClient := TActionClientItem.Create(ActionManager1.ActionBars[0].Items); NewactionClient.Action := NewAction; end;
Вопрос: В чем разница между компонентами PopupActionBar и PopupMenu? Ответ: Разница в них только в стиле отображения. Плюсом PopupActionBar является то, что можно использовать стиль ХР, которого нет в PopupMenu. Вопрос: Как создать алгоритм поиска слов во введенной строке. К примеру, в строке "Наш самый лучший фильм" мне нужно найти слово "наш". Ответ: Пример решения этой задачи ниже: var MF: I: I:
TStringlist; Boolean = True; Word = 0;
S: String; begin if S='' then MessageBox(0, 'Исходный текст пуст.', 'Ошибка...', MB_ICONERROR) else begin I:=MF.Count; if MF.Count<>0 then while MF.Count<>0 do begin if Pos(MF[1], S)=0 then I:=False; if Pos(MF[1], S)=0 then Dec(I); MF.Delete(1); end else MessageBox(0, 'Нет слов для поиска.', 'Ошибка...', MB_ICONERROR); End; end;
Вопрос: Как экспортировать данные в Excel? Ответ: Вот пример работы создания книги Excel и внесения данных в Delphi var Excel:Variant; begin Excel:=CreateOleObject('Excel.Application'); Excel.Workbooks.Add; Excel.ActiveSheet.PageSetup.LeftMargin:= Excel.Application.InchesToPoints(0.44); Excel.ActiveSheet.PageSetup.RightMargin:= Excel.Application.InchesToPoints(0.44); Excel.ActiveSheet.PageSetup.TopMargin:= Excel.Application.InchesToPoints(0.44); Excel.ActiveSheet.PageSetup.BottomMargin:= Excel.Application.InchesToPoints(0.44); Excel.ActiveSheet.PageSetup.Orientation:= 2; Excel.ActiveSheet.PageSetup.CenterFooter:='&8Пример экспорта документа в Excel'+#13+ '&10Делфи это хорошо'; Excel.ActiveWorkBook.WorkSheets[1].Range['A1'].Select; Excel.Selection.Font.ColorIndex:=3; Excel.ActiveWorkBook.WorkSheets[1].Range['A1'].Value:='Text'; Excel.ActiveWorkBook.WorkSheets[1].Range['B1'].Select; Excel.Selection.Font.ColorIndex:=5; Excel.ActiveWorkBook.WorkSheets[1].Range['B1'].Value:='Text'; Excel.ActiveWorkBook.WorkSheets[1].Range['C1'].Select; Excel.Selection.Font.ColorIndex:=6; Excel.ActiveWorkBook.WorkSheets[1].Range['C1'].Value:='Text';
Excel.ActiveWorkBook.WorkSheets[1].Range['D1'].Select; Excel.Selection.Font.ColorIndex:=10; Excel.ActiveWorkBook.WorkSheets[1].Range['D1'].Value:='Text'; Excel.ActiveWorkBook.WorkSheets[1].Range['E1'].Select; Excel.Selection.Font.ColorIndex:=2; Excel.ActiveWorkBook.WorkSheets[1].Range['E1'].Value:='Text'; Excel.ActiveWorkBook.WorkSheets[1].Range['F1'].Select; Excel.Selection.Font.Name:='Courier New'; Excel.Selection.Font.Size:=18; Excel.ActiveWorkBook.WorkSheets[1].Range['F1'].Value:='Text'; Excel.ActiveWorkBook.WorkSheets[1].Range['G1'].Select; Excel.Selection.Font.Bold:=true; Excel.ActiveWorkBook.WorkSheets[1].Range['G1'].Value:='Text'; Excel.ActiveWorkBook.WorkSheets[1].Range['H1'].Select; Excel.Selection.Interior.ColorIndex:=3; // Цвет Excel.ActiveWorkBook.WorkSheets[1].Range['H1'].Value:='Text'; Excel.Visible:=True; end;
Вопрос: Как в C++ Builder узнать серийный номер диска (HDD Serial number)? Ответ: Вот пример: char VolumeName[255], FileSystem[255]; unsigned long SerialNumber, MCLength, SystemFlags; AnsiString VolumeSerial; if (GetVolumeInformation("C:", VolumeName, 254, &SerialNumber, &MCLength, &SystemFlags, FileSystem, 254)) VolumeSerial = AnsiString(SerialNumber);
После этого в переменной VolumeSerial - серийный номер диска C: Вопрос: Операционная система Ubuntu Linux 9.04. Купил себе комплект “Мегафон Модем”. Установил, но уж очень маленькая скорость и половина пакетов теряется. Что мне делать? Ответ: Необходимо зайти в настройку своего мобильного широкополосного соединения. На закладке “Параметры PPP” убираем галочку “Использовать сжатие заголовков TCP”. И на закладке “Параметры Ipv4” выбираем метод “Автоматически (PPP)”. Вот и всё. Наслаждаемся хорошей скоростью. Вопрос: Операционная система Ubuntu Linux 9.04. У меня при воспроизведении музыки в плеерах Totem и Rythmbox слышен треск на битрейте 320 kbps и выше. Ответ: Это может быть связано с косяками в работе микшера Pulseaudio. Если хочется использовать ALSA (Advanced Linux Sound Architecture) c микшером, то нужно микшер удалить, заменив его другим. Как это делается можно найти на www.forum.ubuntu.ru. Так же можно попробовать ALSA без Pulseaudio или OSS (Open Sound System) Вопрос: Операционная система Ubuntu Linux 9.04. Есть весь репозиторий на 6 DVD. Видеокарта GF 8600 GT. Не могу установить проприетарные драйверы. Ставлю через
Система->Администрирование->Драйверы устройств. Вылетает ошибка, о каком то повреждённом пакете и больше ничего. Ответ: Надо делать из командной строки. Пытаемся ставить драйвера вручную. Пусть это будет версия 173: sudo apt-get install nvidia-glx-173
На этом моменте вылетит уведомление о том, что какой пакет повреждён. Теперь вбиваем его имя в поисковик и качаем. Ставим его вручную и повторяем установку драйвера. И вот оно счастье – Compiz во всей его красе.
Written by Костенко Роман aka Lord of Fear E-mail: lord_of_fear@list.ru