| Пособие-самоучитель on-line "Visual Basic с нуля" |
Глава 6. Выбираем файл: DriveListBox, DirListBox, FileListBox. Функции Right и Left. Графические объекты PictureBox. ImagеBox.
Скачать исходник программы "IcoMaker" | Дата создания 28.10.2004 {Автор 4us}

DriveListBox, DirListBox, FileListBox

Я все-таки подумал, что пора потихоньку начинать работать с файлами. Начнем с объектов, которые помогут пользователю выбрать необходимый файл. Откроем новый .exe проект, и поместим на форму три объекта (контрола) . DriveListBox, DirListBox и FileListBox (Рис 12).

Рисунок 12.

Теперь положим на форму Text1и в окне его свойств поставим свойство MultiLine в True (это чтобы текст не выводился в одну строку). Сюда мы будем помещать основные возвращаемые этими объектами значения. Для этого напишем коротенький код. В окне кода для каждого объекта откроем следующие процедуры и впишем в них по три строчки кода:

`Option Explicit`

`Private Sub Drive1_Change()
Text1.Text = Drive1.Drive & vbCrLf
Text1.Text = Text1.Text & Drive1.ListIndex & vbCrLf
Text1.Text = Text1.Text & Drive1.ListCount
End Sub`

`Private Sub Dir1_Click()
Text1.Text = Dir1.Path & vbCrLf
Text1.Text = Text1.Text & Dir1.ListIndex & vbCrLf
Text1.Text = Text1.Text & Dir1.ListCount & vbCrLf
End Sub`

`Private Sub File1_Click()
Text1.Text = File1.FileName & vbCrLf
Text1.Text = Text1.Text & File1.ListIndex & vbCrLf
Text1.Text = Text1.Text & File1.ListCount
End Sub`
Обрати внимание: каждая процедура выводит в Text1 три значения. Чтобы они не сливались в одну строчку, а печатались с новой строки, мы используем константу vbClLf. Она и переводит строчки (но только при условии, если у Text1 включено свойство MultiLine).

Объект Drive1 выводит имена дисков, Dir1 - имена папок, и File1- имена файлов.

Потыкай в эти объекты мышкой и посмотри, какие значения возвращают эти объекты.

Первое свойство (для каждого объекта - свое) возврашает строковое выражение, показывающее имя диска (Drive1.Drive), путь (Dir1.Path) или имя файла (File1.FileName). Нас это свойство интересует больше всего. Свойство .Path может использоваться и с объектом File1 (File1.Path), но не с Drive1.

Второе свойство .ListIndex для Drive1 и File1 возвращает порядковый номер диска или файла в текущей директории, начиная с нулевого. Для Dir1 она возвращает -1 (минус один) для корневой папки и далее с нуля порядковый номер для вложенных в нее папок. В обратную же сторону порядок вложения идет со знаком минус. Проще говоря, посмотри на Рис.13. Синими цифрами показаны значения Dir1.ListIndex.

Рисунок 13.

Теперь с этой фигней должно быть понятнее.

Третье свойство ListCount возвращает общее количество дисков, папок в текущей папке или файлов в текущей папке.

Есть, конечно, и другие свойства, но мы на них зацикливаться не будем (попытка юмора).

Ты должен был обратить внимание, что все объекты работают как-то сами по себе. А хорошо бы их связать, чтобы все-таки можно было бы выбрать файл из нужной папки с нужного диска.

А посему, сотрем весь код, который мы написали для тренировки и напишем код так, чтобы у нас в Text1 выводилось полное имя файла, который мы выбрали:

`Option Explicit`

`Dim PathSearch As String 'переменная для хранения значения пути`

`Dim DiskName As String 'переменная для имени диска`

`Private Sub Form_Load()
PathSearch = App.Path
Drive1.Drive = PathSearch
Dir1.Path = PathSearch
File1.FileName = PathSearch
End Sub`

`Private Sub Dir1_Change()
File1.Path = Dir1.Path
End Sub`

`Private Sub Drive1_Change()
DiskName = Drive1.Drive
Dir1.Path = DiskName & "\"
File1.Path = Dir1.Path
End Sub`

`Private Sub File1_Click()
If Right (File1.Path, 1) = "\" Then
Text1.Text = File1.Path & File1.FileName
Else
Text1.Text = File1.Path & "\" & File1.FileName
End If
End Sub`

В коде должно быть все относительно понятно. Однако поясню. Мы объявили две переменные как строковые, одну для хранения значения пути, другую для имени диска. Чтобы при загрузке программа корректно отображала папки, диски и пр., мы в процедуре Form_Load с помощью функции App.Path ставим тот путь, где находится наша программа. Это очень удобно. В дальнейшем мы будем создавать служебные файлы и папки для хранения данных, необходимых нашей программе. И с помощью функции App.Path VB всегда найдет наш рабочий каталог. Использование промежуточной переменной PathSearch (как впрочем и DiskName) необходимо для корректной работы программы.

