Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

1233

.pdf
Скачиваний:
0
Добавлен:
15.11.2022
Размер:
625.43 Кб
Скачать

¦таблица)

¦

¦

 

 

 

¦

¦

¦

¦

 

 

 

¦

¦Master File Таblе2

¦$MftMirr

¦Зеркальное отображение наибо-¦

¦(копия главной файловой¦

¦лее важных

частей

MFT;

ис-¦

¦таблицы)

¦

¦пользуется для гарантирования¦

¦

¦

¦доступа к MFT в

случае

сбоя¦

¦

¦

¦одиночного сектора.

 

¦

¦

¦

¦

 

 

 

¦

¦Log File

¦$LogFile

¦Список шагов транзакции,

ис-¦

¦(регистрационный файл) ¦

¦пользуемых

Log

File System¦

¦

¦

¦для восстановления состояния¦

¦

¦

¦(recoverability).

 

 

¦

¦

¦

¦

 

 

 

¦

¦Volume (том)

¦$Volume

¦Имя, версия и другая информа-¦

¦

¦

¦ция относительно тома.

¦

¦

¦

¦

 

 

 

¦

¦Attribute Definition

¦$AttrDef

¦Таблица имен атрибутов, номе-¦

¦(определение атрибутов)¦

¦ров и дескрипторов.

 

¦

¦

¦

¦

 

 

 

¦

¦Root Filename Index

¦$.

¦Корневой каталог.

 

 

¦

¦(индекс корня файловых

¦

¦

 

 

 

¦

¦имен)

¦

¦

 

 

 

¦

¦

¦

¦

 

 

 

¦

¦Claster Bitmap

¦$Bitmap

¦Описание содержимого

 

тома,¦

¦(битовый массив

¦

¦показывающее, какие размещае-¦

¦кластеров)

¦

¦мые модули использованы.

¦

¦

¦

¦

 

 

 

¦

¦Boot File

¦$Boot

¦Содержит информацию начальной¦

¦(загрузочный файл)

¦

¦загрузки для тома,

если

том¦

¦

¦

¦является загрузочным

 

¦

¦

¦

¦

 

 

 

¦

¦Bad Cluster File

¦$BadClus

¦Содержит указание

 

положения¦

¦(файл плохих кластеров)¦

¦плохих кластеров тома.

¦

+---------------------------------------------------------------

 

 

 

 

 

+

Сравнение NTFS с HPFS и FAT

NTFS заимствовала лучшие свойства FAT и HPFS. От FAT система NTFS заимствовала философию "простота рождает эффективность". Эффективность увеличивается, когда число дисковых передач минимизировано для общих операций. От HPFS система NTFS унаследовала методы для повышения быстродействия и гибкости. Например, NTFS использует B-tree, подобные применяемым в HPFS дня максимизации эффективности.

NTFS поддерживает и длинные и короткие имена файлов для совместимости с MS DOS, HPFS и другими сетевыми клиентами, включая OS/2, UNIX, АрpleShare и NFS. NTFS также обеспечивает многочисленные расширенные (extended) атрибуты и позволяет будущим приложениям определить другие расширенные атрибуты.

NTFS обеспечивает безопасность данных на фиксированных и сменных жестких дисках, что особенно важно для корпоративных пользователей. Например, предположим, что пользователь Alexander имеет сменный жесткий диск на компьютере. Этот жесткий диск форматируется как том NTFS и имеет разрешения защиты, которые разрешают доступ только Alexander и другому пользователю в этом же домене, Ann. Ann работает в филиале компании. Alexander извлека-

ет диск из компьютера и посылает его Ann, которая устанавливает диск в свой компьютер. При обращении к файлам на диске благодаря тому, что Ann находится в том же самом домене, что и Alexander, она видит, что механизмы защиты внутри области для тома NTFS является неповрежденными.

Кроме этого, NTFS обеспечивает систему восстановления, которая является более надежной, чем у FAT или HPFS; NTFS также отвечает требованиям POSIX.

Втабл. представлены сравнительные характеристики FAT, HPFS

иNTFS применительно к Windows NT:

 

 

Таблица

Сравнение характеристик FAT, HPFS и NTFS

 

+------------------------------------------------------------------

 

 

 

 

 

 

 

 

+

¦Харак-

¦

 

 

¦

 

 

¦

 

¦

¦теристика

¦

FAT

 

¦

HPFS

¦

NTFS

¦

+------------

+

---------------------

 

+--------------

 

 

+----------------

 

¦

¦Filename

¦"Восемь плюс три"

¦254 байта

¦255 символов

¦

¦(имя файла)

¦символа ASCII

¦двухбайтных

¦Unicode (допус- ¦

¦

¦(допускается один

¦символов

 

¦кается несколько¦

¦

¦разделитель - точка);¦(допускается

¦разделителей)

¦

¦

¦в Windows NT 255

¦несколько

¦

 

¦

¦

¦символов Unicode

¦разделителей)

¦

 

¦

¦

¦(допускается несколь-¦

 

 

¦

 

¦

¦

¦ко разделителей)

¦

 

 

¦

 

¦

¦

¦

 

 

¦

 

 

¦

 

¦

¦File size

¦

2^32

байта

¦

2^32

байта

¦ 2^64

байта

¦

¦(размер фай-¦

(4 Гбайта)

¦

(4 Гбайта)

¦(17179869184 Гб)¦

¦ла)

¦

 

 

¦

 

 

¦

 

¦

¦

¦

 

 

¦

 

 

¦

 

¦

¦Partition

¦

2^32

байта

¦

2^32

байта

¦ 2^64

байта

¦

¦(раздел)

¦

(4 Гбайта)

¦

(4 Гбайта)

¦(17179869184 Гб)¦

¦

¦

 

 

¦

 

 

¦

 

¦

¦Maximum path¦64: в Windows NT не

¦He ограничена

¦He ограничена

¦

¦length

¦ограничена

 

¦

 

 

¦

 

¦

¦(максималь- ¦

 

 

¦

 

 

¦

 

¦

¦ная длина

¦

 

 

¦

 

 

¦

 

¦

¦пути)

¦

 

 

¦

 

 

¦

 

¦

¦

¦

 

 

¦

 

 

¦

 

¦

¦Attributes

¦Только несколько

¦Однобитовые

¦Вся информация, ¦

¦(атрибуты)

¦однобитовых флажков

¦флажки плюс

¦включая данные, ¦

¦¦плюс несколько байтов¦64 Кб информа-¦обрабатывается ¦

¦

¦информации

¦ции расширен- ¦как атрибуты

¦

¦

¦расширенных атрибутов¦ных атрибутов ¦файла

¦

¦

¦в Windows NT 3.5

¦

¦

¦

¦

¦

¦

¦

¦

¦Directories

¦He сортируются

¦B-tree

¦B-tree

¦

¦(каталоги)

¦

¦

¦

¦

¦

¦

¦

¦

¦

¦Philosophy

¦Простота

¦Эффективность

