Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.02.25;
Скачать: [xml.tar.bz2];

Вниз

TClientSocket без форм. Возможно ли это?   Найти похожие ветки 

 
Zaratustra   (2004-02-11 17:33) [0]

Добрый день!
Товарищи, не подскажите, можно ли использовать объекты этого компонента в программе, в которой нет формы? Т.е. можно ли создавать его динамически и работать так же как и обычно.

Заранее спасибо!


 
VLAD-MAL   (2004-02-11 17:34) [1]

Да!


 
Zaratustra   (2004-02-11 17:43) [2]

А как?


 
Тимохов   (2004-02-11 17:44) [3]

Что такое программа без формы?


 
VLAD-MAL   (2004-02-11 17:44) [4]

xxx.create не пробовал?


 
Zaratustra   (2004-02-11 18:06) [5]

А работать будет?
Но тут еще один вопрос, а как оформить для этого объекта обработчики событий? Ведь это важно.


 
AkaSaint   (2004-02-11 18:18) [6]

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

procedure ButtonClick(Sender: TObject)
begin
//Обработать нажатие кнопки
end;

Где-то в программе:
var
Btn: TButton;
begin
Btn := TButton.Create;
Btn.OnClick := ButtonClick;
//...
end;
Я думаю, здесь так же.


 
Digitman   (2004-02-11 18:20) [7]


> как оформить для этого объекта обработчики событий? Ведь
> это важно.


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


 
Zaratustra   (2004-02-11 19:16) [8]

Спасибо


 
Zaratustra   (2004-02-11 20:21) [9]

Так что-то с порстым присвоением не катит. Проверял на Timer. Что не так? Пишу так как показано в примере, выдает:

Incompatible types: "method pointer and regular procedure"

Хелп, плиз


 
Тимохов   (2004-02-11 20:27) [10]

возьми 6 и прислушайся к 7 - все получится.

сделай свой обработчик методом какого нить объекта, создай объект, и задай обработчик. Все.


 
имя   (2004-02-11 20:29) [11]

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


 
Тимохов   (2004-02-11 20:31) [12]

Удалено модератором
Примечание: Оффтоп...


 
Zaratustra   (2004-02-11 20:36) [13]

:) :)
На это он сообщает:
Incompatible types: "TNotifyEvent and Pointer"


 
Тимохов   (2004-02-11 20:37) [14]

Слушай 11
+
Читай procedural types в хелпе в разделе object pascal reference.
Обязательно получится.


 
Zaratustra   (2004-02-11 20:48) [15]

Что-то я там ничего не нашел...полезного в данной ситуации


 
Alex Konshin   (2004-02-12 02:47) [16]

По буквам:

1. опиши свой класс

type
TMyCoolEventHandler = class
constructor Create();
// имей в виду, что список параметров для обработчиков должен быть таким, какой требуется для соответствующего события.
procedure MyCoolMethod(Sender: TObject);
procedure MyCoolMethod2(Sender: TObject);
procedure AnotherCoolMethod(Sender: TObject);
// далее, я думаю, уже догадываешься
end;

2. В программе объяви и создай объект этого класса.
var
MyCoolEventHandler : TMyCoolEventHandler;
...

MyCoolEventHandler := TMyCoolEventHandler.Create();

3. Теперь можешь присваивать методы этого объекта

Btn.OnClick := MyCoolEventHandler.AnotherCoolMethod;


 
Defunct   (2004-02-12 03:06) [17]

Человек спросил одно, а все пишут бог знает что... напоминает политическую дискуссию ;>


var Socket : TCustomWinSocket;
...
...
// Создание сокета
Socket := TCustomWinSocket.Create( Nil );

Socket.Address:=RemoteAddr; { IP адрес куда подрубаемся }
Socket.Port:=RemotePort; { Порт куда подрубаемся }

{Обработчик ошибок - обязательно должен содержать строку
ErrorCode := 0; иначе будет выскакивать ссобщение об ошибке винды}
Socket.OnError:=SocketError;

