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

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

Массив компонентов без компонентов [D7, WinXP]


Uzver32.dll ©   (2005-07-12 13:17:00) 

Uzver32.dll

     Здравствуйте.
     Помогите, пожалуйста, решить мою проблему:

Мне необходимо работать с множеством подобных компонентов
и дабы не заваливать форму этими компонентами, я объединил их
в массивы следующим образом и для удобства создал класс:
При попытке привести Senderи обратиться к его свойствам вылетает:

 MyReget.exe raised exception clsee EAccess Violation with message: "Access violation
 at address 00404580 in module 'MyReget.exe'. Read of address FFFFFFFF"


В общем См. исходник:

unit main;
 .................
Type
 TDloadSystem = class(TObject)
   FileStream: array [1..3] of TMemoryStream;
   PacketSize: array [1..3] of integer;
   IsBusySock: array [1..3] of boolean;
   BufferStream: array [1..3] of TMemoryStream;
   Timers: array [1..3] of TTimer;
   Sockets: array [1..3] of TServerSocket;
 end;
 .................
var
  DloadManager: TDloadSystem; //глобалка DloadManager
 .................

procedure TForm1.GatheredDATA(Sender: TObject; Socket: TCustomWinSocket); // это обработчик (см. ниже)
var
 iLen,tLen: Dword;
 SockInd: byte;
begin
 iLen := Socket.ReceiveLength;//Как ни странно это работает
 SockInd:=IntToStr(TServerSocket(Sender).Name[5]); //А вот тут и вылетает "Access violation at addres и т. д."
 //ShowMessage(TServerSocket(Sender).Name); //Так тоже не пашет
 //Думаю, что проблема в Sender
 .................

//В разделе OnCreate формы пишу:
procedure TForm1.FormCreate(Sender: TObject);
var
i:integer;
begin
DloadManager:=TDloadSystem.Create;
for i:=1 to 3 do begin
 DloadManager.Sockets[i]:=TServerSocket.Create(Self);
 DloadManager.Sockets[i].Name:='Sock'+IntToStr(i);
 DloadManager.Sockets[i].Port:=323100+i;
 DloadManager.Sockets[i].OnClientRead:=GatheredDATA; //это ссылка на обработчик
 DloadManager.Sockets[i].Active:=true;
 DloadManager.Timers[i]:=TTimer.Create(Self);
 DloadManager.Timers[i].Name:='Timer'+IntToStr(i);
 DloadManager.Timers[i].Enabled:=False;
 DloadManager.Timers[i].Interval:=10000;
 DloadManager.Timers[i].OnTimer:=Timeout;//А вот с таймерами всё ок
 DloadManager.IsBusySock[i]:=false;
 DloadManager.FileStream[i]:=TMemoryStream.Create;
 DloadManager.BufferStream[i]:=TMemoryStream.Create;
end;
end;
 .................
end.


Uzver32.dll   (2005-07-12 14:09:00) [1]

Спасибо - заработало!
А с портом это я случайно, по-невнимательности, удивительно
что вообще коннектилось


Uzver32.dll   (2005-07-12 14:01:00) [2]

А почему не работает так?
я пытаюсь ясно указать что передавать в Sender
 DloadManager.Sockets[i].OnClientRead:=GatheredDATA(DloadManager.Sockets[i],DloadManager.Sockets[i].Socket);
пишет [Error] main.pas(203): Incompatible types: 'TSocketNotifyEvent' and 'procedure, untyped pointer or untyped parameter'


Digitman   (2005-07-12 14:01:00) [3]


> Name я вручную заполняю в при инициализации  


зачем тебе нужно св-во Name - совершенно неясно ..


> странно я же при объявлении класса ему ясно сказал  


событие возбуждает именно TServerWinSocket, а не TServerSocket


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


у TServerWinSocket есть св-во Data, с которым ты вправе ассоциировать любые дополнительные индивидуальные данные для этого объекта


> Port:=323100


# порта не может иметь значение > 65535


Ega23   (2005-07-12 13:58:00) [4]

Мало ли, что ты ему сказал. В Sender'е вообще nil может придти.


Uzver32.dll   (2005-07-12 13:50:00) [5]

Name я вручную заполняю в при инициализации   DloadManager.Sockets[i].Name:='Sock'+IntToStr(i);
пятый символ индекс сокета приславшего сообщение

Sender.ClassName говорит TServerWinSocket -
странно я же при объявлении класса ему ясно сказал   Sockets: array [1..3] of TServerSocket;

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


Digitman   (2005-07-12 13:41:00) [6]

что говорит Sender.ClassName ?


Ega23   (2005-07-12 13:40:00) [7]

Ну а кто Sender-то у тебя? С какого фига ты так явно тип приводишь?
Сделай простую проверку:

procedure TForm1.GatheredDATA(Sender: TObject; Socket: TCustomWinSocket); // это обработчик (см. ниже)
var
iLen,tLen: Dword;
SockInd: byte;
begin
if not (Sender is TServerSocket) then Exit;
iLen := Socket.ReceiveLength;//Как ни странно это работает
SockInd:=IntToStr(TServerSocket(Sender).Name[5]); //А вот тут и вылетает "Access violation at addres и т. д."
//ShowMessage(TServerSocket(Sender).Name); //Так тоже не пашет
//Думаю, что проблема в Sender


А ещё - у тебя Name может меньше пяти символов быть.


Uzver32.dll   (2005-07-12 13:32:00) [8]

В свойстве объекта
DloadManager.Sockets[i].OnClientRead указываю
на обработчик GatheredDATA
событие произойдет когда в сокет
придут данные


Ega23   (2005-07-12 13:29:00) [9]

А как и где ты вызываешь GatheredDATA?


Наверх

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