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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Менеджер сообщений, Обработка мыши, клавиатуры, и т.п 
V
    Опции темы
C4Grey
Дата 26.8.2010, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Доброго времени суток. Появилась необходимость создать менеджер, обрабатывающий сообщения типа клика мышки, нажатия кнопки клавиатуры и т.п. Нужно это для OpenGL-приложения и реализации GUI в нем. Как работают messages, шарю очень слабо, потому два вопроса :
1. Что должен иметь мой класс для перехвата сообщений, помимо методов-распаковщиков сообщений типа     
procedure WMMButtonDown(var Message: TWMMButtonDown); message WM_MBUTTONDOWN; ?
2. Можно ли осуществлять перехват сообщений несколькими "контролами", то есть моим классом(он вообще-то наследуется от TCоmponent) и, скажем, формой?

Это сообщение отредактировал(а) C4Grey - 26.8.2010, 15:19
PM MAIL   Вверх
cat512
Дата 26.8.2010, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(C4Grey @ 26.8.2010,  15:13)
Доброго времени суток. Появилась необходимость создать менеджер, обрабатывающий сообщения типа клика мышки, нажатия кнопки клавиатуры и т.п. Нужно это для OpenGL-приложения и реализации GUI в нем. Как работают messages, шарю очень слабо, потому два вопроса :
1. Что должен иметь мой класс для перехвата сообщений, помимо методов-распаковщиков сообщений типа     
procedure WMMButtonDown(var Message: TWMMButtonDown); message WM_MBUTTONDOWN; ?
2. Можно ли осуществлять перехват сообщений несколькими "контролами", то есть моим классом(он вообще-то наследуется от TCоmponent) и, скажем, формой?

По конкретней вопросы формулировать можно? Или надо всё вытягивать? Обязанности какие мэнэджер должен выполнять?

Добавлено через 10 минут и 32 секунды
Гуй ты будешь рисовать на OpenGL?
PM MAIL   Вверх
C4Grey
Дата 26.8.2010, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



2cat512
Перехватывает сообщения, рассылает клиентам, определяя активные слои елементов GUI. Сообщения для елементов GUI передаются в виде выполнения метода DispatchEvent, который активирует определенное событие, при его наличии, проверяет определенные флаги...но это уже архитектура OpenGL-части, и к вопросу отношения прямого не имеет. Соответсвенно, в теле метода WMMButtonDown, для примера, будет выполнен DispatchEvent с соответсвующим аргументом, который отвечает за тип события. По идее, там может быть любой код, вплоть до банального вывода сообщения.
Соответственно, если я просто напишу класс, добавлю к нему только методы обработки событий, создам экземпляр, и т.д., при клике на форму будет обрабатыватся метод клика формы, но не метод менеджера. Надеюсь, немного прояснил ситуацию. Извиняюсь, что спрашиваю такие примитивные вещи, но сложно сформулировать правильный поисковый запрос, слишком много информации не по теме нахожу.
PM MAIL   Вверх
cat512
Дата 26.8.2010, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Если я правильно догадываюсь (если не правильно - поправь), Менеджер сообщений будет неким брокером, который будет получать сообщения из винловой очереди и отсылать их неким граф. объектам
реализующих поведение обычных VCL-контролов управления, но таковыми не являющимися?
PM MAIL   Вверх
cat512
Дата 26.8.2010, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Понятно. Начнём с простого. Рассказываю, о самом принципе, потом можешь его усложнять. 
В программе, использующей Vcl, есть основной поток управления,
в котором осуществляется диспетчеризация сообщений.
Основной объект осуществ. диспетчеризацию - Application.
Application - реализует цикл выборки сообщений. Цикл находится в методе ProcessMessage(Msg) ;
Цикл упрощённо выглядит примерно так:
//Хотя там вместо GetMessage - PeekMessage, и много ещё чего.
Код

  While GetMessage() do
  begin
     TranslateMessage(Msg);
     DispatchMessage(Msg);
   end;
  
Соответственно тебе надо вклиниться до DispatchMessage. После DispatchMessage, сообщение уходит конкретному контролу и продолжает обрабатываться там.
Чтобы вклиниться в цикл сообщений есть три варианта;
1.Либо написать свой цикл с нуля (Возможно бы я выбрал этот вариант, всё зависит от сложности системы)

2 Сделать потомка TAppliaction.
тогда нужно
A. Ввести новый метод ProcessMessage(Msg), обрабатывая только сообщения от мыши и клавы.
Б.Добавить метод диспетчеризаци Dispatch для OpenGL;
В. Сделать вызов Из ProcessMessage метода Dispatch.

3. Использовать Application.OnMessage.
У Объекта Application есть свойство - OnMessage, типа указатель на метод. Ты можешь использовать его, в своём Мэнеджере примерно так:
Код

Type 
//Заглушка события для OpenGl
//ХОРОШО БЫ СДЕЛАТЬ TOpenGLEvent - С УПРАВЛЯЕМЫМ ВРЕМЕНЕМ ЖИЗНИ. ИСПОЛЬЗУЯ TIntarfacedObject и ПОДДЕРЖКОЙ ИНТЕРФЕЙСОВ СОБЫТИЙ.
  TOpenGlEvent = class

  end;
  TKeyOpenGLEvent = class(TOpenGlEvent)

  end;

  TMouseOpenGLEvent = class(TOpenGlEvent)

  end;

  TMessageDispatcher = class
  private
     FApplication : TApplication;
     procedure HookMessages(var Msg: TMsg; var Handled: Boolean);
  public
    procedure Dispatch(Event: TOpenGlEvent);
    Constructor Create(A: TApplication);
    Destructor Destroy;override;  
  end;
implementation
constructor TMessageDispatcher.Create(A: TApplication);
begin
  FApplication := A;
  FApplication.OnMessage := HookMessages;
end;

destructor TMessageDispatcher.Destroy;
begin
  FApplication.OnMessage := nil;
end;

procedure Dispatch(Event: TOpenGlEvent);
Begin
//логика диспетчеризации
end;

procedure TMessageDispatcher.HookMessages(var Msg: TMsg; var Handled: Boolean);
var
  Event: TOpenGlEvent
begin
// что бы сообщения не обрабатывались дальше
  Handled := true;
//Сдесь у тебя все сообщения посылаемые окну приложения.
  Case Msg of
//Сообщения от клавы.
    WM_KEYFIRST..WM_KEYLAST: 
    Begin
      //Создаём событие OpenGl для клавы
      Event := TKeyOpenGLEvent.Create;
    end;
    WM_LBUTTONDOWN, WM_RBUTTONDOWN:
    Begin
      //Создаём событие OpenGl для мыши
      Event := TMouseOpenGLEvent.Create;
    End;
  end;
      //Диспетчиризируем его в OPENGL
   Dispatch(Event);
end;

Ещё бы ситуацию немного прояснило реализация Гуя в OpenGL  Если у тебя объекты гуи реализованные от TObject то можно виндовые сообщения не транслировать в события OPENGL, а отсылать как есть. Ну это уже к другой теме относится.


Это сообщение отредактировал(а) cat512 - 26.8.2010, 23:57
PM MAIL   Вверх
C4Grey
Дата 27.8.2010, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Большое спасибо за развернутый ответ, заодно и с теорией разобрался немного, в общем - очень помог. Сегодня-завтра попробую третий вариант - он мне как раз подходит, отпишусь еще.
PM MAIL   Вверх
C4Grey
Дата 7.11.2010, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Зашел на форум, случайно кликнул на профиль и вспомнил, что обещал отписатся :( . Извиняюсь, вылетело начисто с головы. В общем, как и говорил, выбрал 3 вариант, работает отлично, учитывая что к проекту могут подключатся моудли, использующие сообщения, приходящие форме - Handled выставляю в False и все отлично работает. Сделал установку глобального состояния кнопок мыши, координат и т.п. Экземпляры классов событий на ходу не создаются - так как события обрабатываются "в порядке очереди" smile - создл класс менеджера событий, который хранит по экземпляру на каждое заранее известное событие мыши, он хранит "слушателей", которые знают, какому контролу они принадлежат. Создание событий во время работы программы, особенно при перехвате WM_MOUSEMOVE тормозило программу, потому и пришлось немного похитрить. Но в итоге все работает, пользователь свободно может добавлять любые события, сам создавать типы событий и т.п. Выбор пользовательских событий, конечно работает по принципу банального поиска в списке и сравнения строк - но тут уж ничего не поделашь :( . 
P.S. Еще раз спасибо, тема, IMHO, закрыта smile
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.4864 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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