Більш складний приклад: перегляд атрибутів файлів в CBuilder

Прості приклади, які ви бачили в цьому розділі досі, показували, як зробити одне або дві справи, але не показували реального закінченого приклад використання Windows API У цьому прикладі ми розглянемо не одну або дві функції API, а відразу цілу групу функцій, визначену для файлової системи Windows Приклад, який ми збираємося зробити, – простий броузер атрибутів файлів У ньому можна буде вибрати диск, каталог, а потім буде відображена інформація про цей диск, каталозі і файлах, що знаходяться там

Windows API надає багатий набір функцій, які працюють саме з файлової системою Є функції, що дозволяють знайти файли, які підходять під заданий критерій (наприклад, файлову маску), функції для визначення обсягу простору на диску і функції, які повертають імена міток диска

У даному прикладі ми розглянемо використання всіх цих функції для відображення потрібної користувачеві інформації

Рис 94 Форма додатка FileAttributeViewer

На рис 94 наведено форму, з якою ми будемо працювати в цьому прикладі Ви можете зрозуміти, що за інформацію ми будемо показувати, виходячи з типів керуючих елементів, наведених тут Кілька міток статичного тексту потрібні для відображення інформації про диск (логічному диску), тоді як сітка рядків потрібна для відображення інформації про окремих файлах в каталозі, обраному користувачем Кнопка Перегляд потрібна для запуску процесу, а діалог відкриття файлів потрібен для вибору каталогу, з яким слід працювати

Найперше дію, яке ми повинні виконати, – ініціалізувати сітку рядків, щоб заголовки стовпців дозволяли користувачу зрозуміти, що за інформацію він бачить Додайте наступний код в метод FormCreate (Обробник події форми OnCreate):

void __fastcall TForm1::FormCreate(TObject *Sender)

{

StringGrid1-&gtCells[0][0] = &quotFile Name" StringGrid1-&gtCells[1][0] = &quotAttributes" StringGrid1-&gtCells[2][0] = &quotSize"

StringGrid1-&gtColWidths[0] = StringGrid1-&gtClientWidth / 3 StringGrid1-&gtColWidths[1] = StringGrid1-&gtClientWidth / 3 StringGrid1-&gtColWidths[2] = StringGrid1-&gtClientWidth / 3 StringGrid1-&gtRowCount = 1

}

Насамперед користувач буде вибирати каталог з вікна діалогу відкриття файлів (використовуючи кнопку Перегляд) Створіть обробник натискання на кнопку Перегляд і додайте в обробник код:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

if (OpenDialog1-&gtExecute())

{

/ / По-перше, записати диск і каталог

AnsiString strDrive =

ExtractFileDrive (OpenDialog1-&gtFileName) AnsiString strDirectory =

ExtractFileDir (OpenDialog1-&gtFileName)

/ / Отримати імя мітки диска

char szVolName [_MAX_PATH] DWORD  dwVolumeSerialNumber=0

DWORD dwMaxVolumeLength = _MAX_PATH

DWORD dwFileSystemFlags = 0

char szFileSystemNameBuffer [_MAX_PATH] strDrive += &quot\\"

GetVolumeInformation (strDrivec_str (), szVolName, / / ​​буфер для мітки диска

_MAX_PATH, / / ​​Довжина буфера

/ / Буфер для серійного номера диска

&ampdwVolumeSerialNumber,

/ / Покажчик на максимальну довжину імені

/ / Файлу в системі

&ampdwMaxVolumeLength,

/ / Покажчик на прапори файлової системи

&ampdwFileSystemFlags,

/ / Покажчик на імя файлової системи

szFileSystemNameBuffer,

_MAX_PATH / / Довжина буфера для імені файлової системи

)

/ / Обробка мітки вільне місце на диску char szBuffer [80]

DWORD dwSectorsPerCluster, dwBytesPerSector DWORD dwFreeClusters, dwClusters

DWORD dwFreeSpace  GetDiskFreeSpace(strDrivec_str(),  &ampdwSectorsPerCluster,

&ampdwBytesPerSector, &ampdwFreeClusters,  &ampdwClusters) dwFreeSpace =

dwSectorsPerCluster * dwBytesPerSector * dwFreeClusters sprintf(szBuffer, &quot%ld&quot, dwFreeSpace) DriveFreeSpaceLabel-&gtCaption = szBuffer

/ / Помістити інформацію в мітки

DriveLabel-&gtCaption = strDrive + &quot [&quot + szVolName + &quot]" DirectoryLabel-&gtCaption = strDirectory

AnsiString strAll = strDirectory + &quot\\**"

/ / Тепер отримуємо всі файли в каталозі, використовуючи

/ / Функцію API FindFile WIN32_FIND_DATA FindFileData

HANDLE hFirstFileHandle = FindFirstFile (strAllc_str(),

&ampFindFileData) int nRow = 1

while (hFirstFileHandle)

{

/ / Збільшити кількість рядків у сітці

StringGrid1-&gtRowCount++

/ / Отримати розмір файлу

long lFileSize =

(FindFileDatanFileSizeHigh * MAXDWORD) + FindFileDatanFileSizeLow

/ / Отримати атрибути файлу

AnsiString strArchive = &quot"

if (FindFileDatadwFileAttributes &amp FILE_ATTRIBUTE_ARCHIVE)

strArchive += &quotA"

if (FindFileDatadwFileAttributes &amp FILE_ATTRIBUTE_COMPRESSED)

strArchive += &quotC"

if (FindFileDatadwFileAttributes &amp FILE_ATTRIBUTE_DIRECTORY)

strArchive += &quotD"

if (FindFileDatadwFileAttributes &amp FILE_ATTRIBUTE_HIDDEN)

strArchive += &quotH"

if (FindFileDatadwFileAttributes &amp FILE_ATTRIBUTE_READONLY)

strArchive += &quotR"

if (FindFileDatadwFileAttributes &amp FILE_ATTRIBUTE_SYSTEM)

strArchive += &quotS"

if (FindFileDatadwFileAttributes &amp FILE_ATTRIBUTE_TEMPORARY)

strArchive += &quotT"

/ / Помістити дані в сітку рядків StringGrid1-> Cells [0] [nRow] = FindFileDatacFileName

StringGrid1-&gtCells[1][nRow] = strArchive sprintf(szBuffer, &quot%ld&quot, lFileSize) StringGrid1-&gtCells[2][nRow] = szBuffer

if (FindNextFile (hFirstFileHandle, &ampFindFileData)

== FALSE)

{

if (GetLastError() == ERROR_NO_MORE_FILES) break

}

nRow ++

}

}

}

