Прокрутка сообщений!Здорово, пипл!
Тема сегодняшнего урока - юзабилити. Если судить по тем обработкам, которые валяются на просторах тырнета, это тема очень актуальна. Сегодня, перцы, я покажу вам как мониторить сообщения. Ни для кого не секрет, что стандартный message от всеми любимой нами фирмы "1С", если мягко говорить, немного неудобный. Рассмотрим, как хранить, сэйвить, а заодно клерасилить логи. Для пущего эффекта крутить логи мы будем на форме обработки. | | Автор статьи: skunk | Редакторы: Волшебник Последняя редакция №8 от 10.01.06 | История URL: http://kb.mista.ru/article.php?id=64 | |
Начало
Итак, начнем с начала и продолжим до самого конца ;)). Кидаем на форму текст и лезем в его свойства. Там в строке идентификатор обзываем его lbMonitor. Делаем его нужного нам размера, а заодно ставим его в нужное нам место. Решайте сами, каким размером и куда его тыкать. Ведь дизайнеры сейчас Вы. Также кинем на форму кнопку, которую обзовем btAction. В ее капшене (надпись) напишем Действия. Под форму кинем еще один объект типа "Текст", только теперь лезем в формулу и там пишем "SetEnableAction()". Все остальное по вашему желанию и хотению. Как только с дизайнерством покончите, переключайтесь в модуль обработки. Будем баловаться.
Баловство
Начнем как обычно с попы. Если быть точнее, то с функции SetEnableAction(), мы ведь ее не зря писали. Она у нас будет рулить доступностью кнопки btAction. Если у нас в мониторе что-то есть, то она доступна, иначе – нет. Сама функция очень простая. Смотрите код, там все по-русскии:
//*******************************************
function SetEnableAction()
if strlen(Form.lbMonitor.Caption()) = 0 then
Form.btAction.Enable(0);
else
Form.btAction.Enable(1);
endif;
endfunction
Смотрим, что у нас в мониторе есть. Если нифига нет, то доступ к кнопке отключаем. Вкурили? Тогда курим дальше. Курить дальше будем кнопку. Если быть точнее, научим ее реагировать на различные поползновения юзверей. То есть, разрешим ей кое-что делать с информацией в мониторе. Итак, мастерим нашу процедурку:
//*******************************************
procedure btAction()
vlAction = createobject("valuelist");
vlAction.AddValue("clear", "К ядреной матери");
vlAction.AddValue("show", "Заказать историю...");
vlAction.AddValue("save", "Записать историю...");
strCommand = "";
if vlAction.ChooseValue(strCommand, , , , 1) > 0 then
if strCommand = "clear" then
elsif strCommand = "show" then
elsif strCommand = "save" then
endif;
endif;
endprocedure
Что тут и за чем, объяснять думаю не надо. Надо? Ну, грубо создаем список значений, в который заталкиваем набор необходимых нам действий. И даем выбрать пользователю, нужное действие, когда он кликнет по кнопочке. Программировать сами действия будем несколько позже. Когда закодим монитор.
Монитор
Хм, так сказать начинаем делать основную вещь. Выводить на форму текст. Ясно, что текст надо будет выводить в несколько строк. Глупо же крутить монитор в одну строку. Для того, чтобы знать, сколько строк нам отображать, заведем переменную, в которой будем хранить максимальное количество строк. Еще нам потребуется ограничитель по скорости, тьфу, количеству символов в строке. Для хранения истории сообщений заведем переменную типа Текст. Все три переменных должны быть доступны любой процедуре и функции в модуле. То есть делаем их глобальными в нашем модуле.
Объявляем:
//*******************************************
var intCountStrMonitor, intCountChar;
var txtHistory;
Инициализируем:
//*******************************************
procedure OnOpen()
intCountStrMonitor = 16;
intCountChar = 60;
txtHistory = createobject("Text");
endprocedure
Все ограничители подбираются опытным путем. Для вывода сообщения в монитор заводим процедуру, которая по дефолту будет мессачить пустую строку.
//*******************************************
procedure InputMonitor(strMessage = "")
endprocedure
Для начала получим то, что уже вывели на «экранчик»:
strMonitor = Form.lbMonitor.Caption();
Далее начнем разбираться с переданной строкой. И первое, на что обратим внимание, будет linebreak, так как строка может быть многострочной. Как известно, стандартный linebreak состоит из двух символов chr(10) & chr(13). А вот чтобы разделить строки в нашем «мониторе», достаточно одного chr(10). К тому же наличие chr(13) вызывает некоторые неудобства при выводе нужной части «истории сообщений». Так что chr(13) посылаем в баню:
strMessage = strreplace(strMessage, chr(13), "");
Далее проверим по количеству символов в строке на предмет выхода их за наше ограничение. Проверять будем функцией, которую рассмотрим немного позже. Сейчас главное, что она есть, она просто не может не есть. Ну и после всех проверок добавим строку к уже выведенной на экран информации.
strMessage = strCutLength(strMessage, intCountChar);
strMonitor = ?(strlen(strMonitor) = 0, "", strMonitor + chr(10)) + strMessage;
Теперь посмотрим, сколько у нас строк в strMonitor, и, если больше допустимого лимита, сделаем им кирдык:
while strcountoccur(strMonitor, chr(10)) > intCountStrMonitor do
strMonitor = right(strMonitor, strlen(strMonitor) - find(strMonitor, chr(10)));
enddo;
Ну и все. Осталось отобразить на «экране монитора» полученный результат.
Form.lbMonitor.Caption(strMonitor);
История
Теперь займемся историей. Только не той что в учебниках, да на всяких форумах. А историй того, что мы выводили в монитор, чтобы оное можно было смотреть, удалять и куда-нибудь сохранять. Как уже говорилось выше, история будет храниться в переменой txtHistory. В историю, конечно, можно добавлять, имея метод AddLine, но при таком раскладе злополучный chr(10) принимает не совсем кошерный вид. Поэтому будем добавлять кусками:
intPos = find(strMessage, chr(10));
while intPos > 0 do
txtHistory.AddLine(left(strMessage, intPos - 1));
strMessage = right(strMessage, strlen(strMessage) - intPos);
intPos = find(strMessage, chr(10));
enddo;
strCutLength()
Функция это будет рекурсивна. Для чего? Объясняю. Допустим нам передали строку длиной в 180 символов а наш ограничитель всего на 60. Да и есть еще один бэнч. В строке уже может присутствовать символ конца строки. Вот вся функция целиком:
//*******************************************
function strCutLength(strTemp = "", intLength = 255)
Answer = strTemp;
if strlen(Answer) > intLength then
intLineBreak = find(Answer, chr(10));
if intLineBreak = 0 then
if strlen(Answer) > intLength then
Make = "yes";
intPos = intLength;
while Make = "yes" do
chrSimb = mid(Answer, intPos, 1);
if find("""'()\*/-+=_&,.?!^ ", chrSimb) > 0 then
Make = "no";
else
intPos = intPos - 1;
if intPos = 0 then
intPos = intLength;
Make = "no";
endif;
endif;
enddo;
Answer = left(Answer, intPos) + chr(10) +
strCutLength(right(Answer, strlen(Answer) - intPos), intLength);
endif;
elsif intLineBreak > intLength then
Answer = strCutLength(left(Answer, intLineBreak - 1), intLength) + chr(10) +
strCutLength(right(Answer, strlen(Answer) - intLineBreak), intLength);
else
Answer = left(Answer, intLineBreak) +
strCutLength(right(Answer, strlen(Answer) - intLineBreak), intLength);
endif;
endif;
return Answer;
endfunction
Опять к «Действиям»
Возвращаемся к нашей процедуре, которая обрабатывает клик по кнопке btAction. Начнем с очистки истории. Спросим, а то вдруг юзер щелкнул случайно или уже передумал. Если дает добро, то удаляем:
if doquerybox("Вы действительно хотите очиcтить хистори?", 4) = 6 then
txtHistory.Clear();
Form.lbMonitor.Caption(strMonitor);
domessagebox("Истории - писец!!!");
endif;
Следующим пунктом у нас идет шоу. Показывать тоже просто. Вот только одна байда, show объекта text очищает содержимое переменной. Поэтому будем казать не нашу переменную, а другую, предварительно сохранив историю на винтике.
strNameFile = userdir() + "$$$.tmp";
txtHistory.Write(strNameFile);
txtFile = createobject("Text");
txtFile.Open(strNameFile);
txtFile.Show("Ну, типа и вся история");
fs.DeleteFile(strNameFile);
Ну и последнее, научимся хранить историю.
strPath = fs.GetCurrentDirectory();
strFile = "";
if fs.SelectFile(1, strFile, strPath, "сэйвим хистории", "Файло для хистории (*.hst)|*.hst", "*.hst") > 0 then
txtHistory.Write(strPath + strFile);
endif;
Ну, вроде все. Удачи, вам в делах наших тяжких ;))
Пример к статье: http://www.kb.mista.ru/files/64/scrolling-1.zip
Санкт-Петербург, Декабрь 2005 года.
skunk |