Делаем «гляделку» с помощью одинСи. The first part (Preview).Привет всем! Вот и прошел очередной старый новый год. Закончились рождественские каникулы. И мы снова вышли работать во славу наших работодателей. Не знаю как вы, а я встретил новый год как обычно. Бухнул, лег на диван и, не много «спустя» уснул. Хотя на счет «спустя» приврал. На домашнем компе не оказалось соответствующей подборки фотографий, способствующей повышению потенции. А у пьяного без нее не стояло или не стоило, сейчас уже не помню, да и не важно. Сейчас важно другое. Придя после праздников на работу, решил я это дело усугубить. Да вот не задача, постоянно шляющиеся сотрудники фирмы не давали сосредоточиться. Так как из-за них то и дело приходилось сворачивать, абы у них не возникло тяги присоединиться. Любовь эта такая вещь, если не один, то это изврат. И тут у меня возникла, мысля сделать гляделку на одинСи. Абы, зашедший олух, увидав на монике знакомую эсину, не отвлекал меня от любимого занятия. Пацан сказал – пацан сделал. Будем делать. | | Автор статьи: skunk | Редакторы: Волшебник Последняя редакция №6 от 12.01.06 | История URL: http://kb.mista.ru/article.php?id=70 | |
Дизайн.
Как обычно начнем с дизайна. Жаль вот только в книгу знаний низя картинки тылкать, а то мы б развернулись. Ну, нет и суда нет. Опишем кратко в двух словах, что мы там на колдовали. Начнем, пожалуй, со слоев. У меня, их получилось четыре.
Первый основной – «Main». В нем я организовал файловый навигатор с возможностями предварительного просмотра картинки. Не наугад же нам их открывать. А по памяти я уже всех и не помню. Для навигации используем: «СписокЗначений» «vlDisk» в который затолкаем все доступные на компе диски и «ТаблицаЗначений» «vtFile» для показывания списка файлов, в текущей папке. Для отображения информации файла под курсором используем две картинки: «picPreview» и «picNotPreview», как ясно из их названия одна, для того чтобы какзать, когда есть картинка, другая, когда нет. Так же на форму положим парочку «Текстов». С помощью их будем сообщать о всяких возможных ошибках, да и прочей лабуды. Ну и завершает натюрморт две кнопки. Одна: «btAbout» - для показа эбоута. Другая кнопка «btClose» - с ней ясно из названия, что бы закрывать нашу аппликацию.
Второй не менее важный слой, это конечно «About». Скажу по секрету это самый основной слой. Как же это так, люди будут пользоваться и не знать, кто для них мучился. Так дело не пойдет. Вообще по-хорошему любую прогу надо начинать с этого. Что-то мы отвлеклись, вертаемся к дизайну. Что вы на этом слое на дизайничите ваши проблемы. Самое главное не забудьте сделать кнопку для закрытия оного окошка, что бы пользователь смог закрыть его, когда насладиться созерцанием вашего копилевта.
О двух последних слоях поговорим не много позже, в другой жизни… ой, другой части. Сейчас приступим к программированию файлового менеджера.
Диски.
Начнем, пожалуй, с дисков. То бишь, глянем, какие устройства хранения информации присутствуют на нашем полигоне. За свою не долгую жизнь каких только извратов я не видал на этом поприще. Одни еще более менее работали, другие работали так себе. Короче все они нас напрочь не устраивают, оставим их для Левы Баранова, мы пойдем другим путем. Причем без извратов. Ведь мы же парни грамотные знаем, что у винды есть такой объект, как «FileSystemObject». Вот его миленького и будем иметь. У этого самого объекта, гражданской наружности, есть коллекция «Drives», вот она там нам и нужна. Ибо в ней содержится вся информация о присутствующих в системе дисках. Причем не только физических, но и сетевых. Смотрим на пирог:
function vlGetDrive()
Shell = createobject("MSScriptControl.ScriptControl");
Shell.Language = "VBScript";
txtCode =
"function GetDriveList()
| dim tmpDrive
| set objFSO = createobject(""Scripting.FileSystemObject"")
| set oleDrive = objFSO.Drives
| Count = 0
| Answer = ""{""""СписокЗначений"""",{""
| for each tmpDrive in oleDrive
| Answer = Answer & ""{{""""Строка"""","""""" &_
| tmpDrive.Path & """"""},"""""" &_
| ""[-"" & tmpDrive.DriveLetter & "":\-]""
| select case tmpDrive.DriveType
| case 0: TypeDrive = "" Unknown""
| case 1: TypeDrive = "" Removable ""
| if tmpDrive.IsReady then
| TypeDrive = TypeDrive & "" ("" & replace(tmpDrive.VolumeName, """""""", """""""""""") & "")""
| end if
| case 2: TypeDrive = "" HDD""
| if tmpDrive.IsReady then
| TypeDrive = TypeDrive & "" ("" & replace(tmpDrive.VolumeName, """""""", """""""""""") & "")""
| end if
| case 3: TypeDrive = "" Network ("" & replace(tmpDrive.ShareName, """""""", """""""""""") & "")""
| case 4: TypeDrive = "" CD-ROM""
| if tmpDrive.IsReady then
| TypeDrive = TypeDrive & "" ("" & replace(tmpDrive.VolumeName, """""""", """""""""""") & "")""
| end if
| case 5: TypeDrive = "" RAM""
| if tmpDrive.IsReady then
| TypeDrive = TypeDrive & "" ("" & replace(tmpDrive.VolumeName, """""""", """""""""""") & "")""
| end if
| end select
| Answer = Answer & TypeDrive & """""",""""0""""}""
| Count = Count + 1
| if oleDrive.Count > Count then
| Answer = Answer & "",""
| end if
| next
| Answer = Answer & ""}}""
| GetDriveList = Answer
|end function
|";
Shell.AddCode(txtCode);
Answer = valuefromstring(Shell.Run("GetDriveList"));
return Answer;
endfunction
Даже не знаю, как это все пояснить. Вроде просто, как у Федора. Создаем объект «ScriptControl», устанавливаем ему в качестве рабочим языком «VBScript». Далее идет сам код, написанный на данном языке компании, сами знаете какой. Данный код ни фиха толком не делает. Просто подключается к сказанному выше объекту в виндовс и имеет там его коллекцию. На основании данных половых манипуляций из коллекции получается строка. Полученную строку преобразовываем в «СписокЗначений» и отдаем его тому, кто просил. У все, имеем список установленных дискеток.
Файлики.
Так диски получили, займемся файлом. Но на некоторое время вернемся к юзабилити, или дизайну. Согласитесь, было бы не плохо отличать файло от фолдеров, да ведь? Для этого воспользуемся возможностями 1С по отображению пиктограмм в «ТаблицеЗначений». Рисуем картинку которая представляет из себя четыре картинки. Почему четыре? Первая – папка в которую можно зайти. Вторая – из которой можно выйти. Третья – файлик который нам не нужен. И последняя, четвертая – файлик с рисунком. Засовываем полученную пиктури в «ТаблицуЗначений». Все готово к началу осады. Начинаем собирать грибы. Думаете, оговорился. Нисколечко. Кто из вас занимался промышленным сбором грибов, знает, что собирать в маленькое лукошко, и по мере его наполнения высыпать в большое гораздо удобнее, чем тягать по всему лесу большое, особенно когда грибов много. Так и мы грибы, то бишь файлы, будем собирать в маленькое лукошко, а потом сыпать их в большое. Объявляем глобальную переменную и инициализируем ее в процедуре OnOpen, как вы, наверное, знаете, данная процедура выполняется при открытии любого приложения, в концепции 1С отчета, обработки и тому подобного.
var vtCurDir;
//*******************************************
procedure OnOpen()
vtCurDir = createobject("valuetable");
vtCurDir.NewColumn("Icon", "number", 1, , "..", 1);
vtCurDir.NewColumn("Type", "number", 1);
vtCurDir.NewColumn("Name", "string", , , "Имя", 6);
vtCurDir.NewColumn("FullName", "string");
endprocedure
Итак, что мы тут намастырили - «ТаблицуЗначений» и в ней четыре колонки. Одна для отображения пиктограмм. Во вторую будем класть тип. Типов будет три: родительская папка для текущей папки, папки, вложенные в текущую папку и сами файлы. Эта колонка вкупе со следующей будет служить для сортировки, итоговой таблицы. В третьей будем хранить короткое имя файла, ее то и будем показывать зрителям. Последняя, будет хранить полное имя до файла или папки. Если с этим все понятно, едем дальше. Далее для полноценного сбора инфмы о грибах нам потребуется две вещи, о которых фирма 1С наглухо забыла, делая свой «Files». Не будем их за это пинать, ведь они делали бухию, а систему навигации, надо отдать должное, что со своей задачей они справились. Справимся и мы. Мы же програмеры, а не специалисты. Не так ли?
Первое, что нам потребуется это функция, которая бы вернула родительскую папку для текущей папки. Здесь нам опять на помощь придет объект все любимой винды «FileSystemObject», не понимаю, почему все ее так не любят, ведь с ней же жить проще, прям как с Ренаткой.
//*******************************************
function strGetParentFolder(strNameFile = "")
try
oleFSO = createobject("Scripting.FileSystemObject");
objFolder = oleFSO.GetFolder(strNameFile);
return objFolder.ParentFolder.Path;
except
return "fuck";
endtry;
endfunction
Смотрим, что мы тут имеем. Передаем функции строку, полное имя папки родителя которой хотим знать. Пробуем подключиться к FSO и получить объект Folder. Затем смотрим родителя у него и если таковой есть, возвращаем его полное наименование. Если ни чего не удалость, то делаем фак. Сперва я использовал метод Рупора как защиту от дурачков, ведь их еще не всех войной убило. Я даже парочку видел. Но потом при работе с сетевыми дисками всплыла еще одна бяка. Дело в том, что сетевой диск это обычная папка, только расшаренная на другом компе и у нее, как и у любой папки есть родительская папка, но вот получить ее через FSO нельзя. Сделано это для так называемой сетевой безопасности. Хотя получить имя родителя можно, но это уже из другой оперы. Сейчас мы просто швырнем просящего.
Следующее вещь, о которой мы с вами подумаем, это как мы будем отличать нужные нам файлики от ненужных. Мы сейчас пойдем не самым правильным, но самым шустрым способом определения грибов. Определять их будем, как и положено Барановым Львам по его имени, если быть точнее, то по расширению имени файла. Вы, конечно, заметите, что вдруг тот же Лева изменит расширение какого-либо файла на расширение какой-либо картинки. И будете абсолютно правы. Но мы это отнесем к проблемам Льва, ведь в этом случае не мы будем мастурбировать, а он.
//*******************************************
function strGetExpansion(strNameFile = "")
Answer = "";
if find(strNameFile, ".") > 0 then
strTemp = """" + strreplace(strNameFile, ".", """,""") + """";
vlTemp = createobject("valuelist");
vlTemp.FromSeparatedString(strTemp);
Answer = lower(vlTemp.GetValue(vlTemp.GetListSize()));
endif;
return Answer;
endfunction
Для того, что бы получить расширение файла, нам надо передать функции его имя. Полное оно или короткое в данном случае уже не важно. Все равно будем смотреть в попку. То есть, сзади. Опять в тырнете кучу есть решений данной проблемы, видать многим наболело. Но большинство из них подходит не всегда и не везде. Почему поясню простым примером. Допустим у нас есть папка в которой лежат, следующие четыре файла:
Лев_Баранов – ЧМО
Лев_Баранов.ЧМО
Лев_Баранов.мудак
Лев_Баранов.чмо.и.мудак.
Из тех вариантов что видал. Способ первый, почему-то самый распространенный, поиск первой точки с четвертым файлом получим лыжи. Способ второй, вариантов несколько, поиск последней точки. Не будем говорить о громоздкости данной конструкции из-за применения цикла, просто большинство из них вернет не правильный ответ при получении имени файла на вроде первого и последнего. Последний вариант, получение трех последних символов в имени. Получаем грабли с первым, третьим и четвертым. Итак, из четырех файлов все рассмотренные способы вертают правильный ответ только в классическом варианте. Одна точка и три символа после нее. Что не есть гуд.
Возвращаемся к нашей функции. Что делает она. Смотрит если точка как таковая. Если нет, то на нет и суда нет. Возвращает пустое значение. Иначе, преобразует полученное имя из строки, скажем: Лев Баранов.чмо.и.мудак. в строку "Лев Баранов ","чмо","и","мудак","". А затем преобразует полученною строку в «СписокЗначений», после чего значение содержащиеся в самом конце списка преобразует к нижнему регистру и отдает тому, кто попросил. Зачем преобразовывать к нижнему регистру, объяснять надеюсь, не требуется.
Итак, теперь у нас сто пудово все готово. Десантно-штурмовой батальон готов к бою. Начинаем сбор.
//*******************************************
procedure SetFolder(strFolder = "")
if fs.ExistFile(strFolder) = 0 then
strFolder = vlDisk.GetValue(vlDisk.CurSel());
endif;
strFolder = strFolder + "\";
fs.SetCurrentDirectory(strFolder);
vtCurDir.DeleteLines();
Attribute = "";
strNameFile = fs.FindFirstFile("*.*");
while strNameFile <> "" do
if strNameFile <> "." then
vtCurDir.NewLine();
vtCurDir.Name = strNameFile;
vtCurDir.FullName = strFolder + strNameFile;
if strNameFile = ".." then
vtCurDir.FullName = strGetParentFolder(strFolder);
if vtCurDir.FullName = "fuck" then
vtCurDir.DeleteLine();
else
vtCurDir.Icon = 2;
vtCurDir.Type = 1;
endif;
else
fs.GetFileAttr(vtCurDir.FullName, , Attribute);
if mid(Attribute, 4, 1) = "1" then
vtCurDir.Icon = 1;
vtCurDir.Type = 2;
else
strExpansion = strGetExpansion(strNameFile);
if ((find("wmf,emf,ico,gif,bmp,dib,rle,jpg,jpeg,", strExpansion) > 0)
and (emptyvalue(strExpansion) = 0)) then
vtCurDir.Icon = 4;
else
vtCurDir.Icon = 3;
endif;
vtCurDir.Type = 3;
endif;
endif;
endif;
strNameFile = fs.FindNextFile();
enddo;
vtCurDir.Sort("Type,Name");
intCurrentColumn = vtFile.CurrentColumn();
if emptyvalue(intCurrentColumn) > 0 then
intCurrentColumn = 1;
endif;
vtCurDir.Unload(vtFile);
vtFile.ColumnVisibility("Type,FullName", 0);
vtFile.ShowImages("Icon", 1);
vtFile.CurrentLine(1);
vtFile.CurrentColumn(intCurrentColumn);
endprocedure
Начнем разбор того, что мы тут штурманули. Итак, сначала проверим, есть ли та папка, файлы в которой надо выбрать. Если нет, то будем собирать из текущего диска. Текущего, тот который выбран в нашем списке. Далее, на всякий пожарный прибавим символ «\». Их количество роли играет мало, а вот не которых проблем поможет избежать. Наверное, самый яркий пример того, что кашу маслом не испортишь. После чего сделаем полученную папку текущей в системе. Очистим от мусора ТЗ vtCurDir. И далее в выбираем файлы и папки находящиеся в текущей. И ложем их в наше временное «лукошко». В каждой папке, если она конечно не коревая, есть как минимум два файла. Один «.» другой «..». В принципе это одно и тоже. За не большим исключением, но нам сейчас эта разница до лампочки. Поэтому «.» выбрасываем сразу на фих, и смотрим на гриб «..». У него есть одна особенность связанная с сетевыми папками, впрочем я говорил это когда рассматривал функцию strGetParentFolder. Так вот если она нам вернет «fuck», то такой гриб на тоже не нужен на фих, выбрасываем. Иначе запоминаем, полный путь до родительской папки ну и заодно устанавливаем тип и вид пиктограммы в ТЗ.
А вот если имя гриба не то и не другое будем рассматривать гриб ближе. Сперва получим его атрибуты и, глянув на его четвертый флаг, определим папка это или просто обычный файл. Если папка, то пришьем бирку с необходимым типом и иконкой. Если же это файл, то смотрим его расширение, и уже по нему определяем, картинка это или нет.
После того, как собрали все грибы, отсортируем их по типу и имени. Получим текущую колонку в ТЗ которая лежит на форме. Высыпаем урожай в нее. Говорим, что из всех колонок хотим видеть только «Icon» и «Name», причем колонку «Icon» виде пиктограмм. Устанавливаем в текущую строку и колонку. Все.
Moved.
Злосчастный мувед. Согласитесь, было бы не плохо, сразу же казать картинку, как только пользователь ее выбрал. Делать не фих придется ловить фокус. О том, как его ловить я уже рассказывал на втором уроке(Книга знаний: Ловим Фокус.). Поэтому сейчас остановимся только на конечной функции. Ложем на форму «Текст», в формуле которого пишем: «RefreshForm()». Лезем в модуль. Залезли? А теперь немного подумаем. Иногда полезно. После того как хорошо подумали, приходит к выводу, что у нас все есть. Почти все есть. Нам надо только одно. Для повышения скорости выполнения функции нам нужна переменная, в которой будем хранить то, что у нас показано в области предварительного просмотра.
Ну, все, карапузики, хватит думать, пора мышцы напрягать. Клаву к себе и с криком «Ура!» рвемся вперед. Сперва к блоку глобальных переменных, и добавляем нашу переменную, для хранения отображаемой в «Preview» картинки, точнее имени файла с картинкой.
var strShowFile;
Добавляем функцию:
//*******************************************
function RefreshForm()
if intMode = 0 then
return 0;
endif;
intIcon = vtFile.Icon;
if intIcon = 4 then
if vtFile.FullName <> strShowFile then
try
if strShowFile = "NotReload" then
strShowFile = vtFile.FullName;
else
strShowFile = vtFile.FullName;
picPreview.Load(strShowFile);
picPreview.SetDrawMode(3);
endif;
Form.picPreview.Visible(1);
Form.picNotPreview.Visible(0);
Form.lbMessage.Visible(0);
Form.lbError.Visible(0);
except
Form.picPreview.Visible(0);
Form.picNotPreview.Visible(1);
Form.lbMessage.Visible(0);
strError = "Что-то неправильное" + linebreak + "у этой картинки";
Form.lbError.Caption(strError);
Form.lbError.Visible(1);
endtry;
endif;
else
if intIcon = 1 then
strMessage = "Это папка" + linebreak + "возможно в ней есть картинки";
elsif intIcon = 2 then
strMessage = "Это путь наверх" + linebreak + "не путать с дорогой в небеса";
elsif intIcon = 3 then
strMessage = "А за это гуано" + linebreak + "я не фиха не знаю";
endif;
Form.lbMessage.Caption(strMessage);
if strShowFile <> "BackGround" then
Form.picPreview.Visible(0);
Form.picNotPreview.Visible(1);
Form.lbMessage.Visible(1);
Form.lbError.Visible(0);
strShowFile = "BackGround";
endif;
endif;
Form.Refresh();
endfunction
Глядим на функцию. Первые три строчки пока на фих опустим. Для чего они скажу позже, когда будем работать на второй частью.
Первым делом смотрим вид иконки, по виду будем судить, надо нам отображать картинку или не надо. Если надо, то сравним полное имя файла с полным именем файла отображенного рисунка. Не совпадают, значит, курсор в ТЗ попал на другой графический файл, и его надо отобразить на форме. Отображаем. Хотя правильнее пробуем. Мало ли чего. Все-таки Львов Барановых еще ни кто не отменял. Все гуд, значит, кажем картинку «picPreview» пряча все остальное. В противном случае тут был, не будем показывать пальце, и что-то не лады с картинкой – отображаем «picNotPreview» и мессачим об ошибке.
Те, кто внимательно смотрели листинг функции, могут спросить, а это что такое «if strShowFile = "NotReload" then». Поясняю, это для того, что бы при включении слоя нам опять не пришлось загружать картинку сызнова.
Во всех остальных случаях проверяем отображена ли у нас «picNotPreview» и если нет то отображаем, скрывая «picPreview». За одно выводим не большие пояснения, типа это папка, а это файл который не графический.
Выбираем диск.
Прежде чем закончить первую часть нашей лекции перейдем опять к интерфейсу. Поговорим о взаимодействии пользователя с нашей программой. Мы уже не много рассмотрели данный вопрос, разбирая мувед. Сейчас просто кое-что дополним. И начнем с выбора диска.
Мы уже получили все диски в системе, и даже поместили в их в «СписокЗначений», лежащий на форме. Теперь было бы не плохо научить нашу аппликацию реагировать на смену выбранного значения в нем. Для этого в свойствах «vlDisk» в поле формула добавим строку «ChangeDrive()». Ну а в модуле отчета пишем процедуру, которая будет смотреть установленное текущее значение списка, а там у нас, как вы помните храниться диски системы, они же являются родительскими папками для всех остальных папок текущего диска. А это значит что, получив имя диска, мы, используя процедуру «SetFolder(ИмяДиска)» отобразим в «vtFile» файлы и папки текущего диска. Но прежде чем кинуться ваять, не плохо было бы подумать о следующем. А вдруг пользователь выберет устройство со сменным носителем, и носителя в этот момент в устройстве не будет. Лыжи. Не а. Если мы воспользуемся советом от Э Эха. Именно он предложил фичу по проверки наличия диска в устройстве. Пишем функцию, которая проверит, есть ли диск в устройстве и если есть, то вернет 1.
//*******************************************
function intDriveSetup(strDrive = "a:")
return fs.ExistFile(strDrive + "\NUL");
endfunction
Далее, поскольку процедура «SetFolder()» может занимать продолжительное время, зависит от количества имеющихся папок и файлов. Было бы не плохо подстраховаться, на тот случай если пользователь при выборе из списка, выберет тот же диск, что сейчас просматривает. Для этого заведем глобальную переменную, в которой будем хранить номер текущего значения в списке «vlDisk».
var intCurDrive;
Теперь в принципе можно писать «ChangeDrive».
//*******************************************
procedure ChangeDrive()
intDrive = vlDisk.CurSel();
if intCurDrive <> intDrive then
strCurDrive = vlDisk.GetValue(intDrive);
if intDriveSetup(strCurDrive) > 0 then
intCurDrive = intDrive;
SetFolder(strCurDrive);
else
domessagebox("Устройство не доступно, либо отсутствует съемный диск!");
vlDisk.CurSel(intCurDrive);
endif;
endif;
endprocedure
Получаем номер выбранного значения. Сравниваем его с предыдущим. Если он тот же, то больше не делаем не фиха. Иначе идем дальше. По номеру получаем нужного нам диска. Проверим его доступность. Доступен! Да, тогда «SetFolder()». Нет, шлем на три буквы русского алфавита.
Делаем в ТЗ «double click».
Для чего? Как для чего! Что бы скакать по пакам, и показывать графический файл. Итак, в формуле нашей таблице «vtFile» пишем: «OnDoubleClick()». Якши. И лезем опять в модуль. Тут все просто, как в одном месте мамонта. Смотрим, по чему кликнул пользователь. Если папка, то делаем уже известный «SetFolder» с полным именем папки. Если это графический файл, то открываем нашу обработку в другом окне. Для этого используем знак «#». Иначе. А иначе ни чего не делаем, курим. И опять не много подумаем. Ведь для того, что бы открыть нашу обработку нам надо знать ее полное имя. Конечно, в 1С есть процедура, которая позволяет получить путь и имя файла обработки. Из них мы сможем получить полное имя, но каждый раз это делать ломает. Да и мало ли где еще нам понадобиться оное. Значить объявляем глобальную переменную, в которой будем хранить полное имя нашей обработки.
var strReportName;
Далее пишем процедуру, которая устанавливает полное имя обработки, и вызываем ее при открытии формы, то бишь, при запуске нашей обработки.
//*******************************************
procedure SetNameReport()
strFile = "";
strPath = "";
FilePath(strPath, strFile);
strReportName = strPath + strFile;
endprocedure
После чего мастырим процедуру «OnDoubleClick()».
//*******************************************
procedure OnDoubleClick()
if ((vtFile.Type = 1) or (vtFile.Type = 2)) then
SetFolder(vtFile.FullName);
elsif vtFile.Icon = 4 then
if Form.picPreview.Visible() = 1 then
openform("Report#", vtFile.FullName, strReportName);
endif;
endif;
endprocedure
Вместо заключения.
Для наведения красявости, добавим последний штрих. У нашей обработки ведь несколько слоев. Правильно? И если ничего не предпринять, то мы получим кашу из всех четырех слоев, что не есть гуд. Значит, нам нужна процедура, которая рулит слоями.
//*******************************************
procedure ShowLayer(NameLayer = "Main");
Form.UseLayer(NameLayer, 2);
if NameLayer = "Main" then
strShowFile = "NotReload";
endif;
endprocedure
Данная процедура, получив при вызове имя слоя отображает его на форме. По умолчанию таковым будет являться основной слой нашего приложения. При отображении основного слоя может получиться не большая какашка, связанная с переключением слоев. Объясню на пальцах. Допустим, пользователь смотрит файлы. Установив курсор на какой-либо графический файл. А потом решил посмотреть на ваше имя. Переключился в эбоут. Насмотрелся, переключился обратно. Что получаем? Точно. Картинка начала грузиться заново. И вот ту мы вспоминаем про «if strShowFile = "NotReload" then». Теперь поняли для чего этого. Аха. Чтобы не грузить картинку сызнова.
Ну, вроде на сегодня все. Удачи вам в делах наших тяжких. ;))
to be continued…
Сырец тут http://www.kb.mista.ru/files/70/1CSee.zip
Санкт-Петербург, Январь 2006 года.
skunk
|