Далее. Когда мы выбираем диск в Drive1, процедура Drive1_Change через промежуточную переменную DiskName присваивает значение нового диска для Dir1, и в свою очередь значение нового пути для File1. Аналогично при выборе папки в Dir1 процедуа Dir1_Change присваивает новое значение пути для File1. Процедура же File1_Click собирает полное имя файла из пути File1.Path и имени файла File1.FileName. Правда, она осуществляет проверку, оканчивается ли File1.Path обратным слежом (\). Если да, то мы его не вставляем. Это необходимо, потому что имя диска возвращается со слежом, а если есть папка, то без. При этом мы применяем функцию Right.

Функции Left и Right

Мы уже использовали в Главе 4 функции Len, которая определяла число знаков в строке и Mid, с помощью которой мы можем выдернуть из строки необходимое количество знаков. Теперь мы к ним добавим еще две, очень простые:

Right ("строка",число знаков)

Left ("строка",число знаков)

Смысл их в том, что мы выьираем для себя из текстовой строки "строка" справа (функция Right) или слева (функция Left) необходимое нам количество символов число знаков в собственную строку. Эта собственная строка и есть то значение, которое возвращает функция.

Например, такая запись Right ("бармалей",3) возвратит нам значение "лей", а Left ("метрополитен",5) возвратит "метро". Вот и вся математика (арифметика).

Идем дальше.

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

Графические объекты PictureBox. Image.

Это довольно-таки сложная тема. Если не удается въехать в это все, надо просто брать как есть, чтоб потом использовать, не особо вдумываясь. Это просто прием. Ну начинаю грузить...

Все, что мы понаписали, мы используем для создания программки для пробразования графических файлов .jpg или .bmp в иконки .ico. На самом деле файлы ico имеют свой, особый формат и реально мы получим файл bmp размером 32х32 с расширением ico. Но это сейчас не главное. В дальнейшем мы, может сделаем настоящий редактор иконок.
Итак, сперва мы поменяем свойство нашей формы ScaleMode с 1 - Twip на 3 - Пиксель. Потому как с твипами непривычно и трудно работать.

Мы будем использовать два новых элемента PictureBox и Image. В них можно загружать, изменять и сохранять графические файлы. Разместим на нашей форме два PictureBox (Picture1 и Picture2) и один Image (Image1). Я надеюсь, что ты их найдешь. Кроме того положим одну командную кнопку Command1 и один Label1. Назовем кнопку Command1 (свойство Caption) "Сделать иконку 32х32".

Выглядеть это должно приблизительно, как на Рис. 14

Рисунок 14.

Установим свойство Picture1 ScaleMode в окне свойств тоже в 3 - Пиксель, как и у формы.

Вставим в процедуру File1_Click последней строкой (перед End Sub) такую штуку:

`Picture1.Picture = LoadPicture(Text1.Text)`

Эта штука - функция, которая загружает в PictureBox картинку, путь которой отобразится в Text1.

Теперь, с помощью нашей программы выберем какой-нибудь графический файл в компьютере и кликнем по нему. В наш PictureBox загрузится картинка. Хочу предупредить, что из-за недостатка оперативной памяти (менее 256 Mb) в твоем компьютере и большого размера файла картинки (более 1 Mb) этот процесс может не состояться или занять значительное время. Поэтому бери маленькие по объему (300-600 Кб) картинки.

Далее мы видим, что мы не фига не видим. Картинка видна не вся, а только кусочек, который позволяет размер Picture1. Можно, конечно, в окне свойств Picture1 поставить свойство AutoSize из False в True, но тогда Picture1 может так увеличиться, что не влезет в форму и все равно ее видно не будет. Можешь попробовать, но потом восстанови это свойство. Мы так делать на будем.

Что же нам делать? Для начала нам нужно узнать, какого же размера эта чертова картинка и запомнить этот размер. Для этого у Picture существуют свойства .Picture.Height для высоты и .Picture.Width для ширины. Однако, к сожалению значения, которые мы получим, будут в метрической системе HiMetric и чтобы перевести их в пиксели придется использовать методы ScaleX и ScaleY. Ну да ничего, не так страшно. Объявим в (General) две переменные Shirina и Visota

`Dim` `Shirina As Long
Dim Visota As Long`

а после нашего оператора загрузки картинки, в процедуре File1_Click, пишем две строки, которые и дадут нам ширину картинки в пикселях:

