Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
WinAPI.docx
Скачиваний:
49
Добавлен:
16.12.2018
Размер:
3.43 Mб
Скачать

6.4.4 Добавление интерфейса клавиатуры к программе checker

Программа CHECKER2 является той же программой CHECKER1, за исключением того, что здесь добавлен интерфейс клавиатуры. Вы можете использовать клавиши со стрелками для перемещения курсора между 25 прямоугольниками. Клавиша <Home> перемещает курсор к верхнему левому углу прямоугольника; клавиша <End> опускает его в нижний правый прямоугольник. Клавиши и <Spacebar> и <Enter> включают и выключают вывод символа перечеркивания Х.

Логика обработки сообщения WM_KEYDOWN в программе CHECKER2 следующая: определяется положение курсора (GetCursorPos), координаты экрана преобразуются в координаты рабочей области (ScreenToClient), а затем координаты делятся на ширину и высоту прямоугольного блока. Полученные значения х и y показывают положение прямоугольника в массиве 5 на 5. Курсор мыши при нажатии клавиши не всегда находится в рабочей области, поэтому х и y должны быть обработаны макросами min и max таким образом, чтобы гарантировать их попадание в диапазон от 0 до 4.

Для клавиш со стрелками программа CHECKER2 увеличивает или уменьшает на 1 соответственно значение х или y. Если нажатой клавишей является клавиша <Enter> (VK_RETURN) или клавиша <Spacebar> (VK_SPACE), то программа CHECKER2 использует функцию SendMessage для посылки себе же синхронного сообщения WM_LBUTTONDOWN. Такая технология напоминает метод, использованный в программе SYSMETS в главе 5, где для полосы прокрутки окна в программу добавлен интерфейс клавиатуры. Логика обработки сообщения WM_KEYDOWN заканчивается расчетом координат рабочей области, которые являются координатами центра прямоугольника, преобразованием их в координаты экрана (ClientToScreen) и установкой положения курсора (SetCursorPos).

6.4.5 Использование дочерних окон для тестирования попадания

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

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

6.4.6 Дочерние окна в программе checker

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

В программе CHECKER3 имеется две оконные процедуры, которые называются WndProc и ChildWndProc. WndProc — это по-прежнему оконная процедура главного (или родительского) окна. ChildWndProc — это оконная процедура 25 дочерних окон. Обе оконные процедуры должны быть определены как функции обратного вызова (CALLBACK).

Поскольку оконная процедура задается в структуре класса окна, которую вы регистрируете в Windows с помощью функции RegisterClassEx, то для двух оконных процедур в программе CHECKER3.C требуется два класса окна. Первый класс окна — это класс главного окна, и называется он "Checker3". Второму классу окна назначено имя "Checker3_Child".

Большинство полей структурной переменной wndclass просто повторно используются при регистрации класса "Checker3_Child" в WinMain. Поле lpszClassName устанавливается в "Checker3_Child" (имя класса). Поле lpfnWndProc устанавливается в ChildWndProc — оконную процедуру этого класса, а поля hIcon и hIconSm устанавливаются в NULL, поскольку с дочерними окнами значки не используются. Для класса окна "Checker3_Child" поле cbWndExtra структурной переменной wndclass устанавливается равной 2 байтам, или точнее, sizeof(WORD). Это поле требует от Windows зарезервировать 2 байта дополнительного пространства в структуре, которую Windows строит для каждого окна, создаваемого на основе данного класса окна. Вы можете использовать это пространство для хранения информации, которая может быть индивидуальной для каждого окна.

Вызов функции CreateWindow в WinMain создает на основе класса "Checker3" главное окно. Это нормально. Однако, когда WndProc получает сообщение WM_CREATE, она, чтобы создать 25 дочерних окон на основе класса "Checker3_Child", 25 раз вызывает функцию CreateWindow. В следующей таблице дано сравнение параметров вызова функции CreateWindow в WinMain, создающей главное окно и вызова функции CreateWindow в WndProc, создающей 25 дочерних окон.

Обычно для дочерних окон требуются параметры положения, ширины и высоты, но в программе CHECKER3 положение и размер дочерних окон устанавливаются позже в WndProc. Описатель родительского окна для главного окна равен NULL, поскольку оно родительское. Описатель родительского окна необходим при вызове функции CreateWindow для создания дочернего окна.

В главном окне отсутствует меню, поэтому соответствующий параметр равен NULL. Для дочерних окон этот же параметр называется "идентификатором дочернего окна" (child ID). Это число уникально для каждого дочернего окна. Идентификатор дочернего окна приобретает важное значение при управлении дочерними окнами, поскольку сообщения для родительского окна, как мы увидим в главе 8, идентифицируются этим идентификатором дочернего окна. В программе CHECKER3 идентификаторы дочерних окон установлены так, чтобы они соответствовали положению, которое каждое дочернее окно занимает в массиве 5 на 5 внутри главного окна.

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

Каждое дочернее окно имеет свой описатель окна, который хранится в массиве hwndChild. Когда WndProc получает сообщение WM_SIZE, она вызывает функцию MoveWindow для каждого из 25 дочерних окон. Параметры задают верхний левый угол дочернего окна относительно начала координат рабочей области родительского окна, ширину и высоту дочернего окна, а также необходимость перерисовки дочернего окна.

Теперь давайте рассмотрим ChildWndProc. Эта оконная процедура обрабатывает сообщения для всех 25 дочерних окон. Параметр hwnd для ChildWndProc является описателем дочернего окна, получающего сообщение. Когда ChildWndProc обрабатывает сообщение WM_CREATE (что происходит 25 раз, поскольку имеется 25 дочерних окон), она использует функцию SetWindowWord для хранения 0 в дополнительном пространстве, зарезервированном внутри структуры окна. (Вспомните, что мы зарезервировали это пространство с помощью поля cbWndExtra при определении структуры класса окна.) ChildWndProc использует это значение для хранения текущего состояния прямоугольника (зачеркнут он символом Х или нет). Когда в дочернем окне происходит щелчок мыши, логика обработки сообщения WM_LBUTTONDOWN просто изменяет значение этого слова (0 на 1 или 1 на 0) и делает недействительной всю рабочую область дочернего окна. Эта область и является тем самым прямоугольником, в котором произошел щелчок. Обработка сообщения WM_PAINT вполне обычна, поскольку размер рисуемого прямоугольника равен размеру рабочей области окна.

Поскольку файл с текстом исходной программы на С и исполняемый файл .EXE программы CHECKER3 больше, чем аналогичные файлы для программы CHECKER1, то не будем утверждать, что CHECKER3 "проще", чем CHECKER1. Но обратите внимание, что нам больше не нужно делать никакого тестирования попадания для мыши! Если какое-нибудь дочернее окно в программе CHECKER3 получает сообщение WM_LBUTTONDOWN, то значит в этом окне и было нажатие, и это все, что ему нужно знать.

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

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