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

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

Можно ли управлять классом через TComponent ? [D7, WinXP]


Страницы:   1 2

Zoom ©   (2010-05-15 19:46:00) 

var
 TCPClient: TIdTCPClient;
 AOwner: TComponent;
begin
 TCPClient := TIdTCPClient.Create(self);
 AOwner := TCPClient.Owner;
 TIdTCPClient(AOwner).Connect('127.7.0.1', 3615);
 TIdTCPClient(AOwner).IOHandler.Write('Hello');
end;

Access violation at address... а почему ?

существует ли у класса некое подобие handle, зная которое можно управлять классом например из других классов ?


_Юрий   (2010-05-16 11:27:00) [1]


> может мне тогда книгу написать "Новые подходы к программированию
> в ООП" :)))
>
>


Лучше напишешь потом книжку о том, как ты искал в этом коде косяки, которые было совершенно невозможно воспроизвести, но которые регулярно лезли.


Германн   (2010-05-16 03:13:00) [2]


> может мне тогда книгу написать

Угу. "Дельфи  глазами неграмотного хакера".


Германн   (2010-05-16 02:40:00) [3]


> Zoom ©   (16.05.10 02:26) [20]
>
> а что академически верно

Академически  верно сначала  изучить учебник. И хелп.


Zoom   (2010-05-16 02:26:00) [4]

а что академически верно определить наперед класс а потом походу дела изменить его ?  

и чем же обращение к компоненту через TComponent  - является быдлокодерством ??? или это просто ваше непонимание к такому подходу ?

нафига тогда вся Дельфи усеяна в (Sender: TObject) ?

может мне тогда книгу написать "Новые подходы к программированию в ООП" :)))


Германн   (2010-05-16 02:09:00) [5]

Удалено модератором
Примечание: Правила читаем и уважаем


Германн   (2010-05-16 02:02:00) [6]


> Zoom ©   (16.05.10 01:24) [14]
>
> Плохиш - иногда переученный хуже недоученного :)
>
> несмотря на ваши замечания все работает как надо :)
>

Тебе просто не повезло. Это как в случаях с AV. Когда AV возникает на этапе отладки - это просто фантастическая удача!
Когда ошибка "выскочит" у пользователя, тогда и поймёшь.


Плохиш   (2010-05-16 01:28:00) [7]


> Zoom ©   (16.05.10 01:24) [14]
>
> Плохиш - иногда переученный хуже недоученного :)
>
> несмотря на ваши замечания все работает как надо :)

Ну, ну.


Харакири   (2010-05-16 01:27:00) [8]

Удалено модератором
Примечание: Даже если это он, эмоции надо сдерживать


Zoom   (2010-05-16 01:26:00) [9]

Удалено модератором


Zoom   (2010-05-16 01:24:00) [10]

Плохиш - иногда переученный хуже недоученного :)

несмотря на ваши замечания все работает как надо :)

еще раз спасибо ~AQUARIUS~, за то что наставил на путь истинный! респект!

unit Unit2;

interface

uses
 Classes, IdTCPClient, Dialogs;

type
 tnew = class(tthread)
 private
 protected
   procedure execute; override;
 //procedure onreceivestring(buf: string);
 public
   c: TComponent;
 end;

 TOnReceiveString = procedure(buf: string) of object;

 tmyIdTCPClient = class(tIdTCPClient)
   constructor create(AOwner: TComponent);
 protected
   FOnReceiveString: TOnReceiveString;
 public
   thread: tnew;
 published
   property OnReceiveString: TOnReceiveString read FOnReceiveString write FOnReceiveString;
 end;

implementation

constructor tmyIdTCPClient.create(AOwner: TComponent);
begin
 inherited create(AOwner);
//  name := 'n123';
 thread := tnew.Create(true);
 thread.c := self; //  FindComponent(name);
 thread.FreeOnTerminate := true;
 thread.priority := tplowest;
 thread.Resume;
end;

procedure tnew.execute;
var
 i: integer;
 s: string;
