Операционная система Microsoft Windows 3.1 для программиста© Александр Фролов, Григорий ФроловТом 11, М.: Диалог-МИФИ, 1993, 269 стр. 5.6. Текстовый курсорПри вводе текста в среде MS-DOS используется текстовый курсор, указывающий позицию ввода очередного символа. Текстовый курсор в MS-DOS формируется автоматически функциями BIOS или создается программой. В последнем случае программа должна сама следить за перемещением текстового курсора. Если ваше приложение создает свой собственный текстовый редактор (не пользуясь стандартным, который доступен всем приложениям Windows), вы должны сами создать текстовый курсор и заботиться о его внешнем виде, отображении и перемещении. Заметим, что в операционной системе Windows используются два курсора. Один курсор называется cursor и означает курсор мыши. Второй курсор называется caret (знак вставки) и означает текстовый курсор. Текстовый курсор является системным ресурсом Windows. Можно создать только один текстовый курсор. И это правильно, так как в противном случае вы, увидев на экране два или больше приглашений для ввода текста, не будете знать, где же будут отображаться вводимые вами при помощи клавиатуры символы. Как правило, курсор создается окном в момент получения фокуса ввода. Напомним, что при получении фокуса ввода функции окна передается сообщение WM_SETFOCUS. Обработчик этого сообщения может при необходимости создать текстовый курсор. Когда окно теряет фокус ввода, оно должно уничтожить текстовый курсор. При потере фокуса ввода функции окна передается сообщение WM_KILLFOCUS, обработчик которого и должен удалить текстовый курсор, созданный при обработке сообщения WM_SETFOCUS. Для создания текстового курсора обработчик сообщения WM_SETFOCUS должен вызвать функцию CreateCaret, входящую в программный интерфейс Windows: void WINAPI CreateCaret(HWND hwnd, HBITMAP hbmp, int nWidth, int nHeight); Первый параметр функции (hwnd) - идентификатор окна, создающего текстовый курсор. Второй параметр (hbmp) может принимать значения NULL, 1 или он может быть идентификатором битового изображения курсора (bitmap). Если этот параметр равен NULL, текстовый курсор представляет собой вертикальную черту черного цвета. Если этот параметр равен 1, текстовый курсор изображается серым цветом. Вы также можете нарисовать курсор любой произвольной формы в виде битового образа (bitmap) и использовать этот свой курсор, загрузив его из ресурсов приложения и указав идентификатор. В этом случае третий и четвертый параметры функции игнорируются. О ресурсах и битовых образах вы узнаете позже, так как это тема для отдельного разговора. Третий параметр (nWidth) определяет ширину курсора в логических единицах. Если задать для ширины значение NULL, курсор будет иметь ширину, равную ширине рамки, создаваемой вокруг окна. Это значение возвращается функцией GetSystemMetrics, когда ей в качестве параметра указывается константа SM_CXBORDER. Последний, четвертый параметр (nHeight) функции CreateCaret определяет высоту текстового курсора в логических единицах. Для этого параметра также можно указать значение NULL, при этом высота текстового курсора будет равна высоте рамки окна. Это значение возвращается функцией GetSystemMetrics, когда ей в качестве параметра указывается константа SM_CYBORDER. Если для ширины и высоты текстового курсора заданы значения NULL, курсор будет видно при использовании видеорежимов высокого разрешения. Если же вы укажете ширину текстового курсора, равную одному пикселю, в режимах с высоким разрешением курсор окажется слишком тонким для того, чтобы его можно было заметить. При использовании для изображения курсора битового образа (bitmap) форма и размеры курсора полностью определяются самим битовым образом, поэтому третий и четвертый параметры функции могут принимать любые значения. Когда функция окна получает сообщение WM_KILLFOCUS, она должна уничтожить текстовый курсор, вызвав функцию DestroyCaret: void WINAPI DestroyCaret(void); Эта функция не имеет параметров. После ее вызова текстовый курсор пропадает из окна и может быть использован в другом окне, которое получит фокус ввода. Сразу после создания функцией CreateCaret текстовый курсор находится в невидимом, выключенном состоянии. Для того чтобы сделать текстовый курсор видимым, следует вызвать функцию ShowCaret: void WINAPI ShowCaret (HWND hwnd); В качестве параметра этой функции передается идентификатор окна hwnd, создавшего текстовый курсор. Перед тем как перерисовывать окно, приложение должно выключить (скрыть) текстовый курсор. Так как курсор постоянно мигает, если его не выключить во время перерисовки окна, изображение курсора может "размножаться" на экране. Функция BeginPaint самостоятельно скрывает курсор, но, если вы перерисовываете окно во время обработки других сообщений, курсор необходимо выключить (но не уничтожить!), вызвав функцию HideCaret: void WINAPI HideCaret(HWND hwnd); В качестве параметра этой функции передается идентификатор окна hwnd, создавшего текстовый курсор. Функции ShowCaret и HideCaret обладают свойством накопления. Если вы несколько раз подряд вызвали функцию HideCaret, для того чтобы текстовый курсор вновь стал видимым, вам придется столько же раз вызвать функцию ShowCaret. Аналогично, если вы несколько раз вызвали функцию ShowCaret, для того чтобы скрыть текстовый курсор, вам придется столько же раз вызвать функцию HideCaret. Но прежде чем включать курсор, вам необходимо установить его в нужное место окна (вы сами должны заботиться о правильном расположении текстового курсора). Для этого следует вызвать функцию SetCaretPos: void WINAPI SetCaretPos(int x, int y); Первый параметр этой функции определяет горизонтальную X-координату курсора, второй - вертикальную Y-координату курсора. Для получения текущих координат текстового курсора следует воспользоваться функцией GetCaretPos: void WINAPI GetCaretPos(POINT FAR* lppt); Единственный параметр этой функции lppt указывает на структуру типа POINT, в которую будет записана информация о расположении курсора. Тип POINT описан в файле windows.h: typedef struct tagPOINT { int x; int y; } POINT; После возврата из функции GetCaretPos поля x и y структуры будут содержать соответственно X- и Y-координаты текстового курсора. С помощью функций GetCaretBlinkTime и SetCaretBlinkTime приложение может соответственно узнать и изменить период мигания текстового курсора. Функция GetCaretBlinkTime возвращает период мигания текстового курсора в миллисекундах: UINT WINAPI GetCaretBlinkTime(void); С помощью функции SetCaretBlinkTime вы можете установить новое значение периода мигания курсора, указав его в качестве параметра функции (также в миллисекундах): void WINAPI SetCaretBlinkTime(UINT uMSeconds); Управлять текстовым курсором непросто, особенно если учесть, что при редактировании текста могут быть использованы разные шрифты с переменной шириной букв (и даже с наклонными буквами). Но у вас едва ли появится необходимость создания собственного текстового редактора, аналогичного Microsoft Word for Windows (если, конечно, ваша основная работа не связана именно с созданием таких текстовых редакторов!). Для редактирования и ввода отдельных символьных строк или многострочного текста без использования шрифтового оформления проще всего воспользоваться зарегистрированным операционной системой Windows классом окна edit. Этот класс окна специально предназначен для создания текстовых редакторов, обладающих достаточно широкими возможностями (например, в этом классе окна есть поддержка универсального буфера обмена Clipboard, вертикальная и горизонтальная полосы просмотра и т. д.). В свое время мы будем подробно изучать этот "встроенный" в операционную систему редактор текста. |