Последние записи
- Нужен ли сайт разработчику?
- Обсуждаем технологию I2P
- Как запустить программу указанную в Edit.Text
- Скачать файл с использованием потока
- Поиск слова в Memo
- Распаковщик формата .img из GTA San Andreas
- Подсчет количества повторяющихся букв в файле
- Простейший скрипт загрузки картинки с помощью php
- Рассылка. Выпуск 154
- Получение картинки с веб-камеры
20th
Апр
Codelobster PHP Edition – бесплатный PHP, HTML, CSS, JavaScript редактор с плагинами для работы с CMS
Для полноценной работы по созданию сайтов вам обязателньо необходим хороший удобный редактор. Есть очень много платных продуктов для этого, но нам бы хотелось выделить бесплатный очень функциональный и в то же время простой в использовании редактор – Codelobster PHP Edition. (читать всё…)
27th
Дек
SilverLight 4.0 + COM API. Breaking the habit…
Как известно, из SilverLight-приложения достучаться до файловой системы непросто, что вполне логично с точки зрения безопасности. Нет, ну добраться до файла в каталоге «Мои документы» – нет проблем, в ином месте – приходится изобретать велосипед. В этой статье я опишу устройство подобного велосипеда.
автор: dab00
На днях писал одно SilverLight-приложение, в котором было необходимо при создании в базе данных новой записи создавать на файл-сервере каталог с соответствующим названием, добавлять/удалять файлы в/из каталог(а) и пасти информацию обо всех файлах, находящихся в целевом каталоге. Скажем, что-то отдаленно напоминающее систему управления версиями.
И вот когда, наконец, убив несколько дней на разработку я приступил к реализации функционала работы с файловой системой… сначала мне показалось, что я выбрал не ту технологию. Даже всерьез рассматривал вариант переноса пользовательских каталогов «Мои документы» на сервер – куда деваться – неужели столько времени потрачено впустую…
А ларчик просто открывался – на помощь пришла старая добрая технология COM.
Достаточно было импортировать в проект пространство имен System.Runtime.InteropServices.Auto mation, дальше – песня.
Хочешь – FileSystemObject:
Dim fso As Object = AutomationFactory.CreateObject(«Scr ipting.FileSystemObject»)
Хочешь – Shell.Application:
Dim sh As Object = AutomationFactory.CreateObject(«She ll.Application»)
Хочешь WshShell:
Dim wshShell As Object = AutomationFactory.CreateObject(«WSc ript.Shell»)
Со всеми вытекающими свойствами и методами. Просто праздник какой-то .
На всякий случай можно проверить, как там дышит AutomationFactory:
If AutomationFactory.IsAvailable Then
И дело в шляпе. Easy peasy lemon squeezy . Хорошо что приложение было внебраузерным – если бы такие фокусы прокатили в браузере, разработчиков мелкомягких можно было бы смело расстрелять раз несколько. В общем, как добрался я до COM API, отпустило меня . Такая вот история.
P.S. В Silverlight 5 можно обойтись и без «велосипеда». Правда в настоящий момент (11.11.11) доступна только RC-версия.
23rd
Дек
Пишем HTML-приложение для мониторинга ресурсов Windows
Однажды, в студеную зимнюю… заинтересовал меня вопрос мониторинга ресурсов Windows, а конкретно (хочется добавить «чисто» конкретно) мониторинга объема свободной памяти (физической и виртуальной), процента использования файла подкачки и загрузки процессоров. (читать всё…)
23rd
Пишем VBS-приложение для преображения кода VB
Наверное каждый разработчик, написав несколько тысяч строчек некомпилируемого кода рано или поздно начинает задумываться о том, как защитить свои «уникальные» творения .
В один прекрасный день пришел и мой черед. (читать всё…)
21st
Дек
AJAX и кодировка Windows-1251
До сей поры работать с AJAX в кодировке WINDOWS-1251 на кириллице было невозможно.
Однако давайте посмотрим в чем же была проблема? (читать всё…)
11th
Ноя
Организация кода
Во-первых, если только у Вас нет веских причин держаться Борланда, уйдите с него. Дело в том, что господа Embarcadero пытались «усовершенствовать» C++, создав при этом заметно отличающийся диалект; часть этих наработок ушла в язык C#.
Как альтернативы, можно рассматривать Qt от Trolltech-Nokia или C++ express от Microsoft. (читать всё…)
8th
Июл
ActionScript3: Кэширование анимации и ее проигрывание (blitting)
Всем, кто имеет хоть какое– нибудь отношение к игроиндустрии или созданию спецэффектов, хорошо известно, насколько ресурсоемка такая вещь, как отображение векторной анимации и ее расчет в процессе рендеринга. Но к счастью, разработчики оставили нам путь к всеобщему процветанию и дали нам возможность использовать такую великолепную вещь, как вывод на экран предварительно откешированного в растр изображения. Помните, как устроен кинематограф, основанный на смене одной картинки на другую? Вот этим мы сейчас и займемся. (читать всё…)
1st
Июл
Работаем в сетью с помощью libcurl
В этой статье я бы хотел осветить вопросы взаимодействия с Web и Ftp серверами в C++ программе. Никто не запрещает программировать сокеты и самостоятельно реализовывать протоколы. Но зачем изобретать велосипед, когда существует готовое, отлаженное и мощное решение, способное удовлетворить практически любые Ваши потребности? Речь идет о библиотеке libcurl. Это простая в использовании, кроссплатформенная (поддерживаются Linux, Windows, Solaris, Qnx, FreeBSD, OpenBsd, MacOS X и многие другие) клиентская библиотека, позволяющая работать с протоколами FTP, FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, LDAP, LDAPS and FILE. Поддерживаются SSL сертефикаты, HTTP POST, HTTP PUT, FTP закачка, HTTP закачка, прокси-сервера, куки, аутентификация, восстановление закачки файла, тунелирование http proxy и многое другое. Libcurl имеет завязки на множество языков программирования, среди которых: C, C++, Java, Lisp, PHP, Ruby, Perl, Pascal, Haskell. (читать всё…)
18th
Июн
Сознание человека в виртуальной среде. Нейронные сети. Размышление.
Автор: Аблязов Руслан ака rpy3uH
Прежде всего я хочу сразу вас предупредить, что не надо относиться ко всему что будет здесь написано серьёзно, это всего лишь фантазия на свободную тему, всего теория из множества, которые имеют место в этом мире. Я могу ошибаться, я могу в чём-то очень сильно заблуждаться и не надо из-за этого мне долго и со вкусом объяснять, что я не прав. У каждого свой взгляд на этот мир, свой взгляд на положение вещей в этом мире, у каждого своя правда, каждый видит этот мир со своей колокольни. Возможно, то что вы прочитаете далее изменит ваше мировоззрение, у вас откроется новое видение этого мира, этого огромного мира, этого мега-мира. А может сразу после прочтения вас стошнит …
Для максимального понимания или усвоения текста (возможно для некоторых, пустого набора слов или букв) приведённого ниже, необходимо максимально абстрагироваться от того, что вы сейчас знаете, избавиться (хотя бы на время) от предрассудков и предубеждений. Если вам уже не интересно можете не читать, потеряете вы не очень много. А если прочитаете, то как минимум вы узнаете что такое мнение как моё существует и это реально, намного более реально чем ваше и моё существование. И самое главное если вы захотите критиковать то, что я сейчас напишу, то лучше прочитайте до конца всю эту статью.
(читать всё…)
16th
Июн
Test-Driven Development для Java (TDD, разработка через тестирование) на практике.
alexinspir:
Test-Driven Development (TDD, разработка через тестирование) является одной из основополагающих техник экстремального программирования, но к сожалению, в россии очень немногие разработчики умеют ею пользоваться.
Разработка через тестирование подразумевает следующие этапы, которые в 90% случаев идут строго по порядку(об оставшихся 10% скажу позднее):
(читать всё…)
1st
Май
Компилятор домашнего приготовления. Часть 5
Так. Мотор готов, резина согласно погоде… Теперь залить горючее и собрать карбюратор. В качестве горючки у нас будут опкоды, помещенные в отдельный модуль, обернутые в функции их возвращающие. Предлагаю этим и заняться… (читать всё…)
28th
Апр
Кроссплатформенный осциллограф на GTK+/Cairo
Моей основной операционной системой является Linux, а основным окружением рабочего стола – Gnome. Предыдущий мой урок «Анимированный осциллограф на WinAPI в С++» [1] вызвал интерес форумчан, поэтому я решил сделать кроссплатформенную версию этого импровизированного осциллографа и полностью переписал программу на GTK+. Данная статья может быть полезна всем, кто только начал или собирается изучать этот «тулкит». Параллельно в уроке рассматривается использование некоторых функций мощной библиотеки двухмерной графики Cairo. (читать всё…)
28th
Немного о DSP. Часть 2
На этот раз здесь будет много скучной математики, каких-то непонятных формул и рассуждений. Но в итоге будет представлена программка, уже производящая обработку звука на лету. В общем, стоит прочитать и разобраться. (читать всё…)
27th
Фев
Анимированный осцилограф на WinAPI в С++
Вэтой небольшой статье я бы хотел продемонстрировать, как создается окно и как рисовать средствами GDI+. Возможно данный материал будет полезен всем тем, кто хочет разобраться с созданием графический приложений Windows, средствами WinAPI, тем более в преддверии нового учебного года, новых лабораторных, новых сессий. Анимироваться, в данной статье, будет синусоида, получиться своего рода осциллограф.
27th
Компилятор домашнего приготовления. Часть 4
Знаете, я все думал: «С чего бы продолжить написание компилятора, какой следующий шаг важнее?». Описать механизм операторов? Так к ним неплохо бы переменные, и функции могут участвовать в операциях. Описать механизм функций, опять-таки они без операторов – ничто. Описать механизм переменных? Но далеко не все типы можно обработать без функций… Дилемма. И все же продолжать с чего-то надо. А раз надо – почему бы не продолжить с того, что первое придет в голову, все равно придеться много раз править проект все новыми и новыми «фичами»…
27th
Немного о DSP. Часть 1
Благодаря своему универу, пришлось иметь дело с такой вещью, как Digital Signal Processing (DSP). DSP* мне всегда казалось жутко интересным занятием, когда имеешь дело с большим количеством численных данных, применяешь какие-то умные математические приемы и в итоге случается чудо – все работает, и работает как надо. В этой статье попробую начать тему, написать простенький пример. С чего начать? Методы DSP используются для обработки всевозможных данных: звука, изображений, показаний различных датчиков и т.д. Здесь я рассмотрю только звук. Я попробую написать простейшую программу, которая открывает звуковой файл и производит некоторые действия над ним. Вот и плавно переходим к первой части.
27th
Заставляем Firefox шифровать трафик
Однажды в сети появилось видео о краже сессии Вконтакте в публичной Wi-Fi сети http://www.youtube.com/watch?v=jsFODcwiRFY. Это стало причиной обсуждений на различных ресурсах. Я уже долгое время использую плагин для Firefox HTTPS Everywhere, который перенаправляет запросы пользователей таким образом, чтобы они использовали зашифрованное соединение. Список поддерживаемых сайтов велик, но он не затрагивает отечественные ресурсы, к счастью разработчики реализовали создание собственных правил.
27th
Безопасность PHP. Проверка поступивших данных
Одним из наиболее значимых вопросов для WEB-программистов является безопасность PHP-скриптов. Все программисты в той или иной мере используют различные методы, чтобы обезопасить свой проект, но, к сожалению, в большинстве случаев используется защита от нескольких уязвимостей, при этом остальные проблемные места даже не рассматриваются. В данной статье перечислены основные виды уязвимостей PHP и рассмотрены способы защиты от них.
27th
Общение между запущенными копиями своих программ
Рассматривать задачу будем на конкретном примере некоего приложения. Опишем предметную область и постановку задачи: необходимо, чтобы наше приложение, зарегистрировав себя как протокол в системе Windows, при нажатии на ссылку вида testproject:\\xxxxx запустило наше приложение (если оно не запущено) и передало ему параметры ссылки. Если же приложение уже запущено, то необходимо запущенной копии приложения сообщить параметры ссылки.
27th
Шифровка с помощью пароля. Улучшаем алгоритм
Доброго времени суток. Если не все читали мою предыдущую статью «Шифруем файл с помощью пароля» [1], то рекомендую прочитать перед прочтением данного материала. В ней я описал методику шифрования файлов с помощью пароля. Это конечно довольно-таки простая методика. В этой же статье, я расскажу про более сложную методику шифрования с помощью пароля. Итак, приступим…
27th
Компилятор домашнего приготовления. Часть 3
Всем доброго. В прошлой статье я описал как охладить в холодильнике квас, пока пишется ядро компилятора. Помните? Нет?! Странно… Впрочем, это не проблема. Наши журналы хранятся по адресу [1], так что освежить память – не проблема. Поскольку ядро, генерирующее PE файл готово (по минимуму, но готово) и его можно использовать для генерации исполняемого файла, то теперь вполне можно подумать более глобально (в общем, углубиться дальше в лес). Вообще, некоторым может понравиться писать прямо в опкодах, да еще в собственном компиляторе – это интересно и познавательно. Придется перелопатить кучу литературы, которая направит на путь над пропастью по тонкой нити, потому как опкоды не позволяют сосредоточиться на стратегических задачах, постоянно отвлекая на тактические мелочи: то учесть адрес переменной, то работа со стеком. Уже сама операция 2+2 подразумевает, как минимум: положить в переменную число, прибавить к ней второе число. Это две операции, плюс ко всему нужно еще знать адрес переменной. Конечно не абсолютный, а относительный, но при наличии, скажем сотни, переменных хранить в голове все их адреса – достаточно круто. К этому нужно привыкнуть. Или переменная локальная – она лежит в стеке, а потом же не забыть этот стек очистить от мусора – еще одна операция. Не получиться в опкодах записать выражение (2+2)*18/(32+sin(pi/3.4)) в одну строку вот так просто. Придеться думать о том, какой приоритет, какому оператору задать. Каждый оператор имеет свою команду, а если брать «синус», тут еще серьезнее – придеться работать с FPU командами: поместить в стек сопроцессора число, получить из него синус, и выдернуть из стека в переменную – это уже три операции как минимум. В общем, люди, которые по натуре своей ленивы, естественно желают разгрузить себя, переложив рутинные операции на машину. Поэтому высокоуровневые языки программирования всегда снабжаются модулями разбора и анализа написанного кода на более понятном и близком к человеку языке. Машине-то все равно: разбор текста – тоже вычисления, а уж она это умеет делать гораздо быстрее человека, да еще и надежнее. Следующая важная задача – разработка механизма трансляции исходного кода в операционный код. Именно этим и займемся в этой части. Так что, устраивайтесь поудобнее и включайте свой разум на прием информации о том, как можно упростить себе жизнь…
27th
Шаблон класса односвязной очереди в библиотеке STL
В свое время, изучая все богатство возможностей библиотеки STL и, применяя эти возможности на практике, обнаружил, что основным необходимым мне контейнером является односвязная очередь типа FIFO: «первым зашел – первым вышел». В одной из своих программ насчитал 27 очередей под различные типы данных. Видимо это связано со спецификой разрабатываемых программ: взаимодействие с различными внешними устройствами, также разработанных нашей фирмой. Обмен ведется сообщениями через последовательные интерфейсы: COM, USB, протокол TCP/IP…
27th
USBMaster. Управляем флешками в офисе
В этой статье я расскажу Вам, как стать властелином USB-устройств хранения информации (далее – флешек) используя: Windows Script Host, Windows Management Instrumentation и VBScript, – на мой взгляд, довольно несложные вещи, которые по умолчанию имеют место быть в операционных системах Windows начиная с XP.
26th
Фев
О правильном составлении ТЗ. Часть 3
В этом номере я с радостью готова представить вам 3-ю часть моего письменного рассказа о премудростях составления ТЗ. В первых двух статьях я рассказала вам о ТЗ в общих чертах, привела примерное содержание и постаралась показать, что необходимо писать в первых 4 главах. Сегодня я постараюсь освятить еще несколько глав. Приятного чтения…
25th
Фев
Близкие контакты третьего вида с Visual Foxpro
Многие наверняка, в свое время, задавались интересным вопросом: «А вот как бы задействовать всю силу применяемой в моем проекте СУБД? Не только стандартные SQL запросы, а и скрытые возможности». Тогда ведь можно будет получать результат наиэффективнейшими методами…
25th
Запись дисков в Delphi средствами IMAPI
Доброго времени суток уважаемые любители Delphi. В этой статье я расскажу про запись CD/DVD дисков в среде Delphi. Общие принципы, изложенные в этой статье подойдут не только для языка Delphi, но и для языка С++. Для прочтения этой статьи с максимальной пользой, читателю рекомендуется получить базовые понятия об OLE/COM, впрочем даже незнание этих понятий вряд ли помешает понимаю этой статьи, так как классы и компоненты Delphi (так же как и классы С++), которые мы будет использовать полностью скрывают от нас все тонкости и неудобства использования COM интерфейсов для записи дисков.
25th
MrtOS. Мини-операционная система для MK Avr
При разработке практически любого программного обеспечения для микроконтроллеров выясняется, что программа должно состоять из нескольких, сравнительно самостоятельных задач с возможностью коммуникации этих задач между собой. То есть существует потребность в общей управляющей программе по типу мини-операционной системы…
Вячеслав Мовила
http://movila.site11.com
mRTOS. Общие сведения [1...8]
mRTOS (micro Real-Time Operating System) – является кооперативной ОС с приоритетным планированием. Причины появления этой ОС таковы:
- необходимость ОС для малых и средних контроллеров AVR. Большинство проектов автора используют именно такой тип микроконтроллеров;
- ОС для компилятора CodeVisionAVR.
23rd
Фев
WMI. Wладение Mагической Iнформацией. Часть 2
Здравствуйте, уважаемые читатели! Помните меня? А статью про WMI, где я на двух языках показывал как просто получить власть над Windows посредством… Ктулху? Не-е-е. Читаем дальше? Однозначно, сегодня мы продолжим наши изыскания…
Продолжение. Начало смотрите в предыдущем номере журнала…
Виталий Белик
by Stilet www.programmersforum.ru
Ну, да ладно. Мы же пойдем ровным путем, дающим краткое, но четкое представление о том, как будет работать система. Заранее раскрывая карты, скажу, что с Делфийском коде обращение к записям и полям таблицы будет похоже на обращение к ячейкам массива.
Двумерного разумеется. На С++
TWMIRecord *r=0;
// Инициируем итератор для списка
list<twmirecord>::iterator k;
// Пройдемся циклом по списку пока не дойдем
// до указанной по номеру записи
for(k=RecList.begin();(k!=RecList.end())&&(i>0);k++,i–);
// Если записть такая нойдена, в том смысле
// что индекс запрошенной записи
// не вылезает за пределы списка
// то вернем объект из списка
if(k!=RecList.end()&&i>=0){
r=&*k;
}
return r;
};Syhi-подсветка кода
Здесь единственный бок – я не знаю, как проверить выход за пределы списка указанного номера запрошенной записи, и так же не знаю другого способа получить по номеру из списка без прохода циклом. Поэтому я решил просто написать проход циклом по списку, пока не конец, или пока нужный номер записи в списке не достигнут. В принципе это работает, так что пусть так и остается.
Ладушки. Пора приступать к описанию второго класса, класса отвечающего за обработку записи TWMIRecord (на Делфи):
private
// Список полей и их значений
FFields:TStringList;
// Процедура получения данных из полей записи
Procedure Enum(Obj:OleVariant);
Constructor Create;
Destructor Free;
function GetItem(v: Variant): String;
public
Path:String;
// Функция возвращающая число полей
Function HighRecordIndex:Integer;
// Функция, возвращающая имя i-того поля
Function FieldName(i:integer):String;
// Свойство получающее значение определенного поля
Property Item[v:Variant]:String read GetItem; default;
end;Syhi-подсветка кода
Здесь особое внимание должно быть уделено процедуре Enum(), которая, приняв объект-запись от энумератора записей, прокатится по ее полям, выделив ее значения в свой список, и свойство Item, объявленное по умолчанию. Оно может принимать как строку – при этом получить значение по имени поля, так и число, чтоб получить значение из поля по определенному номеру. Это дает серьезную мобильность, можно в цикле пройтись по полям, а можно просто получить значение по имени поля (на С++):
// Имя поля
wstring Name;
// Значение поля, переведенное в строку
wstring Value;
};
class TWMIRecord
{
private:
// Свойство, принимающее значение поля
VARIANT Prop;
// Обьект-записи полученный от провайдера
IWbemClassObject *Obj;
wstring FString;
// Список полей и их значений
list<sfield> FFields;
// Количество полей
int CountList;
public:
TWMIRecord(IWbemClassObject *AObj);
~TWMIRecord(void);
// Метод, получающий поле по имени
sField Field(wstring AName);
// Метод получающий поле по номеру
sField Field(int iName);
// Функция, получающая верхний индекс в списке полей
int high();
};Syhi-подсветка кода
Кто-то скажет: «А зачем Field(wstring AName) возвращает структуру, достаточно ведь вернуть значение?». Верно, но вдруг захочется пополнить структуру еще какой-нибудь характеристикой поля, например, типом, так что пусть этот метод возвращает всю структуру – ничего пагубного в этом нет. Ок. Реализуем этот класс (на Делфи):
constructor TWMIRecord.Create;
begin
// Создается класс списка полей и их значения
FFields:=TStringList.Create;
// Здесь я не предполагал хранить ничегокроме имя и значения поля
// так что TString’a вполне хватит
end;
// Метод проходя по полям
procedure TWMIRecord.Enum(Obj: OleVariant);
var PropEnum:IEnumVariant; i:Cardinal; s:string; d:double;
begin
// Приготовим список для внесения в него данных
FFields.Clear;
// Инициализируем энумератор
PropEnum:=IEnumVariant(IUnknown(Obj.Properties_._NewEnum)); //Поля
// и начнем по нему лазить, пока он выбирает записи
while (PropEnum.Next(1, Obj, i) = S_OK) do begin
try
// Здесь я прикрутил распознавание типа даты
// если поле содержит дату, то привести ее в
// понятный человеку вид
if obj.CIMType=$00000065 then begin
s:=Obj.Value;
s:=copy(s,7,2)+‘.’+copy(s,5,2)+‘.’+copy(s,1,4);
end else
// если же это не дата, то пусть сама программа приводит
// значение к строке. в противном случае в строку
// должно писаться значение [NULL], если такое поле пусто
if VarIsNull(Obj.Value) then s:=WMIValueNull else s:=Obj.Value;
FFields.Values[Obj.Name]:=s;
except
end;
end;
end;
function TWMIRecord.FieldName(i: integer): String;
begin Result:=»;
// если номер попадает в список полей, вернем имя поля
// по его номеру
if (i>=0)and(i<FFields.Count) then
Result:=FFields.Names[i];
end;
destructor TWMIRecord.Free;
begin
// Освободим список, уберем мусор
FFields.Free;FFields:=nil;
end;
function TWMIRecord.GetItem(v: Variant): String;
begin
Result:=»;
// Если мы хотим получить значение по номеру поля
// нужно проверить, не выходит ли указанный индекс
// за пределы списка полей
if VarIsOrdinal(v)and(v>=0)and(v<FFields.Count) then
// И если не выходит – вернуть это поле
Result:=FFields.Values[FFields.Names[v]];
// если же мы хотим получить значение поля по имени
if VarIsStr(v) then
// мы просто передаем имя, и если
// поле с таким именен есть возвращается его значение
Result:=FFields.Values[v];
// иначе вернется пустая строка
end;
function TWMIRecord.HighRecordIndex: Integer;
begin
// Последний индекс в списке полей
Result:=FFields.Count-1;
end;Syhi-подсветка кода
Что тут добавить еще? Энумератором получаем поля и их значения, раскладывая в «массив». И даем возможность выбирать из этого массива в самой программе, любым способом, по индексу или по имени. И еще константа const WMIValueNull=’[NULL]‘. На С++:
{
Obj=AObj;
HRESULT hres;
BSTR pstrName;
VARIANT pVal;
CIMTYPE pvtType;
sField field;
// Начинаем перечисление
hres=Obj->BeginEnumeration(0);
CountList=0;
// Если это возможно конечно, проходимся циклом
// пока не нарвемся на ошибку, или пока энумератор не
// выберет все данные
while(!FAILED(hres)&&(hres!=WBEM_S_NO_MORE_DATA)){
// Получим очередное "следующее" поле
hres=Obj->Next(0,&pstrName,&pVal,&pvtType,0);
// Если оно удачно получено
if(!FAILED(hres)&&(hres!=WBEM_S_NO_MORE_DATA)){
field.Name.clear();
// Запишем его имя
field.Name=wstring(_bstr_t(pstrName,false));
// Если его значение не пусто
if(pVal.vt!=VT_NULL){
field.Value.clear();
// получим его, преобразовав в строку в зависимости
// от типа
switch(pvtType){
case wbemCimtypeBoolean:
field.Value=(pVal.boolVal)?L"TRUE":L"FALSE";
break;
case wbemCimtypeString:
field.Value=wstring(_bstr_t(pVal.bstrVal,false));
break;
case wbemCimtypeSint32:
int i=pVal.intVal;
char c[30]="";
itoa(i,c,10);
for(int i=0;i<10&&c[i]!=0;i++){field.Value+=c[i];}
break;
}
}
// и внеся новое поле в наш список
FFields.push_back(field);
// увеличим счетчик количества полей
CountList++;
}
}
}
int TWMIRecord::high()
{
// Вернем верхний индекс списка полей
return CountList-1;
}
TWMIRecord::~TWMIRecord(void)
{
// Освободим список
FFields.clear();
}
sField TWMIRecord::Field(wstring AName){
FString=L"";
sField res={L"",L""};
// Приготовим итератор для прохода по списку
list<sfield>::iterator i=FFields.begin();
// пока не конец списка
for(;i!=FFields.end();i++){
// получим очередной элемент
sField ws=*i;
// проверим не совпадает ли имя поля
// полученного элемента с указанным нами
if(ws.Name==AName){
// Если совпадает – выйдем из цикла
res=*i;
break;
}
}
return res;
};
sField TWMIRecord::Field(int iName){
FString=L"";
sField res;
// Приготовим итератор для прохода по списку
list<sfield>::iterator i;
// пока не конец списка или не достигнут указанный индекс поля
for(i=FFields.begin();(i!=FFields.end())&&(iName>=0);i++,iName–);
// Если список полей весь пройден а индекс поля еще не достигнут
// вернем пустые строки.
if(i!=FFields.end() && iName>=0){ res.Name=L"";res.Value=L"";}
// Иначе вернем данные из списка
else {res=*i;}
return res;
};Syhi-подсветка кода
Опять-таки, итерации по списку – в Делфи, дяди из Борланда дали возможность обращаться к элементам списка как к массиву, как сделано в STL я не знаю, поэтому банально – прошелся циклом по list’y.
Так… Вроде ничего не забыли описать? Если нет, то пора попробовать эту махину в действии.
Starting Line
Начнем, пожалуй, с Делфи. Создадим проект с формой, на него кинем StringGrid, и в обработчике создания формы OnCreate напишем такой код (на Делфи):
var w:TWMI;i,j:integer; wr:TWMIRecord;
begin
// Создадим обьект WMI
w:=TWMI.Create(nil);
// Выкатим ему запрос
w.SQL:= ‘SELECT caption, CommandLine FROM Win32_Process’;
with StringGrid1 do begin
// Развернем Грид на нужно е количество записей
RowCount:=w.HighObject+1;
FixedCols:=0;
// В цикле пройдясь по записям
for i:=0 to w.HighObject do begin
wr:=w[i];
if ColCount<(wr.HighRecordIndex+1) then ColCount:=(wr.HighRecordIndex+1);
// впишем значения полей в таблицу
for j:=0 to wr.HighRecordIndex do begin
Cells[j,i]:=wr[j];
end;
end;
end;
w.Free;
end;Syhi-подсветка кода
Перед этим не забудем создать в проекте Unit (назовем его Unit2), и вложить в него код классов, не забыв в нем указать необходимые модули для работы механизма в описанный классах uses Classes,contnrs,variants,ActiveX,Comobj; Не забыв указать в разделе uses модуля формы этот самый Unit2.
Теперь код обработчика на форме связан с модулем, где описаны классы.
Если все проделано правильно после жмака по F9 на экран выкатится форма со списком процессов (см. рисунок 1):
Рис. 1. Работа программы написанной на Делфи
Ну вот. Запрос SELECT caption, CommandLine FROM Win32_Process получил набор с заголовками запущенных в целевой системе процессов, и путями к файлам этих процессов. Администратору сразу видно, что запущено у пользователя, не нужно идти к нему, или использовать платные средства удаленного администрирования. Увы, не все они могут показать такую информацию, а иногда это важно для понимания состояния системы.
А теперь тоже самое но на С++. Лукаво не мудрствуя, сделаем это в консоли, это попроще будет:
#include "TWMI.h"
#include <locale>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
// Включим русский язык для консоли
setlocale(LC_ALL,"russian");
// Создадим класс WMI
TWMI *wmi=new TWMI();
// Скормим ему запрос
if(wmi->SetQuery("SELECT caption FROM Win32_Process")){
// Если запрос удачно обработал
printf("Получили данные\n");
int i=0;
// В цикле пройдемся по записям,
for(TWMIRecord *r=wmi->Item(i);r;i++,r=wmi->Item(i)){
// И выведем значение поля
wcout<<r->Field(L"Caption").Value<<‘\n‘;
}
} else {printf("Неудача");}
// после чего уберем мусор
delete wmi;
getchar();
return 0;
}Syhi-подсветка кода
Здесь тоже самое, разве что я изменил запрос. Попросил только заголовки процессов. В консоли красиво не выведешь. Здесь же применен метод получения поля по его имени, но с таким же успехом его можно заменить на:
sField f=r->Field(i);
wcout<<f.Name<<‘=’<<f.Value<<‘\n‘;
} wcout<<‘\n‘;Syhi-подсветка кода
Где в цикле будет вестись проход по всем полям по их номеру. Запустим и посмотрим, что же получилось (см. рисунки 2, 3):
Рис. 2. Получение по имени поля
Рис. 3. Получение нескольких полей
Запрос на рисунке 2 показывает, что все хорошо прошло. Объект получил от провайдера WMI информацию, и программа вывела ее на экран. На втором же рисунке показана возможность показа всех полей, одна запись тут разделена пустой строкой. Вообще я в запросе указал два поля CommandLine, но провайдер предоставляет кроме этого еще несколько, судя по всему стандартных полей, характеризующих тип самого запроса. Например, свойство __PROPERTY_COUNT=2 говорит о том, что мы запросили два поля, между прочим, им можно пользоваться, чтоб узнать количество полей. А __CLASS=Win32_Process говорит о том, какое «представление» использовалось. Мы хотели получить список процессов – вот и получили, соответственно и класс Win32_Process. Ну и, конечно же, в конце данные о тех самых наших полях, которые мы запрашивали, Caption и CommandLine. Все работает замечательно.
Теперь можно самостоятельно написать свою «тулзу» для удаленного администрирования. Учитывая, что классов в WMI много, можно много чего узнать о компьютерах в сети. Например, можно узнать, что за пользователи описаны в компьютере, выкатив запрос SELECT * FROM Win32_Account (см. рисунок 4):
Рис. 4. Информация о пользователях на целевой машине
Или предположим звонит юзер:
-у меня материнка с ума сошла, дайте дрова!
-какая у вас материнка?
-пластиковая, из магазина…
Да-да. Это не анекдот. Юзеры, иногда в силу своей компьютерной неграмотности, такое откалывают, что Задорнов «плякаль». А, запросив SELECT * FROM Win32_BaseBoard у виндоуса того пользователя можно увидеть, что у него (см. рисунок 5):
Рис. 5. Параметры материнской платы
Оказывается Асус. О! И даже серийник есть. Ну, теперь просто запросить на сайте производителя дровишки для P5GZ-MX и удаленно RAdmin’ом например проинсталлировать. Кто-то скажет: «Так, а чего самим РАдмином или типа него не посмотреть денить в свойствах?» Где? Все знают, где информация такая лежит? Ану-ка, партизаны: «шнель шпрехен… ». Я лично не знаю, где можно посмотреть такие подробности. А тут раз – и все как на ладони. А тем паче, своя Наташка… ))))
Post Scriptum
Ну вот. Собственно, на этом можно поставить точку. А можно и троеточие, ибо WMI помимо получения информации позволяет управлять компьютером. Опять-таки теми же запросами. «Тушить процессы» или выключать компьютер удаленно.
Например, если вызвать метод Terminate класса, полученного по запросу на Win32_Process, то можно потушить все процессы из запроса. Порывшись в MSDN, можно даже найти пример [2]. Если ссылку еще не завалили, посмотрите, как это делается: Запросом получается набор объектов, у которых вызывается метод Terminate, и они тушатся.
В общем, все это очень обнадеживает, и, если системный администратор владеет этим каратэ – цены ему нет. Домен свой он будет держать атланту подобно. Так что рекомендую вляпаться в эти микрософтовские катакомбы – не пожалеете.
The Чтиво
- Ресурс вики http://ru.wikipedia.org/wiki/WMI
- MSDN http://msdn.microsoft.com/en-us/library/aa393907%28VS.85%29.aspx
Статья из девятого выпуска журнала «ПРОграммист».
Обсудить на форуме – WMI. Wладение Mагической Iнформацией. Часть 2
23rd
Быстрое написание программ на WinAPI
Все программисты делятся на две группы – oldschool и новую волну. Сыны старой школы помнят историю о 640 килобайтах, помнят о тысяче игр на одной дискете… Новая волна, чаще всего, даже не знает устройство компьютера, но так же считается – программистами. Использование IDE изменило представление о программистах. Посмотрим, что же может дать отказ от визуального программирования. В этой статье я опишу один из способов быстрого написания приложений с использованием функций WinAPI.
Алексей Шишкин
by Alex Cones http://flsoft.ru
Вступление или «Кому это нужно?»
Вы можете задаться вопросом, зачем же насиловать свой мозг, если давным-давно изобретена VCL, MFC и прочие прелести визуального программирования? Для ответа на этот вопрос давайте посмотрим на плюсы и минусы визуального и низкоуровневого* программирования.
Итак, рассмотрим плюсы визуального программирования:
- быстрое написание программ (достаточно накидать кнопок на форму и написать их процедуры);
- удобство использования (это удобнее, чем описывать каждый шаг на низком уровне, не нужно заботиться о памяти).
И минусы:
- огромный размер приложений – «пустое» приложение на Delphi «весит» ~300 кб;
- из-за огромного количества надстроек быстродействием приходится пренебречь, особенно в плане графики на Canvas.
И в противоположность, рассмотрим плюсы низкоуровневого программирования на WinAPI:
- малый размер конечных файлов (согласитесь, что между 30 кб и 300 кб есть большая разница);
- быстродействие на достаточно высоком уровне (быстрее получится только, если писать целиком на ассемблере – то еще удовольствие).
И минусы:
- нет визуализации (труднее представить, что создать, что уничтожить, что где писать);
- для создания обычного окна потребуется примерно 50 строк кода (создать и зарегистрировать само приложение, создать окно, заботиться о всех параметрах);
- необходимо помнить о необходимости следить за использованием памяти – освобождением, взятием. Здесь обычным *.Free не обойдешься.
Но, если мы представим, что избавились о минусах программирования на WinAPI, чаша весов склонится в сторону низкоуровневого программирования. Так как же нам от них избавиться? Итак, взглянем в сторону фреймворков, которые это позволяют. За всю мою практику программирования на Delphi сталкивался с таким только единожды** – APIx 2 (Visual WinAPI). Но данное средство разработки не предполагает активное использование графики, только создание окон и кнопок. Поэтому я решил создать такую библиотеку, которая позволит не только быстро создавать окна, но и активно использовать графику.
Не хвастаясь особо, сообщу, что мне это удалось. И через три недели разработки GRAY FUR был готов.
WTF… или что это даст?
Mon ami, это же элементарно: не нужно заботиться о расходе и приходе памяти, размышлениям о бренности окон. Да, мы по прежнему не имеем дела с визуальностью, но, согласитесь, что намного удобнее вызвать одну процедуру, чем записывать пару десятков с многочисленными параметрами. Так, например отрисовать текстуру на экране можно так:
Loc : HDC;
TNum : Integer;
Begin
Loc := CreateCompatibleDC(DC);
SelectObject(Loc, Bitmap);
BitBlt(DC,
X, Y,
Width,
Height,
Loc,
0, 0,
SRCCOPY);
DeleteDC(Loc);
End;Syhi-подсветка кода
А можно и так:
Причем, если мы не подумаем о том, как создать двойную буферизацию в первом случае изображение будет мерцать при отрисовке. Во втором случае все это уже встроено в систему.
Panic button
Рассмотрим написание Panic button с использованием нашей системы. Для того, кто еще не читал моей статьи о создании Panic Button на WinAPI [1] поясню, что эта кнопка на экране будет сворачивать все окна по нажатию на нее.
Итак, скачаем FrameWork и посмотрим, как же это делается. По привычке, я буду делать это на Lazarus, но вы так же можете использовать Delphi, используя пакет для разработки под Delphi.
Для начала создадим то, что кнопка должна делать:
Begin
Keybd_event(VK_LWIN,0,0,0); // Эмулируем нажатие клавиши Win
Keybd_event(VK_D ,0,0,0); // Эмулируем нажатие клавиши D
Keybd_event(VK_D ,0,KEYEVENTF_KEYUP,0); // Отпустим D – все окна свернутся
Keybd_event(VK_LWIN,0,KEYEVENTF_KEYUP,0); // Отпустим Win.
End;Syhi-подсветка кода
Так же сделаем процедуру закрытия приложения:
Begin
DestroyTimer(ID); // Удалим таймер, созданием которого мы еще займемся
DestroyApplication; // Уничтожим приложение
End;Syhi-подсветка кода
И для полного счастья сделаем так, чтобы кнопка всегда была наверху:
Begin
SetformOnTop(Form1, TRUE); // Установим её всегда сверху.
End;Syhi-подсветка кода
Да, и еще создадим функцию для вычисления вертикальной позиции:
Var
R : Rect;
H : Handle;
W : Integer;
PH : Integer;
Begin
W := GetSystemMetrics(SM_CYSCREEN); // Получаем вертикальное разрешение
ZeroMemory(@R, SizeOf(R));
H := FindWindow(‘Shell_TrayWnd’, Nil); // Найдем окно панели задач
GetWindowRect(H, R); // Его размеры
PH := R.Bottom – R.Top; // Вычислим высоту
Result := W – PH – Form1.Height; // И получим искомое
End;Syhi-подсветка кода
Рассмотрим само тело программы:
{$mode delphi}{$H+} // Директивы для Lazarus
Uses
Windows, // Подключим Windows
Scow; // Подключим модуль-связку проекта
Var
Form1 : TForm; // Наше главное окно. Тип описан в Scow
ID : Integer; // ID таймера
// Здесь находятся процедуры, описанные выше
begin
CreateApplication; // Создаем приложение
SetApplicationReaction1(HN_LBUTTONDOWN, HideAll); // Назначим событие по левому клику
SetApplicationReaction1(HN_RBUTTONDOWN, KillMe); // Назначим событие по правому клику
CreateForm(Form1, FALSE); // Создадим форму FALSE – не показывать на панели задач
ShowForm(Form1, TRUE); // Покажем ее на экране
ResizeForm(Form1, 64, 64); // Назначим размеры
MoveForm(Form1, 0, CalculateYp); // И положение
LoadTexture(Form1, ‘Button.bmp’, ‘Button’); // Загрузим текстуру в хранилище****
Draw(Form1, ‘Button’, 0, 0, FALSE); // Нарисуем текстуру на буфере
BufferDraw(Form1); // И выведем его на экран
ID := CreateTimer(1000, OnTop); // Создадим таймер для вызова процедуры OnTop
CollectMessages; // И организуем цикл сбора сообщений для корректной работы приложения
end. // That’s all, folks!Syhi-подсветка кода
Да, и это все, как и говорится в последней строке программы. Попробуйте поискать многочисленные работы с памятью и прочими непристойностями – их просто нет. Таким образом, мы избавились от главного минуса программ на WinAPI – скорости и сложности написания. И получили плюсы – размер проекта на Delphi всего ~20 кБ по сравнению с ~300 и 39 кБ в Lazarus по сравнению с ~900 кБ. Так же не пострадало и быстродействие – прямые работы с памятью в операциях с графикой и прямой вызов WinAPI функций в проекте.
Вместо заключения
Итак, использование фреймворка дало свои плюсы. Быстрота написания (на это у меня ушло не более 3-х минут), малый размер и быстродействие – все это в одном флаконе. Так же, так как практически все функции имеют понятные названия и параметры то его можно запросто использовать для обучения основам управления программой на WinAPI. В общем, я надеюсь, что он, повторяя путь развития паскаля, перейдет в массы.
Ссылки
- Алексей Шишкин. WinAPI графика. Panic button. – ПРОграммист, Клуб ПРОграммистов, 2010, №8, с.24
- Скачать проект GRAY FUR http://squary.ru/wiki/index.php
Статья из девятого выпуска журнала «ПРОграммист».