begin
 repeat
   if Assigned(c) then
   try
     if TIdTCPClient(c).Connected then
     begin
       TIdTCPClient(c).IOHandler.CheckForDataOnSource(10);
       if TIdTCPClient(c).IOHandler.InputBuffer.Size > 0 then
       begin
         i := TIdTCPClient(c).IOHandler.InputBuffer.Size;
         s := TIdTCPClient(c).IOHandler.ReadString(i);
//          ShowMessage(s);
         tmyIdTCPClient(c).OnReceiveString(s);
       end;
     end;
   except
     exit; // а тут я еще подумаю как лучше выходить например "if halt then exit;"....
   end;
 until false;
end;

end.
///////////////////////////

procedure TForm1.Button1Click(Sender: TObject);
var
 TCPClient: tmyIdTCPClient;
begin
 TCPClient := tmyIdTCPClient.create(Self);
 TCPClient.OnReceiveString := OnReceiveString1;
 TCPClient.Connect('127.0.0.1', 3615);
 TCPClient.IOHandler.Write('Hello');
end;

procedure TForm1.OnReceiveString1(buf: string);
begin
memo1.Lines.Add(buf);
end;


Плохиш   (2010-05-16 01:19:00) [11]


> Zoom ©   (15.05.10 23:32) [7]


> type
>  tmyIdTCPClient = class(tIdTCPClient)
>    constructor create(AOwner: TComponent);
>
>  public
>    thread: tnew;
>  end;
>

Бессмысленно ненужный и крайне вредный класс, ибо привязывается к какому-то предку, который может быть уничтожен во время работы трэда, что повлечёт за собой исключение, причину которого будет ой как трудно найти.

В конструкторе трэда создавай необходимый ему экземпляр TIdTCPClient.


Харакири   (2010-05-16 01:19:00) [12]

Насколько же надо быть глупым и насколько оптимистичными, чтобы писать столько много такого глючного и бесполезного кода?

Послушай, Зум! Остановись! Учи основы! Учи язык программирования! Ты такой бред тут несешь, просто страшно! Это не дилетантство, не быдлокодерство. Это хуже!

type
tmyIdTCPClient = class;

tnew = class(tthread)
private
protected
  procedure execute; override;
//procedure onreceivestring(buf: string);
public
  c: tmyIdTCPClient;
end;

//type
tmyIdTCPClient = class(tIdTCPClient)
  constructor create(AOwner: TComponent);

public
  thread: tnew;
end;


Хотя нет, ни к чему это. Потому что весь твой код - куча отстойной псевдопрограммистской ахинеи! Начиная с форматирования, и заканчивая непонимаением основ программирования, построениея VCL и прочего, прочего, прочего.

P.S. И у этого... кхм... не знаю, как его назвать... в анкете тоже прописано высшее образование! Аллес капут!


Zoom   (2010-05-16 00:25:00) [13]

>А вот так, пытаешься найти себя в своём же списке компонентов.
Плохиш , так это мне и надо !

thread.c := self; а вот так получилось! и даже нет необходимости в уникальном "name"

осталось прикрутить TNotifyEvent...

и разобраться с деструктором  - чтоб корректно останавливать дополнительный поток при выходе... почти все что я и хотел...


Плохиш   (2010-05-16 00:08:00) [14]


> Zoom ©   (15.05.10 23:56) [9]
>
> Плохиш, как не там ?

А вот так, пытаешься найти себя в своём же списке компонентов.


Zoom   (2010-05-15 23:56:00) [15]

Плохиш, как не там ?

сообщение с сервера в отдельном потоке читает нормально ...

если такой вариант работает:  
var
 TCPClient: tmyIdTCPClient;
begin
 TCPClient := tmyIdTCPClient.create(Self);
 TCPClient.thread.c := FindComponent(TCPClient.name);
 TCPClient.Connect('127.0.0.1', 3615);
 TCPClient.IOHandler.Write('Hello');


просто хочу  TCPClient.thread.c := FindComponent(TCPClient.name);
как-то вставить в конструктор... вот и все...


Плохиш   (2010-05-15 23:47:00) [16]


> thread.c := FindComponent(name);
> находит вместо компонента nil...

Не там ищешь.


> P.S. Мне кажется, рановато ты за потоки взялся, если только
> еще изучаешь ООП и не всегда понимаешь, что пишешь и как
> это работает.

В этой фразе первые два слова лишнии.


Zoom   (2010-05-15 23:32:00) [17]

Харакири , с потоками как раз все понятно запустил себе, он там своей жизнью и живет... вот что у меня получилось...
есть другая пословица - "Волков боятся, в лес не ходить" :)
почти все заработало , но действительно этот участок:

thread.c := FindComponent(name);
находит вместо компонента nil...

а как еще компонент может найти сам себя в процессе инициализации ???

/////////////////////////////////////////////////////////
unit Unit2;

interface

uses
 Classes, IdTCPClient, Dialogs;

type
 tnew = class(tthread)
 private
 protected
   procedure execute; override;
 //procedure onreceivestring(buf: string);
 public
   c: TComponent;
 end;

type
 tmyIdTCPClient = class(tIdTCPClient)
   constructor create(AOwner: TComponent);

 public
   thread: tnew;
 end;

implementation

constructor tmyIdTCPClient.create(AOwner: TComponent);
begin
 inherited create(AOwner);
 name := 'n123';
 thread := tnew.Create(true);
 thread.c := FindComponent(name);
 thread.FreeOnTerminate := true;
 thread.priority := tplowest;
 thread.Resume;
end;

procedure tnew.execute;
var
 i: integer;
 s: string;
begin
 repeat
   if Assigned(c) then
     if TIdTCPClient(c).Connected then
     begin
       TIdTCPClient(c).IOHandler.CheckForDataOnSource(10);
       if TIdTCPClient(c).IOHandler.InputBuffer.Size > 0 then
       begin
         i := TIdTCPClient(c).IOHandler.InputBuffer.Size;
         s := TIdTCPClient(c).IOHandler.ReadString(i);
         ShowMessage(s);
     //  onreceivestring(s); // on receive string
       end;
     end;
 until false;
end;

end.


Харакири   (2010-05-15 23:01:00) [18]

>> один статический компонент который заранее инициализирован

И что мешает объявить поле для этого, кхм, компонента? В общем-то, когда ты кидаешь компонент на форму, Delphi сама делает это за тебя.

>> я хочу построить свой класс на основе TIdTCPClient прилепить к нему tthread в котором будет обращение к IdTCPClient

Компоненты в TThread? Не делай этого.VCL потоконезащищенная библиотека. Компоненты изначально не предназначены для работы в потоках. Будет у тебя большая беда с методами типа FindComponent().

P.S. Мне кажется, рановато ты за потоки взялся, если только еще изучаешь ООП и не всегда понимаешь, что пишешь и как это работает. Помнишь пословицу "Пуганая ворона куста боится"? Смотри, а то станут твои потоки этим самым кустом, и будешь от них шарахаться, как ошпаренный. Шел бы ты как-то поэтапно, системнее, что ли.


Zoom   (2010-05-15 22:37:00) [19]

Плохиш, а как тогда назначить уникальный creat() при создании ?

~AQUARIUS~ , спасибо, так получилось!

Харакири , еслиб так все просто... один статический компонент который заранее инициализирован... я хочу построить свой класс на основе TIdTCPClient прилепить к нему tthread в котором будет обращение к IdTCPClient
в принципе можно создать повторно IdTCPClient от TIdTCPClient и к нему присваивать уже проинициализированный объект... в общим я пока тренируюсь с ООП, и то что предложил  ~AQUARIUS~ , это то что мне надо!

procedure tnew.execute; // от tthread
begin
 repeat
 if TIdTCPClient(c).Connected then
 begin
    TIdTCPClient(c).IOHandler.CheckForDataOnSource(10);
   
   if TIdTCPClient(c).IOHandler.InputBuffer.Size > 0 then
   begin
     i := TIdTCPClient(c).IOHandler.InputBuffer.Size;
     s := TIdTCPClient(c).IOHandler.ReadString(i);
     onreceivestring(s);// on receive string
   end;
 end;
 until false;
end;


Anatoly Podgoretsky   (2010-05-15 22:10:00) [20]


> а почему ?

А вот из-за этого AOwner := TCPClient.Owner;


Страницы:   1 2

Наверх

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