`Shirina = ScaleX(Picture1.Picture.Width, vbHimetric, vbPixels)
Visota = ScaleY(Picture1.Picture.Height, vbHimetric, vbPixels)`

где Picture1.Picture.Width - ширина в HiMetric, vbHimetric - константа, из какой метрической системы переводим, vbPixels - константа, в какую метрическую систему переводим.

Далее для красоты выведем ширину и высоту в Label1

`Label1.Caption = Shirina & " x " & Visota`

Зная реальный размер картинки мы можем вписать ее в заданный размер, например Image1, не зря ж мы его клали, надо использовать как-нибудь. Я установил его размер 265 на 265 пикселей, исходя из размера нашей формы. И нам надо подогнать размеры нашей картинки, пропорционально изменив длину и ширину. Сперва надо узнать вертикальная картинка (высота больше ширины) или горизонтальная (ширина больше высоты). Это мы сделаем условием If. В нем мы вычислим коэффициент Koeff (его тоже придется объявить), разделив большую сторону картинки на длину соответствуюшей стороны Image1. (Раcчет коэффициента можно сделать и по-другому: взять отношение большей стороны к меньшей Picture1).

`If` `Shirina > Visota Then
Koeff = Shirina / Image1.Width
Else
Koeff = Visota / Image1.Height
End If`

Как бы не хотелось, а придется объявлять еще две переменные для хранения нового размера для меньшей картинки. Их можно объявить локально, здесь же, в процедуре File1_Click

`Dim` `ShirinaNew As Long
Dim VisotaNew As Long`

Получаем новые значения для ширины и длины Image1.

`ShirinaNew = Shirina / Koeff
VisotaNew = Visota / Koeff`

У есть Image1 свойство Stretch. Если оно False (по умолчанию), то сам объект Image1 меняет свой размер по размеру картинки, а если True, то картинка меняется по размеру Image1, что нам сейчас и нужно.

`Image1.Stretch = True`

Выставляем новые значения размеров Image1

`Image1.Height = VisotaNew
Image1.Width = ShirinaNew`

и передаем картинку в Image1

`Image1.Picture = Picture1.Picture`

Тут еще вот какие нюансы. Поскольку мы каждый раз меняем размер Image1, надо его восстанавливать. Делать это лучше в начале нашей процедуры File1_Click.

`Image1.Width = 265
Image1.Height = 265`

Кроме того ее желательно очищать, впрочем как и Picture1. Для этого им передаются пустые значения.

`Picture1.Picture = LoadPicture("")
Image1.Picture = LoadPicture("")`

А кроме того, поскольку мы в Picture1 все равно ни черта не видим, сделаем ее невидимой, для чего в окне свойств изменим ее свойство Visible c True на False.

Теперь перейдем к тому, то ради чего мы все это затеяли: как же нам все-таки иконку-то сделать?

Изменим следующие свойства Picture2 на значение 36: Height, Width, ScaleHeight и ScaleWidth. (Почему 36, а не 32 не знаю. Если поставить 32, то иконки получаются размером 28х28). Свойство AutoRedraw, которое отвечает за перерисовку, обязательно поставим в True. Создадим процедуру Command1_Click для нашей командной кнопки. В ней объявим локальную переменную Ima для создания нового имени, под которым мы запишем нашу иконку.

`Private Sub` `Command1_Click()
Dim Ima As String`

Теперь, используя известные нам функции Len и Mid отсечем справа 4 знака (это предполагается расширение 3 знака и точка) и вместо него прибавим расширение .ico.

`Ima = Mid(Text1.Text, 1, Len(Text1.Text) - 4) & ".ico"`

Теперь используем метод PaintPicture. Он позволит нам перерисовать картинку из Picture1 в Picture2, масштабировав ее при этом

`Picture2.PaintPicture Picture1, 0, 0, 32, 32, 0, 0, , , vbSrcCopy`

Это происходит так. Picture2.PaintPicture записывает картинку из Picture1 в Picture2 с координатами в Picture2 0,0 c размером Picture2 32,32 и координаты в Picture1 0,0. vbSrcCopy - этот параметр - константа - необязателен (им устанавливается побитная операция).

Далее с помощью оператора SavePicture мы записываем полученную в Picture2 иконку в файл.

`SavePicture Picture2.Image, Ima`

Готово! Заработало. У нас крутейшая программка. Скачать исходник можно вверху страницы. Конечно это в общем-то всего лишь пример, но тем не менее у нее большой потенциал. Поработай с исходником, попробуй сделать, чтобы имя иконки мог задавать пользователь, сделай иконки другого размера, измени дизайн, разработай, короче, интерфейс.

Copyright © 2004 4us