Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции-ТРПС.doc
Скачиваний:
13
Добавлен:
15.11.2018
Размер:
810.5 Кб
Скачать

13. Приложение "Тестер файлов"

В заключение рассмотрим исходный текст приложения, предназначенного для проверки целостности файлов на магнитном носителе, например, на дискете. Конечно, операционная система включает в свой состав служебную программу проверки диска. Однако она выполняет проверку для всей поверхности, что порой требует достаточно много времени. Данная утилита проверяет – путем чтения – только дисковые файлы, значит, в некоторых случаях, может быть более эффективной по затратам компьютерных ресурсов. С другой стороны, автор создавал данное приложение с учебными целями и не претендует, чтобы утилита считалась полностью системной.

Перечислим основные идеи и особенности приложения:

1. Для задания имени драйвера, на котором проводится тестирование файлов, используется командная строка приложения. Так как информация из командной строки потребуется в функции окна, определен указатель, объявленный как глобальная переменная.

2. Функция WinMain() обычна. Цикл обработки сообщений тоже не содержит каких-либо особенностей.

3. В обработчике WM_CREATE функции главного окна создается Win32 элемент управления ListView, который позволяет отображать различную информацию в колонках каждой строки. Приложение использует четыре колонки: имя файла, статус проверки, длина файла и время его создания. Здесь же создаются две кнопки для запуска процесса проверки и его остановки.

4. При нажатии кнопки начала проверки или нажатии клавиши "Enter", главный процесс запускает рабочий поток, который выбирает все файлы на указанном разделе и выполняет их проверку обычным чтением. Если встречается директория, то выполняется рекурсивный вызов функции проверки для этой директории. Результаты проверки отображаются в виде новой строки элемента ListView.

5. При нажатии кнопки останова, процесс сбрасывает дескриптор окна в нулевое значение, что является сигналом для рабочего потока, к прекращению своей работы. Одновременно в главном потоке запускается таймер, при обработке которого приложение проверяет, не закончился ли рабочий поток. Аналогичная проверка с использованием таймера выполняется при закрытии приложения.

Проект включает три файла:

TestDisk.cpp

исходный код приложения;

Resource.h

файл идентификаторов;

TestDisk.rc

файл ресурсов приложения.

Создайте файл Resource.h и определите в нем следующие идентификаторы (числовые значения могут быть иными):

IDS_ERROR 1 IDS_APP_NAME 2 ID_BUTT_BEG 101 ID_BUTT_END 102 ID_LISTVIEW 103

Файл TestDisk.rc для этого проекта содержит только один ресурс – строковый:

STRINGTABLE DISCARDABLE BEGIN IDS_ERROR "Ошибка" IDS_APP_NAME "Тестер файлов на диске " ID_BUTT_BEG "Проверить" ID_BUTT_END "Прервать" END

Далее приводится полный текст файла TestDisk.cpp.

13.1. Функция WinMain()

#define STRICT #define WIN32_LEAN_AND_MEAN #include <Windows.h> // Заголовочный файл для Win32 элементов управления #include <CommCtrl.h>

#include "Resource.h"

// Используем два таймера #define TIMER_CLOSE 4444 #define TIMER_WAIT 4445

// Структура для отображения информации // о тестируемом файле в ListView struct NEW_FILE_DATA { TCHAR szName [MAX_PATH]; TCHAR szLen [16]; TCHAR szDate [32]; TCHAR szCheck[16]; };

// Структура для параметров // функции рабочего потока struct THREADPARAM { HWND hWnd; HWND hwndList; DWORD idThread; TCHAR szRoot[MAX_PATH]; };

//////////////////////////////////////////////////////// // Глабальные переменные HINSTANCE g_hInst; LPCSTR g_szCmd;

//////////////////////////////////////////////////////// // Прототипы функций int InitApplication (LPCTSTR szClass); void ViewError (HWND hWnd); LPTSTR StrFromRC (int IDstr);

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // Приложение использует командную строку, // через которую можно задать диск для проверки. // Например, "TestDisk.exe D:\" // В этом случае тестируются файлы на диске D: // Если параметр не задан, используется A:\

// Сохраняем глобальные переменные g_hInst = hInstance; g_szCmd = lpCmdLine; if (!*g_szCmd) g_szCmd = TEXT("a:\\");

// Подключаем библиотеку Win32 стандартных элементов, // но испотльзовать будем только ListView

INITCOMMONCONTROLSEX commItems; commItems.dwSize = sizeof(commItems); commItems.dwICC = ICC_LISTVIEW_CLASSES; InitCommonControlsEx(&commItems);

// Регистрируем класса главного окна LPCTSTR szClass = TEXT("FileTester32"); if ( !InitApplication(szClass) ) { // Возникла ошибка ViewError(NULL); return -1; }

// Создание главного окна int proc = 20;//% int xW = ::GetSystemMetrics(SM_CXSCREEN); int yW = ::GetSystemMetrics(SM_CYSCREEN); int x = (proc*xW)/100; int y = (proc*yW)/100;

// Шаблон имени окна хранится в ресурсах. // Добавляем имя тестируемого диска. TCHAR szTitle[128]; lstrcpy(szTitle, StrFromRC(IDS_APP_NAME)); lstrcat(szTitle, g_szCmd); HWND hWnd = ::CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, szClass, szTitle, WS_OVERLAPPEDWINDOW, x, y, ((100-2*proc)*xW)/100, ((100-2*proc)*yW)/100, NULL, NULL, g_hInst, NULL); if (!hWnd) { // Возникла ошибка ViewError(NULL); return -1; }

::ShowWindow(hWnd, nCmdShow); ::UpdateWindow(hWnd);

// Цикл обработки сообщений MSG msg; while (::GetMessage(&msg, NULL, 0, 0)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); }

return 0; }