- •Задание 3. Создание кода, отображающего текст
- •Задание 4. Использование стандартных шрифтов
- •Задание 5. Поддержка средств прокрутки
- •Подведение итогов
- •Глава 9. Ввод текста
- •Чтение кодов управляющих клавиш и управление полосой прокрутки
- •Виртуальные коды клавиш, которые не генерируют сообщения wm_char
- •Задание 1. Обработка сообщения wm_keydown
- •Чтение кодов символьных клавиш и отображение символов
- •Наиболее часто используемые управляющие клавиши
- •Задание 2. Обработка сообщения wm_char
Задание 1. Обработка сообщения wm_keydown
Выполните описанные ниже действия для добавления в программу TextDemo функции CTextDemoView::OnKeyDown().
Откройте проект TextDemo, выполнив команду FileOpenProject…. Откройте окно Properties для класса CTextDemoView и щелкните на кнопку Messages. В появившемся списке идентификаторов сообщений Windows выберите сообщение WM_KEYDOWN и выполните команду <Add> OnKeyDown. Мастер добавления функций добавит обработчик сообщения с именем OnKeyDown() в класс представления программы.
Добавьте в функцию CTextDemoView::OnKeyDown() фрагмент программы, приведенный ниже полужирным шрифтом. Операторы добавленного кода сначала определяют размер документа. Затем создается объект клиентской области и определяется размер окна представления. Далее проверяется виртуальный код клавиши и в зависимости от его значения посылается сообщение окну для управления полосой прокрутки.
void CTextDemoView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default CSize DocSize = GetTotalSize (); RECT ClientRect; GetClientRect (&ClientRect); switch (nChar) { case VK_LEFT: // left arrow if (ClientRect.right < DocSize.cx) SendMessage (WM_HSCROLL, SB_LINELEFT); break; case VK_RIGHT: // right arrow if (ClientRect.right < DocSize.cx) SendMessage (WM_HSCROLL, SB_LINERIGHT); break; case VK_UP: // up arrow if (ClientRect.bottom < DocSize.cy) SendMessage (WM_VSCROLL, SB_LINEUP); break; case VK_DOWN: // down arrow if (ClientRect.bottom < DocSize.cy) SendMessage (WM_VSCROLL, SB_LINEDOWN); break; } CScrollView::OnKeyDown(nChar, nRepCnt, nFlags); }
Скомпилируйте и запустите программу TextDemo. Выполните команду OptionsFont…. Выберите атрибуты любого шрифта и закройте диалоговое окно Font. Нажимая на клавиши управления курсором , , , , выполните прокручивание текста при наличии соответствующих полос прокрутки. Попробуйте прокрутить текст с помощью клавиш PgUp (Page Up) или PgDn (Page Down). Вы увидите, что эта возможность еще не реализована.
Добавьте в функцию CTextDemoView::OnKeyDown() код, реализующий проверку нажатия клавиш PgUp и PgDn, Home, End, Ctrl+Home, Ctrl+End. Нажатие этих клавиш должно обеспечить постраничную прокрутку текста, а также переход на начало или конец строки максимальной длины (клавиши Home, End) и на начало или конец документа (комбинация клавиш с Ctrl). Для проверки состояния клавиши Ctrl (нажата или опущена) необходимо знать значение старшего бита результата, возвращаемого функцией ::GetKeyState(). Напомним, что используемое в операторе if шестнадцатеричное число 0x8000 в двоичной системе счисления имеет значение 1000 000 000 000 000, что означает установку единицы в старший бит значения, возвращаемого функцией ::GetKeyState(). Как обычно, добавленный код представлен полужирным шрифтом.
void CTextDemoView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default CSize DocSize = GetTotalSize (); RECT ClientRect; GetClientRect (&ClientRect); switch (nChar) { case VK_LEFT: // left arrow if (ClientRect.right < DocSize.cx) SendMessage (WM_HSCROLL, SB_LINELEFT); break; case VK_RIGHT: // right arrow if (ClientRect.right < DocSize.cx) SendMessage (WM_HSCROLL, SB_LINERIGHT); break; case VK_UP: // up arrow if (ClientRect.bottom < DocSize.cy) SendMessage (WM_VSCROLL, SB_LINEUP); break; case VK_DOWN: // down arrow if (ClientRect.bottom < DocSize.cy) SendMessage (WM_VSCROLL, SB_LINEDOWN); break; case VK_HOME: // Home key if (::GetKeyState (VK_CONTROL) & 0x8000)//Ctrl pressed { if (ClientRect.bottom < DocSize.cy) SendMessage (WM_VSCROLL, SB_TOP); } else //Home key alone { if (ClientRect.right < DocSize.cx) SendMessage (WM_HSCROLL, SB_LEFT); } break; case VK_END: //End key if (::GetKeyState (VK_CONTROL) & 0x8000)//Ctrl pressed { if (ClientRect.bottom < DocSize.cy) SendMessage (WM_VSCROLL, SB_BOTTOM); } else // End key alone { if (ClientRect.right < DocSize.cx) SendMessage (WM_HSCROLL, SB_RIGHT); } break; case VK_PRIOR: // PgUp key if (ClientRect.bottom < DocSize.cy) SendMessage (WM_VSCROLL, SB_PAGEUP); break; case VK_NEXT: // PgDn key if (ClientRect.bottom < DocSize.cy) SendMessage (WM_VSCROLL, SB_PAGEDOWN); break; } CScrollView::OnKeyDown(nChar, nRepCnt, nFlags); }
Изменения программы TextDemo завершены. Теперь можно скомпилировать окончательную версию программы и выполнить ее.
Во время работы программы вы увидите ее главное окно, которое не отображает полосы прокрутки. После выбора шрифта отобразится текст и в окне появится вертикальная полоса прокрутки. Если уменьшить размеры окна по горизонтали, то появится и горизонтальная полоса прокрутки. Нажатие клавиш управления курсором обеспечивает прокрутку текста. Нажатие символьных клавиш не приводит к каким-либо отображаемым в окне представления эффектам. Дело в том, что нажатие символьных клавиш генерирует дополнительное сообщение, которое требуется обработать. В противном случае вы не сможете получить отображение этих символов в окне программы. В следующем параграфе рассматривается технология обработки сообщения, посылаемого при нажатии символьной клавиши.