¦Быстрота,

¦

¦(философия)

¦

¦на больших

¦восстанав-

¦

¦

¦

¦дисках

¦ливаемость

¦

¦

¦

¦

¦и безопасность

¦

¦

¦

¦

¦

¦

¦Built-in

¦

¦

¦

¦

¦security

¦Нет

¦Нет

¦Есть

¦

¦features

¦

¦

¦

¦

51

¦(встроенные ¦

¦

¦

¦

¦средства

¦

¦

¦

¦

¦безопас-

¦

¦

¦

¦

¦ности)

¦

¦

¦

¦

+------------------------------------------------------------------

 

 

 

+

Следующий раздел описывает еще одно важное различие между файловыми системами FAT, HPFS и NTFS - способ, которым каждая из них гарантирует целостность данных на диске.

Целостность и восстановимость данных в файловых системах

До настоящего момента существовали два типа файловых систем - файловые системы с точной записью (careful-write) и файловые системы с ленивой записью (lazy-write). NTFS является третьим типом - восстанавливаемой файловой системой.

Файловый системы с точной записью

Файловые системы с точной записью основываются на идее важности сохранения согласованной структуры тома. Примером файловой системы с точной записью является FAT в MS DOS.

Файловая система с точной записью работает следующим образом. Когда она осуществляет изменение структуры тома, то дается команда для записи на диск. Большинство модификаций тома производятся за один раз. Записи на диск для каждой модификации производятся таким образом, что сбой системы между двумя операциями дисковой записи оставляет том в распознаваемом состоянии с возможностью "ожидаемой" несогласованности. Диск остается пригодным для использования. Выполнение утилит типа chkdsk редко требуется для файловой системы с точной записью (в FAT, например, chkdsk необходима только для исправления последствий сбоя системы и обеспечивает быстрый способ восстановления согласованности файловой системы).

Недостатком фазовых систем с точной записью является медленное выполнение преобразованных в последовательность операций записи. Это происходит вследствие того, что первая запись на диск должна быть произведена и завершена прежде, чем сможет начаться вторая запись и т. д. Для мощных компьютеров подобный подход дает далеко не самое эффективное использование его возможностей.

Файловые системы с ленивой записью

Второй вид файловой системы, типа FAT в Windows NT и большинства файловых систем UNIX, называются системой с ленивой записью. Этот тип был разработан для ускорения дискового доступа. Т. к. вероятность возникновения дисковых сбоев достаточно низкая, файловая система с ленивой записью разрабатывалась с учетом использования интеллектуальной стратегии управления кэшем и обеспечения способа восстановления данных (типа утилиты chkdsk) в случае сбоя диска.

Работа с данными производится через буфер системы ввода-вы- вода. В то время как пользователь просматривает каталоги или чи-

тает файлы, необходимые для записи на диск данные накапливаются

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

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

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

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

Восстанавливаемые файловые системы

NTFS является восстанавливаемой (recoverable) файловой системой. Она сочетает быстродействие файловой системы с ленивой записью и практически мгновенное восстановление.

NTFS гарантирует согласованность данных тома, используя стандартную регистрацию транзакций и методы восстановления. Она включает метод ленивой записи и систему восстановления тома, которая обычно занимает одну или две секунды после перезагрузки компьютера. Регистрация транзакции, позволяющая NTFS производить быстрое восстановление, требует значительно меньших затрат по сравнению с файловыми системами точной записи.

При использовании раздела на одиночном устройстве, NTFS позволяет производить восстановление системы после сбоя, однако в результате ошибки ввода-вывода часть данных может быть потеряна. В сочетании с поддержкой зеркального отражения (mirroring) или контролем четности с чередованием (parity stripping), что выполняется отказоустойчивым драйвером (описывается в ниже), NTFS может выдержать любой одиночный сбой.

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

NTFS также поддерживает горячее фиксирование (hot-fixing), которое позволяет файловой системе при возникновении ошибки из-за плохого сектора переместить информацию в другой сектор и отметить первоначальный в качестве плохого. Этот подход прозрачен для любых приложений, выполняющих дисковые операции вво- да-вывода. Горячее фиксирование позволяет устранить сообщения об ошибках типа "Abort, Retry, or Fail ?", которые происходят, когда файловая система типа FAT сталкивается с плохим сектором.

При использовании NTFS на отказоустойчивом устройстве и обнаружении ошибки в одной копии кластера данные могут быть восс-

52

тановлены. Плохой кластер отмечается в файле плохих кластеров (Bad Cluster File) и заменяется другим кластером. Далее копия первоначальных данных записывается в новый кластер.

NTFS поддерживает размеры кластера 512, 1024, 2048 и 4096 байт. Хотя команда format автоматически выбирает соответствующий диску размер кластера, можно использовать параметр /а для явного назначения размера кластера. Более подробную информацию можно получить при помощи команды format /?.

Целостность данных и восстановление в NTFS

Каждая операция ввода-вывода, которая изменяет файл на томе NTFS, рассматривается файловой системой как транзакция и может выполняться как неделимый блок.

При модификации файла пользователем сервис файла регистрации (Log File Service) фиксирует всю информацию по повторению (redo) или откату (undo) транзакции. Применительно к восстановлению, redo - информация, которая сообщает NTFS о путях повторения транзакции, undo - об отмене транзакции, которая не была завершена или имела ошибку.

+------------------------------

 

+

¦

NTFS

<-+

+---------------------------

 

/|\+ ¦

+-+--------------------------

 

+-+ ¦

¦ ¦ Сервис файла регистрации

¦ ¦ ¦

+-+--------------------------

 

+-+ ¦

+-+--------------------------

 

+-+ ¦

¦ ¦

Диспетчер кэша

¦ ¦ ¦

+-+--------------------------

 

+-+ ¦

+-+--------------------------

 

+-+ ¦

¦ ¦

Управление памятью

¦ <-+

+-+--------------------------

 

+-+

+--------------------------

 

+

Взаимодействие между NTFS и другими компонентами Windows NT

Если транзакции завершена успешно, производится модификация файла. Если транзакция не завершена, NTFS заканчивает или производит откат транзакции, следуя инструкциям в информации отмены. Если NTFS обнаруживает ошибку в транзакции, транзакция также прокручивается обратно.

Восстановление файловой системы осуществляется NTFS очень просто. При сбое системы NTFS выполняет три прохода: проход анализа (analysis pass), повторный проход (redo pass) и проход отмены (undo pass). В течение прохода анализа, на основании информации файла регистрации, NTFS оценивает повреждение и точно определяет, какие кластеры должны быть модифицированы. Во время повторного прохода выполняются все этапы транзакции от последней контрольной точки (checkpoint). Проход отмены осуществляет возрат любых незавершенных транзакций.

Ленивая передача

Ленивая передача (lazy commit) - важная особенность NTFS. Она позволяет NTFS минимизировать затраты регистрации для под-

держания высокой эффективности.

Ленивая передача подобна ленивой записи. Вместо использования ресурсов для немедленной отметки транзакции как успешно завершившейся, эта информация заносится в кэш и записывется в файл регистрации как фоновый процесс. Если происходит сбой до того, как информация о транзакции была зарегистрирована, NTFS произведет повторную проверку транзакции для определения ее успешности. Если NTFS не может гарантировать, что транзакция была завершена успешно, производится откат транзакции. Никакие незавершенные модификации тома не позволяются.

Периодические контрольные точки файла регистрации

Каждые несколько секунд, NTFS проверяет кэш, чтобы определить состояние ленивой записи, и отмечает это состояние в качестве контрольной точки в файле регистрации (checkpoint). Если вслед за определением контрольной точки последует сбой, система имеет возможность приведения своего состояния к состоянию, зафиксированному контрольной точкой. Этот метод использует наиболее оптимальное время восстановления, сохраняя очередь событий, которая может потребоваться в процессе восстановления.

АСИНХРОННЫЕ ОПЕРАЦИИ С ФАЙЛАМИ

Все ранее рассмотренные файловые функции Windows API обеспечивали синхронные операции над данными. Это означает, что приложение приостанавливает свою работу до завершения операции обмена с внешним устройством. Приложение, запущенное в среде Microsoft Windows NT, может совместить операции ввода-вывода с выполнением другой работы.

Когда функции ReadFile и WriteFile вызываются в асинхронном режиме, они только инициируют процесс чтения или записи, сразу же возвращая управление. Для выполнения операции операционной системой неявно создается отдельная задача. Ее синхронизация с вызвавшей задачей осуществляется с помощью объекта-события.

Открывая или создавая файл функцией CreateFile, следует ука-

зать флаг FILE_FLAG_OVERLAPPED. Перед вызовом функций ReadFile

или WriteFile надо подготовить структуру типа OVERLAPPED и передать ее адрес этим функциям через параметр lpOverlapped. Структура OVERLAPPED определена следующим образом:

typedef struct _OVERLAPPED

{

DWORD

Internal;

// Зарезервировано

DWORD

InternalHigh;

// Зарезервировано

DWORD

Offset;

// Младшее слово позиции в файле

DWORD

OffsetHigh;

// Старшее слово позиции в файле

HANDLE

hEvent;

// Идентификатор события, который

 

 

// будет отмечен после завершения

 

 

// операции

} OVERLAPPED;

Объект-событие создается предварительно и его идентификатор передается функциям обмена для синхронизации. Если в качестве hEvent передать NULL, то будет использоваться идентификатор файла. Например, для ожидания завершения обмена можно использовать функ-

цию WaitForSingleObject(hFile, INFINITE) с идентификатором файла hFile в качестве первого параметра.

Кроме того, имеется специальная функция

53

BOOL GetOverlappedResult(

 

HANDLE

hFile,

// Идентификатор файла

LPOVERLAPPED lpOverlapped,

// Адрес структуры OVERLAPPED

LPDWORD lpNumberOfBytesTransferred, // Адрес счетчика байтов

BOOL

bWait);

// Флаг ожидания

По адресу счетчика байтов записывается действительное количество прочитанных или записанных байт. Если задать bWait значение TRUE, то функция будет дожидаться завершения выполнения операции и вернет результат TRUE. При использовании значения FALSE функция проверяет завершенность операции и возвращает TRUE в случае успеха и FALSE, если операция еще не завершена.

Две дополнительные функции Windows API специально предназначены для выполнения асинхронных файловых операций:

BOOL ReadFileEx(

 

 

HANDLE

hFile,

// Идентификатор файла

LPVOID

lpBuffer,

// Адрес буфера

LPDWORD lpNumberOfBytesToRead, // Количество байт для чтения

LPOVERLAPPED lpOverlapped,

// Адрес структуры OVERLAPPED

LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);

// адрес функции, вызываемой

после завершения операции

BOOL WriteFileEx(

 

 

 

HANDLE

hFile,

 

 

LPVOID

lpBuffer,

 

 

LPDWORD lpNumberOfBytesToWrite,

 

 

LPOVERLAPPED lpOverlapped,

 

 

LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);

Через параметр lpCompletionRoutine передается адрес функции

с прототипом

 

 

 

VOID WINAPI CompletionRoutine(

 

 

DWORD dwErrorCode,

 

// Код завершения

DWORD dwNumberOfBytesTransferred, // Число переданных байтов

LPOVERLAPPED lpOverlapped);

// Адрес структуры OVERLAPPED

ФАЙЛЫ, ОТОБРАЖАЕМЫЕ НА ПАМЯТЬ

Файлы, отображаемые на память - это средство для интерпретации данных на внешних устройствах как полей в основной памяти. Например, можно открыть файл базы данных с использованием отображения на память и адресоваться к записям как к элементам массива, расположенного в основной памяти. При этом операционная система при необходимости будет самостоятельно выполнять чтение данных из файла и запись данных в файл.

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

Для манипулирования отображенной информацией из файлов применяется виртуальная память процесса.

Создание отображения файла

Прежде всего приложение должно открыть файл функцией CreateFile. Если в файле предполагаются изменения, необходимо установить флаги GENERIC_READ и GENERIC_WRITE. При совместном использовании файла несколькими процессами устанавливают флаги FILE_SHA-

RE_READ и FILE_SHARE_WRITE.

Затем вызывается функция

HANDLE CreateFileMapping(

 

 

HANDLE hFile,

// Идентификатор отображаемого файла

LPSECURITY_ATTRIBUTES lpFileMappingAttributes, // Дескриптор

 

//

защиты

DWORD flProtect,

// Флаги защиты

DWORD dwMaximumSizeHigh,

// Старшее слово размера файла

DWORD dwMaximumSizeLow,

// Младшее слово размера файла

LPCTSTR lpName);

// Имя отображения

В качестве первого параметра передается идентификатор, полученный от функции CreateFile или значение 0xFFFFFFFF. Второй случай применяют при передаче данных между приложениями. Дескриптор защиты обычно передают как NULL. Флаги защиты представляют собой

логическую комбинацию

значений

PAGE_READONLY

-

доступ только для чтения

PAGE_READWRITE -

доступ для чтения и записи

PAGE_WRITECOPY -

доступ для копирования при записи

SEC_COMMIT

-

выделение физических страниц

SEC_IMAGE

-

отображение файла с исполняемым кодом

SEC_NOCACHE

-

отмена кэширования

SEC_RESERVE

-

резервирование страниц виртуальной памяти

Размер файла указывается двумя параметрами. Если файл имеет длину менее 4 Гб, то нужно указывать нулевое значение dwMaximumSizeHigh. Указание нулевых значений для обоих параметров длины, означает, что размер файла изменяться не будет. Имя отображения будет доступно всем приложениям и должно представлять собой уникальную текстовую строку. Если совместное использование отображения не предполагается, достаточно задания значения NULL.

Выполнение отображения на память

Получив от функции CreateFileMapping идентификатор отображе-

