![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
GUI [Delphi, OpenGL]
К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?".
Я и думал после его ответа перенаправить его взор не на методы, а на
события.
Но вы, дорогой товарищь, меня опередили... :)