Входными параметрами для строкового редактора являются нажатия алфавитно-цифровых и некоторых функциональных клавиш. Он также отслеживает состояние системных клавиш для задействования т.н. «горячих клавиш». Строковый редактор должен реагировать и на нажатия левой или правой кнопок мыши.
Выходные параметры строкового редактора.
Выходными параметрами строкового редактора являются:
à отображение редактируемого текста;
à сообщение WM_LBUTTONDBLCLK, посылаемое оконной процедуре родительского окна;
à сообщение WM_COMMAND, посылаемое оконной процедуре родительского окна.
Сообщение WM_COMMAND посылается в случае, если необходимо переместить окно строкового редактора или нажата «горячая клавиша».
Алгоритм работы строкового редактора.
1. Отображение редактируемого текста.
2. Обработка сообщений, связанных с вводом с клавиатуры.
3. Обработка сообщений, связанных с нажатиями кнопок мыши.
При работе по приведенному алгоритму используются следующие переменные:
à Bufed – символьная строка, содержащая редактируемый текст;
à Leng – длина редактируемого текста (содержимого Bufed) в символах;
à Poz – положение каретки (число символов) от левого края окна;
à Cod – главный код нажатой клавиши;
à Sccod – информационный код нажатой клавиши;
à Codv – код возврата (0‑нет коррекций; 1‑есть коррекция).
Все переменные, кроме Bufed, – целочисленные.
Первый пункт алгоритма реализуется следующим образом.
После создания окна строкового редактора, но перед его отображением, оконная процедура получает сообщение WM_CREATE. При его обработке обнуляются переменные Cod, Sccod, Codv. Задаются шрифт и цвет выводимого в окно текста. Окно получает фокус ввода. Вывод редактируемого текста, т.е. содержимого Bufed, происходит при получении сообщения WM_PAINT и осуществляется функцией TextOut:
bret = TextOut (hdc, nXStart, nYStart, lpString, cbString),
где: bret – логическая переменная, принимающая значение TRUE или FALSE соответственно при успешном или неуспешном завершении функции; hdc – дескриптор контекста устройства, на которое выводится текст; nXStart и nYStart – координаты начальной позиции вывода текста; lpString – указатель на символьную строку, которая содержит текст; cbString – количество символов в этой строке.
Затем каретка устанавливается на позицию, определяемую переменной Poz (если каретка отсутствует, она предварительно создается и отображается).
При получении сообщения WM_DESTROY обнуляется переменная hWEdit, уничтожается каретка и закрывается окно строкового редактора.
Второй пункт алгоритма.
Для удобства работы в Компоновщике расчетных схем предусмотрена возможность использования т.н. «горячих клавиш». «Горячая клавиша» – это комбинация клавиш, которую пользователь может нажать для вызова к.-л. функции. В рассматриваемой программе используются две группы комбинаций: CTRL + <буква>, ALT + <буква>. Отслеживание к.-л. комбинации из первой группы не вызывает особых затруднений, в то время как использование клавиши ALT имеет свои особенности.
ОС Windows нажатия клавиш делятся на системные и несистемные. Системные нажатия – это нажатия клавиш, используемых для управления приложением и Windows. В IBM PC для этой цели Windows использует клавишу ALT, поэтому можно сказать, что нажатия клавиши ALT являются системными. При нажатии клавиши ALT (или любой другой клавиши, если ALT при этом удерживается нажатой) оконная процедура имеющего фокус ввода окна получает сообщение WM_SYSKEYDOWN. Нажатия всех остальных клавиш считаются несистемными, в этом случае оконная процедура окна с фокусом ввода получает сообщение WM_KEYDOWN.
В оконной процедуре строкового редактора при получении любого из этих сообщений фиксируется информационный код нажатой клавиши (sccod), переменная cod обнуляется. Затем вызывается подпрограмма edit с параметром hEdit.
При получении сообщения WM_CHAR, генерируемого рассмотренной ранее функцией TranslateMessage, фиксируется главный код нажатой клавиши (cod), переменная sccod обнуляется, а затем также вызывается подпрограмма edit с параметром hEdit.
Предусмотрена перекодировка из Windows‑кодировки в MS DOS‑кодировку. При необходимости этот модуль можно убрать.
В подпрограмме edit производятся следующие операции:
а) если нажата одна из тех «горячих клавиш», которые дублируют органы управления панели инструментов, то параметру wParam присваивается значение идентификатора соответствующего органа управления и в оконную процедуру родительского окна посылается сообщение WM_COMMAND.
б) если нажата одна из тех «горячих клавиш», которые дублируют операции выделения строк или блоков, операцию снятия маркировки, то параметру wParam присваивается значение идентификатора соответствующего пункта всплывающего меню оконного редактора и в его оконную процедуру посылается сообщение WM_COMMAND.
в) если нажата клавиша «ESCAPE» или «ENTER», переменной sccod присваивается соответственно 0 или значение, соответствующее информационному коду клавиши «стрелка вправо», а затем оконной процедуре оконного редактора посылается сообщение WM_COMMAND с параметром wParam, равным -1.
г) если значение переменной cod не равно нулю, т.е. была нажата клавиша в алфавитно-цифровой части клавиатуры, происходит изменение редактируемого текста, переменной sccod присваивается значение, соответствующее информационному коду клавиши «стрелка вправо».
д) если значение переменной cod равно нулю, по информационному коду нажатой клавиши проверяется ее принадлежность к группе функциональных клавиш или клавиш управления курсором, которые выполняют следующие действия:
à клавиша «стрелка влево» (VK_LEFT) – каретка перемещается на одну позиции влево. Если одновременно с клавишей была нажата клавиша Ctrl или каретка вышла за левую границу окна строкового редактора, оконной процедуре оконного редактора посылается сообщение WM_COMMAND с параметром wParam, равным -1;
à клавиша «стрелка вправо» (VK_RIGHT) – каретка перемещается на одну позиции вправо. Если одновременно с клавишей была нажата клавиша Ctrl или каретка вышла за правую границу окна строкового редактора, оконной процедуре оконного редактора посылается сообщение WM_COMMAND с параметром wParam, равным -1;
à клавиша «Delete» (VK_DELETE) – происходит удаление символа над кареткой, переменной codv присваивается значение 1;
à клавиша «Home» (VK_HOME) – происходит перемещение каретки в начало окна. Если одновременно с клавишей была нажата клавиша Ctrl, оконной процедуре оконного редактора посылается сообщение WM_COMMAND с параметром wParam, равным -1;
à клавиша «End» (VK_END) – происходит перемещение каретки в конец окна. Если одновременно с клавишей была нажата клавиша Ctrl, оконной процедуре оконного редактора посылается сообщение WM_COMMAND с параметром wParam, равным -1;
à клавиша «F5» (VK_F5) – происходит удаление текста слева от каретки;
à клавиша «F6» (VK_F6) – происходит удаление текста справа от каретки;
à клавиша «F7» (VK_F7) – происходит удаление всего текста.
При изменении редактируемого текста код возврата принимает значение, равное 1, а оконная процедура строкового редактора получает сообщение WM_PAINT путем вызова функции InvalidateRect.
Третий пункт алгоритма.
При получении оконной процедурой строкового редактора сообщения WM_LBUTTONDOWN определяются координаты курсора мыши и каретка перемещается в позицию (с учетом ширины символов), соответствующую местоположению курсора мыши.
При получении оконной процедурой строкового редактора сообщения WM_RBUTTONDOWN на экран выводится всплывающее меню, вид которого представлен на рис. 3.6.
Рис. 3.6. Всплывающее меню строкового редактора
При щелчке левой кнопкой мыши на к.-л. пункте всплывающего меню оконной процедуре строкового редактора посылается сообщение WM_COMMAND, содержащее в младшем слове параметра wParam идентификатор выбранного пункта меню. Переменной sccod присваивается значение идентификатора выбранного пункта меню и вызывается подпрограмма edit.
Двойной щелчок левой кнопкой мыши на рабочей области окна строкового редактора порождает сообщение WM_LBUTTONDBLCLK. При получении этого сообщения оконная процедура строкового редактора «переправляет» его родительскому окну, т.е. оконному редактору, где оно и обрабатывается.
В рассматриваемой программе оконная процедура строкового редактора и подпрограмма edit объединены в одном модуле, что позволяет рассматривать строковый редактор как «черный ящик». «Черный ящик» получает некоторые сообщения и определенным образом на них реагирует (рис. 3.7).
Рис. 3.7. Строковый редактор
Строковый редактор отображается на поверхности оконного редактора все время и уничтожается только по завершении его работы.
3.7 Оконный редактор
Оконный редактор предназначен для отображения и редактирования базы данных.
Оконный редактор является дочерним окном главного окна и выводится на его рабочую поверхность. Размер и местоположение оконного редактора устанавливаются с помощью функции SetWindowPos. Ширина окна определяется длиной строки базы данных, а высота – условием неперекрытия диалоговых окон (панели инструментов, панели состояния и, если активен режим ввода названий узлов, окна ввода названий узлов).