Блог Александра Божко
Архивы
Рубрики
Поделись с другими!
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

Проблема, с которой столкнулся лично, и решение которой нашел тут, среди прочих полезных советов.

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

TCommonCustomForm = class(TFmxObject, IRoot, IContainerObject, IAlignRoot)

public
 constructor Create(AOwner: TComponent); override;
 constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); virtual;
 destructor Destroy; override;
 procedure InitializeNewForm; virtual;
 procedure AfterConstruction; override;
 procedure BeforeDestruction; override;
 procedure AddObject(AObject: TFmxObject); override;
 { children }
 function ObjectAtPoint(P: TPointF): IControl; virtual;
 { called from Platform }
 procedure SetMarkedText(const AMarkedText: string); virtual;
 procedure PaintRects(const UpdateRects: array of TRectF); virtual;
 procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single); virtual;
 procedure MouseMove(Shift: TShiftState; X, Y: Single); virtual;
 procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single); virtual;
 procedure MouseWheel(Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean); virtual;
 procedure MouseLeave; virtual;
 procedure KeyDown(var Key: Word; var KeyChar: System.WideChar; Shift: TShiftState); virtual;
 procedure KeyUp(var Key: Word; var KeyChar: System.WideChar; Shift: TShiftState); virtual;
 function GetImeWindowRect: TRectF; virtual;
 procedure Activate;
 procedure Deactivate;
 procedure DragEnter(const Data: TDragObject; const Point: TPointF); virtual;
 procedure DragOver(const Data: TDragObject; const Point: TPointF; var Accept: Boolean); virtual;
 procedure DragDrop(const Data: TDragObject; const Point: TPointF); virtual;
 procedure DragLeave; virtual;
 procedure EnterMenuLoop;

Мы можем просто переопределить событие для нашей формы. Примерно так:

type
  TForm1 = class(TForm)
    Memo1: TMemo;
  private
  public
    procedure KeyDown(var Key: Word; var KeyChar: Char; Shift:
TShiftState); override;
  end;

//...

procedure TForm1.KeyDown(var Key: Word; var KeyChar: Char; Shift:
TShiftState);
begin
  if Key = vkEscape then
    Close
  else
    inherited;
end;

Таким образом, мы научили нашу FireMonkey форму реагировать на нажатие клавиш.

Слегка настораживает только то, почему эти события не опубликованы в FireMonkey форме по умолчанию. У меня есть соображения на данный счет, но пока я их излагать не стану. Будет о чем поговорить в комментариях :).

fmmacos

Под MAC OS это тоже работает (cпасибо Всеволоду Леонову за помощь).

Другие статьи серии:

FireMonkey. Tips & Tricks #0
FireMonkey. Tips & Tricks #1
FireMonkey. Tips & Tricks #3
FireMonkey. Tips & Tricks #4


Поделись с другими!
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

17 комментариев: FireMonkey. Tips & Tricks #2 (Upd2)

  • Столкнулся с такой же непоняткой, только при работе с FMX.TreeView – у самого дерева события пашут, каждый узел имеет тучу событий в Инспекторе…а ни одно событие не пашет :( Неудобно.

  • Много где такой подход — нормальная практика. Это всего-лишь отход от традиций VCL, не более.

    • Возможно и так. Но “отход от традиций VCL” в Delphi немного тревожит. В том плане, что для Delphi разработчика это все-равно кажется не логичным, и начинаешь искать эту самую логику.
      Я думал сначала, что это событие “плохо обрабатывается” под другими ОС. Нет. Все нормально.
      Если так, то тогда, вероятно, это просто “приближение к нормальным практикам в других языках/библиотеках”

  • что то я не понял чутка (сейчас под рукой делфей нету с фмх).

    хотите сказать что в родительском KeyDown нет кода вида:
    if assigned(FOnKeyDown) then FOnKeyDown(….) ?

    или оно просто в инспекторе объектов не видно? если не видно, то надо в OnCreate формы задавать onKeyDown = KeyDown

    • Он не Published и в инспекторе его нет, соответственно. Там всего 9 событий

      • а зачем тогда перекрытие метода, а не назначение обработчика события в OnCreate?
        система событий к этому предрасполагает по идее то.

        зы: а Published от TControl можно понизить до Public в TForm ?
        компоненты как не разрабатываю дак че то и не в курсе.
        по идее то в TControl это должно быть все в секции public, а конечных классах, все нужные свойства, которые надо вытаскивать в инспектор перекидываются в published? ну т.е VCL то на таком принципе построен.
        все TCustom компоенты имеют свойства в protected/public а разработчик конечного класса решает которые должны быть видны, и повышает область видимости до public/published.
        а тут получается как то наоборот, в родителе они published а в наследнике выходит public, т.е еще каким то образом область видимости снижена, хотя по идее public и published равнозначны сами по себе, и скорее всего их можно менять местами безобидно.

        • На Delphi 5 можно было скрыть published-свойство из Инспектора, если я понял о чём вы.

          Нужно было зарегистрировать нестандартный редактор свойств со значение nil

          Наверное и в XE2 можно скрыть, тоьлко зачем в данном контексте ?

  • Добрался до дому посмотрел на FMX, у меня установлен апдейт-1.
    с этого начинаются расхождения со статьей.
    цепочка наследования у TForm не такая. он не наследуется от TControl.

    TForm = class(TCustomForm)
    TCustomForm = class(TCommonCustomForm, …)
    TCommonCustomForm = class(TFmxObject, …)
    ни один и перечисленных классов свойства OnKeyDown/Up не имеет.
    но TCommonCustomForm имеет такие методы для обработки. Так что видимо перекрытие методов является единственным решением.

    Имхо через пару апдейтов эту ситуацию допилят, и объекты будут пополняться новыми событиями.

  • Хм-м, а что за сообщение на рисунке? Код нажатой кнопки? Не видно :)

  • Я так понимаю этот “геморой” с событиями сделан для того чтобы пересадить всех на новый “подход” ЛайвБиндинг (Как в WPF.net ДатаБиндинг). Или для чего это было сделано? (я думаю врят ли ответ: забыли)

  • А вы еще не пробовали шрифт изменить в FMX.TStringGrid! Вот там то точно приключения с нырянием в код))

Ответить на Юрий Отмена ответа

Ваш email не будет опубликован. Обязательные поля отмечены *

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Продукты DevArt
Купить онлайн:



Читай русскоязычные Delphi блоги
Каталог блогов Blogdir.ru
Яндекс.Метрика