Socket.OnConnect:=SocketConnect; { не обязательно }
Socket.OnDisconnect:=SocketDisconnect; { не обязательно }
Socket.OnRead:=SocketRead; { Прием данных }
Socket.OnWrite:=SocketWrite; { завершение посылки необязательно обслуживать }
Socket.Active:=True; { Соединение }


 
Defunct   (2004-02-12 03:09) [18]

Забыл добавить приведенный код работает на Delphi 5
на D6-D7 немножко по-другому, но идея та же.


 
Alex Konshin   (2004-02-12 03:09) [19]

Defunct (12.02.04 03:06) [17]
Вот-вот, и ты в их числе.

Лично я ответил на это:
Zaratustra © (11.02.04 18:06) [5]


 
Defunct   (2004-02-12 03:26) [20]

Мда уж, это конечно интересно [16], но абсолютно бесполезно. Человеку надо работать с сокетом, возможно в консольном приложении, вот шапки обработчиков для моего примера в [17]:


Procedure SocketError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
Procedure SocketConnect(Sender: TObject;
Socket: TCustomWinSocket);
Procedure SocketDisconnect(Sender: TObject; Socket:TCustomWinSocket);
Procedure SocketRead(Sender: TObject; Socket:TCustomWinSocket);
Procedure SocketWrite(Sender: TObject; Socket:TCustomWinSocket);


 
Defunct   (2004-02-12 03:30) [21]

вдогонку Alex, в твоем примере описанные методы имеют тип TNotifyEvent, который для обработчиков сокета не подходит.


 
Alex Konshin   (2004-02-12 03:44) [22]

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

Кстати, из приведенного тобой фрагмента ясно, что ты не понял ни вопрос, ни то, чем процедура отличается от метода.


 
Defunct   (2004-02-12 04:05) [23]

Хорошо дополняю свой пример, специально для Alex Koshin. (PS: то что ты не знаешь как работать с сокетом не оправдание для введения нового класса в программу, который просто будет хранить обработчики. Почему бы тогда просто не описать наследника TCustomWinSocket с соответствующими обработчиками, кстати самый правильный вариант). Зачем ему "TMyCoolClass"? В свое время я поражался таким ответам типа[16], спрашиваешь вроде одно, а в ответ дают хливкий общий пример как оно долно быть в вообще. Например, если у меня проблема с компонентом SQL_Direct, мне не нужны общие примеры работы с ADO, потому что оно не подходит.

Создание и запуск собственного сокета:

TClientForm = class(TForm)
// на месте TForm может быть любой наследник TObject
...
...
Public
Socket : TCustomWinSocket;

Procedure SocketError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
Procedure SocketConnect(Sender: TObject;
Socket: TCustomWinSocket);
Procedure SocketDisconnect(Sender: TObject; Socket:TCustomWinSocket);
Procedure SocketRead(Sender: TObject; Socket:TCustomWinSocket);
Procedure SocketWrite(Sender: TObject; Socket:TCustomWinSocket);

Procedure NewSocket;
End;

Constructor TClientForm.NewSocket;
Begin
Сюда вставить код из ответа[17]
End;


 
Alex Konshin   (2004-02-12 04:18) [24]

Теперь внимательно перечитай оригинальный вопрос автора и пост [5].


 
Alex Konshin   (2004-02-12 04:23) [25]

// на месте TForm может быть любой наследник TObject
Кстати, сравни еще с тем примером, что написал я.

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


 
Defunct   (2004-02-12 04:53) [26]

Да, в общем виде пример правильный[16], сомнений нет.
И с фразой[25] я тоже согласен, но иногда бывают моменты когда надо чтобы программа просто начала работать, с сетью это важно. Оставляет первое впечатление.

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

В данном случае ответ на [1] и [5] можно решить так (нужно перекрыть конструктор и обработчики приема и ошибочных ситуаций):

