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

Учебное пособие 800564

.pdf
Скачиваний:
3
Добавлен:
01.05.2022
Размер:
5.57 Mб
Скачать

Рис. 74. Организация подсистемы ввода-вывода

Обработка прерываний

Прерывания должны быть скрыты как можно глубже в недрах ОС, чтобы как можно меньшая часть ОС имела с ними дело.

161

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

Драйверы устройств

Весь зависимый от устройства код помещается в драйвер устройства.

Каждый драйвер управляет устройствами одного типа или, может быть, одного класса.

В ОС только драйвер устройства знает о конкретных особенностях какого-либо устройства.

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

Независимый от устройств слой ОС

Типичные функции:

обеспечение общего интерфейса к драйверам устройств;

именование устройств;

защита устройств;

обеспечение независимого размера блока;

буферизация;

распределение памяти на блок-ориентированных устройствах;

распределение и освобождение выделенных устройств;

уведомление об ошибках.

Пользовательский слой ПО

Большая часть ПО ввода-вывода находится внутри ОС, Некоторая его часть содержится в библиотеках, связы-

ваемых с пользовательскими программами.

Системные вызовы, включающие вызовы ввода-вывода, обычно делаются библиотечными процедурами.

162

Если программа, написанная на языке С, содержит вызов count = write (fd, buffer, nbytes),

то библиотечная процедура write будет связана с программой.

Набор подобных процедур является частью системы вво- да-вывода.

В частности, форматирование ввода или вывода выполняется библиотечными процедурами.

Функции API

1. Клавиатура

О состоянии клавиатуры дают информацию следующие функции API: GetKeyState, GetAsyncKeyState, GetKeyboardState.

1.1. Функция GetKeyState

Описание: function GetKeyState(VirtKey: Integer): Integer;

Функция определяет каково состояние виртуальной клавиши: поднята, нажата или пеpеключается.

Паpаметpы:

VirtKey - виpтуальная клавиша.

Возвpащаемое значение:

Клавиша нажата, если стаpший бит pавен 1, и клавиша пеpеключается, если младший бит pавен 1.

Функция GetKeyState (другое описание)

Declare Function GetKeyState Lib "user32.dll" (ByVal nVirtKey As Long) As Integer

Платформа

Windows NT: Требуется Windows NT 3.1 или выше.

Windows 2000: Поддерживается.

163

GetKeyState определяет текущее состояние клавиши. Функция находит, нажата ли клавиша в настоящее время или нет, и определяет, переключается ли клавиша в настоящее время.

Возвращаемое значение

Если установлен параметр &H1, клавиша переключается. Если установлен параметр &H80, то клавиша в данный момент нажата.

Параметры

nVirtKey - код виртуальной клавиши.

Windows NT, 2000: Это может быть один из следующих флажков, которые различают левый и правый Ctrl, Alt, и SHIFT:

Const VK_LSHIFT = &HA0 Левый Shift.

Const VK_RSHIFT = &HA1

Правый Shift.

Const VK_LCONTROL = &HA2

Левый Ctrl.

Const VK_RCONTROL = &HA3

Правый Ctrl.

Const VK_LMENU = &HA4

Левый Alt.

Const VK_RMENU = &HA5

Правый Alt.

Пример:

' Отобразим текущее состояние клавиши ENTER. Dim keystate As Long ' состояние клавиши

'Читаем текущее состояние клавиши ENTER. keystate = GetKeyState(VK_RETURN)

'Отобразим состояние переключателя клавиши ENTER. If (keystate And &H1) = &H1 Then

164

Debug.Print "Клавиша ENTER в настоящее время переключается."

Else

Debug.Print "Клавиша ENTER в настоящее время не переключается."

End If

' Нажимается ли Клавиша ENTER или нет. If (keystate And &H80) = &H80 Then

Debug.Print "Клавиша ENTER в настоящее время нажа-

та."

Else

Debug.Print "Клавиша ENTER сейчас не нажата." End If

Функция GetKeyboardState

Declare Function GetKeyboardState Lib "user32.dll" (pbKeyState As Byte) As Long

Платформа

Windows NT: Требуется Windows NT 3.1 или выше.

Windows 2000: Поддерживается.

GetKeyboardState отыскивает состояние каждой клавиши на клавиатуре и размещает информацию в массив. Каждый элемент массива с 256 элементами идентифицирует информацию относительно виртуальной клавиши, чей код виртуальной клавиши соответствует индексу элемента. На вашей клавиатуре нет 256 клавиш? Это сделано с прицелом на будущее. Если установлен бит &H1 , та клавиша выключена. Если установлен бит &H80, клавиша в настоящее время включена.

Примечание: Обратите внимание, что функции передается массив, указывая его первый элемент.

Возвращаемое значение

165

В случае ошибки функция возвращает 0 (используйте GetLastError для получения кода ошибки). В успешном случае функция возвращает значение отличное от нуля.

Параметры

pbKeyState - массив байтов с 256 элементами, который получает информацию состояния для всех виртуальных клавиш.

Каждая клавиша идентифицирована элементом, соответствующим коду виртуальной клавиши.

Windows NT, 2000: В дополнение к виртуальным клавишам, массив также получает информацию, способную различать левый и правый клавиши Ctrl, Alt, и SHIFT, которые помещены в массив в следующих индексах:

