...
...

Возвращение неправильного десктопа

Возвращение неправильного десктопа

Опубликованная давным-давно статья о "неправильном десктопе" до сих пор напоминает о себе. Последнее письмо (на этот раз на украинском языке) содержало уже привычный текст: мол, набрал текст вашего воллпапера, но не заработало. Не сохранились ли у вас исходники? Сохранились, дорогой. Только рассылать я их больше не буду, ибо трафик исходящей почты незнакомым людям не должен измеряться мегабайтами. Спамом попахивает.

В ближайшее время будет открыта домашняя страничка вашего покорного слуги, с которой все желающие смогут скачать описанные некогда мной "живые" обои для рабочего стола и их новый, продвинутый вариант. Если же у вас нет доступа к Сети — сегодня я опишу их усовершенствованную версию. Но, пожалуй, я увлекся. Ведь не все читатели понимают, о чем идет речь, и прежде следует объяснить, о чем я вообще собрался рассказывать.

Практически всем известно, что "Виндовс" позволяет использовать в качестве обоев не только картинку в форматах BMP, JPEG, GIF, PNG, но и страничку HTML. Эта возможность, на мой взгляд, очень удобна, и меня удивляет, что никто не пользуется такой интересной вещью. Перепробовав множество всяких напоминалок, записных книжек, календарей и других программ, я в конце концов стер их с винчестера и повесил на десктоп HTML-страничку, которая отображала список моих текущих дел и телефонный справочник.
Время шло, статья о живом воллпапере долгое время была весьма популярна (судя по количеству писем), но я в своем новом десктопе быстро разочаровался. Когда количество телефонов в экранном справочнике перевалило за две сотни, искать, редактировать и добавлять номера стало очень неудобно: пришло время перемен. Но прежде, чем взяться за работу, попробуем сформулировать задачу:

1. Воллпапер должен быть простым в понимании и модификации. На практике это означает: минус Flash, минус Java, используются только HTML и JavaScript (или VB-Script — на любителя).
2. Добавление новых возможностей не должно сопровождаться полным переписыванием HTML-кода. Добавления будут оформляться в виде отдельных модулей на JavaScript.
3. Само собой, обои должны быть быстрыми и красивыми, дабы у вас уже на второй день не возникло желания сменить их на какой-нибудь HONDA.JPG.
Ну что же, задача ясна и ожидает реализации. Первым делом подумаем, какие модули нам понадобятся в первую очередь. Это телефонная книга, часы, календарь, лаунчер для запуска программ, справочник людей и адресов. Дабы упростить задачу, совместим справочник с телефонной книгой, а часы с календарем. Лаунчер можно пока отложить, ибо обычные ярлычки "Виндовс" после установки нового воллпапера никуда не денутся, да и добавить новую возможность никогда не поздно.
Итак, с составом обоев мы определились. Они будут состоять из пяти файлов, которые для удобства вынесем в отдельную директорию (в моем случае это директория c:\home\settings\wallpaper). Вот список этих файлов:

• wallpaper.html — собственно HTML-страничка, которая будет использоваться в качестве обоев.
• background.jpg — фоновая картинка для десктопа. Она будет вставлена на фон странички-десктопа.
• clock.unit — модуль на JavaScript, отвечающий за реализацию часов и календаря.
• finder.unit — небольшая программа на том же языке, которая будет искать нужные записи в базе данных и выводить их на десктоп.
• database.unit — база данных, оформленная как двумерный массив строк на JavaScript.

Теперь разберем содержимое и назначение этих файлов более детально. Начнем с файла, который менее всего нуждается в комментариях: background.jpg. Это фоновая картинка. Я рекомендую выбрать любой не слишком яркий рисунок, чтобы текст, который будет впоследствии на нем рисоваться, был хорошо виден. Мне, например, приглянулись светящиеся радиационные поганки. Вот сам рисунок:

В верхней части рисунка видна панелька. Конечно, ее можно было бы отрисовать средствами HTML, однако это хоть ненамного, но замедлило бы работу компьютера и неизбежно усложнило исходный код обоев. Поэтому я загрузил картинку в "Фотошоп", нарисовал эту полоску и вытянул на ней "утолщения", в которых позже разместятся ярлычки программ, часики с текущей датой и форма ввода для поиска по базе данных. Признаюсь, я не сразу попал выступами в нужные места, но эта задачка решилась элементарно: закончив написание прочих частей проекта, я поставил почти готовый воллпапер на рабочий стол, сделал скриншот экрана (нажатие клавиши PrintScreen помещает содержимое экрана в буфер обмена "Виндовс") и, воспользовавшись полученной картинкой как шаблоном, подогнал все размеры и расстояния на картинке BACKGROUND.JPG.
Следующий файл — WALLPAPER.HTML — вот его содержимое и комментарии:

<html>
<head>
<script src="clock.unit"> </script>
<script src="finder.unit"> </script>
<script src="database.unit"> </script>
</head>

Здесь, в заголовке HTML-странички, размещаются строки, загружающие скрипты. Более корректным был бы вызов с указанием языка, на котором написаны скрипты — за это отвечает атрибут language тега script. В нашем случае необходимости в этом нет, так как страничка, которую мы пишем, корректно воспроизводится браузером Internet Explorer, а адаптировать ее для других браузеров нет нужды — ведь это будущий десктоп, а не часть сайта.

<body bgcolor="black"
link="#ffffff"
alink="#ffffff"
vlink="#ffffff"
background="background.jpg"
bgproperties="fixed"
scroll="no"
leftmargin="0"
rightmargin="0"
topmargin="8"
bottommargin="0">

В теге-контейнере BODY прописано несколько атрибутов, которые во многом определяют вид нашего десктопа. Атрибуты BGCOLOR, LINK, ALINK, VLINK определяют цвета фона (на случай, если бэкграунд будет прозрачным — полностью или частично) и ссылок (не понадобится в нашем случае, но пригодится, если вы решите добавить вашему десктопу функциональности).
Прочие атрибуты отвечают за название фоновой картинки, ее свойства и отступы от краев экрана, или, если быть точным, от границ окна браузера, в котором отображается данная страничка. Впрочем, этим окном будет весь десктоп, так что особых отличий вы не увидите, пока на запустите поиск по базе данных в отдельном окне (а это делается одним нажатием клавиши).

<basefont face="arial">
<table width="100%" height="48" align="left" border="0" cellspacing="0" cellpadding="0">
<tr height="48">
<td>
 
</td>
<td width=192 height=48 align="left" valign="bottom">

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

<form name='clock'>

Вот мы и добрались до модулей. Обратите внимание на имя создаваемой формы: модуль clock.unit будет ориентироваться на это имя, отображая на экране текущие время и дату.