Це занадто великий шматок коду, щоб розібрати його відразу весь Давайте розглядати його по частинах, щоб спробувати зрозуміти, що відбувається Спочатку користувач вибирає конкретний файл в якому-небудь каталозі в вікні діалогу відкриття файлу Коли файл обраний, програма отримує букву диска і каталог, в яких лежить файл, використовуючи допоміжні функції ExtractFileDrive і ExtractFileDir Ці функції, описані в заголовному файлі vcl \ sysutilshpp в каталозі з системою CBuilder, повернуть вам частини повного шляху файлу, відповідно визначають імя диска і каталог У разі каталогу ця інформація включає в себе також і диск (наприклад, D: \ dir \), так що ми пізніше можемо використовувати її для пошуку файлів в каталозі

Коли у нас є імя (буква) диска, на якому знаходиться файл, нашим наступним кроком буде отримання мітки для цього диску Імя мітки диска – це імя диска, яке зявляється в лістингах каталогів цього диска Наприклад, ваш диск C: в Windows Explorer (і інших лістингах каталогів) виглядає приблизно як C: (Windows 95) Імя мітки диска в даному випадку в дужках, тобто Windows 95 Хоча вони й не дуже інформативні для жорстких дисків, як C:, але дуже корисні для однозначного визначення компакт-диска або іншого знімного пристрою

Після інформації про мітку диска наша програма отримує інформацію про кількість вільного місця на диску Ви, напевно, думаєте, що це робиться викликом небудь одній функції типу GetDriveFreeSpace Тут ви помиляєтеся При запиті про вільне місце на диску функція API повертає три різних значення, які потім потрібно скомбінувати, щоб

отримати кількість вільного місця на диску Інформація, яку ми отримуємо, включає SectorsPerCluster, тобто кількість секторів в одному кластері жорсткого диска, потім BytesPerSector, що є кількість байтів в одному секторі диска, і кількість вільних кластерів Між іншим, це дуже важливі параметри диска Деякі жорсткі диски дозволяють вам займати місце побайтно, а інші вирівнюють все по межі найближчого кластера Ось чому розмір файлу не відображає насправді розмір дискового простору, який цей файл займає

Три значення перемножуються, і результат заноситься в подвійне слово (DWORD) dwFreeSpace Потім ця інформація форматується і поміщається в мітку, яка буде показувати вільний простір на диску

Разом з вільним місцем на диску у відповідні поля статичного тексту (мітки) поміщаються імя каталогу, імя диска і мітка диска Наступний крок – відображення інформації про файли, що знаходяться в одному каталозі з обраним файлом

Для пошуку всіх файлів в каталозі використовуються функції API FindFirstFile і FindNextFile Ці функції знайдуть вам файли, які підходять під заданий критерій, наприклад всі файли (* *), Всі вихідні файли (* Cpp) або всі бібліотечні файли (* Lib) Крім того, так як ви можете задавати будь-яку маску, ви можете знайти всі файли, що починаються з «Fred», використавши маску Fred * * або навіть всі файли з Fred всередині їх імені, вибравши * Fred * в якості маски Маска файлів нечутлива до регістру символів, так що файли з великими і маленькими літерами відрізнятися не будуть

Функція API FindFirstFile має два параметри: файлову маску та адресу структури типу WIN32_FIND_DATA Серед усього іншого, WIN32_FIND_DATA містить імя файлу в елементі структури cFileName У разі вдалого пошуку функція FindFirstFile поверне посилання (handle), яку можна потім використовувати з функцією API FindNextFile

Джерело: Теллес М – Borland C + + Builder Бібліотека програміста – 1998

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*