Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

GUI [Delphi, OpenGL]


Страницы:   1 2

К8 ©   (2006-10-05 00:14:00) 

Пытаюсь написить свой GUI (WinAPI+OpenGL), столкнулся с рядом трудностей.
1 создал класс кнопки. Как сделать так, чтобы для каждого экземпляра этого класса можно было создавать свой метод .click?
2 как создать движок в который можно было бы кидать элементы различных классов, а он для каждого из них выполнял методы .draw .click и им подобные?
помогите пожалуйста!
если у кого-то есть исходники, не откозался бы посмотреть.
зарание спасибо.


Cash   (2006-10-10 14:57:00) [1]

Pa5ha ©   (10.10.06 14:31) [25]:
Я на вебфайле себе место держу, ну ни за зря же? :)
Хоть и 4 Kb, но ни к себе же их на сайт складывать? :)


Pa5ha   (2006-10-10 14:31:00) [2]

Ketmar, хочу! -)

Cash, псип, очень познавательно -) Ушел учить матчасть :) Кстати, нашел куда выложить 3 кб -))


Cash   (2006-10-10 08:28:00) [3]

k8   (09.10.06 23:41) [21]:
Посмотри этот бред:
http://www.webfile.ru/1144015

тока что, в порядке отдыха, накидал.
Окромя налаживания связей там ничего нет. Дальше - сам.

Cash ©   (10.10.06 07:50) [23]:
Приписка к скобкам в скобках :)
(эта тихая речь, похожая на ахинею, велась про весь двиг целиком)


Cash   (2006-10-10 07:50:00) [4]

k8   (09.10.06 22:59) [20]:
Ага, ща, тока погоди, я свой двиг в полном составе упакую и тебе намылю! :)
Другими словами, я тебе теорию дал, но то, как я это сделал на практике -
не дам! В течении дня, если желание будет, я тебе левый примерчик
накидаю. С коментариями и пояснениями.

[21]:
Ты не тупой, быть может это я опять все мудачно написал, а может и у
тебя знаний недостаточно для понимания этого текста.

(В любом случае, такие вещи за бесплатно не отдаются. Там не только мои
знания в графике, там знания, доверенные мне от профессоров, доцентов,
докторов технических наук и от одно членкора СО РАН! И я за эти знания
заплатил! Много!)


Ketmar   (2006-10-10 00:18:00) [5]

хочешь мою библиотеку консольного UI на 200 кил исходников? %-) только психотерапевта я тебе оплачивать не буду, так и знай. %-)


k8   (2006-10-09 23:41:00) [6]


> Cash ©   (08.10.06 20:56) [15]

И все же я не вижу ответа на вопрос (наверно я совсем тупой)!
Без примерчика не обойтись :)


k8   (2006-10-09 22:59:00) [7]

to real.
спасибо. почти понял. осталось попробовать реализовать.
to cash.
а на примерчике слабо? :)
попробую прочитать это еще раз, может что пойму. :)
ps
понял что надо глубже копать в сторону ооп и динамической памяти.


Ketmar   (2006-10-09 21:57:00) [8]

>[18] Pa5ha(c) 9-Oct-2006, 21:44
>перекрыть функции родителя? без виртуала.
может. но лишаешься позднего связывания. матчасть учи. она рулит. %-))


Pa5ha   (2006-10-09 21:44:00) [9]

боюсь показаца недалеким, но разве наследник не может перекрыть функции родителя? без виртуала.


@!!ex   (2006-10-09 14:36:00) [10]


> Pa5ha ©   (09.10.06 14:30) [16]

Виртуальные функции - это функции, которые можно перекрывать.

Делаем класс Button с фенкцией Draw.
Делаем наследника CoolButton от Button, Хотим свой Draw.
Вот для этого и нужен virtual.
Ну и в полностью абстрактных классах без виртуальных методов вообще не обойтись... Потому что все методы там виртуальные. :)


Pa5ha   (2006-10-09 14:30:00) [11]

Давно хотел спросить зачем нужны виртуальные функции и какой прок от их виртуальности? Почему они не могут быть обычными, не виртуальными.


Cash   (2006-10-08 20:56:00) [12]

(Внимание! Перед прочтением настоятельно рекомендовано ознакомиться с
базовыми классами среды Object Pascal (Delphi)) ^^.

> тогда точно не понял. как можно в один список похать элементы
> различных классов?


Создаешь класс-контейнер, в нем располагаешь экземпляр класса TList,
это и будет сам контейнер контролов. Этот класс-контейнер пишешь в
отдельном от всех контролов модуле. В самом классе предусматриваешь
два базовых метода - метод, регистрирующий контрол,
и метод - снимающий регистрацию.
Эти два метода упаковываешь в области Protected класс-контейнера.
Само собой, регистрация - это занесение указателя в контейнер, а снятие
регистрации - удаление этого указателя.
Далее в класс-контейнере создаешь еще два метода, 1: DrawControls,
2: ProcessControls. Первый будет проходить по контролам и рисовать их,
а второй - будет давать каждому контролу пожить своей жизнью.

Про обработку мыши и клавиатуры не скажу, т. к. точно не знаю что нужо.
(ляпну еще чего не то...)

Так, с главным классом GUI покончено, теперь надо о контролах позаботиться!

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

Все контролы наследуешь от этого Про-класса.

Вороде объяснил не понятно. :))) Я старался! :)


Rial   (2006-10-08 15:35:00) [13]

> [13] К8   (07.10.06 22:23)
> to real.
> тогда точно не понял. как можно в один список похать элементы
> различных классов? поясни


Я там вообще без классов обошелся. %)
А по сути дела, есть два выхода.

1 Способ.

TBaseClass = Class(TObject)
public
 constructor Create;
 destructor Destroy; override;
 ...
 procedure Draw; virtual; abstract;
end;

TLabel = Class(TBaseClass)
public
 procedure Draw; override;
end;

...

procedure TLabel.Draw;
begin
...
pElement.Draw;
...
end;

И, соответственно, деаешь так:

procedure TEngine.Add(Const Element : TBaseClass);
begin
...
end;

...
Engine.Add(Label1);
Engine.Add(Button2);
...

2 Способ. Нехороший, но имеет право на жизнь.

Type
TLabel = Class(TObject)
 ...
end;
TButton = Clas(TObject)
 ...
end;

Const
nidLabel  = $00;
nidButton = $01;

1.1

procedure TEngine.Add(Const Element : TObject; Const Id : Integer);
begin
...
pElement.Link := Element;
pElement.Id   := Id;
...
end;

...
Engine.Add(TObject(Label1), nidLabel);
Engine.Add(TObject(Button2), nidButton);
...

1.2
procedure TEngine.Add(Const Element : TObject);
begin
...
pElement.Link := Element;
If (Element is TLabel)then
 pElement.Id   := nidLabel
  else
   If (Element is TButton)then
    pElement.Id   := nidButton
...
end;

...
Engine.Add(TObject(Label1));
Engine.Add(TObject(Button2));
...

Отображение:

procedure TEngine.Draw;
begin
...
Case Id of
 nidLabel   : (pElement.Link as TLabel).Draw;
 nidButton  : (pElement.Link as TButton).Draw;
end;
end;

Но за такое бьют больно по рукам, поэтому не советую. %)


К8   (2006-10-07 22:23:00) [14]

to real.
тогда точно не понял. как можно в один список похать элементы различных классов? поясни
to fosgen
спасибо, разберемся.