<input type='text'
style="border-top-width: 0px;
border-right-width: 0px;
border-left-width: 0px;
border-bottom-width: 0px;
font-size: 15px;
background: none transparent scroll repeat 0% 0%;
color: white;
text-align: left;
font-weight: bold;
filter: shadow(color=#000000, direction=135);"
name='clock_display'
value='Standby for time'
size=24>
</form>
<script> clock_start()</script>
</td>

В форме находится всего один элемент — форма ввода. Вводить в нее мы ничего не будем: этим займется модуль. Атрибуты, которые присвоены здесь этой форме (размер, стиль и т.д. — кроме имени) можно было бы задавать в модуле, но если количество подключаемых модулей исчисляется единицами, то есть смысл их немного разгрузить и облегчить себе их написание и отладку. Единственная вызываемая функция clock_start() запускает часы — теперь они будут отрисовываться раз в секунду и перезапускать себя, дабы через секунду быть активированными вновь.

<td width=80>
 
</td>

Еще одна ячейка — всего лишь элемент форматирования, разделяющий часы и поле для поиска данных.

<td width=80 height=48 align="left" valign="bottom">
<form name='finder'>
<input type='text'

name='finder_display'
value='FINDER'
size=8>
</form>
</td>

В этой ячейке, которая по содержанию практически идентична ячейке таблицы с часиками, есть только одно несущественное отличие — строчка onClick="this.value=''". Просто мне было неудобно стирать старые данные (а без этого результаты поиска маячили на экране) или тянуться к клавише F5, чтобы полностью обновить экран. Действие этой строки — обнуление содержимого формы, по которой произведен щелчок мышью.

<td width=64>
 
</td>
</tr>
</table>
</basefont>
<br>
<hr>

Табличка, формирующая изображение в верхней части экрана, закончена. Тег <BR>, то есть перенос строки, служит для отделения того, что будет рисоваться дальше, от декоративных элементов на верхнем краю десктопа.

<form name='finderoutput'>
</form>
<script> finder_start()</script>
</body> </html>

Вот, собственно, и весь основной файл. Осталась лишь форма finderoutput для предоставления данных пользователю.
Теперь давайте разберемся с содержимым трех оставшихся файлов. Хотя они имеют расширение .unit, а не .js, они фактически являются программами на языке программирования JavaScript. Расширение здесь не имеет значения, поскольку файлы загружаются через атрибут src тега script и воспринимаются браузером именно так, как нам нужно. Начнем с модуля clock.unit как с самого простого и доступного для понимания:

var timerID=null;
var timerRunning=false;

Эти две переменные являются определяющими, основными для данного модуля. В первой задается функция, которая будет вызываться при обнулении таймера. Вторая является флагом-переключателем, необходимым для корректной работы часов.

function stopclock()
{
if (timerRunning) clearTimeout (timerID);
timerRunning=false;
};

Данная функция очищает значение таймера, которое отсчитывается в миллисекундах.

function clock_start()
{
stopclock();
showtime();
};

Эта функция служит для первого запуска часов и их перезапуска каждую секунду. Как можно понять из ее содержимого, она останавливает отсчет и вызывает функцию отрисовки и перезапуска часов.

function showtime()
{
var now=new Date();
document.clock.clock_display.value=now.toLocaleString();
timerID=setTimeout("clock_start()",1000);
timerRunning=true;
};

Основная функция в модуле. При помощи переменной now, которая имеет тип Date, она выводит текущие время и дату в форму clock, которую мы задали в основном тексте воллпапера (файл wallpaper.html). Затем эта функция дает текущему окну браузера, то есть десктопу, команду вызвать функцию clock_start() через тысячу миллисекунд и запускает отсчет времени.

Теперь рассмотрим текст database.unit:

var database = new Array
(
Array("Петров","Петр","Петрович","01.01.1960","токарь","знакомые","7202020, 202021","Токарь с местного завода. Познакомились в январе 2000 года на дне рождения у Сидорова."),
Array("Иванов","Иван","Иванович","02.02.1960","слесарь","знакомые","7202021, 202022","Товарищ с золотыми руками."),
Array("Федоров","Федор","Федорович","03.03.1960","сантехник","знакомые","7202022, 202320","Заядлый рыбак и отчаянный хвастун."),
Array("Сидоров","Сидор","Сидорович","04.04.1960","маляр","друзья","7202320, 202420","Коллега Андреева и талантливый скульптор."),
Array("Васильев","Василий","Васильевич","05.05.1960","электрик","знакомые","7242020, 252020","Гений по части чего-нибудь закоротить."),
Array("Максимов","Максим","Максимович","06.06.1960","певец","знакомые","7202550, 202620","Товарищ с тонкой душой и грубым голосом. Думает, что он певец. Друзья ему правды не говорят, потому как обидится"),
Array("Андреев","Андрей","Андреевич","07.07.1960","художник","знакомые","7202660, 202720","Забулдыга."),
Array("Рабинович","Исаак","Абрамович","08.08.1960","программист","друзья","7202020, 202820","В свободное от безделья время зарабатывает на корочку хлеба и ложечку икры написанием утилит."),
Array("Андерсон","Томас","","09. 09.1960","снайпер","друзья","7202770, 292020","Работали над одним совместным проектом.")
);

Те, кто более или менее знаком с синтаксисом JavaScript, сразу поймут, что это просто заданный пользователем двумерный текстовый массив, в каждой из записей которого через запятую перечислены фамилия, имя, отчество, день рождения человека, его роль, группа, к которой мы его относим, номер телефона и краткий комментарий к данной записи. Обратите внимание: после последней записи нет запятой — там стоят просто скобка и точка с запятой. Это требования языка, и я несколько раз наступал на одни и те же грабли при пополнении базы данных. Синтаксис языка следует соблюдать с предельной аккуратностью, чтобы избежать труднообнаруживаемых ошибок.
Последний модуль, который мы сегодня разберем, нужен для поиска по базе данных и вывода найденных записей на экран. Он называется finder. unit. Это самая сложная и большая часть нашего маленького проекта, и ее мы разберем более подробно:

var finderID=null;
var finderRunning=false;
var currentQuery="";
function stopFINDERclock()
{
if (finderRunning) clearTimeout (finderID);
finderRunning=false;
};
function finder_start()
{
stopFINDERclock();
showFINDERresult();
};

Данный фрагмент практически идентичен (за исключением имен переменных) содержимому большей части модуля, обслуживающего часы и календарь, поэтому опустим подробные комментарии за ненадобностью. Единственное отличие — мы задали переменную currentQuery, в которой мы будем держать текущий запрос пользователя для поиска по БД. Чтобы на экран что-то выводилось, его придется перерисовывать функцией showFINDERresult.

function finderAddRecord(counter)
{
var temp="<tr valign=top> <td width=200 align=right>  ";
temp+="<font face=arial color=green size=2> <b> Тел.: </font> <font face=arial color=gold size=2> "+database[counter][6]+"</b> </font>   <br> ";
if (database[counter][3]!="")
{temp+="<font face=arial color=green size=2> <b> Дата рождения: </font> <font face=arial color=gold size=2> "+database[counter][3]+"</b> </font>   <br> ";};
if (database[counter][5]!="")
{temp+="<font face=arial color=green size=2> <b> Группа: </font> <font face= arial color=gold size=2> "+database [counter][5]+"</b> </font>   <br> ";};
if (database[counter][4]!="")
{temp+="<font face=arial color=green size=2> <b> Роль: </font> <font face=arial color=gold size=2> "+database[counter][4]+"</b> </font>   <br> ";};
temp+="</td> <td> ";
temp+="  <font face=arial color=yellow size=4> <b> "+database[counter][0];
temp+=" "+database[counter][1]+" "+ database[counter][2]+"</b> </font> <br> ";
temp+="<font face=arial color=gold size=2> "+database[counter][7]+"</font> ";
temp+="</td> </tr> ";
return(temp);
};

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

function finderAddDelimiter()
{
var temp="<tr> <td> <Br>  </td> </tr> ";
return(temp);
};

Эта функция выполняет задачи, схожие с назначением предыдущей функции, хотя и кажется несравнимо менее сложной. Она добавляет разделитель между отдельными записями при выводе на экран. У меня это просто пустое пространство, заданное тегом <BR>, хотя здесь могла бы быть цветная горизонтальная линия или какой-нибудь декоративный элемент.

function showFINDERresult()
{
finderID=setTimeout("finder_start()",100);
finderRunning=true;
if (currentQuery!=document.finder.fin-der_display.value)
{
currentQuery=document.finder.fin-der_display.value;
var currentData="<table border=0 bordercolor=white width=80%> ";
var recordCounter=0;
for (counter=0; counter<database. length; counter++)
{
comparestring="";for(i=0;i<=7;i++) comparestring+=" "+database[counter][i];
comparestring=comparestring.toUpperCase();
currentQuery=currentQuery.toUpper Case();
findResult=comparestring.search(currentQuery);
if (findResult> 0)
{
if (recordCounter<6)
{
currentData+=finderAddDelimiter();
currentData+=finderAddRecord(counter);
}
recordCounter++;
};
};
if (recordCounter> 0)
{
currentData+=finderAddDelimiter();
currentData+="</table> ";
if (recordCounter> 6)
{
currentData+="<font color=cyan> <b> Показано 6 записей из "+recordCounter+" найденных. Уточните запрос.</b> </font> ";
}
document.finderoutput.innerHTML=currentData;
}
else
{
document.finderoutput.innerHTML="<table border=0 bordercolor=white width=80%> <tr valign=top> <td align=left> <font face=arial color=cyan size=2> Для сбора информации введите строку в поле поиска (справа от часов на верхней панели).</font> </td> </tr> </table> ";
};
};
};

Самая длинная и сложная функция в модуле. Десять раз в секунду она проверяет, какое значение находится в поле ввода на вашем воллпапере (и использует для этого тот же механизм, что и часики из предыдущего модуля), и в случае, если это значение отличается от предыдущего, то есть если пользователь ввел или убрал символы в искомой строке, база данных считывается снова, и записи, в которых обнаружена введенная строка, выводятся на экран. Конечно, если записей окажется много, то они не уместятся на экране. Я ограничил количество выводимых записей шестью, после чего выдается сообщение о количестве выведенных и найденных записей. Моим рабочим разрешением экрана является 1280 на 1024 точек, но если монитор позволяет, количество выводимых записей можно увеличить. Того же эффекта можно добиться, уменьшив размер шрифта выводимых сообщений. Вот как сейчас выглядит мой десктоп после ввода нескольких символов в поле поиска:
Конечно, эту функцию поисковым механизмом можно назвать лишь с огромной натяжкой, но для моих нужд этого вполне достаточно. Если хотите добавить поиск с условиями, прокрутку записей, любые другие функции, достаточно лишь небольших познаний в JavaScript или VBScript и минимум старания. Все в ваших руках.
Я же намерен добавить аналоговые часики, вывод календаря, если пользователь не запросил никаких данных, и предупреждения перед днями рождения знакомых, записи о которых имеются в базе данных. Все обновления и разработанные модули будут выкладываться на моей страничке, откуда вы сможете скачать их вместе с инструкциями по "подключению" к десктопу.
Если вам понравилась идея использования возможностей "Виндовс" "на всю катушку", я с благодарностью приму от вас письма с идеями по добавлению тех или иных возможностей, которые вы сочтете полезными для себя. Авторы самых интересных и полезных идей получат в подарок компакт-диск с реализацией своего замысла и коллекцией лучших фоновых картинок, подготовленных для использования на "неправильном десктопе". Ну, а сейчас пришло время оставить вас наедине с творческими замыслами, которые наверняка появились у вас после прочтения этой статьи. До новых встреч на страницах КГ.

Поляков Александр,
Lecosson@mail.ru



© Компьютерная газета

полезные ссылки
IP камеры видеонаблюдения
Корпусные камеры видеонаблюдения