ния, мы должны выполнить само отображение, вызвав функцию

 

LPVOID MapViewOfFile(

 

 

 

HANDLE hFileMappingObject,

 

// Идентификатор отображения

DWORD dwDesiredAccess,

 

// Режим доступа

DWORD dwFileOffsetHigh,

// Старшее слово смещения в

файле

DWORD dwFileOffsetLow,

// Младшее слово смещения в

файле

DWORD dwNumberOfBytesToMap);

// Число отображаемых байтов

или

 

 

 

LPVOID MapViewOfFileEx(

 

 

 

HANDLE hFileMappingObject,

 

// Идентификатор отображения

DWORD dwDesiredAccess,

 

// Режим доступа

DWORD dwFileOffsetHigh,

// Старшее слово смещения в

файле

DWORD dwFileOffsetLow,

// Младшее слово смещения в

файле

DWORD dwNumberOfBytesToMap, // Число отображаемых байтов

LPVOID lpBaseAddress); // Предполагаемый адрес для отображе-

 

// ния файла

Режимы доступа:

 

FILE_MAP_WRITE

- доступ на запись и чтение

FILE_MAP_READ

- доступ только на чтение

FILE_MAP_ALL_ACCESS

- аналогично FILE_MAP_WRITE

FILE_MAP_COPY

- доступ для копирования при записи

Функция MapViewOfFileEx позволяет задать предполагаемый адрес общей доступной нескольким процессам памяти. Обе функции

54

возвращают адрес отображенной области памяти.

Если несколько процессов используют совместно одно и то же отображение, первый процесс создает это отображение, а остальные открывают его функцией

HANDLE OpenFileMapping(

 

DWORD dwDesiredAccess,

// Режим доступа

BOOL bInheritHandle,

// Флаг наследования

LPCTSTR lpName);

// Имя отображения

передавая через параметр lpName имя отображения. Флаг наследования разрешает или запрещает наследование идентификатора отображения.

Отмена отображения выполняется с помощью функции

BOOL UnmapViewOfFile(LPVOID lpBaseAddress)

с передачей ей адреса отображенной области памяти. Если приложение создало несколько отображений для файла, перед завершением работы все они должны быть отменены. Далее следует закрыть идентификаторы отображения с помощью CloseHandle. После отмены отображений все измененные страницы памяти записываются в отображаемый файл. Принудительная запись измененных страниц возможна через

BOOL FlushViewOfFile(

LPCVOID lpBaseAddress,// Начальный адрес сохраняемой области

DWORD dwNumberOfBytesToFlush); // Размер области СРЕДСТВА ВВОДА ИНФОРМАЦИИ С КЛАВИАТУРЫ

Ввод информации в программу может быть выполнен на трех уров-

нях:

обращением к функциям операционной системы; обращением к функциям BIOS;

физическим доступом к аппаратным средствам.

Ввод на уровне ОС позволяет пропустить сигналы от клавиатуры через инсталируемые драйверы, обеспечивает отслеживание нажатия Ctrl+C (Ctrl+Break), стандартную обработку ошибок. На этом уровне работают функции ввода из стандартного файла stdin, функции кон-

сольного ввода getch(), getche().

Доступ к клавиатуре на уровне BIOS позволяет отслеживать нажатие всех клавиш, выполнять управление аппаратурой клавиатуры. Интерфейс с BIOS реализует функция Borland C bioskey(), которая выполняет функции 00..02h прерывания 16h.

Непосредственный доступ к буферу клавиатуры резко повышает производительность программы. С другой стороны, непосредственный доступ может быть использован для имитации нажатия на клавиши в демонстрационных версиях программных средств или при реализации экранных органов управления пользовательского интерфейса - радиокнопок, контактных кнопок и т.п.

Аппаратные и программные средства ввода информации с клавиатуры

Клавиатура содержит специализированный микропроцессор, кото-

рый при каждом нажатии и отпускании

клавиши определяет ее порядко-

вый номер и помещает его в порт 64h

(или 60h)

программируемого пе-

риферийного интерфейса Intel 8042.

Младшие 7

бит содержат номер

клавиши, а старший бит устанавливается в нуль при нажатии (прямой скэн-код) и единицу при отпускании (обратный скэн-код) клавиши. Когда скэн-код записан в порт 64h программируемого периферийного интерфейса, выдается сигнал подтверждения и генерируется прерыва-

ние 09h для вызова стандартного обработчика прерываний от клавиатуры. BIOS анализирует скэн-код и преобразует его.

Если клавиша нажата дольше времени задержки (delay value), микропроцессор клавиатуры генерирует с заданной частотой (typematic rate) прямой скэн-код клавиши.

Контроллер клавиатуры генерирует прерывание по линии 1 (IRQ1) на каждое нажатие и отпускание клавиши. IRQ1 распределена за обработчиком прерывания 09h и обслуживается BIOS.

Порт 60h является только записываемым и поддерживается для совместимости с ранними моделями персональных компьютеров.

Порт 64h служит для записи команд и данных, а также для чтения статуса клавиатуры. Перед посылкой команды клавиатуре BIOS тестирует ее состояние командой

in AL,64h

для предотвращения ситуаций переполнения буфера или нажатия на клавишу.

Чтобы избежать критических ситуаций, например, при установке частоты генерации кода, следует установить небольшую задержку между двумя операциями записи в порт:

mov al,cmd_code out 64h,al

mov cx,2000h ;приблизительное значение delay: loop delay

mov al,data_value out 64h,al

Для управления клавиатурой применяются команды:

0FFh - восстановление клавиатуры и запуск диагностики; 0FEh - повторная передача последнего сообщения; 0FDh..0F7h - зарезервировано;

0F6h - установить состояние клавиатуры по умолчанию и продолжить ввод;

0F5h - установить состояние клавиатуры по умолчанию и отменить ввод;

0F4h - клавиатура доступна. Выполняется посылка 'ACK', очищается буфер и запускается ввод;

0F3h - установить частоту генерации и время задержки. Сначала посылается команда 0F3h, а затем байт данных:

+7-6-5-4-3-2-1-0+

¦0¦dly¦ reptRate¦

+---------------+

¦+-+ +--------- биты 0..4 устанавливают частоту генерации

¦+------------ биты 5..6 устанавливают задержку перед ге-

¦

нерацией: 00=250 мс; 01

= 500мс;

¦

10 = 750мс; 11 = 1000мс

 

+---------------

бит 7 всегда 0

 

 

Частота генерации

устанавливается в соответствии с табл. 1

Недостающие значения определяются интерполяцией.

 

 

 

 

Таблица 1

+---------------------------------------------

 

 

 

+

¦ Биты 0..4 ¦ Частота генерации, символов/с

¦

+-----------

 

+---------------------------------

 

¦

¦

0

¦

30.0

¦

¦

1

¦

26.7

¦

¦

2

¦

24.0

¦

55

¦

4

¦

20.0

¦

¦

8

¦

15.0

¦

¦

0aH

¦

10.0

¦

¦

0dH

¦

9.2

¦

¦

10H

¦

7.5

¦

¦

14H

¦

5.0

¦

¦

1fH

¦

2.0

¦

+---------------------------------------------+

Первоначально для клавиатуры устанавливается время задержки 0.5 с и частота повторений 10 символов/с.

Задержка и частота повторения могут устанавливаться через функцию AH = 03h прерывания 16h BIOS.

0F2h..0EFH - зарезервировано;

0EEh - эхо. Просто посылает значение 0EEh;

0EDh - управление триггерными клавишами и индикаторами. Посылается 0EDh, а затем байт, в котором используются только биты 0..2

+7-6-5-4-3-2-1-0+

¦

¦c¦n¦s¦

+---------------+

¦ ¦ +- ScrollLock

01H

= включен

¦ +--- NumLock

02H

= включен

+----- CapsLock

04H

= включен

Анализ и преобразование скэн-кода

Клавиши в зависимости от алгоритма обработки скэн-кода делят-

ся на

шифт-клавиши Shift, Alt, Ctrl - правые (right) и левые

(left);

 

 

 

 

 

 

 

 

 

триггерные клавиши

 

NumLock,

ScrollLock,

CapsLock,

Insert

(Ins), Pause;

 

 

 

 

 

 

 

 

 

клавиши c буферизацией расширенного кода;

 

 

 

 

специальные клавиши

PrintScrn,

Ctrl+Alt+Del,

 

Ctrl+C,

Ctrl+Break.

 

 

 

 

 

 

 

 

 

Состояние шифт- и

 

триггерных

клавиш отражается

в

слове

40:17h (табл. 2).

 

 

 

 

 

 

 

 

 

Текущее состояние

 

шифт- и триггерных клавиш используется BI-

OS-обработчиком прерываний

от клавиатуры

при

преобразовании

скэн-кода от других

клавиш. При нажатии клавиши c буферизацией

расширенного кода в буфер клавиатуры помещается

двухбайтовый код

(BIOS-код клавиши): младший

байт

содержит

ASCII-код или нуль;

старший байт содержит скэн-код или расширенный скэн-код.

 

Комбинация ASCII-код/скэн-код генерируется,

во-первых, если

нажата ASCII-клавиша,

с учетом Shift и CapsLock,

во-вторых, при

одновременном нажатии

Ctrl

и ASCII-клавиши,

а также для клавиш

BackSpace, Enter, Tab, Esc. Младший байт имеет код 0..31.

 

Комбинация 0/расширенный

скэн-код

генерируется

для

клавиш

F1..F12, Insert (Ins), Delete (Del), Down, Up, Left, Right, Home,

End, PgUp, PgDn и их сочетаний с Alt, Shift, Ctrl, а также Аlt+AS- CII-символ. Значение расширенного скэн-кода определяется технической документацией BIOS. Расширенный скэн-код и скэн-код не совпадают.

Таблица 2

+-----------------------------------------------------------+

¦ Бит ¦ Состояние ¦

+-----------------------------------------------------------

 

 

 

¦

¦

 

 

40:17h

¦

+-----------------------------------------------------------

 

 

 

¦

¦

0

¦ Нажата Right Shift

 

¦

¦

1

¦ Нажата Left Shift

 

¦

¦

2

¦ Нажата Right Ctrl

 

¦

¦

3

¦ Нажата Right Alt

 

¦

¦4 ¦ Зафиксирован скроллинг экрана (ScrollLock - включен)¦

¦

5

¦ Включена цифровая клавиатура

(NumLock

- включен)¦

¦

6

¦ Зафиксирован верхний регистр

(CapsLock

- включен)¦

¦

7

¦ Включен режим вставки

(Ins

- включен)¦

+-----------------------------------------------------------

 

 

 

¦

¦

 

40:18h

 

¦

+-----------------------------------------------------------

 

 

 

¦

¦

0

¦ Нажата Left Ctrl

 

¦

¦

1

¦ Нажата Left Alt

 

¦

¦

2

¦ Нажата System

 

¦

¦

3

¦ Включен режим Pause (Ctrl+NumLock)

¦

¦

4

¦ Нажата ScrollLock

 

¦

¦

5

¦ Нажата NumLock

 

¦

¦

6

¦ Нажата CapsLock

 

¦

¦

7

¦ Нажата Ins

 

¦

+-----------------------------------------------------------

 

 

 

+

Нажатие на специальную клавишу PrintScrn приводит к прерыванию 5h, которое стандартно закреплено за функцией печати текстового экрана. Одновременное нажатие Ctrl+Alt+Del запускает программу начальной загрузки операционной системы без тестирования аппаратуры (мягкая перезагрузка). Использование комбинации клавиш Ctrl+C (Ctrl+Break) позволяет по адресу 0047h записать 80h (флаг сигнализации о желании приостановить выполнение текущей программы). Этот флаг проверяется функциями, которые способны генерировать прерыва-

ние 23h.

Буфер клавиатуры

Буфер клавиатуры занимает 32 байта (40:1Eh..40:3Eh). Запись выполняет обработчик прерывания 09h, чтение - обработчик прерывания 16h. Буфер рассчитан на 15 двухбайтовых кодов вводимой строки и один двухбайтовый код для клавиши Enter, нажатие на которую служит признаком завершения ввода для интерпретатора команд ОС.

Буфер организован как кольцевая очередь, доступ к которой осуществляется через два указателя, расположенных по адресам

0040:001Ah - указатель "головы" (Head Pointer), 0040:001Ch - указатель "хвоста" (Tail Pointer).

Значения в указателях равны смещению от сегмента 0040h. Tail Pointer показывает на первое свободное слово буфера, Head Pointer показывает на начало очереди.

Схема работы буфера

При нажатии на клавишу код записывается в буфер и указатель "хвоста" увеличивается на два. Если значение указателя "хвоста" больше 003Eh, то буфер считается переполненным, новые коды не принимаются и из динамика компьютера звучит предупреждающий сигнал.

Обработчик прерывания 16h использует указатели "головы" и "хвоста" для ввода с клавиатуры. Функция АН = 0 (чтение буфера с

56

разрушением информации) позволяет прочитать из буфера два байта и увеличивает значение указатель "головы" на два. Если значения указателей равны, это говорит о том, что буфер пуст. Обработчик прерывания выполняет бесконечный цикл ожидания до неравенства значений указателей.

Функция АН = 1 (чтение без разрушения) служит для передачи слова в программу. Значение указателя "головы" не меняется. Если значения указателей совпадают, то выставляется флаг CF = 1 и обработчик прерывания 16h аварийно завершается.

Буфер клавиатуры - это классический пример использования кольцевой очереди для организации асинхронного взаимодействия двух программ по схеме "производитель-потребитель" (обработчик прерывания 09h производит данные, а 16h - потребляет).

ВВОД ИНФОРМАЦИИ С КЛАВИАТУРЫ В ПРИЛОЖЕНИЯХ WINDOWS

