Міністерство освіти, науки, молоді та спорту України
Національний університет “Львівська політехніка”
Кафедра ЕОМ
/
Курсова робота
з дисципліни
"Системне програмне забезпечення"
«Розробка файлового менеджера»
Завдання
Розробити програму для: роботи з файлами на жорсткому диску, отримання інформації про логічні локальні диски (тип файлової системи, кількість вільних байт, кількість зайнятих байт), отримання інформації про використання ресурсів операційною системою (відсоток завантаженості процесору та пам’яті).
Анотація
Розроблено програму для роботи з файлами та папками, отримання деякої системної інформації (відсоток завантаженості процесору та пам’яті). Цілевою платформою є ОС Windows 7.
Програма виконує: копіювання, переіменування, перенесення, видалення файлів та папок, створення нової папки, отримання системної інформації про логічні диски, процесор та пам’ять. Цей весь функціонал було розміщено у простому, інтуїтивно зрозумілому інтерфейсі.
Зміст
Вступ……………………………………………………………………………….5
1. Теоретична частина.............................................................................................6
1.1. Поняття файлу……………………………………………………………....6
1.2. Поняття каталогу….......................................................................................6
1.3. Файловий менеджер………………………………………………………..7
1.4. Файлова система NTFS…………………………………………………….8
2. Аналіз завдання та способи його вирішення………………………………..10
3. Розробка програми……………………………………………………............11
3.1. Структура програми…………………………………………………….....11
3.2. Інтерфейс програми………………………………………………………..19
4. Тестування та інструкції використання програми………………………….23
4.1. Інструкції використання програми……………………………………….23
4.2. Тестування програми……………………………………………………...25
Висновок…………………………………………………………………………28
Список використаної літератури……………………………………………….39
Додаток А. Лістинг програми…………………………………………………..30
Вступ
Необхідно реалізувати програму для перегляду, копіювання, перенесення, переіменування та видалення файлів\папок. Програма з такими функціями називається «Файловий менеджер».
Файлові менеджери – це програми-оболонки для роботи з операційною системою. За допомогою файлового менеджеру користувачі можуть переглядати, копіювати, видаляти та створювати каталоги та файли, виконувати програми, тощо. Одним з перших файлових менеджерів був Norton Commander для роботи з ОС DOS, який був створений Пітером Нортоном. У ньому екран ділився на дві самостійні області, або панелі, в кожній з яких відображалось вмістиме каталогів та файлів на дисках. Файловий менеджер Norton Commander став основоположником класу програм – класичних файлових менеджерів.
Сьогодні існує безліч різноманітних файлових менеджерів. Найпопулярніші з них – FAR та Total Commander.
Теоретична частина
Поняття файлу
Важливо зазначити, що файлові системи можуть надавати інтерфейс доступу не тільки до диска, але й до інших пристроїв. Є навіть файлові системи, які не зберігають інформацію, а генерують її динамічно за запитом. Втім, для приклад них програм усі такі системи мають однаковий вигляд. До головних задач файлової системи можна віднести: організацію її логічної структури та її відображення на фізичну організацію розміщення даних на диску; підтримку програмного інтерфейсу файлової системи; забезпечення стійкості проти збоїв; забезпечення розподілу файлових ресурсів за умов багатозадачності та захисту даних від несанкціонованого доступу.
У сучасних ОС файли у файловій системі не прийнято зберігати одним невпорядкованим списком (зазначимо, що можливі винятки, наприклад, для вбудованих систем). Десятки гігабайтів даних, що зберігаються зараз на дисках, вимагають упорядкування, файли, в яких перебувають ці дані, мають бути ефективно організовані. Підходи, що були запропоновані для вирішення цього завдання, наведено нижче.
Поняття каталогу
Розділи є основою організації великих обсягів дискового простору для розгортання файлових систем. Для організації файлів у рамках розділу зі встановленою файловою системою було запропоновано поняття файлового каталогу (file directory) або просто каталогу. Каталог — це об'єкт (найчастіше реалізований як спеціальний файл), що містить інформацію про набір файлів. Про такі файли кажуть, що вони містяться в каталозі. Файли заносяться в каталоги користувачами на підставі їхніх власних критеріїв, деякі каталоги можуть містити дані, потрібні операційній системі, або її програмний код.
Каталог можна уявити собі як символьну таблицю, що реалізує відображення імен файлів у елементи каталогу (зазвичай в таких елементах зберігають низькорівневу інформацію про файли).
Файловий менеджер
Файловий менеджер – це програма, яка дозволяє користувачеві керувати файлами та папками на комп’ютері. За допомогою файлового менеджеру можна копіювати, переносити, перейменовувати папки та файли.
Існує два основних типи файлових менеджерів:
навігаційні (просторові) – наприклад Провідник Windows (рис. 1.1):
/
Рис. 1.1 Провідник Windows
двопанельні – наприклад FAR, Total Commander (рис. 1.2):
/
Рис. 1.2 Приклад двопанельного провідника.
Файлові менеджери, в залежності від операційної системи, в якій вони використовуються, діляться на:
менеджери Windows (Провідник, FAR, Total Commander);
менеджери Linux (Gnome Commander, Krusader);
менеджери Mac OS (Finder (вбудований), Disk Order);
кросплатформові (працюючі на декілької операційних системах) – JC, muCommander.
Найбільша перевага двопанельних менеджерів над навігаційними – це, звичайно, зручність та швидкість роботи. Кількість дій при роботі з файлами (копіювання, переміщення) знижується в декілька разів.
Файлова система NTFS
Вона є стандартною файловою системою для сімейства операційних систем Microsoft Windows NT.
NTFS файлову систему FAT, яка використовувалась в MS-DOS та Microsoft Windows. NTFS підтримує систему метаданих і використовує спеціалізовані структури даних для зберігання інформації про файли для покращення продуктивності, надійності та ефективності використання дискового простору. NTFS зберігає інформації про файли в головній файловій таблиці – Master File Table (MFT). Вона має вбудовані можливості розширити доступ до даних для різних користувачів та груп користувачів (списки контролю доступу – Access Control Lists (ACL) а також назначати квоти (обмеження на максимальний об’єм дискового простору для кожного користувача). NTFS також використовує систему жерналювання USN для підвищення надійності файлової системи.
Розроблена на основі файлової системи HPFS (High Performance File System – високопродуктивна файлова система), як була створена компанією Microsoft в співпраці з IBM для операційної системи OS/2.
Специфікації файлової системи є закритими. Це викликає труднощі при реалізації її підтримки в сторонніх продуктах, які не належать Microsoft (розробникам драйверів для «вільних» операційних систем доводиться займатись зворотною розробкою системи).
Аналіз завдання та способи його вирішення
Відповідно до поставленої задачі, програма повинна виконувати наступні функції:
вивід файлів та папок, які знаходяться за адресою, яку, за допомогою інтерфейсу, вказав користувач;
копіювання, перенесення, переіменування та видалення папок;
копіювання, перенесення, переіменування та видалення файлів;
відкриття файлу;
відкриття папки (відображення її вмістимого);
створення нової папки;
відображення об’єму файлів, які виводяться на екран;
можливість оновити список дисків, не закриваючи програму (на випадок підключення зовнішнього носія);
можливість збереження шляхів до певних папок для швидкого переходу по цих шляхах в майбутньому;
вивід відсотку завантаженості процесору та пам’яті;
вивід типу файлової системи та вільного простору на логічних дисках;
вивід кількості файлів та папок у конкретному каталозі\диску.
Так, як WINAPI функції CopyFile та MoveFile не підтримують копіювання\перенесення папок, доведеться розробити алгоритм по файлового копіювання\перенесення, використовуючи ці функції, та функцію CreateDirectory.
Розробка програми
Середовищем програмування було обрано Microsoft Visual Studio 2005, мова програмування С++, для розробки користувацького інтерфейсу був використаний пакет Microsoft Foundation Classes.
Структура програми
Алгоритм програми не є однозначним, тому, що, вона не виконується послідовно, а чекає, поки користувач обере дію, яку буде виконувати програма. А от у цих дій вже є свої алгоритми.
Граф – схема алгоритму роботи програми (рис. 3.1):
Рис. 3.1 Граф-схема алгоритму роботи програми.
Граф – схема алгоритму отримання списку доступних дисків (рис. 3.2):
Рис. 3.2 Схема алгоритму отримання списку доступних дисків.
DWORD WINAPI GetLogicalDriveStrings(
__in DWORD nBufferLength,
__out LPTSTR lpBuffer
);
За допомогою цієї функції я отримую імена всіх доступних логічних дисків та зовнішніх накопичувачів (функція повертає їх у рядок DrivesBuff). Далі оголошується показник *p типу TCHAR для того, щоб з рядку, де лежать всі імена, було зручно вибирати одне. За допомогою функції:
BOOL WINAPI GetDiskFreeSpace(
__in LPCTSTR lpRootPathName,
__out LPDWORD lpSectorsPerCluster,
__out LPDWORD lpBytesPerSector,
__out LPDWORD lpNumberOfFreeClusters,
__out LPDWORD lpTotalNumberOfClusters
);
виконувалась перевірка, чи з диском можна працювати (якщо функція повертала “true” це означало, що диск має ненульовий об’єм пам’яті, тобто, він є і з ним можна працювати). У випадку повернення “true”, програма заносила ім’я цього диску у списки (правий та лівий) та збільшувала значення показника. Якщо новий показник існує, проробляла описані вище кроки вже з новим диском.
Граф – схема алгоритму копіювання\перенесення (рис. 3.3а, 3.3б):
Рис. 3.3а Граф-схема алгоритму копіювання\перенесення.
Рис. 3.3б Граф-схема алгоритму копіювання\перенесення.
Основні функції:
WINAPI FindFirstFile:
HANDLE WINAPI FindFirstFile(
__in LPCTSTR lpFileName,
__out LPWIN32_FIND_DATA lpFindFileData
);
typedef struct _WIN32_FIND_DATA {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
TCHAR cFileName[MAX_PATH];
TCHAR cAlternateFileName[14];
} WIN32_FIND_DATA, *PWIN32_FIND_DATA, *LPWIN32_FIND_DATA;
ФФВЦФ
Функція повертає у структуру WIN32_FIND_DATA інформацію, про перший, знайдений у заданому каталозі, файл.
WINAPI CreateDirectory:
BOOL WINAPI CreateDirectory(
__in LPCTSTR lpPathName,
__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes
);
Створює папку (директорію) за заданою адресою.
WINAPI FindNextFile:
BOOL WINAPI FindNextFile(
__in HANDLE hFindFile,
__out LPWIN32_FIND_DATA lpFindFileData
);
За отриманим після виконання функції №1 дескриптором, шукає наступний файл і також заповнює структуру WIN32_FIND_DATA.
WINAPI FindClose:
BOOL WINAPI FindClose(
__inout HANDLE hFindFile
);
Знищує дескриптор пошуку (припиняє його)
WINAPI CopyFileEx:
BOOL WINAPI CopyFileEx(
__in LPCTSTR lpExistingFileName,
__in LPCTSTR lpNewFileName,
__in_opt LPPROGRESS_ROUTINE lpProgressRoutine,
__in_opt LPVOID lpData,
__in_opt LPBOOL pbCancel,
__in DWORD dwCopyFlags
DWORD CALLBACK CopyProgressRoutine(
__in LARGE_INTEGER TotalFileSize,
__in LARGE_INTEGER TotalBytesTransferred,
__in LARGE_INTEGER StreamSize,
__in LARGE_INTEGER StreamBytesTransferred,
__in DWORD dwStreamNumber,
__in DWORD dwCallbackReason,
__in HANDLE hSourceFile,
__in HANDLE hDestinationFile,
__in_opt LPVOID lpData
);
Копіює файл з можливістю відслідковування прогресу та скасування копіювання.
WINAPI MoveFileWithProgress:
BOOL WINAPI MoveFileWithProgress(
__in LPCTSTR lpExistingFileName,
__in_opt LPCTSTR lpNewFileName,
__in_opt LPPROGRESS_ROUTINE lpProgressRoutine,
__in_opt LPVOID lpData,
__in DWORD dwFlags
);
Аналогічна функція до минулої, тільки для перенесення файлу.
SHFileOperation:
int SHFileOperation(
__inout LPSHFILEOPSTRUCT lpFileOp
);
typedef struct _SHFILEOPSTRUCT {
HWND hwnd;
UINT wFunc;
PCZZTSTR pFrom;
PCZZTSTR pTo;
FILEOP_FLAGS fFlags;
BOOL fAnyOperationsAborted;
LPVOID hNameMappings;
PCTSTR lpszProgressTitle;
} SHFILEOPSTRUCT, *LPSHFILEOPSTRUCT;
Ця функція дозволяє копіювати, переміщувати та видаляти файли, але у моєму випадку вона використовувалась тільки для видалення.
Після отримання адрес джерела та приймача, виконується підготовка до виконання модуля копіювання\переміщення (оголошення, ініціалізація та підготовка змінних). Далі програма перевіряє, чи джерело є папкою. Якщо ні, тобто джерело є файлом, програма копіює\переміщує його згідно з адресою – приймачем. Якщо ж, джерело є папкою, проводиться оголошення додаткових змінних, таких, як індекс у масиві ієрархії (вкладеності), сам масив ієрархії (потрібен для вказання кількості папок\файлів, які вже пройдені на певній сходинці вкладеності, цим самим дозволяє не зберігати адреси минулих сходинок) та показник того, чи зустрічалась на певній сходинці папка. Далі створюється пуста папка за адресою приймача з аналогічною назвою, як у джерела. Після того, як всі операції підготовки закінчились, виконується пошук першого у файлу у папці – джерелі, перевіряється, чи програма вже тут «була» та отримуються атрибути цього файлу. Якщо це папка – «заходимо» у неї, формуємо нові адреси та встановлюємо прапорець bClearFolder у “false”, це значить те, що на своєму шляху ми зустріли папку. Якщо ми зустріли файл, то, згідно операції, яку ми обрали, копіюємо або переносимо його. Якщо виконалась операція перенесення, то видаляємо папку, з якої ми перенесли файл. Далі проводиться пошук нового файлу у адресі – джерелі. (функція FindNextFile()). Якщо ця операція пройшла вдало, то повертаємося на початок та отримуємо атрибути цього файлу. Якщо не вдало – перевіряємо показник bClearFolder та, згідно нього, приймаємо рішення, чи потрібно повертатись назад по рівням вкладеності. Якщо індекс рівня вкладеності досягне 0, то модуль завершить своє виконання.
Також, під цей процес виділено своє вікно та потік.
Процес переіменування:
Він був реалізований однією функцією MoveFileEx:
BOOL WINAPI MoveFileEx(
__in LPCTSTR lpExistingFileName,
__in_opt LPCTSTR lpNewFileName,
__in DWORD dwFlags
);
Функція призначена для переміщення файлів. У моєму випадку, використовується тільки для переіменування.
Процес видалення:
Використана, описана вище, функція SHFileOperation з параметром FO_DELETE.
Процес відображення системної інформації:
Для отримання завантаженості процесора, реалізована функція CPUusage(), яка повертає значення у відсотках. Ця використовує наступні системні виклики:
NtQuerySystemInformation() з параметром SystemProcessorPerformanceInformation,який повертає структуру:
typedef struct
_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
LARGE_INTEGER IdleTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER Reserved1[2];
ULONG Reserved2;
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
Для визначення поточної завантаженості процесора використовується алгоритм:
curInfo – поточний стан;
lastInfo - попередній стан,тобто lastCPUusege = currentCPUusege, так зберігається попередній стан при опитуванні.
Формула розрахунку:
/
IdleTime – інтервал часу простою системи;
KernelTime – інтервал часу, за який система знаходилась у режимі ядра (потоки у всіх процесах,на всіх процесорах);
UserTime - інтервал часу,за який система знаходилась у режимі користувача (потоки у всіх процесах,на всіх процесорах).
Для отримання відсотків задіяної оперативної пам‘яті, реалізована функція PhysicalMemory() у якій задіяний системний виклик GlobalMemoryStatus().Виклик повертає структуру в якій знаходться змінна dwMemoryLoad, в ній зберігається кількість використаної оперативної пам‘яті у відсотках.
Для цієї інформації було виділено окреме вікно, де, за допомогою сторонніх бібліотек виводяться графіки та діаграми.
Інтерфейс програми
Головне вікно (рис. 3.4):
/
Рис. 3.4 Головне вікно програми
Були використані такі інструменти MFC:
Button – кнопка, після натискання якої виконується певна дія:
“<” – Кнопка навігації. Виводить список файлів та папок, каталогом вище (повернення). Для кожного вікна своя;
Open – «Зайти» у папку, яка була вказана мишею. Альтернатива – подвійний клік по бажаній папці (файлу). Для кожного вікна своя клавіша;
Link – Зберегти адресу папки, у якій зараз знаходиться відповідне вікно у списку швидкого доступу. Для кожного вікна своя клавіша;
Rfsh – Оновити список папок\файлів. Для кожного вікна своя клавіша;
Оновити список – Оновити список дисків (на випадок під’єднання зовнішньої пам’яті);
Система – Виводить вікно з системною інформацією.
ListControl – Список з підтримкою іконок, колонок та реакцій на дії користувача:
Лівий – Відображає список файлів та папок, обраних у цьому ж списку, або у ComboBox, що знаходиться у лівій частині діалогу (у випадку переходу між дисками);
Правий – Відображає список файлів та папок, обраних у цьому ж списку, або у ComboBox, що знаходиться у правій частині діалогу (у випадку переходу між дисками).
Static Text – Весь текст діалогу, на який не можна клікнути (Стрічка навігації, кількість папок та файлів, файлова система, допомога по клавішам і т.д.);
ComboBox – меню, що «випадає», при натисканні:
меню дисків (ліве та праве);
меню швидкого доступу (ліве та праве).
Вікно копіювання\перенесення (рис. 3.5):
/
Рис. 3.5 Діалог копіювання\перенесення
Були використані такі інструменти MFC:
ProgressBar – відображення смужки прогресу:
Верхній – відображення прогресу копіювання\перенесення файлу, що копіюється (за умови копіювання папки);
Нижній – відображення загального прогресу копіювання (за умови копіювання папки).
StaticText – Весь текст, який можна побачити на рис. 8.
Вікно переіменування (рис. 3.6):
/
Рис. 3.6 Діалог переіменування
Були використані такі інструменти MFC:
EditControl – поле для вводу даних, а саме – для вводу нової назви папки\файлу;
StaticText – Весь текст, який можна побачити на рис. 9.
Вікно відображення системної інформації (рис. 3.7):
/
Рис. 3.7 Діалог з системною інформацією
Були використані такі інструменти MFC:
Custom Control – дозволяє вивести будь-яку інформацію попіксельно. У моєму випадку їх було використано 3 штуки: 2 – для побудови графіків CPU та RAM (Керуються класом CChartCtrl), інший – для побудови кругової діаграми, на якій зображено кількість вільного місця на обраному диску (Керується класом PIE_CHART_CTRL);
Static Text – Текст, на який не можна натиснути (CPU x%, RAM x%, Файлова Система: хххх, Вільно МВ:, Всього МВ).
Тестування та інструкції використання програми
Інструкції використання програми
Після запуску програми зразу буде відображено файли та папки, що знаходяться на диску С. Щоб перейти у інший диск, потрібно натиснути на меню дисків, та обрати його (рис. 4.1):
/
Рис. 4.1 Меню навігації між дисками.
Щоб відкрити файл або папку, один раз клікаємо мишею на потрібну позицію у списку та натискаємо кнопку “Open” (рис. 4.2):
/
Рис. 4.2 Відкриття папки
Щоб повернутись у минулий каталог, потрібно натиснути клавішу “<”.
Щоб скопіювати або перенести файл\папку, потрібно вже задіяти два вікна виводу файлів. Причому, те вікно, де ви останній раз клікнули, буде джерелом, а інше вікно – приймачем. Безпосередньо, копіювання виконується натисканням клавіші F2 на клавіатурі комп’ютера, переміщення – F3 (рис. 4.3):
/
Рис. 4.3 Підготовка до процесу копіювання.
Натиснувши «Ок» почнеться копіювання\переміщення. Прогрес цього процесу буде видно на екрані (рис. 4.4):
/
Рис. 4.4 Процес копіювання.
Після закінчення цієї процедури, стане доступною кнопка «ОК», за допомогою якої можна буде вийти з цього діалогу.
Дуже подібний до цього, є процес переіменування, видалення та створення.
Щоб отримати системну інформацію, потрібно натиснути клавішу «Система» у головному діалозі. Там, за допомогою списку дисків, можна отримувати інформацію про повний та доступний об’єми пам’яті обраного диску та побачити відсоток завантаженості процесора та пам’яті.
Тестування програми
Послідовність виконання тестування:
Створимо на диску Д папку з назвою Тест;
Переіменуюємо її на Тест2;
Скопіюємо у папку Тест2 файл за адресою: D:\\iso\FileForTest.txt;
Перемістимо папку Тест2 на диск С;
Порівняємо графіки швидкодії диспетчеру задач з графіками, які виведе нам діалог «Система» програми.
Виконання:
Виконано успішно (рис. 4.5):
/
Рис. 4.5 Результат виконання першого пункту.
Виконано успішно (рис. 4.6):
/
Рис. 4.6 Результат виконання другого пункту.
Виконано успішно (рис. 4.7):
/
Рис. 4.7 Результат виконання третього пункту.
Виконано успішно (рис. 4.8):
/
Рис. 4.8 Результат виконання четвертого пункту.
Виконано успішно (рис. 4.9):
/
Рис. 4.9 Результат виконання останнього тесту.
Отже, можна з впевненістю стверджувати, що всі функції працюють коректно, тобто програма написана без помилок.
Висновок
Виконуючи дану роботу, мною детально були опрацьовані та обдумані всі тонкощі роботи з файлами та папками у ОС Windows, вдосконалені знання C++ а саме: робота з текстовими рядками, робота з діалоговими програмами та робота з потоками. Щодо програми, можна з впевненістю сказати, що поставлена задача виконана. Але, нажаль, не ідеально: декілька незначних помилок в програмі все ще лишились, таких як: відображення об’єму недоступного для програми файлу, переміщення пустої папки, вивід загального прогресу при копіюванні\переміщенні папки (непропорційно розмірам). Перевагами можна вважати: програма була націлена на зручну роботу з файлами, вивід системної інформації та підтримка «гарячих» клавіш. Також, було реалізовано алгоритм копіювання\перенесення папок (це було виконано у зв’язку з тим, що функції WINAPI CopyFile та MoveFile не розраховані на роботу з файлами).
Список використаної літератури
A. Шеховцов, Операційні системи – К.: Питер, 2006. – 555с.
Гордеев А. В., Молчанов А. Ю., Системное программное обеспечение. – СПб.: Питер, 2001. – 736с.
Холзнер С. Visual C++6: Учебный курс – СПб: Питер, 2001. – 576 с.
Андрей Александреску,Современное проектирование на С++ - СПб.:Вильямс,2002.- 335с.
Брюс Эккель,Философия С++ - К.: Питер,2004, - 575с.
Бекон Дж., Гарріс Т. Операційні системи. – К.: Видавнича група ВНV, Питер, 2004. – 608с.
Jeffrey Richter, Programming Applications for Microsoft Windows – Microsoft Press, 2004. – 723 c.
Солдатов В. П. Программирование драйверов для Windows. – М.:Бином, 2003. – 432с.
Р.Лафоре, Объектно-ориентированное программирование в С++. К.: Питер,2004, - 920с.
Е.Л.Романов,Практикум по программированию на С++. СПб:БВХ-Петербург, 2004. – 425 с.
Додаток А. Лістинг програми
UsbLabDlg.cpp
// USBLabDlg.cpp : implementation file
//
#include "stdafx.h"
#include "USBLab.h"
#include "USBLabDlg.h"
#include "UseShGetFileInfo.h"
#include "CopyMove.h"
#include "Rename.h"
#include "System.h"
#define HGRADE 128
double dCSize=0;
int nGrade=0,nGradeOne=0,nGradeTwo=0,nFilesCount=0,nFilesProcessed=0,nOperation=0;/*1-copyfile,2-movefile/folder*/
long nFree;
CString csSource1,csDest1,csMSource,csMDest,csSourceC,csDestC;
bool bFolder;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CCopyMove *m_pDlg;
CRename * m_pRename;
CSystem * m_pDlg2;
unsigned int uThread;
HANDLE hThread;
static DWORD CALLBACK ProgressRoutine(LARGE_INTEGER,LARGE_INTEGER,LARGE_INTEGER,LARGE_INTEGER,DWORD,DWORD,HANDLE,HANDLE,LPVOID lpData);
//static DWORD CALLBACK MoveProgressRoutine(LARGE_INTEGER,LARGE_INTEGER,LARGE_INTEGER,LARGE_INTEGER,DWORD,DWORD,HANDLE,HANDLE,LPVOID lpData);
static unsigned _stdcall OperationThread(void*);
static unsigned _stdcall MoveThread(void*);
void FoldersRide(CString Source,CString Dest);
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CUSBLabDlg dialog
CUSBLabDlg::CUSBLabDlg(CWnd* pParent /*=NULL*/)
: CDialog(CUSBLabDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CUSBLabDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST4, m_DriveTwo);
DDX_Control(pDX, IDC_LIST3, m_DriveOne);
DDX_Control(pDX, IDC_BUTTON1, m_Find);
DDX_Control(pDX, IDC_BUTTON3, m_Open);
DDX_Control(pDX, IDC_COMBO2, m_ComboOne);
DDX_Control(pDX, IDC_COMBO1, m_ComboTwo);
DDX_Control(pDX, IDC_Diskinfo, m_Diskinfo);
DDX_Control(pDX, IDC_Diskinfo2, m_Diskinfo2);
DDX_Control(pDX, IDC_Diskinfo3, m_DiskinfA1);
DDX_Control(pDX, IDC_Diskinfo4, m_DiskinfA2);
DDX_Control(pDX, IDC_COMBO3, m_CLinkOne);
DDX_Control(pDX, IDC_COMBO4, m_CLinkTwo);
}
BEGIN_MESSAGE_MAP(CUSBLabDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON1, &CUSBLabDlg::OnClickRefresh)
ON_NOTIFY(NM_CLICK, IDC_LIST4, &CUSBLabDlg::OnNMClickList4)
ON_BN_CLICKED(IDC_BUTTON3, &CUSBLabDlg::OnClickOpenOne)
ON_NOTIFY(NM_DBLCLK, IDC_LIST3, &CUSBLabDlg::OnNMDblclkList3)
ON_BN_CLICKED(IDC_BUTTON4, &CUSBLabDlg::OnClickLink1)
ON_BN_CLICKED(IDC_BUTTON5, &CUSBLabDlg::OnClickRefresh1)
ON_BN_CLICKED(IDC_BUTTON6, &CUSBLabDlg::OnClickRefresh2)
ON_CBN_SELCHANGE(IDC_COMBO10, &CUSBLabDlg::OnCbnSelchangeCombo1)
ON_CBN_SELCHANGE(IDC_COMBO1, &CUSBLabDlg::OnCbnSelchangeCombo2)
ON_BN_CLICKED(IDC_BUTTON8, &CUSBLabDlg::OnClickOpenTwo)
ON_NOTIFY(NM_DBLCLK, IDC_LIST4, &CUSBLabDlg::OnNMDBLClickList4)
ON_BN_CLICKED(IDC_BUTTON2, &CUSBLabDlg::OnClickBack1)
ON_BN_CLICKED(IDC_BUTTON9, &CUSBLabDlg::OnClickBack2)
ON_BN_CLICKED(IDC_BUTTON10, &CUSBLabDlg::OnClickLink2)
ON_CBN_SELCHANGE(IDC_COMBO3, &CUSBLabDlg::OnCbnCLink1)
ON_CBN_SELCHANGE(IDC_COMBO4, &CUSBLabDlg::OnCbnCLink2)
ON_NOTIFY(NM_CLICK, IDC_LIST3, &CUSBLabDlg::OnNMClickList3)
ON_NOTIFY(NM_SETFOCUS, IDC_LIST3, &CUSBLabDlg::OnNMSetfocusList3)
ON_NOTIFY(NM_SETFOCUS, IDC_LIST4, &CUSBLabDlg::OnNMSetfocusList4)
ON_BN_CLICKED(IDC_BUTTON11, &CUSBLabDlg::OnBnClickedButton11)
END_MESSAGE_MAP()
// CUSBLabDlg message handlers
BOOL CUSBLabDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
m_pDlg2= new CSystem(this);
m_pDlg2->Create(IDD_SYSTEM);
m_pDlg2->ShowWindow(SW_HIDE);
m_DriveOne.InsertColumn(0,_T("Назва"), LVCFMT_LEFT,250);
m_DriveOne.InsertColumn(1,_T("Тип"), LVCFMT_LEFT,150);
m_DriveOne.InsertColumn(2,_T("Розмір"), LVCFMT_LEFT,80);
m_DriveTwo.InsertColumn(0,_T("Назва"), LVCFMT_LEFT,250);
m_DriveTwo.InsertColumn(1,_T("Тип"), LVCFMT_LEFT,150);
m_DriveTwo.InsertColumn(2,_T("Розмір"), LVCFMT_LEFT,80);
csPath2="";
csPath1="";
m_DriveTwo.DeleteAllItems();
m_DriveOne.DeleteAllItems();
TCHAR DrivesBuff[100];
GetLogicalDriveStrings(sizeof(DrivesBuff)/sizeof(TCHAR),DrivesBuff);
for (TCHAR *p = DrivesBuff; *p ;p+=_tcslen(p)+1)
{
LPCTSTR sDrivePath = p;
UINT uDriveType = GetDriveType(sDrivePath);
if(GetDiskFreeSpaceEx(p,NULL,NULL,NULL))
{
m_ComboOne.AddString(p);
m_ComboTwo.AddString(p);
}
}
CUseShGetFileInfo FileInfo;
imagelist1.Attach(FileInfo.GetSystemImageListHandle(TRUE));
imagelist2.Attach(FileInfo.GetSystemImageListHandle(TRUE));
m_DriveOne.SetImageList(&imagelist1,LVSIL_SMALL);
m_DriveTwo.SetImageList(&imagelist1,LVSIL_SMALL);
m_Diskinfo.SetWindowText(_T(""));
m_Diskinfo2.SetWindowText(_T(""));
m_DiskinfA1.SetWindowText(_T(""));
m_DiskinfA2.SetWindowText(_T(""));
if(!fIni.Open(_T("Links.ini"),CFile::modeReadWrite))
{
fIni.Open(_T("Links.ini"),CFile::modeCreate|CFile::modeRead|CFile::modeWrite,0,0);
fIni.Write(_T("[LINKS]\r\n"),18);
}
else
{
int i=9;
CString csTemp;
TCHAR chBuf[4096];
CString csRTemp1;
fIni.Read(chBuf,4096);
while(1)
{
while(1)
{
csTemp += chBuf[i];
i++;
if(chBuf[i] == ';')
{
i=i+2;
break;
}
if(chBuf[i] == '\0')
break;
}
csszLinks.Add(csTemp);
csTemp = _T("");
if(chBuf[i] == '\0')
break;
i++;
}
for(i=0;i<csszLinks.GetCount();i++)
{
CString csTmpp = csszLinks.GetAt(i);
if(csTmpp.Find('\\')!=-1)
{
m_CLinkOne.AddString(csTmpp);
m_CLinkTwo.AddString(csTmpp);
}
}
}
bActiveWindow1=false;
bActiveWindow2=false;
m_ComboOne.SetCurSel(0);
m_ComboTwo.SetCurSel(0);
OnCbnSelchangeCombo1();
OnCbnSelchangeCombo2();
return TRUE; // return TRUE unless you set the focus to a control
}
void CUSBLabDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
void CUSBLabDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
HCURSOR CUSBLabDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CUSBLabDlg::OnClickRefresh()
{
m_ComboOne.ResetContent();
m_ComboTwo.ResetContent();
TCHAR DrivesBuff[100];
GetLogicalDriveStrings(sizeof(DrivesBuff)/sizeof(TCHAR),DrivesBuff);
for (TCHAR *p = DrivesBuff; *p ;p+=_tcslen(p)+1)
{
LPCTSTR sDrivePath = p;
UINT uDriveType = GetDriveType(sDrivePath);
m_ComboOne.AddString(p);
m_ComboTwo.AddString(p);
}
}
void CUSBLabDlg::OnNMClickList4(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
bActiveWindow1=false;
bActiveWindow2=true;
*pResult = 0;
}
void CUSBLabDlg::OnClickOpenOne()
{
CString csTmp = _T("");
CString csTmp2 = _T("");
int i=1;
int nSelectedPos = m_DriveOne.GetSelectionMark();
csTmp = csCPath1;
csTmp += m_DriveOne.GetItemText(nSelectedPos,0);
DWORD rc = ::GetFileAttributes(csTmp);
bool isdir = (rc != (DWORD)0xFFFFFFFF && (rc & FILE_ATTRIBUTE_DIRECTORY) != 0);
if(!isdir)
{
ShellExecute(0,0,csTmp,0,NULL,SW_SHOWNORMAL);
}
else
{
csCPath1 += m_DriveOne.GetItemText(nSelectedPos,0);
SetDlgItemText(IDC_EDIT4,csCPath1);
csCPath1 += "\\";
m_DriveOne.DeleteAllItems();
csPath1 = csCPath1;
csPath1 += "\*";
FillList1();
}
}
void CUSBLabDlg::OnNMDblclkList3(NMHDR *pNMHDR, LRESULT *pResult)
{
OnClickOpenOne();
*pResult = 0;
}
void CUSBLabDlg::OnClickLink1()
{
fIni.Write(csCPath1+_T(";\r\n"),(csCPath1.GetLength()*2+6));
m_CLinkOne.AddString(csCPath1);
m_CLinkTwo.AddString(csCPath1);
}
void CUSBLabDlg::FillList1()
{
UCHAR szFileSys[255],szVolNameBuff[255];
DWORD dwSerial,dwMFL,dwSysFlags;
CString Drive=_T("");
int nFiles=0,nFolders=0;
CUseShGetFileInfo FileInfo;
m_DriveOne.DeleteAllItems();
WIN32_FIND_DATA fd;
HANDLE hFind=::FindFirstFile(csPath1, &fd);
CString csSize,csOutput1;;
Drive += csCPath1[0];
Drive += _T(":\\");
GetVolumeInformation(Drive,(LPTSTR)szVolNameBuff,255,&dwSerial, &dwMFL,&dwSysFlags,(LPTSTR)szFileSys,255);
GetDiskFreeSpaceEx(csCPath1,&lpTotal,NULL,NULL);
int nFree = static_cast<int>(lpTotal.QuadPart/1024);
CString Diskname,csOutput;
Diskname += csCPath1[0];
switch(GetBytesGrade(nFree))
{
case 0:
{
csOutput.Format(_T("Диск: %s Файлова система: %s Вільно: %d B"),Diskname,szFileSys,nFree);
break;
}
case 1:
{
csOutput.Format(_T("Диск: %s Файлова система: %s Вільно: %.02Lf KB"),Diskname,szFileSys,dCSize);
break;
}
case 2:
{
csOutput.Format(_T("Диск: %s Файлова система: %s Вільно: %.02Lf MB"),Diskname,szFileSys,dCSize);
break;
}
case 3:
{
csOutput.Format(_T("Диск: %s Файлова система: %s Вільно: %.02Lf GB"),Diskname,szFileSys,dCSize);
break;
}
}
dCSize=0;
m_Diskinfo.SetWindowTextW(csOutput);
DWORD rc;
bool isdir;
if(hFind != INVALID_HANDLE_VALUE)
{
do{
if(fd.cFileName[0] == '\0' || (fd.cFileName[0] == '.' && fd.cFileName[1] == '\0') || (fd.cFileName[0] == '.' && fd.cFileName[1] == '.' && fd.cFileName[2] == '\0'))
{
}
else
{
rc = ::GetFileAttributes(csCPath1+fd.cFileName);
isdir = (rc != (DWORD)0xFFFFFFFF && (rc & FILE_ATTRIBUTE_DIRECTORY) != 0);
if(isdir)
{
nFolders++;
nListIndex = m_DriveOne.InsertItem(0,fd.cFileName,FileInfo.GetDirIconIndex(TRUE));
m_DriveOne.SetItemText(nListIndex , 1 , FileInfo.GetFileType(fd.cFileName));
}
else
{
nGrade=0;
nFiles++;
dCSize = static_cast<int>(fd.nFileSizeLow);
while(dCSize/1024 > 1)
{
dCSize /= 1024;
nGrade++;
}
nListIndex = m_DriveOne.InsertItem(0,fd.cFileName,FileInfo.GetFileIconIndex(fd.cFileName,TRUE));
m_DriveOne.SetItemText(nListIndex , 1 , FileInfo.GetFileType(fd.cFileName));
switch(nGrade)
{
case 0:
{
csSize.Format(_T("%d B"),fd.nFileSizeLow);
m_DriveOne.SetItemText(nListIndex,2,csSize);
break;
}
case 1:
{
csSize.Format(_T("%.02Lf KB"),dCSize);
m_DriveOne.SetItemText(nListIndex,2,csSize);
break;
}
case 2:
{
csSize.Format(_T("%.02Lf MB"),dCSize);
m_DriveOne.SetItemText(nListIndex,2,csSize);
break;
}
case 3:
{
csSize.Format(_T("%.02Lf GB"),dCSize);
m_DriveOne.SetItemText(nListIndex,2,csSize);
break;
}
}
}}
}while(::FindNextFile(hFind, &fd));
csOutput1.Format(_T("Папок: %d Файлів: %d"),nFolders,nFiles);
m_DiskinfA1.SetWindowTextW(csOutput1);
::FindClose(hFind);
}
}
void CUSBLabDlg::OnClickRefresh1()
{
FillList1();
}
void CUSBLabDlg::OnClickRefresh2()
{
FillList2();
}
void CUSBLabDlg::OnCbnSelchangeCombo2()
{
int nSelectedPos = m_ComboTwo.GetCurSel();
m_ComboTwo.GetLBText(nSelectedPos,csCPath2);
csCPath2 += "\\";
SetDlgItemText(IDC_EDIT1,csCPath2);
csPath2 = csCPath2;
csPath2 += "\\*";
FillList2();
}
void CUSBLabDlg::OnCbnSelchangeCombo1()
{
int nSelectedPos = m_ComboOne.GetCurSel();
m_ComboOne.GetLBText(nSelectedPos,csCPath1);
csCPath1 += "\\";
SetDlgItemText(IDC_EDIT4,csCPath1);
csPath1 = csCPath1;
csPath1 += "\\*";
FillList1();
}
void CUSBLabDlg::FillList2()
{
UCHAR szFileSys[255],szVolNameBuff[255];
DWORD dwSerial,dwMFL,dwSysFlags;
CString Drive=_T("");
int nFiles=0,nFolders=0;
CUseShGetFileInfo FileInfo;
m_DriveTwo.DeleteAllItems();
WIN32_FIND_DATA fd;
HANDLE hFind=::FindFirstFile(csPath2, &fd);
CString csSize,csOutput1;
Drive += csCPath2[0];
Drive += _T(":\\");
GetVolumeInformation(Drive,(LPTSTR)szVolNameBuff,255,&dwSerial, &dwMFL,&dwSysFlags,(LPTSTR)szFileSys,255);
GetDiskFreeSpaceEx(csCPath2,&lpTotal,NULL,NULL);
int nFree = static_cast<int>(lpTotal.QuadPart/1024);
CString Diskname,csOutput;
Diskname += csCPath2[0];
switch(GetBytesGrade(nFree))
{
case 0:
{
csOutput.Format(_T("Диск: %s Файлова система: %s Вільно: %d B"),Diskname,szFileSys,nFree);
break;
}
case 1:
{
csOutput.Format(_T("Диск: %s Файлова система: %s Вільно: %.02Lf KB"),Diskname,szFileSys,dCSize);
break;
}
case 2:
{
csOutput.Format(_T("Диск: %s Файлова система: %s Вільно: %.02Lf MB"),Diskname,szFileSys,dCSize);
break;
}
case 3:
{
csOutput.Format(_T("Диск: %s Файлова система: %s Вільно: %.02Lf GB"),Diskname,szFileSys,dCSize);
break;
}
}
dCSize=0;
m_Diskinfo2.SetWindowTextW(csOutput);
DWORD rc;
bool isdir;
if(hFind != INVALID_HANDLE_VALUE)
{
do{
if(fd.cFileName[0] == '\0' || (fd.cFileName[0] == '.' && fd.cFileName[1] == '\0') || (fd.cFileName[0] == '.' && fd.cFileName[1] == '.' && fd.cFileName[2] == '\0'))
{
}
else
{
rc = ::GetFileAttributes(csCPath2+fd.cFileName);
isdir = (rc != (DWORD)0xFFFFFFFF && (rc & FILE_ATTRIBUTE_DIRECTORY) != 0);
if(isdir)
{
nFolders++;
nListIndex = m_DriveTwo.InsertItem(0,fd.cFileName,FileInfo.GetDirIconIndex(TRUE));
m_DriveTwo.SetItemText(nListIndex , 1 , FileInfo.GetFileType(fd.cFileName));
}
else
{
nGrade=0;
nFiles++;
dCSize = static_cast<int>(fd.nFileSizeLow);
while(dCSize/1024 > 1)
{
dCSize /= 1024;
nGrade++;
}
nListIndex = m_DriveTwo.InsertItem(0,fd.cFileName,FileInfo.GetFileIconIndex(fd.cFileName,TRUE));
m_DriveTwo.SetItemText(nListIndex , 1 , FileInfo.GetFileType(fd.cFileName));
switch(nGrade)
{
case 0:
{
csSize.Format(_T("%d B"),fd.nFileSizeLow);
m_DriveTwo.SetItemText(nListIndex,2,csSize);
break;
}
case 1:
{
csSize.Format(_T("%.02Lf KB"),dCSize);
m_DriveTwo.SetItemText(nListIndex,2,csSize);
break;
}
case 2:
{
csSize.Format(_T("%.02Lf MB"),dCSize);
m_DriveTwo.SetItemText(nListIndex,2,csSize);
break;
}
case 3:
{
csSize.Format(_T("%.02Lf GB"),dCSize);
m_DriveTwo.SetItemText(nListIndex,2,csSize);
break;
}
}
}
}
}while(::FindNextFile(hFind, &fd));
csOutput1.Format(_T("Папок: %d Файлів: %d"),nFolders,nFiles);
m_DiskinfA2.SetWindowTextW(csOutput1);
::FindClose(hFind);
}
}
void CUSBLabDlg::OnClickOpenTwo()
{
CString csTmp = _T("");
CString csTmp2 = _T("");
int nSelectedPos = m_DriveTwo.GetSelectionMark();
csTmp = csCPath2;
csTmp += m_DriveTwo.GetItemText(nSelectedPos,0);
DWORD rc = ::GetFileAttributes(csTmp);
bool isdir = (rc != (DWORD)0xFFFFFFFF && (rc & FILE_ATTRIBUTE_DIRECTORY) != 0);
if(!isdir)
{
ShellExecute(0,0,csTmp,0,NULL,SW_SHOWNORMAL);
}
else
{
csCPath2 += m_DriveTwo.GetItemText(nSelectedPos,0);
SetDlgItemText(IDC_EDIT1,csCPath2);
csCPath2 += "\\";
m_DriveTwo.DeleteAllItems();
csPath2 = csCPath2;
csPath2 += "\*";
FillList2();
}
}
void CUSBLabDlg::OnNMDBLClickList4(NMHDR *pNMHDR, LRESULT *pResult)
{
OnClickOpenTwo();
*pResult = 0;
}
void CUSBLabDlg::OnClickBack1()
{
int i=2,k=0;
CString csTmp = csPath1;
csTmp.MakeReverse();
csPath1=_T("");
while(csTmp[i]!='\\')
i++;
while(csTmp[i]!=NULL)
{
csPath1 += csTmp[i];
i++;
k++;
}
csPath1.MakeReverse();
SetDlgItemText(IDC_EDIT4,csPath1);
csCPath1 = csPath1;
csPath1 += "\*";
FillList1();
}
void CUSBLabDlg::OnClickBack2()
{
int i=2,k=0;
CString csTmp = csPath2;
csTmp.MakeReverse();
csPath2=_T("");
while(csTmp[i]!='\\')
i++;
while(csTmp[i]!=NULL)
{
csPath2 += csTmp[i];
i++;
k++;
}
csPath2.MakeReverse();
SetDlgItemText(IDC_EDIT1,csPath2);
csCPath2 = csPath2;
csPath2 += "\*";
FillList2();
}
int CUSBLabDlg::GetBytesGrade(int nFreee)
{
dCSize = 0;
dCSize = static_cast<double>(nFreee);
nGrade=1;
while(dCSize/1024 > 1)
{
dCSize /= 1024;
nGrade++;
}
return nGrade;
}
BOOL CUSBLabDlg::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message==WM_KEYDOWN)
{
if(pMsg->wParam==VK_BACK)
{
if(bActiveWindow1==true && bActiveWindow2==false)
OnClickBack1();
if(bActiveWindow1==false && bActiveWindow2==true)
OnClickBack2();
}
if(pMsg->wParam==VK_RETURN)
{
if(bActiveWindow1==true &&...