VK_LSHIFT = &HA0 Левый Shift. VK_RSHIFT = &HA1 Правыйt Shift. VK_LCONTROL = &HA2

Левый Ctrl. VK_RCONTROL = &HA3

Правый Ctrl. VK_LMENU = &HA4

Левый Alt. VK_RMENU = &HA5

Правый Alt.

Пример

'Установим статус для каждой клавиши на клавиатуре

'на "не включено"

Dim keystates(0 To 255) As Byte ' содержит статус всех клавиш в массиве

Dim c As Integer ' счетчик

Dim retval As Long ' возвращаемое значение

166

'Сначала, получим текущее состояние клавиатуры. retval = GetKeyboardState(keystates(0))

'Теперь, установим бит для всех клавиш в 0.

For c = 0 To 255

' Удостоверимся,что бит &H1 не установлен. keystates(c) = keystates(c) And (Not &H1) Next c

' Наконец, установим это к текущему состоянию клавиа-

туры.

retval = SetKeyboardState(keystates(0))

Процедура keybd_event

Declare Sub keybd_event Lib "user32.dll" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

Платформа

Windows NT: Требуется Windows NT 3.1 или выше, но устарела для Windows NT 4.0 с Service Pack 3 (SP3) или выше;

пользуйтесь SendInput.

keybd_event имитирует нажатия клавиш на клавиатуре. keybd_event не является функцией и не возвращает ни-

каких значений.

Параметры

bVk - виртуальный код клавиши для имитации нажатия и отпускания клавиши;

bScan - зарезервировано (установлено в 0).

dwFlags - комбинация следующих флагов определяет различные способы имитации:

KEYEVENTF_EXTENDEDKEY

Префикс скэн-кода с префиксным байтом, имеющим значение &HE0.

KEYEVENTF_KEYUP

167

Клавиша, указанная в bVk будет отпущена. Если этот флажок не определен, клавиша будет нажата.

dwExtraInfo - дополнительное 32-разрядное значение, связанное с событием клавиатуры.

Константы

Const KEYEVENTF_EXTENDEDKEY = &H1 Const KEYEVENTF_KEYUP = &H2

Пример

' Имитируем нажатия клавиш CTRL+ESC для нажатия кнопки Пуск

keybd_event VK_CONTROL, 0, 0, 0 ' нажимаем CTRL keybd_event VK_ESCAPE, 0, 0, 0 ' нажимаем ESC keybd_event VK_CONTROL, 0, KEYEVENTF_KEYUP, 0

' отпускаем CTRL

keybd_event VK_ESCAPE, 0, KEYEVENTF_KEYUP, 0 '

отпускаем ESC

2. Мышь

2.1.Функция GetDoubleClickTime

Declare Function GetDoubleClickTime Lib "user32.dll" () As

Long

Платформа: Win NT

GetDoubleClickTime определяет максимальный промежуток временив миллисекундах между двумя щелчками мыши, которые обрабатываются системой как двойной щелчок.

Пример:

'Показываем промежуток времени

'между двумя щелчками мыши в событии DoubleClick Dim doubletime As Long

doubletime = GetDoubleClickTime() ' получаем значение

промежутка времени в миллисекундах

Debug.Print doubletime; "миллисекунд"

168

2.2.Функция ReleaseCapture

Declare Function ReleaseCapture Lib "user32.dll" () As Long

Платформа

Windows NT: Требуется Windows NT 3.1 или выше.

Windows 2000: Поддерживается.

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

В успешном случае функция возвращает значение, отличное от нуля, в противном случае функция возвратит 0 (используйте GetLastError для получения кода ошибки).

Пример

'Перемещаем форму за любое место,

'а не только за заголовок

' Вставьте код в Form_MouseMove

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)

Dim retval As Long 'возвращаемое значение

If Button = 1 Then

Call ReleaseCapture

'посылаем сообщение о нажатии левой кнопки мыши на заголовке нашей формы

retval = SendMessage(Me.hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&)

End If

End Sub

' код для Form_Paint Private Sub Form_Paint()

Me.Print "Щелкните на форме и удерживая кнопку перетаскивайте форму"

End Sub

169

2.3.Функция SwapMouseButton

Declare Function SwapMouseButton Lib "user32.dll" (ByVal bSwap As Long) As Long

Платформа

Win 95/98, Win NT

SwapMouseButton изменяет настройку, используемую для кнопок мыши. Windows позволяет Вам интерпретировать щелчки с левой кнопкой как щелчки с правой кнопкой и наоборот. Эти функциональные возможности предназначены для левшей. Делайте это с предостережением - новые настройки будут действовать во всех программах. Функция возвращает 1 в успешном случае, или 0 в случае ошибки.

Параметры

bSwap - определяет настройки кнопки мыши.

Значение "0" не меняет кнопки . Значение "1" меняют левые и правые кнопки .

Пример

' Меняем кнопки местами

Dim retval As Long ' возвращаемое значение

retval = SwapMouseButton(1) ' переключаем кнопки Debug.Print "Вы поменяли местами левую и правую

кнопки мыши!"

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

Просмотреть функции API, описанные выше и относящиеся к данному заданию, применить их в приложении (самостоятельно).

Для языка программирования С# использовать:

170