TMyWinSocket = class(TCustomWinSocket)
Private
Procedure SocketRead(Sender: TObject; Socket:TCustomWinSocket); Procedure SocketError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
Public
Constructor Create(ASocket:TSocket);Override;
End;

Constructor TMyWinSocket.Create;
Begin
Inherited;
OnRead := SocketRead;
OnError := SocketError;
End;

Procedure TMyWinSocket.SocketRead;
Begin
// Прием в Stream, Buffer или String
End;

Procedure TMyWinSocket.SocketError;
Begin
ErrorCode := 0; {Обязательно!!!}
// обработка ошибки, если надо
End;

Собсно все, а дальше уже в программе динамически создавать сколько угодно TMyWinSocket

Sockets : Array of TMyWinSocket
I : Integer;
...
...
SetLengths(Sockets, {Скока надо} }
For I:=0 To Скока надо -1 Do
Begin
Sockets[i] := TMyWinSocket.Create(Nil);
// задать адрес/порт и Active:= True
End;


Это будет уже на всю жизнь ;>

Слово Override = Перекрытый, т.е. если есть переменная класса родителя A, заполнена наследником AB, то при вызове метода A.X вызовется метод AB.X

Слово Inherited - Унаследованный, при вызове в теле AB метода X как Inherited X, вызовется метод A.X


 
Alex Konshin   (2004-02-12 05:19) [27]

Это будет уже на всю жизнь ;)
Сомневаюсь.
Я, например, компоненты из Internet вообще не использую.
Я использую Winsock2 чего и другим советую, особенно для случая серверов и сервисов.


 
Defunct   (2004-02-12 05:24) [28]

Напоследок скажу, что TClientSocket на самом деле хуже чем TCustomWinSocket, объясню почему. Дело в том, что TClientSocket, мало того что является наследником TCustomSocket, так он еще и содержит дополнительно экземпляр TCustomWinSocket. Лишняя избыточность. Отличается он визуальной секцией Published, для отображения настроек в Object Inspector. Прн динамическом создании сокета, эта часть абслолютно не нужна.
Да и при работе с TClientSocket надо работать так:
TClientSocket. Socket.ReadString();
А при работе с TCustomWinSocket так:
TCustomWinSocket.ReadString();
Как видно, отпадает лишнее слово "Socket" ;>

TClientSocket = class(TCustomSocket)
private
FClientSocket: TClientWinSocket;
...
...
public
property Socket: TClientWinSocket read FClientSocket;
...
...

published // все что написано после этого слова отображается в Object Inspector
property Active;
property Address;
// и т.д. все, что видно в Object Inspector
..
End;


 
Defunct   (2004-02-12 05:28) [29]

Alex Konshin © (12.02.04 05:19) [27]

Ну, это уж кому что.
Я тоже Winsock2 использую.
Но с Internet секцией пришлось поработать когда еще Winsock2 не было.


 
Alex Konshin   (2004-02-12 06:13) [30]

Но с Internet секцией пришлось поработать когда еще Winsock2 не было.

Ой, ну и повеселил ты меня, извини.
Это вот как раз Winsock2 был еще до того, как закладка Internet появилась и уж тем более не было никаких TCustomWinSocket.
Ты, кстати, загляни в копирайт юнита Winsock2, вместе посмеемся :)


 
Defunct   (2004-02-12 07:06) [31]

Winsock2.h
* This file includes parts which are Copyright (c) 1982-1986 Regents
* of the University of California.

Ну и?
Если ты об этом, parts и в африке парт.
модуль датирован 04.06.2002


 
Defunct   (2004-02-12 07:17) [32]

Цитата с Вашего сайта, ув. Alex


