Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
 
Вот здесь http://www.sanmaster-m.ru/santehnicheskie-raboty/zamena-trub/ недорого заменят трубы.

Перевод и адаптация под DELPHI раздела Win32 SDK посвященного клавиатурным курсорам.

Каретки (Carets)

Содержание

  • Про каретки
  • Скрытие/уладение кареток
  • Использование кареток
  • Создание и отображение кареток
  • Скрытие кареток
  • Удаление кареток
  • Настройка времени мерцания
  • Обработка ввода с клавиатуры
  • Список функций
  • Функция CreateCaret
  • Функция DestroyCaret
  • Функция GetCaretBlinkTime
  • Функция GetCaretPos
  • Функция HideCaret
  • Функция SetCaretBlinkTime
  • Функция SetCaretPos
  • Функция ShowCaret
  • Одной из проблемм, с которой я столкнулся при подготовке этой статьи, стала проблема выбора эквивалента английскиму слову caret. Вроде бы все привыкли называть текстовый курсор курсором, не смотря на то, что возникает некоторая путаница с курсорами мыши. Я даже с нежностью вспомнил те времена, когда мыши еще не расплодились, и слово курсор означало только мигающую горизонтальную черточку (или блочек), показывающий место вставки символа. В результате я принял волевое решение вспомнить старый термин "каретка" (может кто еще помнит, что клавиша Enter когда-то гордо именовалась возвратом каретки), который созвучен английскому термину.

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

    Поскольку только одно окно может иметь в данный момент фокус ввода (быть активным), то в системе может быть только одна каретка. Каждое окно, содержащее каретку, должно создавать ее при получении фокуса, и освобождать при потере фокуса.

    Все программы, написанные под Microsoft® Windows® могут создавать каретки, отображать или скрывать их, перемещать их, а также изменять время мерцания.

    Про каретки

    Программа должна использовать функцию CreateCaret чтобы задать параметры каретки. Окно формирует каретку путем инвертирования цветов в прямоугольной области, задаваемой позицией каретки, ее шириной и высотой. Ширина и высота каретки задаются в логических единицах, поэтому внешний вид каретки зависит от режима отображения окна. В Delphi по умолчанию логической единицей является пиксель.

    После того, как каретка определена, программа должна использовать функцию ShowCaret, чтобы отобразить ее на экране. После своего появления на экране, каретка автоматически начинает мерцать. При изображении сплошной каретки, Windows инвертирует каждый пиксел в прямоугольной области, задаваемой кареткой. При изображении серой каретки, Windows инвертирует каждый второй пиксель (в шахматном порядке). Название "серая" возникло из-за того, что как для белого фона, так и для черного результат будет серым - смесь белых и черных пикселов. Ниже на рисунке показаны две фазы мерцания серой каретки, и центральные части этих же рисунков в увеличенном виде.

    Каретки в виде рисунка отличает то, что там при мерцании белые пиксели рисунка инвертируются полностью, под черными пикселами остается фоновое изображение, для цветных же пикселей происходит инвертация цвета в соответствии с тем, какме цвет присутствует на картинке. Белй цвет соответствует инвертации цвета фона, черный же сохраняет цвет фона. Справедлива формула

    Цвет_изображения = Цвет_фона XOR (NOT Цвет_рисунка_каретки)

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

    Время в миллисекундах, после которого изображение начинает инвертироваться, называется временем мерцания каретки (blink time). Пользовать может установить это время используя панель управления. Программы должны уважать настройки, выбранные пользователем. Программа может определить время мерцания каретки при помощи функции GetCaretBlinkTime. Если вы пишите приложения, позволяющие пользователю настраивать время мерцания каретки, аналогичные апплетам панели управления, то вы должны использовать функцию SetCaretBlinkTime для установки времени мерцания каретки в миллисекундах. Полным временем мерцания каретки (flash time) называется время, которое требуется каретки для выполнения нивертирования пикселей и возрата в исходное востояние. Полное время мерцания каретки равно удвоенному времени мерцания каретки.

    Программа может определить положение каретки с использованием вызова функции GetCaretPos. Позиция в клиентских координатах копируется в структуру TPoint, ссылка на которую передается в качестве параметра при вызове GetCaretPos. Программа может перемещать каретку внутри окна путем использования функции SetCaretPos. Окно может перемещать каретку только в том случае, если оно владеет ею. SetCaretPos перемещает каретку вне зависимости от того, видима она или нет.

    Скрытие/удаление кареток

    Программа должна использовать функцию HideCaret для того, чтобы скрыть каретку с экрана. Это необходимо, когда программа захочет перерисовать область под кареткой, в ответ на какое-либо сообщение. Когда программа закончит отрисовку, она может снова отобразить каретку путем вызова функции HideCaret, то необходимо сделать пять вызовов ShowCaret, прежде чем каретка появиться на экране.

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

    Использование кареток

    Создание и отображение кареток

    При получении фокуса, окно должно создать и отобразить каретку. Вы должны использовать функцию CreateCaret для создания каретки в данном окне. Затем вы должны вызвать функцию SetCaretPos для того, чтобы задать текущую позицию каретки и функцию ShowCaret чтобы сделать каретку видимой.

    Когда окно получает фокус, операционная система посылает ему сообщение WM_SETFOCUS. Поэтому программа должна создавать и отображать каретку в ответ на это сообщение.

      procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
    
      ..........................................................................
    
      procedure TForm1.WMSetFocus(var Message: TWMSetFocus);
      var
        X, Y: Integer;
        CaretWidth, CaretHeight: Integer;
      begin
    
        // Создаем сплошную черную каретку.
        CreateCaret(Handle, 0, CaretWidth, CaretHeight);
    
        // Устанавливает положение каретки в клиентских координатах.
        SetCaretPos(X, Y);
    
        // Отображение каретки.
        ShowCaret(Handle);
    
      end;
    

    Для создания каретки в виде рисунка, вы должны задать дескриптор рисунка при использовании функции CreateCaret. Вы можете использовать графический редактор для создания рисунка и компилятор ресурссов или любой механизм для того, чтобы присоединить рисунок к программе. Например, для создания каретки в виде рисунка, вы должны заменить вызов CreateCaret в предыдущем примере на следующие строки:

      // Загрузить определенный в приложении ресурс каретки
      Bitmap.LoadFromResourceName(hInstance, 'CaretPic');
    
      // Создать каретку в виде рисунка
      CreateCaret(Handle, Bitmap.Handle, 0, 0);
    

    Если при создании каретки программа передает дескриптор рисунка, то функция CreateCaret игнорирует параметры ширины и высоты, так как ширина и высота задаются самим рисунком.

    Скрытие кареток

    Когда ваша программа должна что-то нарисовать на экране в ответ на сообщение, отличное от WM_PAINT, она должна сделать каретку невидимой путем вызова функции HideCaret. После завершения прорисовки, восстановить каретку на экране можно путем использования функции ShowCaret. Если программа обрабатывает сообщение WM_PAINT (в компонентах Delphi это обычно делает метод Paint), то в этом нет необходимости, скрытие и восстановление курсора выполняются автоматически.

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

      procedure WMChar(var Message: TWMChar); message WM_CHAR;
    
      ..........................................................................
    
      procedure TForm1.WMChar(var Message: TWMChar);
      var Ch: Char;
      begin
        Ch := Char(Message.CharCode);
        case Ch of
    
          #8: begin
              // Нажата клавиша Backspace
              ..................................
            end;
    
          #9: begin
              // Нажата клавиша Tab
              ..................................
            end;
    
          #13: begin
              // Нажата клавиша Enter
              ..................................
            end;
    
          else begin
              // Скрытие каретки
              HideCaret(Handle);
    
              // Рисуем символ на экране
              ..................................
              Canvas.TextOut(CaretPosX*CharX, CaretPosY*CharY, Ch);
              ..................................
    
              // Отображаеи каретку
              ShowCaret(Handle);
            end;
    
        end;
    
      end;
    

    Если программа делает несколько вызовов функции HideCaret, то каретка не появится на экране, пока вы не сделаете точно такое же количество вызовов функции ShowCaret.

    Удаление кареток

    Операционная система посылает окну сообщение WM_KILLFOCUS, когла окно теряет фокус. В ответ на это сообщение программа должна удалить каретку путем использования функции DestroyCaret. Следующий фрагмент программы демонстрирует, как необходимо удалять каретку когда окно больше не имеет фокус ввода.

      procedure WMKillFocus(var Message: TWMSetFocus); message WM_KILLFOCUS;
    
      ..........................................................................
    
      procedure TCaretEdit.WMKillFocus(var Message: TWMSetFocus);
      begin
        DestroyCaret;
      end;
    

    Настройка времени мерцания

    В программах, написанных под Win16 (в частности под Windows 3.x), программа могла во время обработки сообщения WM_SETFOCUS вызывать функцию GetCaretBlinkTime для сохранения текущего времени мерцания, а затем вызывать SetCaretBlinkTime для настройки собственного времени мерцания. Потом, в ответ на сообщение WM_KILLFOCUS программа могла путем вызова SetCaretBlinkTime восстановить сохраненное время мерцания. Однако эта техника не работает под Win32, потому как она поддерживают действительную многозадачность. В частности, потеря фокуса одним приложением не засинхронизирована с получением фокуса другим, поэтому если одна программа "повисла", то другая может все еще иметь фокус.

    Программы, написаные под Win32, должны уважать настройки, выбраные пользователем. Вы должны вызывать функцию SetCaretBlinkTime только если ваша программа предоставляет пользователю возможность настраивать время мерцания.

    Обработка ввода с клавиатуры

    Ниже приведена ссылка на пример, который демонстрирует использование кареток в Delphi. Этот пример реализует простейший текстовый редактор в виде компоненты. Пример сделан в академических целях, поэтому многие функции редактора показаны схематично и не полностью. Взять компонент и демонстрационную программу можно здесь.

    Функции для работы с кареткой

    Следующие функции используются для работы с каретками


    Функция CreateCaret

    Функция CreateCaret устанавливает новую форму для системной каретки и устанавливает указанное окно владельцем каретки. Каретка может иметь форму линии, прямоугольника или рисунка.

    function CreateCaret(
      hWnd: HWND;            // дескриптор окна, нового владельца каретки 
      hBitmap: HBITMAP;      // дескриптор рисунка - вида каретки 
      nWidth: Integer        // ширина каретки 
      nHeight: Integer       // высота каретки 
    ): BOOL; stdcall;
    

    Параметры

    hWnd
    Идентифицирует окно - владельца каретки

    hBitmap
    Указывает рисунок, который задается в качестве формы каретки. Если этот параметр равен 0, то каретка будет сплошной. Если этот параметр равен 1, то каретка будет серой. Если этот параметр задает дескриптор рисунка, то форма каретки задается этим рисунком.

    nWidth
    Задает ширину каретки в логических единицах. Если этот параметр равен нулю, то каретка имеет значение ширины, определенное в системе. Если в качестве параметра hBitmap задается дескриптор рисунка, то значение параметра nWidth игнорируется, а а качестве ширины каретки используется ширина рисунка.

    nHeihgt
    Задает высоту каретки в логических единицах. Если этот параметр равен нулю, то каретка имеет значение высоты, определенное в системе. Если в качестве параметра hBitmap задается дескриптор рисунка, то значение параметра nHeight игнорируется, а а качестве высоты каретки используется высота рисунка.

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

    В случае успешного завершения функция возвращает True. В случае возникновения ошибки, функция возвращает False. В этом случае для получения расширенной информации об ошибке необходимо сделать вызов функции GetLastError.

    Примечания

    Параметры nWidth и nHeight задают ширину и высоту каретки в логических единицах, точное значение ширины и высоты каретки в пикселах зависит от режима отображение окна.

    Функция CreateCaret автоматически разрушает предыдущу форму каретки, не обращая внимания на окно, которое было владельцем каретки до этого вызова. Каретка будет скрытой до тех пор, пока программа не выполнит вызов ShowCaret для того, чтобы сделать каретку видимой.

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

    Вы можете получить параметры системной высоты и ширины каретки путем вызова функции GetSystemMetrics, задав ей значения SM_CXBORDER и SM_CYBORDER. Использование границы окна в качестве ширины или высоты каретки гарантирует то, что каретка будет видима при любом разрешении экрана.

    Смотри также

    DestroyCaret , GetSystemMetrics, HideCaret , ShowCaret


    Функция DestroyCaret

    Функция DestroyCaret разрушает текущую форму каретки, разрывает ее связь с текущим окном и удаляет ее с экрана.

    Если форма каретка задана в виде рисунка, то функция DestroyCaert не освобождает связанный с ней дескриптор рисунка.

    function DestroyCaret: BOOL; stdcall;
    

    Параметры

    Функция не имеет параметров

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

    В случае успешного завершения функция возвращает True. В случае возникновения ошибки, функция возвращает False. В этом случае для получения расширенной информации об ошибке необходимо сделать вызов функции GetLastError.

    Примечания

    Функция DestroyCaret разрушает каретку только если в текущей задаче окно в текущей задаче окно владеет кареткой. Если в текущей задаче окно не владеет кареткой, то функция DestroyCaret не выполнит ничего и вернет False.

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

    Смотри также

    CreateCaret , HideCaret , ShowCaret


    Функция GetCaretBlinkTime

    Функция GetCaretBlinkTime возвращает время в миллисекундах, требуемое для того, чтобы каретка проинвертировала пиксели. Пользователь может установить это значение при помощи пенели управления.

    function GetCaretBlinkTime: UINT; stdcall;
    

    Параметры

    Функция не имеет параметров.

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

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

    Смотри также

    SetCaretBlinkTime


    Функция GetCaretPos

    Функция GetCaretPos копирует текущее положение каретки в структуру TPoint.

    function GetCaretPos(
      var lpPoint: TPoint // ссылка на структуру-получатель координат каретки
    ): BOOL; stdcall;
    

    Параметры

    lpPoint
    Ссылка на структуру TPoint, куда будут записаны текущие координаты каретки.

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

    В случае успешного завершения функция возвращает True. В случае возникновения ошибки, функция возвращает False. В этом случае для получения расширенной информации об ошибке необходимо сделать вызов функции GetLastError.

    Примечания

    Позиция каретки всегда возвращается в клиентских координатах окна, содержащего каретку.

    Смотри также

    SetCaretPos , POINT


    Функция HideCaret

    Функция HideCaret скрывает каретку с экрана. Функция HideCaret не уничтожает текущую форму каретки и ее положения.

    function HideCaret(
      hWnd: HWND     // дескриптор окна, содержащего каретку
    ): BOOL; stdcall;
    

    Параметры

    hWnd
    Указывает окно, которое является владельцем каретки. Если в качестве параметра передано 0, то функция HideCaret исчет среди всех окон текущей задачи окно, которое является владельцемн каретки.

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

    В случае успешного завершения функция возвращает True. В случае возникновения ошибки, функция возвращает False. В этом случае для получения расширенной информации об ошибке необходимо сделать вызов функции GetLastError.

    Примечания

    Функция HideCaret скрывает каретку только если указанное окно владеет каретой. В противном случае функция HideCaret не выполняет ничего и возвращает значение False.

    Операция скрытия каретки кумулятивна, то есть чтобы каретка отобразилась на экране вы должны сделать ровно столько же вызовом ShowCaret, сколько до этого было вызовов HideCaret.

    Смотри также

    CreateCaret , DestroyCaret , GetCaretPos , SetCaretPos , ShowCaret


    Функция SetCaretBlinkTime

    Функция SetCaretBlinkTime позволяет установить время мерцания каретки в миллисекундах. Время мерцания каретки есть время, которое должно пройти прежде чем каретка начнет инвертировать свои пиксели.

    function SetCaretBlinkTime(
      uMSeconds: UINT       // время мерцания в миллисекундах
    ): BOOL; stdcall;
    

    Параметры

    uMSeconds
    Задает новое время мерцания в миллисекундах.

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

    В случае успешного завершения функция возвращает True. В случае возникновения ошибки, функция возвращает False. В этом случае для получения расширенной информации об ошибке необходимо сделать вызов функции GetLastError.

    Примечания

    Пользователь может установить время мерцания курсора используя панель управления. Программа должна уважать настройки пользователя. Функцией SetCaretBlinkTime можно пользоваться только если ваша программа позволяет настраивать время мерцания курсора, вроде апплетов панели управления.

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

    Смотри также

    GetCaretBlinkTime


    Функция SetCaretPos

    Функция SetCaretPos перемещает каретку в указанное положение. Если окно, которое является владельцем каретки было создано с флагом класса окна CS_OWNDC, то указанные координаты зависят от контекста устройства, связанного с окном.

    function SetCaretPos(
      X: Integer;   // положение по горизонтали
      Y: Integer    // положение по вертикали
    ): BOOL; stdcall;
    

    Параметры

    X
    Задает новую координату x каретки

    Y
    Задает новую координату y каретки

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

    В случае успешного завершения функция возвращает True. В случае возникновения ошибки, функция возвращает False. В этом случае для получения расширенной информации об ошибке необходимо сделать вызов функции GetLastError.

    Примечания

    Функция SetCaretPos перемещает каретку вне зависимости от того, видима она, или нет.

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

    Смотри также

    GetCaretPos , HideCaret , ShowCaret


    Функция ShowCaret

    Функция ShowCaret делает каретку видимой на экране в текущей позиции. После того, как каретка стала видимой, она автоматически начинает мерцать.

    function ShowCaret(
      hWnd: HWND    // дескриптор окна с кареткой
    ): BOOL; stdcall;
    

    Параметры

    hWnd
    Дескриптор окна, которое является владельцем каретки. Если этот параметр равен 0, ShowCaret произведет поиск такого окна в текущей задаче.

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

    В случае успешного завершения функция возвращает True. В случае возникновения ошибки, функция возвращает False. В этом случае для получения расширенной информации об ошибке необходимо сделать вызов функции GetLastError.

    Примечания

    Функция ShowCaret выводит каретку на экран только если указанное окно владеет кареткой, для каретки задана форма и каретка не была скрыта два и более раз. Если одно или несколько из жэтих условий выполнено, то функция ShowCaret не выполнит ничего и вернет значение False.

    Операция скрытия каретов кумулятивна. То есть для того, чтобы отобразить каретку, необходимо сделать в точности столько же вызовов ShowCaret, сколько предшествовало вызовов HideCaret.

    Каретка является общедоступным ресурсом, в системе может боть только одна каретка. Окно должно показывать каретку только если оно активно и имеет фокус ввода.

    Смотри также

    CreateCaret , DestroyCaret , GetCaretPos , HideCaret , SetCaretPos


       Внимание! Запрещается перепечатка данной статьи или ее части без согласования с автором. Если вы хотите разместить эту статью на своем сайте или издать в печатном виде, свяжитесь с автором.
    Автор статьи:  Мистик Домашняя страница автора
      

    Другие статьи Наверх


      Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо