- •Содержание
- •Часть 1. Общие сведения о технологии программирования 5
- •Часть 2. Windows программирование 24
- •Введение
- •Часть 1. Общие сведения о технологии программирования
- •1. Задачи технологии программирования
- •1.1. Базовые определения
- •1.2. Невозможность доказательства отсутствия программных ошибок
- •1.3. Надежность программного средства
- •1.4. Технология программирования как способ создания надежных программных средств
- •1.5. Этапы развития технологии программирования
- •1.6. Технология программирования и информатизация общества
- •2. Общие принципы разработки программных средств
- •2.1. Специфика разработки программных средств
- •2.2. Основные подходы при создании пс
- •2.3. Жизненный цикл программного средства
- •2.4. Понятие качества программного средства
- •2.5. Обеспечение надежности – основной критерий разработки программных средств
- •2.5.1. Методы борьбы со сложностью
- •2.5.2. Обеспечение точности перевода
- •2.5.3. Преодоление барьера между пользователем и разработчиком
- •2.5.4. Контроль принимаемых решений
- •3. Архитектура программного средства
- •3.1. Понятие архитектуры программного средства
- •3.2. Основные классы архитектур программных средств
- •3.3. Архитектурные функции
- •4. Тестирование и отладка программного средства
- •4.1. Основные понятия
- •4.2. Принципы и виды отладки программного средства
- •4.3. Заповеди отладки программного средства
- •4.4. Автономная отладка программного средства
- •4.5. Комплексная отладка программного средства.
- •Часть 2. Windows программирование
- •5. Основные характеристики Windows платформ
- •5.1. Краткая история Windows
- •5.2. Отличия и общие свойства Windows платформ
- •5.2.1. Общие свойства Windows платформ
- •5.2.2. Отличия Win32 платформ
- •5.2.3. Окна и сообщения
- •5.2.4. Приложения, потоки и окна
- •5.2.5. Классы окон
- •5.2.6. Венгерская нотация
- •5.2.7. Типы сообщений
- •5.2.8. Сообщения и многозадачность
- •5.2.9. Очереди сообщений
- •5.2.10. Процессы и потоки
- •5.2.11. Потоки и сообщения
- •5.2.12. Оконная функция – функция обратного вызова
- •5.2.13. Синхронные и асинхронные сообщения
- •5.2.14. Функции Windows
- •5.2.15. Другие api
- •6. Структура Windows приложений
- •6.1. Файлы заголовков
- •6.2. Глабальные переменные
- •6.3. Точка входа в приложение
- •6.4. Необходимые переменные
- •6.5. Регистрация класса окна
- •6.6. Создание главного окна
- •6.7. Отображение главного окна
- •6.8. Цикл обработки сообщений
- •6.9. Функция окна
- •7. Обработка сообщений в оконной функции
- •7.1. Создание окна wm_create
- •7.2. Определение размера окна wm_size
- •7.3. Отображение содержимого окна wm_paint
- •7.3.1. Случаи генерации сообщения wm_paint
- •7.3.2. Особенность сообщения wm_paint
- •7.3.3. Правила обработки wm_paint
- •7.3.4. Отрисовка вне wm_paint
- •7.3.5. Определение возможностей контекста устройства
- •7.3.6. Системные метрики
- •7.4. Определение расположения окна wm_move
- •7.5. Использование оконных полос прокрутки
- •7.5.1. Диапазон и положение полос прокрутки
- •7.5.2. Сообщения полос прокрутки
- •7.6. Клавиатурный ввод
- •7.6.1. Фокус ввода и активное окно
- •7.6.2. Генерация клавиатурных сообщений
- •7.6.3. Аппаратные сообщения
- •7.6.3.1. Системные аппаратные сообщения
- •7.6.3.2. Несистемные аппаратные сообщения
- •7.6.3.3. Битовые поля параметра lParam
- •7.6.3.4. Виртуальные коды клавиш
- •7.6.4. Символьные сообщения
- •7.6.5. Обработка сообщения wm_char
- •7.6.6. Определение состояния управляющих клавиш
- •7.6.7. Наборы символов
- •7.7. Системный таймер
- •7.7.1. Использование таймера. Первый способ
- •7.7.2. Использование таймера. Второй способ
- •7.8. Удаление окна, сообщение wm_destroy
- •8. Ресурсы приложения и их использование
- •8.1. Меню приложения
- •8.1.1. Виды меню
- •8.1.2. Возможные состояния пунктов меню
- •8.1.3. Сообщения от пунктов меню
- •8.1.4. Создание главного меню приложения
- •8.1.5. Функции для работы с меню
- •8.2. Стандартные элементы управления
- •8.2.1. Создание стандартных элементов управления
- •8.2.2. Разрушение элементов управления
- •8.2.3. Функции для работы с элементами управления
- •8.2.4. Сообщения дочерних окон
- •8.2.5. Сообщения родительского окна дочерним окнам
- •8.2.6. Расширенное управление дочерними окнами
- •8.2.7. Оконные процедуры элементов управления
- •8.2.8. Элемент управления кнопка
- •8.2.8.1. Стили кнопок
- •8.2.8.2. Сообщения от кнопок, получаемые родительским окном
- •8.2.8.3. Сообщения от родительского окна к кнопке
- •8.2.8.4. Кнопки-переключатели
- •8.2.8.5. Сообщение от переключателей
- •8.2.8.6. Сообщение от родительского окна к переключателям
- •8.2.9. Структура drawitemstruct
- •8.2.10. Стандартный элемент управления окно ввода
- •8.2.10.1. Стили окна редактирования
- •8.2.10.2. Сообщения от редактора к родительскому окну
- •8.2.10.3. Сообщения от родительского окна к редактору
- •8.2.11. Стандартный элемент управления статический текст
- •8.2.11.1. Стили элемент управления static
- •8.2.11.2. Сообщения от статического элемента управления
- •8.2.11.3. Сообщения от родительского окна к static
- •8.2.12. Стандартный элемент управления список
- •8.2.12.1. Стили элемента управления список
- •8.2.12.2. Сообщения от списка к родительскому окну
- •8.2.12.3. Сообщения от родительского окна к списку
- •8.2.13. Стандартный элемент управления список с вводом
- •8.2.13.1. Стили элемента управления combobox
- •8.2.13.2. Сообщения от combobox к родительскому окну
- •8.2.13.3. Сообщения от родительского окна к combobox
- •9. Создание и использование диалоговых окон
- •9.1. Этапы создания диалога
- •9.1.1. Создание шаблона диалога
- •9.1.2. Функция диалога
- •9.1.2.1. Сходства между диалоговой функцией и оконной процедурой
- •9.1.2.2. Различия между диалоговой функцией и оконной процедурой
- •9.2. Типы диалоговых панелей
- •9.3. Создание модального диалога
- •9.4. Закрытие модального диалога
- •9.5. Окна сообщений.
- •9.6. Немодальные диалоги
- •9.7. Диалоговые окна общего пользования
- •10. Управление файлами
- •10.1. Доступ к файловой системе
- •10.2. Потоковый ввод/вывод
- •10.3. Функции ядра Windows для работы с файлами
- •10.4. Специализированные функции для работы с файлами
- •11. Печать документов
- •11.1. Последовательность печати документа
- •11.2. Контекст устройства принтера
- •11.3. Диалог отмены печати
- •11.4. Запуск процесса печати
- •11.5. Печать страницы документа
- •11.6. Завершение печати документа
- •12. Процессы и потоки
- •12.1. Диспетчеризация потоков
- •12.2. Проблемы многопоточной технологии
- •12.3. Создание рабочего потока
- •12.4. Организация взаимодействия потоков
- •12.4.1. Рабочий поток – процесс
- •12.4.2. Процесс – рабочий поток
- •12.5. Общая схема взаимодействия потоков
- •13. Приложение "Тестер файлов"
- •13.1. Функция WinMain()
- •13.2. Функция главного окна
- •13.3. Вспомогательные функции
- •13.4. Функция рабочего потока
- •Литература к первой части
- •Литература ко второй части
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; }