Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как отключить "перехват" событий контролами? 
:(
    Опции темы
AnTeml
Дата 2.10.2012, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 19.3.2009

Репутация: нет
Всего: нет



Здравствуйте!

Наверное, задам глупейший вопрос, хотел даже в раздел для новичков написать, но это всё же ближе к винапи smile

Есть форма, на ней контролы  конкретно - TImage. Создаю их димамически, но не суть.

для формы задана реакция на OnMouseMove, MouseDown/Up ну и ещё на кучу событий

и что получается, когда мышь находится над дочерним контролом - есс-но, событие OnMouseMove формы не возникает, а отрабатывает одноимённое событие контрола

а мне нужно обработать событие в обработчике формы!

Пока сделал следующим образом, для всех контролов назначаю события, делегирующие отработку в событие формы, типа того:


Код

procedure TfmMain.img_1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  MouseMove(Shift, X + (Sender as TControl).Left, Y + (Sender as TControl).Top);
end;



но как-то некрасиво это. Может, я чего-то упустил, быть может, можно отключить перехват событий дочерними контролами?
PM MAIL   Вверх
bems
Дата 2.10.2012, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



сделай форме обработчик WM_MOUSEMOVE


--------------------
Обижено школьников: 8
PM MAIL   Вверх
AnTeml
Дата 3.10.2012, 03:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 19.3.2009

Репутация: нет
Всего: нет



дак это... та же байда, даже попробовал - как только заезжаешь на родительский контрол, так всё... мессажи идут ему, т.е. в пустоту..

видимо, тут вопрос не столько делфи, сколько винапи, причём, насколько понимаю, вопрос по базовым понятиям диспетчирования событий венды

Это сообщение отредактировал(а) AnTeml - 3.10.2012, 03:48
PM MAIL   Вверх
bems
Дата 3.10.2012, 03:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



тут две вещи:
1) если мышь над дочерним контролом - наследником TGraphicControl (как например TImage про который ты говорил) то форма получает виндовое сообщение, но генерирует из него событие для дочернего контрола. Тут применим мой первый совет
2) если мышь над дочерним контролом - наследником TWinControl (как все контролы, которые могут быть родительскими для других) то винда шлет сообщение сразу в окно этого контрола. И тут пожалуй можно использовать хуки

Добавлено через 11 минут и 29 секунд
Щас проверил, обработчик сообщения должен быть именно в перекрытой процедуре WndProc
а message-метод вызывается слишком поздно. наверное поэтому и была "та же байда"


--------------------
Обижено школьников: 8
PM MAIL   Вверх
AnTeml
Дата 3.10.2012, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 19.3.2009

Репутация: нет
Всего: нет



Спасибо! немного понятнее стало. Нет, хуками я пользоваться не буду. Напишу процедурку, переберу все контролы на форме и перебью им OnMouseMove и пр так, чтобы в вызов отправляли обратно в соответствующие обработчики формы smile

походу дела, это оказывается самым красивым решением smile)) и без привязки к винапи, всё через дельфовые обёртки, т.е. глючить вроде не должно при практически любых перспективах

Это сообщение отредактировал(а) AnTeml - 3.10.2012, 12:38
PM MAIL   Вверх
AnTeml
Дата 3.10.2012, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 19.3.2009

Репутация: нет
Всего: нет



Нет, это просто кошмар какой-то! smile

Сначала начиналось всё хорошо.... Меня интересуют только события мыши, точнее три этих события, которые покрываю, по-моему, все "мышиные" задачи:

Код

procedure TfmMain.DelegateReturn_MouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  MouseUp(Button, Shift, X + (Sender as TControl).Left, Y + (Sender as TControl).Top);
end;

procedure TfmMain.DelegateReturn_MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  MouseDown(Button, Shift, X + (Sender as TControl).Left, Y + (Sender as TControl).Top);
end;

procedure TfmMain.DelegateReturn_MouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
  MouseMove(Shift, X + (Sender as TControl).Left, Y + (Sender as TControl).Top);
end;


По какой-то неведомой мне причине, все события у TControl-ов засунуты в protected секцию! 
предположу, что это потому, что наборы событий у различных наследником разный. Потому просто так пробежаться по Components, устанавливая им соответствующие события, не получилось, - приходится вручную перебирать все возможные типы :(

Код
procedure TfmMain.SetDelegateReturnMousesEvents;
var i: integer; CurrComponent: TComponent;
begin
  for i := 0 to ComponentCount - 1 do
  begin
    CurrComponent := Components[i];
    if CurrComponent is TImage then
    begin
      (CurrComponent as TImage).OnMouseDown := DelegateReturn_MouseDown;
      (CurrComponent as TImage).OnMouseUp := DelegateReturn_MouseUp;
      (CurrComponent as TImage).OnMouseMove := DelegateReturn_MouseMove;
    end
    else if CurrComponent is TButton then
    begin
      (CurrComponent as TButton).OnMouseDown := DelegateReturn_MouseDown;
      (CurrComponent as TButton).OnMouseUp := DelegateReturn_MouseUp;
      (CurrComponent as TButton).OnMouseMove := DelegateReturn_MouseMove;
    end
    else if CurrComponent is TCheckBox then
    begin
      (CurrComponent as TCheckBox).OnMouseDown := DelegateReturn_MouseDown;
      (CurrComponent as TCheckBox).OnMouseUp := DelegateReturn_MouseUp;
      (CurrComponent as TCheckBox).OnMouseMove := DelegateReturn_MouseMove;
    end
    ....

  end;

end;


всё работает на ура, но это же полный трындец!

вот и закончилась идея о "красоте"... на досуге почитаю о хуках...
PM MAIL   Вверх
bems
Дата 3.10.2012, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



с RTTI было бы красивее. Там можно установить свойство по имени


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Gwire
Дата 4.10.2012, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 216
Регистрация: 7.8.2007
Где: Николаев

Репутация: 1
Всего: 4



Код

type
  TFishrodEvent = class(TControl)
  published
    property Color; // просто для примера
    property OnMouseDown;
    property OnMouseUp;
    property OnMouseMove;
  end;


Код

begin
  for i := 0 to ComponentCount - 1 do
  begin
    CurrComponent := Components[i];
    TFishrodEvent(CurrComponent).Color:= clRed;
    TFishrodEvent(CurrComponent).OnMouseDown := DelegateReturn_MouseDown;
    TFishrodEvent(CurrComponent).OnMouseUp := DelegateReturn_MouseUp;
    TFishrodEvent(CurrComponent).OnMouseMove := DelegateReturn_MouseMove;
  end



Для установки атрибутов можно использовать такой способ
Код

uses TypInfo;
// . . .
begin
  for i := 0 to ComponentCount - 1 do
  begin
    CurrComponent := Components[i];
    if IsPublishedProp(CurrComponent, 'Color') then SetOrdProp(CurrComponent, 'Color', clRed);
    // Как установить property типа OnMouseDown этим способом - не понял
    // Можешь посмотреть другие TypInfo.Set..(); может разберешься, что это за процедура.
  end


Так-как SizeOf(TMouseEvent)=8 (64bit) может SetInt64Prop подойдет.
Как-то типа 
Код

var MD, MU: TMouseEvent;
    MM: TMouseMoveEvent;
begin
    MD:= DelegateReturn_MouseDown;
    SetInt64Prop( CurrComponent, 'OnMouseDown', Int64(@MD) );


PS: B да результаты в студию. Интересно же, прокатит SetInt64Prop или нет.

Это сообщение отредактировал(а) Gwire - 4.10.2012, 12:18
PM MAIL   Вверх
Gwire
Дата 4.10.2012, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 216
Регистрация: 7.8.2007
Где: Николаев

Репутация: 1
Всего: 4



И вот еще. Если у тебя есть TImage который ты используешь просто для красоты у него можно Enabled := True, тогда все события "останутся на форме".
PM MAIL   Вверх
AnTeml
Дата 13.10.2012, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 19.3.2009

Репутация: нет
Всего: нет



Прошу прощения! Завалило работой. Вот, кое как разгрёбся, возвращаюсь к моему прожекту.

Спасибо за ответы! , но.. папунктам

Код

TFishrodEvent(CurrComponent).OnMouseDown := DelegateReturn_MouseDown;
Invalid class typecast.

так что до установки атрибутов не дошёл :(

Цитата

И вот еще. Если у тебя есть TImage который ты используешь просто для красоты у него можно Enabled := True, тогда все события "останутся на форме".
от блин smile работает!

Да, у меня TImage для виду, просто чтобы было куда картинку загрузить. А какие могут быть подводные камни, если я его заенаблю в офф?



Вообще, цель такая. Пишу игру для ребёнка, все объекты на экране - разные карточки-картинки, которые, собс-но, по сценарию можно таскать с одного места в другое, некоторые не таскаются, а играют роль кнопок. в общем, обрабатывается всего три события мыши.

Карточек много. Решил по максимуму отвязаться от VCL, сам организую менеджер картинок, определяю, над кем мышь. Однако, чтобы не париться с перерисовкой картинки, для каждой карточки решил использовать свой TImage. Креатю их списком для каждой "комнаты" или как это назвать, собрался двигать, затем уничтожить.

Может, по ходу дела появятся какие-нибудь более остроумные идеи реализации? Очень бы помогло!
PM MAIL   Вверх
Gwire
Дата 26.10.2012, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 216
Регистрация: 7.8.2007
Где: Николаев

Репутация: 1
Всего: 4



Если тягать картинки нужно так тебе вообще достаточно только событие мышей на TImage-ах обрабатывать. 
Размещаешь их в рабочей области (на TPanel) и ловишь на них эти 3 события. 
Код

var
  MousePress : Boolean;
  MousePressPos : TPoint;

procedure TMainForm.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
    with TImage(Sender) do
    begin
        BringToFront;
        MousePress:= True;
        MousePressPos:= Point(X, Y);
    end;
end;

procedure TMainForm.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin 
    if MousePress and
       (X <> MousePressPos.X) and
       (Y <> MousePressPos.Y) then
    with TImage(Sender) do
    begin
        // Расчет новой позиции
        Left:= Left + X - MousePressPos.X;
        Top:= Top + Y - MousePressPos.Y;

        // Дискретность перемещения
        Left:= Left div 16 * 16;
        Top:= Top div 16 * 16;

        // Не перемещать за граници
        if Left < 0 then Left := 0;
        if Top < 0 then Top := 0;
        if Left > Parent.ClientWidth-Width then Left := Parent.ClientWidth-Width;
        if Top > Parent.ClientHeight-Height then Top := Parent.ClientHeight-Height;
    end;
end;

procedure TMainForm.Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin 
    MousePress:= False;
end;

MousePress, MousePressPos можно объявить в классе формы

//-----------------------------------------------------

А если нужно перемещать только по горизонтали или вертикали комментируй в Image1MouseMove все для Left или Top

Это сообщение отредактировал(а) Gwire - 26.10.2012, 17:45
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

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

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0521 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.