WinSock 2.2 API unit (winsock2.zip, rev.2, 13 Feb 2001, ~31K, D2+) Хотя в дистрибутивах к Delphi 4 и присутствует описание WinSock 2 API (файл sock2.hlp), но модуль winsock.pas, к сожалению, соответствует всего лишь первой версии, в которой нет очень многих возможностей второй версии. Самое удивительное то, что даже в Delphi 5 подобное безобразие продолжается! Данный файл исправляет это упущение. Это второй, исправленный и дополненный вариант. Добавлены переводы wsipx.h, wsnwlink.h, wsnetbs.h, svcguid.h.


В Dephi 4 Internet секция точно была.


 
Verg   (2004-02-12 07:44) [33]


> Defunct (12.02.04 04:53) [26]


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


 
Verg   (2004-02-12 07:59) [34]


> Defunct


И вообще, батенька, чего-то вы тут, мягко говоря на... (забыл правило лаг-лож).

Особенно хороша вот эта конструкция из [17]:

> Socket := TCustomWinSocket.Create( Nil );


 
Alex Konshin   (2004-02-12 08:09) [35]

Defunct (12.02.04 07:17) [32]
Цитата с Вашего сайта, ув. Alex
>WinSock 2.2 API unit (winsock2.zip, rev.2, 13 Feb 2001, ~31K, D2+)

Дык это ж далеко не первый вариант.
А в копирайте первой ревизии есть год - 1998. Причем я не уверен, что я не использовал его для собственных нужд до этого, но в 1998 он точно уже был опубликован.


 
Alex Konshin   (2004-02-12 08:25) [36]

Хотя... да, scktcomp.pas есть в Delphi 3.01, который появился до 1998. По крайней мере мой юнит winsock2 для других видимо еще не был доступен. Ладно, в этом был неправ.
Но ведь ws2_32 существовала задолго до Delphi 3, никто не запрещал ею пользоваться.


 
Digitman   (2004-02-12 08:31) [37]


> Zaratustra © (11.02.04 17:33)


надеюсь, ты намерен использовать TClientSocket в режиме ctBlocking ?

в ctNonBlocking вся эта конструкция (равно как и вариант от Defunct) работать без принятия спец.мер не будет : конс.приложение должно организовать цикл выборки/диспетчеризации оконных сообщений


 
Alex Konshin   (2004-02-12 08:38) [38]

в ctNonBlocking вся эта конструкция (равно как и вариант от Defunct) работать без принятия спец.мер не будет : конс.приложение должно организовать цикл выборки/диспетчеризации оконных сообщений

Это тоже было моей первой мыслью :), но похоже, что TCustomWinSocket сам создает окно (смотри GetHandle).
Он использует функцию AllocateHwnd из classes (ее еще раньше TThread использовал, не знаю как сейчас).
Так что похоже, что проблемы не будет, хотя не буду утверждать наверняка - я этими классами не пользуюсь, а более досконально рабираться влом. :)


 
DVM   (2004-02-12 09:07) [39]

А создать невидимое окно на API и принимать в него сообщения асинхронных сокетов не подойдет? Размер программы не увеличится (если это было причиной отказа от "форм"). Работать все даже понадежнее будет и чуть побыстрее.


 
Anatoly Podgoretsky   (2004-02-12 09:16) [40]

Defunct (12.02.04 04:53) [26]
Inhеrited только косвенно относится к методам, косвенно поскольку его можно применить и к ним. На самом деле эта такая конструкция, которая позволяет опустить указание имени наследника и в случае методов еще и их аргументы если они совпадают. Аналогично использованию Self



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2004.02.25;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.027 c
3-79614
Пубертанец
2004-01-30 16:40
2004.02.25
Проблема с внешними ключами в Interbase


1-79752
KADAN
2004-02-11 14:08
2004.02.25
Несовместимость ОС


14-80182
syte_ser78
2004-01-31 12:45
2004.02.25
прогресс загрузки страници


1-79769
jiurajhgjhgty
2004-02-11 21:21
2004.02.25
Что делать!!! Программа не загружается.


1-79926
akiro
2004-02-09 17:59
2004.02.25
Как записать в реестр переменную типа tagWINDOWPLACEMENT ?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский