Текущий архив: 2007.09.16;
Скачать: CL | DM;
ВнизGUI Найти похожие ветки
← →
К8 (2006-10-05 00:14) [0]Пытаюсь написить свой GUI (WinAPI+OpenGL), столкнулся с рядом трудностей.
1 создал класс кнопки. Как сделать так, чтобы для каждого экземпляра этого класса можно было создавать свой метод .click?
2 как создать движок в который можно было бы кидать элементы различных классов, а он для каждого из них выполнял методы .draw .click и им подобные?
помогите пожалуйста!
если у кого-то есть исходники, не откозался бы посмотреть.
зарание спасибо.
← →
Ketmar © (2006-10-05 00:16) [1]собственно, а чем не устраивает подход VCL? исходники -- в любой пиратское Delphi или в честной TurboDelphi. %-)
← →
Rial © (2006-10-05 11:32) [2]Создаешь движок, в который добавляешь каждый из новых элементов.
MyBtn:=TGLButton.Create;
Engine.AddButton(MyBtn);
Все события обрабатываются в Engine, в зависимости от ситуации
вызываются соотв. методы элементов.
Например, есть
With MyBtn do
begin
Left:=10;
Top :=20;
With:=30;
Height:=40;
Frame:=1; - окно
end;
Engine.Frame:=2;
TEngine.OnMouseClick(Const X, Y : Integer);
begin
...
Components.First;
While (Not Conponents.Eof) do begin
If (X <= Conponents.Current.Right)and
(X >= Conponents.Current.Left)and
...
then
begin
Conponents.Current.Click(X, Y);
end;
Conponents.Next;
end;
...
end;
В зависимости от типов элементов вешаешь на них
различные события.
TEngine.Draw;
begin
Components.First;
While (Not Conponents.Eof) do begin
If (Conponents.Current.Frame = CurrentFrame)and
...
then
Conponents.Current.Draw;
Conponents.Next;
end;
end;
← →
Cash © (2006-10-05 13:34) [3]К8:
Э-э-э-э... :\
А что такое click? Ну типа Draw я уже понял, а вот что делает click - нет!
Поясни.
← →
@!!ex © (2006-10-05 13:43) [4]
> К8 (05.10.06 00:14)
У меня есть исходники.
← →
@!!ex © (2006-10-05 13:51) [5]не влазят сюда.... А выкидвать на скачивание нету времени.
Модераторы, потрите эти два моих сообщения, плиз.
← →
Fosgen (2006-10-05 14:18) [6]Cash © (05.10.06 13:34) [3]
В классе "кнопки" надо завести проперть Click или как еще его часто называют OnClick.
Почитай хелп Дельфи по методам и пропертям (св-вам) классов.
Далее данному полю-проперти присваивается адрес однотипной (с пропертью) процедуры (а таких для разных кнопок могет быть много). Она и будет обработчиком события, который будет вызываться если двиг ГУЯ определит что на данную кнопку кликнули мышой (возникло событие)...
Т.е. для разных кнопок одного класса можно назначать разные обработчики кликов.
Т.е. процедуры-обработчики описываются вне класса кнопки, но по типу совпадают с пропертью OnClick.
А Draw - собственный метод класса, который соответственно одинаков для всех объектов такого класса.
← →
Cash © (2006-10-05 14:50) [7]Fosgen (05.10.06 14:18) [6]:
Гы! :)
А чел пишет: "... этого класса можно было создавать свой метод .click?".
Я и думал после его ответа перенаправить его взор не на методы, а на
события.
Но вы, дорогой товарищь, меня опередили... :)
← →
К8 (2006-10-05 23:00) [8]to Real.
Как я понял, внутри движка для каждого класса (а таких штук 10) придется организовывать свой список. А нельзя ли в один?
to Fosgen.
Пока не догнал, но думается это то что надо. Был бы счастлив если пояснил это на примере. А так попробую разобраться.
Всем спасибо! Жаль с примерами gui напряжно :(
← →
Ketmar © (2006-10-05 23:33) [9]>[8] К8 5-Oct-2006, 23:00
>Жаль с примерами gui напряжно :(
Ян Хорн -- это наше всё!
← →
Rial © (2006-10-06 04:32) [10]> [8] К8 (05.10.06 23:00)
> to Real.
> Как я понял, внутри движка для каждого класса (а таких штук 10) придется организовывать свой список.
Понял неверно.
Есть один общий движок, назовем ео TEngine.
А есть набор его элементов, как то TGLButton TGLLabel и т.п.
Так вот список будет именно один, т.к. экземпляр TEngine нужен один.
А без списка не обойтись, т.к. движок должен о всех своих
элементах знать.
Массив не рекумендую, т.к. не получится тогда быстрого удаления
и добавления элементов.
Вот часть исходников моего движка меню:
http://www.Rial578.narod.ru/source/menu.rar
Компилироваться не будет, т.к. исходники движка OpenGL
и менеджера памяти я тебе не дам :)
Но принцип поймешь, если захочешь.
Правда, там подход не классовый.
← →
@!!ex © (2006-10-06 08:46) [11]
> Rial © (06.10.06 04:32) [10]
Не ожидал, что кто-то еще пишет без ООП....
← →
Fosgen (2006-10-06 10:11) [12]
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;
Не претендую на оптимальную реализацию, но как пример - думаю можно разобраться.
← →
К8 (2006-10-07 22:23) [13]to real.
тогда точно не понял. как можно в один список похать элементы различных классов? поясни
to fosgen
спасибо, разберемся.
← →
Rial © (2006-10-08 15:35) [14]> [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;
Но за такое бьют больно по рукам, поэтому не советую. %)
← →
Cash © (2006-10-08 20:56) [15](Внимание! Перед прочтением настоятельно рекомендовано ознакомиться с
базовыми классами среды Object Pascal (Delphi)) ^^.
> тогда точно не понял. как можно в один список похать элементы
> различных классов?
Создаешь класс-контейнер, в нем располагаешь экземпляр класса TList,
это и будет сам контейнер контролов. Этот класс-контейнер пишешь в
отдельном от всех контролов модуле. В самом классе предусматриваешь
два базовых метода - метод, регистрирующий контрол,
и метод - снимающий регистрацию.
Эти два метода упаковываешь в области Protected класс-контейнера.
Само собой, регистрация - это занесение указателя в контейнер, а снятие
регистрации - удаление этого указателя.
Далее в класс-контейнере создаешь еще два метода, 1: DrawControls,
2: ProcessControls. Первый будет проходить по контролам и рисовать их,
а второй - будет давать каждому контролу пожить своей жизнью.
Про обработку мыши и клавиатуры не скажу, т. к. точно не знаю что нужо.
(ляпну еще чего не то...)
Так, с главным классом GUI покончено, теперь надо о контролах позаботиться!
В том же модуле, что и класс-контейнер, создаешь еще один класс, это
будет Про-класс для всех контролов. У этого класса создаешь виртуальный
конструктор и перекрываешь деструктор. В качестве параметра конструктора
указываешь объект того же типа, что и класс-контейнер. В самом конструкторе
вызываешь (это можно, но только в пределах одного модуля) метод регистрации
контрола у полученного, в виде параметра, экземпляра класс-конструктора.
Все, контрол зарегин, и его хозяин, тот, что был в качестве параметра
конструктора, знает о том, что у него есть подчиненный контрол.
Само собой, в перекрытом деструкторе про-контрола говоришь, что
снимаешь регистрацию у хозяина и, только после этого, вызываешь наследный
деструктор.
Все контролы наследуешь от этого Про-класса.
Вороде объяснил не понятно. :))) Я старался! :)
← →
Pa5ha © (2006-10-09 14:30) [16]Давно хотел спросить зачем нужны виртуальные функции и какой прок от их виртуальности? Почему они не могут быть обычными, не виртуальными.
← →
@!!ex © (2006-10-09 14:36) [17]
> Pa5ha © (09.10.06 14:30) [16]
Виртуальные функции - это функции, которые можно перекрывать.
Делаем класс Button с фенкцией Draw.
Делаем наследника CoolButton от Button, Хотим свой Draw.
Вот для этого и нужен virtual.
Ну и в полностью абстрактных классах без виртуальных методов вообще не обойтись... Потому что все методы там виртуальные. :)
← →
Pa5ha © (2006-10-09 21:44) [18]боюсь показаца недалеким, но разве наследник не может перекрыть функции родителя? без виртуала.
← →
Ketmar © (2006-10-09 21:57) [19]>[18] Pa5ha(c) 9-Oct-2006, 21:44
>перекрыть функции родителя? без виртуала.
может. но лишаешься позднего связывания. матчасть учи. она рулит. %-))
← →
k8 (2006-10-09 22:59) [20]to real.
спасибо. почти понял. осталось попробовать реализовать.
to cash.
а на примерчике слабо? :)
попробую прочитать это еще раз, может что пойму. :)
ps
понял что надо глубже копать в сторону ооп и динамической памяти.
← →
k8 (2006-10-09 23:41) [21]
> Cash © (08.10.06 20:56) [15]
И все же я не вижу ответа на вопрос (наверно я совсем тупой)!
Без примерчика не обойтись :)
← →
Ketmar © (2006-10-10 00:18) [22]хочешь мою библиотеку консольного UI на 200 кил исходников? %-) только психотерапевта я тебе оплачивать не буду, так и знай. %-)
← →
Cash © (2006-10-10 07:50) [23]k8 (09.10.06 22:59) [20]:
Ага, ща, тока погоди, я свой двиг в полном составе упакую и тебе намылю! :)
Другими словами, я тебе теорию дал, но то, как я это сделал на практике -
не дам! В течении дня, если желание будет, я тебе левый примерчик
накидаю. С коментариями и пояснениями.
[21]:
Ты не тупой, быть может это я опять все мудачно написал, а может и у
тебя знаний недостаточно для понимания этого текста.
(В любом случае, такие вещи за бесплатно не отдаются. Там не только мои
знания в графике, там знания, доверенные мне от профессоров, доцентов,
докторов технических наук и от одно членкора СО РАН! И я за эти знания
заплатил! Много!)
← →
Cash © (2006-10-10 08:28) [24]k8 (09.10.06 23:41) [21]:
Посмотри этот бред:
http://www.webfile.ru/1144015
тока что, в порядке отдыха, накидал.
Окромя налаживания связей там ничего нет. Дальше - сам.
Cash © (10.10.06 07:50) [23]:
Приписка к скобкам в скобках :)
(эта тихая речь, похожая на ахинею, велась про весь двиг целиком)
← →
Pa5ha © (2006-10-10 14:31) [25]Ketmar, хочу! -)
Cash, псип, очень познавательно -) Ушел учить матчасть :) Кстати, нашел куда выложить 3 кб -))
← →
Cash © (2006-10-10 14:57) [26]Pa5ha © (10.10.06 14:31) [25]:
Я на вебфайле себе место держу, ну ни за зря же? :)
Хоть и 4 Kb, но ни к себе же их на сайт складывать? :)
Страницы: 1 вся ветка
Текущий архив: 2007.09.16;
Скачать: CL | DM;
Память: 0.53 MB
Время: 0.05 c