Заметки
MaskEdit – прокачка функции Delete

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: MVP ::

:: RSS ::

Яндекс.Метрика


А что, собственно, не так с Delete у MaskEdit, и зачем ее прокачивать? Чтобы лучше понять суть этого вопроса, рассмотрим ближайший аналог MaskEdit – компонент Edit, и его реакцию на нажатие клавиш Backspace и Delete.

При нажатии Backspace текст удаляется слева от курсора до тех пор, пока не будет удален полностью (до начала строки), или пока кнопка не будет отпущена. При нажатии Delete текст удаляется справа от курсора до конца строки, или пока не будет отпущена кнопка.

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

Именно таким компонентом является MaskEdit. Почему описанная выше логика реализована в нем не в полной мере, для меня остается очень большой загадкой (поэкспериментируйте с кнопкой Delete). Тем более что весь необходимый для этого функционал в компонент заложен! Я имею ввиду процедуру CursorInc (парная ей процедура CursorDec используется при обработке нажатия кнопки Backspace).

Как бы то ни было, проблема обозначена и надо ее решать.

unit overMaskEdit;

interface

uses
  Winapi.Windows, System.Classes, Vcl.Mask, System.MaskUtils;

type
  TMaskEdit = class(Vcl.Mask.TMaskEdit)
  private
    procedure CursorInc(CursorPos: Integer; Incr: Integer);
  protected
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  end;

implementation

{ TMaskEdit }

procedure TMaskEdit.CursorInc(CursorPos, Incr: Integer);
var
  NuPos: Integer;
begin
   NuPos := CursorPos + Incr;
   NuPos := GetNextEditChar(NuPos);
   if IsLiteralChar(EditMask, nuPos) then
      NuPos := CursorPos;
   SetCursor(NuPos);
end;

procedure TMaskEdit.KeyDown(var Key: Word; Shift: TShiftState);
var
  SelStart, SelStop: Integer;
begin
   if (Key = VK_DELETE) and not (ssAlt in Shift) then
   begin
      if ReadOnly then
         Exit;

      GetSel(SelStart, SelStop);
      if SelStop <= Length(EditText) then
      begin
         inherited;
         Key := 0;
         if SelStop - SelStart <= 1 then
            CursorInc(SelStart, 1)
         else
            CursorInc(SelStop-1, 1);
      end;
   end;

   inherited;
end;

end.

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

А у меня на этом все, успехов в программировании!

.: Пример к данной заметке :.


При использовании материала - ссылка на сайт обязательна