Fosgen   (2006-10-06 10:11:00) [15]

 TGLWidget = class  //базовый класс
 private
   FMinimized: Boolean;
 protected
   procedure SetMinimized(const val : Boolean);
 public
   Parent: ^TGLWidget;
   Group: Byte;
   Active, Damaged, Busy: Boolean;
   NumWindow: Byte;
   IndexOf: Byte;
   IndexN: Integer;
   FColor: TColor;
   FontColor: TCOlor;
   fSprite: THUDSprite;//спрайт самого объекта
   Textures: array [0..3] of string;
   ObjectLink: Pointer;  //link to controlled object
   ObjectType: Byte;   //type of the controlled object
   ChildWidget: array of ^TGLWidget; //array of child interface components
   ChildCount: Byte;
   ChildIndex: Byte;
published
   property Minimized: Boolean read FMinimized write SetMinimized;
   function ClickTest(wX, wY: Integer): Boolean; virtual; abstract;
   constructor Create(AOwner: TGLBaseSceneObject; bX, bY, bWidth, bHeight: Single);
   destructor Destroy; override;
 end;

 PGLWidget = ^TGLWidget;
 TGLNotify = procedure(Sender: TGLWidget; EventCode: Byte) of object;//тип обработчика и проперти

 TGLClickWidget = class(TGLWidget)//потомок, имеющий обработчик события
 private
 public
     Event: Byte;
     FonClick: TGLNotify;
 published
   property onClick: TGLNotify read FonClick write FonClick;//та самая проперть
 end;


Ну и потом в другом модуле:

procedure TCockpit.CreateAssignEventHandlers;
var
I: Integer;
MP: Pointer;
Met: TMethod;
CurrentItem: TGLClickWidget;
begin
for I := Low(GUI.WidgetItems) to High (GUI.WidgetItems) do
begin
  CurrentItem:=GUI.WidgetItems[I] as TGLClickWidget; //перебираем все элементы текущего интерфейса
  MP := MethodAddress(HUDCommands[CurrentItem.Event]);//ссылка на массив, содержащий адреса обработчиков
  Met.Code := MP;
  Met.Data := Self;
  CurrentItem.onClick := TGLNotify(Met);//присвоение обработчика
end;
end;


Не претендую на оптимальную реализацию, но как пример - думаю можно разобраться.


@!!ex   (2006-10-06 08:46:00) [16]


> Rial ©   (06.10.06 04:32) [10]

Не ожидал, что кто-то еще пишет без ООП....


Rial   (2006-10-06 04:32:00) [17]

> [8] К8   (05.10.06 23:00)
> to Real.
> Как я понял, внутри движка для каждого класса  (а таких штук 10) придется организовывать свой список.

Понял неверно.
Есть один общий движок, назовем ео TEngine.
А есть набор его элементов, как то TGLButton TGLLabel и т.п.
Так вот список будет именно один, т.к. экземпляр TEngine нужен один.
А без списка не обойтись, т.к. движок должен о всех своих
элементах знать.
Массив не рекумендую, т.к. не получится тогда быстрого удаления
и добавления элементов.

Вот часть исходников моего движка меню:
http://www.Rial578.narod.ru/source/menu.rar

Компилироваться не будет, т.к. исходники движка OpenGL
и менеджера памяти я тебе не дам :)
Но принцип поймешь, если захочешь.
Правда, там подход не классовый.


Ketmar   (2006-10-05 23:33:00) [18]

>[8] К8 5-Oct-2006, 23:00
>Жаль с примерами gui напряжно :(
Ян Хорн -- это наше всё!


К8   (2006-10-05 23:00:00) [19]

to Real.
Как я понял, внутри движка для каждого класса (а таких штук 10) придется организовывать свой список. А нельзя ли в один?
to Fosgen.
Пока не догнал, но думается это то что надо. Был бы счастлив если пояснил это на примере. А так попробую разобраться.
Всем спасибо! Жаль с примерами gui напряжно :(


Cash   (2006-10-05 14:50:00) [20]

Fosgen   (05.10.06 14:18) [6]:
Гы! :)
А чел пишет: "... этого класса можно было создавать свой метод .click?".

Я и думал после его ответа перенаправить его взор не на методы, а на
события.
Но вы, дорогой товарищь, меня опередили... :)


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо