Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 13.09.2015, 19:25
Anthony68 Anthony68 вне форума
Прохожий
 
Регистрация: 26.11.2011
Сообщения: 18
Репутация: 10
По умолчанию Как объявить событие OnMouseWheel для компонента, который его не имеет?

Как объявить событие OnMouseWheel для компонента, который его не имеет?..

Мне необходимо это событие для компонента TDBGridEh (сторонняя библиотека EhLib 7 версии) и для встроенного (в среду Delphi XE7) компонента TSpeedButton.

Как сделать чтобы это событие появилось для этих компонент в Object Inspector?
Ответить с цитированием
  #2  
Старый 13.09.2015, 21:12
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,093
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Сделать свой компонент - наследник от нужного, в нем объявить это свойство, установить новый компонент. И будет тебе счастье.

Вот только вопрос появился. Ну с гридом я еще понимаю, хотя он и так должен отрабатывать скрол мышки, зачем его перегружать не совсем понятно. А вот что ты будешь со скролом делать на кнопке???

ЗЫ. Можно захачить компоненты, если тебе уж так надо сделать это событие, а по полной программе возиться неохота. В object inpector'е оно не появится, но можно будет назначить туда свой обработчик из кода. Делается так:
1. Дизайнишь форму со всеми нужными тебе компонентами.
2. До описания класса формы вставляешь создание класса с таким же именем, наследующимся от стандартного с указанием имени модуля.
3. В этом классе объявляешь все нужные тебе события.
4. В OnCreate формы присваиваешь нужные тебе обработчики.
5. Все работает в рантайме.
Выглядит примерно так (имена наверняка попутал, проверь):
Код:
unit MyFrm;

uses
  ..., StdCtrls, ...;

interface

type
  TSpeedButton=class(StdCtrls.TSpeedButton)
  private
    FMyEvent : TNotifyEvent;
  protected
     procedure DoMyEvent(var Message : TMessage); message WM_MOUSEWEEL;
  public
    property OnMyEvent : TNotifyEvent read FMyEvent write FMyEvent;
  end;

  TMyForm=class(TForm)
    SpeedButton1 : TSpeedButton;
  ...
    procedure FormCreate(Sender : TObject);
  ...
    procedure MyEventHandlet(Stnder : TObject);
  ...
implementation

procedure TSpeedButton.DoMyEvent(var Message : TMessage);
begin
  if Assigned(FMyEvent) Then FMyEvent(Self);
end;

procedure TMyForm.FormCreate(Sender : TObject);
begin
  SpeedButton1.OnMyEvent := MyEventHandler;
end;

procedure TMyForm.MyEventHandler(Sender : TObject);
begin
  ShowMessage('Got event!');
end;

...

Последний раз редактировалось lmikle, 14.09.2015 в 19:18.
Ответить с цитированием
  #3  
Старый 14.09.2015, 11:43
Anthony68 Anthony68 вне форума
Прохожий
 
Регистрация: 26.11.2011
Сообщения: 18
Репутация: 10
По умолчанию

Большое спасибо за ответ!! Чуть позже я напишу вам, для чего нужно событие колеса мышки, это интересная тема... А пока я пробую запустить ваш код и не получается.., а именно - компилятор делает красным строку

Код:
procedure DoMyEvent; message WM_MOUSEWHEEL;
И пишет при этом в информационном окошке: Unit "Vcl.FileCtrl" is specific to a platform
и когда я нажимаю на эту строку-сообщение об ошибке, он перекидывает меня на фрагмент текста, где в секции uses указано (среди многих других) использование модуля FileCtrl.

... И как мне всё это понимать?
Ответить с цитированием
  #4  
Старый 14.09.2015, 12:10
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

через перехват WM_MOUSEWHEEL:

Код:
type
  TButton = class(StdCtrls.TButton)
  private
    FMouseWheelEvent: TNotifyEvent;
  protected
    procedure WMMOUSEWHEEL(var Message: TMessage); message WM_MOUSEWHEEL;
  published
    property OnMouseWheelEvent: TNotifyEvent read FMouseWheelEvent write FMouseWheelEvent;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure MouseWheelEventHandler(Sender: TObject);
  end;
...
{ TButton }

procedure TButton.WMMOUSEWHEEL(var Message: TMessage);
begin
  inherited;
  if Assigned(FMouseWheelEvent) then FMouseWheelEvent(Self);
end;

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  Button1.OnMouseWheelEvent:=MouseWheelEventHandler;
end;

procedure TForm1.MouseWheelEventHandler(Sender: TObject);
begin
  Windows.Beep(1000, 250);
end;

только вот с TSpeedButton проблема - это не окно!!!

Код:
  TSpeedButton = class(Buttons.TSpeedButton)
  public
    procedure MouseWheelHandler(var Message: TMessage); override;
  end;
...
{ TSpeedButton }

procedure TSpeedButton.MouseWheelHandler(var Message: TMessage);
begin
  inherited;
  Windows.Beep(1000, 250);
end;

работает когда на кнопке мышь нажата и крутится колесо.
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #5  
Старый 14.09.2015, 18:09
Anthony68 Anthony68 вне форума
Прохожий
 
Регистрация: 26.11.2011
Сообщения: 18
Репутация: 10
По умолчанию

Спасибо большое!
Присланный вами код работает. Но, есть вот какое затруднение:

Ведь событие вы определили типа TNotyfyEvent; Такое событие содержит только один параметр типа Tobject. А нужное мне событие - OnMouseWheel должно быть типа TMouseWheelEvent, и содержать гораздо больше параметров, которые как раз и нужны мне для обработки...

Так вот, я вставил ваш код в программу (для грида) - всё заработало - при вращении колеса мышки, раздаются звуки... Но мне то нужно как-то перевести это событие в процедуру, с большим количеством параметров! Мне недостаточно передать только Self.

И когда я подставляю в Form.Create вместо
MyGrid.OnMouseWheelEvent:=MouseWheelEventHandler;

строку :
MyGrid.OnMouseWheelEvent:=MyGridMouseWheel;

- то компилятор выдаёт ошибку, что количество параметров не сходится...
Ответить с цитированием
  #6  
Старый 14.09.2015, 18:21
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Код:
type
  TButton = class(StdCtrls.TButton)
  public
    property OnMouseWheel;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure MouseWheelEventHandler(Sender: TObject; Shift: TShiftState;
      WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  end;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
  Button1.OnMouseWheel:=MouseWheelEventHandler;
end;

procedure TForm1.MouseWheelEventHandler(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
  Windows.Beep(1000, 250);
end;
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #7  
Старый 14.09.2015, 19:02
Anthony68 Anthony68 вне форума
Прохожий
 
Регистрация: 26.11.2011
Сообщения: 18
Репутация: 10
По умолчанию

Очень благодарен! Всё теперь заработало.. Скажите, а в какой книге можно прочесть про те способы объявления событий, которые здесь приведены?

Хотелось бы детально понять, как это происходит... А то я скопировал это просто, но сути так и не понял.

И ещё - а можно ли также сделать в компоненте TSpeedButton - это будет работать, также как с TButton?

Меня спрашивали, зачем я меняю эти события, я поясню:

1) Кнопки. Для экономии места на экране на одну кнопку можно кроме самого действия по её нажатию, прицепить какие-либо настройки этого действия. Например, если есть кнопка, выбирающая кисть для рисования, то для пользователя будет удобно выбирать ширину кисти вращением мышки над этой кнопкой, а при нажатии - будет выбрана кисть с этой шириной. Чтобы не запутаться - вращение колеса мышки сопровождается сменой изображения диаметра кисти на этой кнопке.

2) Таблица с текстом или текстовый редактор. Здесь ещё интереснее.
Например, мой грид отображает закладки (на каком-то тексте). Закладки входят в группы, в виде дерева (как в интернет-браузере). И закладок много..., несколько сотен. Пользователю долго их прокручивать, потому что колесо мышки крутит (в стандартном событии) строки таблицы только по одной.
Я делю поле грида (по вертикали, условно) на несколько областей, например 3. Центральное, допустим, занимает 4/6 от ширины площади грида. Левая и правая область - по 1/6 ширины. И когда пользователь вращает колесо мышки, держа указатель около середины грида, он скроллируется построчно. Когда ближе к правому краю - постранично.
А когда около левого края - указатель грида "прыгает" по узлам дерева.

С текстовым редактором такая же история. Листать построчно, или постранично, немного сместив указатель мышки по экрану - очень удобно. Пользователи благодарили меня за эту возможность, вот.
Ответить с цитированием
Этот пользователь сказал Спасибо Anthony68 за это полезное сообщение:
Gareth (05.03.2022)
  #8  
Старый 15.09.2015, 18:29
Anthony68 Anthony68 вне форума
Прохожий
 
Регистрация: 26.11.2011
Сообщения: 18
Репутация: 10
По умолчанию

Последний вариант кода, который работает с гридом, я точно также написал для TSpeedButton. Компилятор ошибки не выдал, но на событие OnMouseWheel компонент TSpeedButton почему то не откликается(

Что не так? Подскажите пожалуйста...
Ответить с цитированием
  #9  
Старый 15.09.2015, 18:35
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,093
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Со SpeedButton есть маленькая проблемка. Как уже говорилось, SpeedButton - это не окно, соответвенно, оно "ловить" сообщения не может. Если все-таки очень хочется прикрутить это сообщение именно к быстрой кнопке, то надо ловить его на родительском компоненте (а то и просто у формы), по координатам мышы вычислять какой компонент находится под ней и, если это нужный компонент, выполнять соотв. действия.
Ответить с цитированием
  #10  
Старый 15.09.2015, 19:35
Anthony68 Anthony68 вне форума
Прохожий
 
Регистрация: 26.11.2011
Сообщения: 18
Репутация: 10
По умолчанию

Спасибо за ответ!
Ответить с цитированием
  #11  
Старый 16.09.2015, 04:36
Anthony68 Anthony68 вне форума
Прохожий
 
Регистрация: 26.11.2011
Сообщения: 18
Репутация: 10
По умолчанию

Всё-таки непонятно, если TSpeedButton не умеет ловить сообщения, то как же тогда эта кнопка отрабатывает стандартное событие OnMouseDown ??..
Ответить с цитированием
  #12  
Старый 16.09.2015, 08:07
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Цитата:
Сообщение от Anthony68
Всё-таки непонятно, если TSpeedButton не умеет ловить сообщения, то как же тогда эта кнопка отрабатывает стандартное событие OnMouseDown ??..
магия VCL
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 17:58.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025