Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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
6-1169490868
Khabibulin
2007-01-22 21:34
2007.09.16
Авторизация с помощью idHTTP


15-1187518755
Piter
2007-08-19 14:19
2007.09.16
Странный режим 1C: Монопольно


8-1165916716
zenov
2006-12-12 12:45
2007.09.16
как подключить к своей проге плагины аудиовывода из Winamp?


11-1171022650
WiseImp
2007-02-09 15:04
2007.09.16
Turbo Delphi?


15-1187705040
oldman
2007-08-21 18:04
2007.09.16
Хочу съездить в Финляндию...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский