![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Можно ли управлять классом через TComponent ? [D7, WinXP]
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;