Достатый в пень, готов я жать на стоп...

Шекспир, сонет 66 в пер. В. Шаповала

Все приложения, написанные для Microsoft Windows, способны осуществлять ввод данных с клавиатуры. В основу работы приложения

склавиатурой положена следующая модель.

+----------+

¦Клавиатура¦

+----------+

¦ скэн-код

 

 

 

 

 

 

¦

 

 

 

 

 

 

 

+----------

+

+---------

+

+---------

+

+---------

+

¦Драйвер

¦сообщение¦Очередь

¦

¦Задача

¦

¦Цикл

¦

¦клавиатуры+---------

¦системных+--

¦обработки+--

¦обработки¦

+----------

+

¦сообщений¦

¦сообщений¦

¦сообщений¦

 

 

+---------

+

+---------

+

+---------

+

 

 

 

 

 

+

----------

+

¦Приложение¦

¦Windows

¦

+----------

+

Windows обеспечивает независимую от устройств поддержку клавиатурного ввода с помощью установки драйвера клавиатуры. Также поддерживается языковая независимость входного потока. Драйвер клавиатуры получает скэн-коды, которые перетранслируются в виртуальные коды клавиш (virtual-key code) и формируют сообщения, пересылаемые в очередь системных сообщений. Специализированная задача обработки сообщений выбирает их из очереди и рассылает ок- нам-абонентам приложений. Выбор окна-абонента осуществляется в соответствии с временным свойством окна, называемым фокусом, поскольку общий клавиатурный поток должен быть разделен между всеми окнами. Задача может вызвать функцию GetFocus, чтобы определить, какое окно имеет в настоящий момент фокус ввода. Передача фокуса

выполняется функцией SetFocus. При передаче фокуса от одного окна другому система посылает сообщение WM_KILLFOCUS тому окну, которое теряет фокус, и WM_SETFOCUS окну, получающему фокус.

Нажатие на клавишу приводит к помещению в очередь сообщений WM_KEYDOWN или WM_SYSKEYDOWN, которые передаются окну, имеющему фокус ввода. Сообщения о нажатиях и отжатиях клавиш передаются в общем случае парами, однако, если пользователь держит клавишу надатой в течении продолжительного времени так, что включается функция автоповтора, система генерирует множество сообщений

WM_KEYDOWN или WM_SYSKEYDOWN и одно WM_KEYUP или WM_SYSKEYUP.

Сообщения о нажатиях на клавиши предоставляют разнообразную информацию, но не включают символьный код клавиши. Чтобы получить символьный код, приложение должно вызывать функцию TranslateMessage в цикле обработки сообщений. При этом проверяется виртуальный код и, если он соответствует символу, возвращается кодовый эквивалент с учетом состояния SHIFT и CAPS LOCK клавиш. Генерируется символьное сообщение, которое помещается в вершину очереди сообщений. Следующая итерация цикла обработки сообщений забирает его и передает ожидающему ввода окну.

ПОДДЕРЖКА ГОРЯЧИХ КЛАВИШ (Hot-Key)

Windows включает ряд функций, которые приложение может использовать, чтобы определить горячие клавиши. Горячая клавиша представляет собой кодовую комбинацию, возвращающую сообщение WM_HOTKEY. Приложение использует горячие клавиши для создания высокоприоритетного клавиатурного ввода. Например, определяя горячую клавишу из комбинации CTRL+C key, приложение может обеспечить аварийное завершение некоторой операции.

Чтобы определить горячую клавишу, выполняется вызов функции RegisterHotKey с указанием комбинации клавиш, идентификатора ок- на-получателя сообщения и идентификатора горячей клавиши. Перед тем как завершить приложение необходимо вызвать UnregisterHotKey чтобы разрушить описание горячей клавиши.

ЯЗЫКИ И ЛОКАЛИЗАЦИЯ

На уровне Windows API поддерживается работа с национальными языками и диалектами. Приложения обычно используют локализацию (т.е. установку национального языка) для ввода и отображения информации).

Каждая кодовая таблица оснащается идентификатором, который определяет язык.

Обычно приложение само не манипулирует языками. Напротив, поьзователь может устанавливать языковую кодовую таблицу или переключаться между ними. Функция ActivateKeyboardLayout устанавливает входной язык для текущей задачи. Идентификаторы кодовых страниц могут быть получены от функций LoadKeyboardLayout или

GetKeyboardLayoutList.

УПРАВЛЕНИЕ МАНИПУЛЯТОРОМ "МЫШЬ"

АППАРАТНЫЕ СРЕДСТВА МАНИПУЛЯТОРА

"Мышь" - один из самых распространенных пультов управления компьютером. Профессиональные приложения не имеют шансов на коммерческий успех при отсутствии поддержки ввода с "мыши".

57

Мышь представляет собой устройство, подключаемое к одному из адаптеров последовательной связи ПК (иногда и к параллельным портам). Формат информации, передаваемой в адаптере, зависит от режима работы "мыши":

mouse mode - 3 управляющие кнопки; microsoft mode - 2 управляющие кнопки.

Большинство конструкций "мыши" позволяют переключаться из режима в режим либо аппаратно (например, Genius Mouse), либо программно, т.е. с помощью драйвера "мышь". Если при загрузке драйвера нажата левая кнопка, то выбирается второй режим, иначе первый.

В состав "мыши" входят:

-датчики перемещения в горизонтальном и вертикальном направлениях,

-пульт и блок связи с интерфейсом RS-232.

 

 

 

 

Пульт

 

Блок

связи

+---

+

 

 

+-----------

+

передает в адап-

¦

¦

 

 

+-----------

¦

тер байты данных

¦ X

+<¦

 

 

+-----------

¦

при любом

нажа-

¦

¦

 

 

+-----------

+

тии кнопок и пе-

+---

+

---

 

¦

 

ремещения "мыши"

¦

+----------

 

+

+---------------

+

на величину боль-

¦

¦

Y

+---

+--

шую "микки"(mic-

¦

+----------

 

+

¦ Блок связи с

¦

key)=1/200 дюйма

+------------------

 

 

 

>¦ интерфейсом

+<--

иногда 1/320,

Датчики перемещения

¦

¦

1/400).

 

 

 

 

 

+---------------

+

 

 

ПРОГРАММНАЯ ПОДДЕРЖКА "МЫШИ" (на примере MS DOS)

Использование "мыши" требует загрузки драйвера, который поставляется вместе с манипулятором в одной одной из двух форм: как инсталляционный драйвер (.sys) или .exe(.com) файл. Основными частями драйвера являются:

1.Секция инсталляции -- проверяет, подключена ли "мышь" нужного типа и не был ли драйвер установлен ранее. Инсталлятор подменяет вектор прерывания 0Ch (com1 для AT) или 0Bh (com2) точкой входа в собственный обработчик. Многие драйверы позволяют указать порт. Инсталлятор настраивает аппаратуру адаптера на генерацию запросов прерываний, деблокирует в контроллере прерываний биты, соответствующие IRQ4, устанавливает нужный формат слова и частоту передачи. Кроме того подменяется вектор прерывания 10h (старый вектор включается каскадно). В таблицу векторов помещается адрес обработчика 33h. Ряд внутренних переменных устанавливается по умолчанию.

2.Обработчик прерываний от адаптера последовательной связи

-принимает данные от "мыши" и изменяет внутренние переменные: текущие координаты, состояние кнопок, характер нажатия (одиночный/двойной) и т.д. Выполняется перемещение курсора по экрану.

3.Обработчик прерывания 33h -- коллекция функций, образующих интерфейс программы. Номер функции задается в АХ.

4.Обработчик прерывания 10h -- поддерживает форму курсора, отслеживает переключение режимов видеоадаптера.

ОСНОВНЫЕ ФУНКЦИИ ИНТЕРФЕЙСА ПРОГРАММЫ

С МАНИПУЛЯТОРОМ "МЫШЬ" (int 33h)

Функция инициализации и определения текущего состояния драйвера - AX = 0h. Возвращает:

AX = 0h - драйвер отсутствует (или нет аппаратуры); AX = FFFFh - "мышь" готова к работе;

BX = 0000h - неизвестное число кнопок;

BX = 0002h - 2 кнопки; BX = 0003h - 3 кнопки.

Устанавливаются следующие параметры драйвера:

-курсор в центре и выключен;

-чувствительность по вертикали 2 микки/пиксел, по горизонтали 1 микки/пиксел;

-порог удвоенной скорости = 64 микки/сек.;

-форма курсора по умолчанию;

-координаты верхнего левого угла = (0,0), правый нижний = (максимальные координаты - 1).

Успешное завершение инициализации позволяет продолжить работу по подготовке к использованию "мыши". Следующая операция связана с определением типа и формы курсора. В текстовом режиме драйвер поддерживает 2 типа курсора:

-"жесткий", совпадающий с обычным курсором текстового ре-

жима;

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

Функция AX = 0Ah задает BX = 00h - программируемый курсор;

01h - жесткий курсор;

CX - AND-маска экрана для программируемого курсора или номер верхней линии для жесткого курсора;

DX - XOR-маска экрана для программируемого курсора или номер нижней линии для жесткого курсора.

При формировании программируемого курсора модифицируется слово видеобуфера, соответствующего знакоместу :

screen_word = screen_word & AND_mask ^ XOR_mask.

При перемещении курсора прежнее содержимое видеобуфера восстанавливается. Распространенным является программированный

курсор с AND_mask = FFFFh и

XOR_mask = 7700h. В этом случае ин-

вертируется как цвет фона,

 

так и цвет символа,

что гарантирует

видимость курсора.

 

 

 

 

 

 

В графическом

режиме

 

может быть описана любая собственная

форма курсора в пределах

прямоугольника 16х16.

Функция

AX

=

0009h.

BX,

CX - номера столбца и строки "горячего пятна". ES:DX

- указатель

на 32 символа масок (AND и XOR - маски по 16

слов).

Соотношение битов масок дает желаемый эффект :

 

 

 

+---------------------------------------------------------

 

 

 

 

 

 

 

+

¦Бит AND маски¦Бит XOR

маски¦ Цвет панели на экране

 

¦

+-------------

 

 

+-------------

 

+-----------------------------

 

 

¦

¦

 

0

¦

0

¦ Цвет фона

 

 

¦

¦

 

0

¦

1

¦ Белый цвет

 

 

¦

¦

 

1

¦

0

¦ Текущий цвет пиксела (ТЦП)

¦

¦

 

1

¦

1

¦ Побитовая инверсия ТЦП

 

¦

+---------------------------------------------------------

 

 

 

 

 

 

 

+

В режиме 13h (а также 4h и 5h) используются только четные столбцы в битовых масках (иначе курсор был бы очень большим).

58

Функция 9h ничего не возвращает.

Курсор, видимый на любом фоне, образуется AND-маской = FFFFh и XOR-маской в форме курсора (единицами).

Для ограничения области перемещения "мыши" используют функ-

ции :

AX = 0007h - установка вертикальных границ; AX = 0008h - установка горизонтальных границ; CX, DX - min и max границы. Возврата нет.

В графическом режиме границы задаются в пикселах, для текстового режима в "виртуальных" пикселах из расчета размера знакоместа 8х8. Если минимальная граница больше максимальной, то функции меняют содержимое CX и DX. Если курсор находится вне диапазона, он отображается на границе. Для установки чувствительности драйвера используют AX = 000Fh :

CX - по горизонтали(максимально микки/8 пикселов);

DX - по вертикали(максимально микки/8 пикселов), возврата нет, а минимальные значения СХ и DX равны по 1.

При движении "мыши" с высокой скоростью, превышающей порог удвоенной скорости, драйвер удваивает каждый сигнал о перемещении. Для далекого перемещения курсора нужно сделать "мышью" по столу резкое движение в нужном направлении, а затем медленно подвести курсор в точку. Установку порога удвоенной скорости выполняет AX = 0013h со значением порога в DX. Функция AX = 001Bh позволяет прочитать установку чувствительности (BX, CX) и порога

(DX).

Включение курсора осуществляется AX = 0001h, выключение AX

= 0002h.

Внутренняя переменная драйвера, отвечающая за видимость курсора, имеет значение 0-курсор видим или 1-курсор невидим. Функция 0001h увеличивает переменную до 0-ля, 0002h - уменьшает на 1. Поэтому на каждое выключение курсора должно приходится включение.

Изменение информации на экране следует выполнять с выключением курсора, т.к. изменения под курсором не будут известны драйверу и он восстанавливает прежнее значение пикселов при перемещении курсора.

ЧТЕНИЕ ПОЗИЦИИ КУРСОРА И СОСТОЯНИЯ КНОПОК "МЫШИ"

AX = 0003h - определение координат курсора и состояния кнопок. Возвращает в BL :

Бит, установленный в единицу 0 - нажата левая кнопка; 1 - нажата правая кнопка; 2 - нажата средняя кнопка.

СХ - горизонтальная координата, DX - вертикальная координата. АХ = 0005h - определение количества нажатий кнопок.

0006h - определение количества отпусканий.

BX = 0 - запрос о левой кнопке, 1 и 2 соответственно о правой и средней. Возвращает в BX число нажатий/отпусканий с момента последнего обращения к функции; СХ - горизонтальная координата в момент нажатия; DX - вертикальная координата в момент нажатия.

АХ = 000Bh - определение значения счетчика сигналов микки. Возвращает: CX - перемещение по горизонтали в микки с момента последнего вызова функции; DX - по вертикали.

Значения имеют тип int. Отрицательные соответствуют движе-

нию влево или вниз, положительные - вправо или вверх.

AX = 0004h: позиционирование курсора из программы. CX - горизонтальная координата; DX - вертикальная координата.

УПРАВЛЕНИЕ МЫШЬЮ В ПРИЛОЖЕНИЯХ WINDOWS

Несмотря на то, что мышь является важным устройством для приложений Wundows, ее наличие не является обязательным. Приложение может определить, входит ли мышь в состав аппаратных средств компьютера с помощью функции GetSystemMetrics, передавая ей зна-

чение SM_MOUSEPRESENT.

Приложения Windows получают входной поток от мыши в форме сообщений, которые посланы или переданы их окнам. Окно, имеющее фокус ввода, получает сообщение и от мыши. В этом окне в общем случае должна находиться горячая точка мыши, хотя возможно получение сообщений от мыши даже если ее курсор находится вне окна.

В системе хранится переменная, которая управляет скоростью перемещения мыши. Используя функцию SystemParametersInfo с флагами SPI_GETMOUSE или SPI_SETMOUSE, можно получить (или установить) скорость.

Windows поддерживает мышь с тремя кнопками. В сообщениях и именованных константах используются буквы L, M и R, чтобы идентифицировать соответственно левую (главную), среднюю и правую кнопки. Приложение может определить число кнопок мыши, передавая зна-

чение SM_CMOUSEBUTTONS функции GetSystemMetrics. Чтобы сконфигу-

рировать мышь для левши, используется функция SwapMouseButton, которая меняет назначение левой и правой кнопок. Иначе это можно сделать, передавая SPI_SETMOUSEBUTTONSWAP функции SystemParametersInfo. Отметим, однако, что мышь является разделяемым ресурсом, и все изменения будут значимы для любых приложений.

Мышь генерирует событие всегда при ее перемещении, нажатии и отпускании кнопок. События от мыши конвертируются в сообщения и передаются задаче формирования очереди сообщений. Когда сообщения мыши передаются быстрее, чем они могут быть обработаны задачей, Windows оставляет только самые последние сообщения. Сообщения мыши делятся на две группы: относящиеся к клиентской области окна и не относящиеся. Обычно приложение обрабатывает клиентские сообщения и игнорирует неклиентские. При перемещении мыши в пределах клиентской области система передает сообщение WM_MOUSEMOVE. При нажатии и отпускании кнопок в пределах клиентской области передаются следующие сообщения:

WM_LBUTTONDBLCLK

- двойной щелчок левой кнопкой.

WM_LBUTTONDOWN

- нажатие левой кнопки.

WM_LBUTTONUP

- отпускание левой кнопки.

WM_MBUTTONDBLCLK

- двойной щелчок средней кнопкой.

WM_MBUTTONDOWN

- нажатие средней кнопки.

WM_MBUTTONUP

- отпускание средней кнопки.

WM_RBUTTONDBLCLK

- двойной щелчок правой кнопкой.

WM_RBUTTONDOWN

- нажатие правой кнопки.

WM_RBUTTONUP

- отпускание правой кнопки.

Параметр lParam сообщения клиентской области показывает позицию горячей точки курсора мыши. Младшее слово относится к координате X, старшее - к координате Y клиентской области. Левый верхний угол клиентской области окна имеет координаты (0,0).

Параметр wParam содержит флаги состояния кнопок мыши, а так-

же клавиш CTRL и SHIFT.

59

Обработка двойного щелчка (Double-Click Messages)

Система генерирует сообщение о двойном щелчке, когда пользователь дважды нажимает кнопку за короткое время. При первом щелчке система определяет прямоугольную область, в пределах которой находится горячая точка курсора и делает отметку времени нажатия. При повторном нажатии той же кнопки система сравнивает позицию курсора с границами прямоугольника и вычисляет время, которое прошло с момента первого щелчка. Если курсор не перемещался и время не превышает установленного для мыши тайм-аута, система генерирует сообщение о двойном щелчке. Приложение может определить или установить продолжительность тайм-аута через GetDoubleClick-

Time и SetDoubleClickTime, либо передавая флаг SPI_SETDOUBLECLICKTIME функции SystemParametersInfo. Размеры прямоугольника, по которому Windows определяет двойной щелчок, устанавливаются пере-

дачей флагов SPI_SETDOUBLECLKWIDTH и SPI_SETDOUBLECLKHEIGHT. От-

метим, что приложение должно зарегистрировать окно, получающее сообщение о двойном щелчке, в классе CS_DBLCLKS.

В самом общем виде двойной щелчок представляет собой серию сообщений

WM_LBUTTONDOWN

WM_LBUTTONUP WM_LBUTTONDBLCLK WM_LBUTTONUP.

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

Сообщения неклиентской области

Окно получает сообщения неклиентской области, когда события, связанные с мышью, происходят вне клиентской области. К неклиентской области относятся границы окна, меню, заголовок, линейки протяжки, системное меню (спрятанное за пиктограммой окна) и экранные кнопки. Прежде всего, Windows генерирует сообщения неклиентской области для собственного употребления. Например, Windows использует эти сообщения для переключения формы курсора при подводе горячей точки к границе окна.

Названия неклиентских сообщений мыши аналогичны клиентским и отличаются только префиксом "NC". Например, перемещение курсора в неклиентской области генерирует сообщение WM_NCMOUSEMOVE, нажатие левой кнопки мыши - WM_NCLBUTTONDOWN. В отличие от клиентских сообщений параметр lParam содержит экранные, а не оконные координаты горячей точки курсора.

Активизация окна

Когда пользователь производит щелчок по неактивному главному окну приложения или неактивному дочернему окну, Windows среди прочих посылает сообщение WM_MOUSEACTIVATE. Оно передается перед сообщением о нажатии кнопки.

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

MA_ACTIVATE - активизирует окно и не очищает очередь сообщений от мыши;

MA_NOACTIVATE - не активизирует окно и не очищает очередь сообщений от мыши;

MA_ACTIVATEANDEAT - активизирует окно и очищает очередь сообщений от мыши;

MA_NOACTIVATEANDEAT - не активизирует окно и очищает очередь сообщений от мыши.

АЛГОРИТМЫ СЖАТИЯ И КОДИРОВАНИЯ

Введение

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

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

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

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

Общие принципы работы программ упаковки

Любые методы сжатия данных основаны на поиске в файле избыточной информации и последующем ее кодировании с целью получения минимального объема. Существует несколько основных методов сжатия данных, которые с теми или иными модификациями используются практически всеми упаковщиками. Обычно упаковщики осуществляют сжатие информации сразу несколькими способами. Такой прием применяется для получения наибольшей степени сжатия. Выбор способа зависит от типа данных, и определяется упаковщиком для каждого конкретного случая. Рассмотрим, в каких случаях данные могут содержать избыточную информацию, и как от этого можно было бы избавиться.

Простейший способ сжатия данных основан на анализе требований, предъявляемых к ним со стороны конкретной прикладной задачи, и последующем сохранении только самой необходимой информации. Например, латинский ASCII текст использует 7-битный код, однако каждый символ обычно записывается 8 битами. Этим с самого начала

60

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]