-
Здравствуйте. Изучаю ActiveX. Цель: на html страницу поместить ActiveForm который устанавливает канал связи с клиентом и получает данные. Вначале создим ActiveForm и кладем компоненту ServerS типа TserverSocket и пропишем в событии
procedure TActiveFormX.ServerSGetThread(Sender: TObject; ClientSocket: TServerClientWinSocket; var SocketThread: TServerClientThread); Begin SocketThread := TD_ServerThread.Create(False, ClientSocket); Edit1.Text:= ' GetThread: RemoteHost '+ ' (' + ClientSocket.RemoteAddress + ')'; End; Клиент подключается поток создается, но не выполняется почему? Если сделать простым приложением то все работает Может быть в потоке что-то не создал для ActiveX? type EServerThread = class( Exception ); TD_ServerThread = class(TServerClientThread) private Stream : TWinSocketStream; s2: string; public procedure ClientExecute; override; procedure AddRecord; end;
procedure TDbServerThread.ClientExecute; begin inherited FreeOnTerminate := true;
Stream := TWinSocketStream.Create(ClientSocket, 5000); try while not Terminated and ClientSocket.Connected do
try ……… …….. Buffer := ''; SetLength(Buffer,nn); дальше работаем с полученными данными ……………………… except on e:exception do begin ClientSocket.Close; Terminate; end; end;
finally begin Stream.Free; ClientSocket.Close; Terminate; end; end;
end;
-
> поток создается, но не выполняется
Врать не есть хорошо.
-
> finally > begin Stream.Free; ClientSocket.Close; > Terminate; end; > end;
Эт чиво такое ? Контрольный в голову что ли ?)
-
дело в том, что форма (ActiveX) отображается на html странице. Нажимаю кнопку активизируя сервер на компоненте TserverSocket срабатывает ServerSGetThread (т е подключился клиент), создается поток SocketThread (отображается на Edit1.Text), дальше , повидимому, не вызывается TDbServerThread.ClientExecute Поток как бы застывет и обработка данных не происходит Хотя в простом приложении все работает в потоке происходит прием данных идальше отображаются на форме Наверное поток созданный TserverSocket и форма (ActiveX) ни как между собой не взаимодействуют а вот где?
> finally > begin Stream.Free; ClientSocket.Close; > Terminate; end; > end;
>>Эт чиво такое ? >>Контрольный в голову что ли ?)
а это .. html страница у меня Access Violation
-
> дальше , повидимому, не вызывается TDbServerThread.ClientExecute
На чем же основаны эти умозаключения ? Исключительно на "видимости" ? В таком случае тебе в чукчи ("что вижу, то и пою"), а не в программисты.
Есть встроенный отладчик - на его информации следует полагаться, в 1-ю очередь, а не на "интуицию".
> html страница у меня Access Violation
Угу.
А в справке так и написано, мол, ежели у вас "html страница Access Violation", то немедля вызывайте Terminate ..
Угадал ?
-
> procedure TDbServerThread.ClientExecute; > begin <- СЮДА ставишь брейкпойнт и убеждаешься в необоснованности своего "полагаю" > inherited FreeOnTerminate := true; <- ЭТОТ бред убери и никому больше не показывай
-
Наверное я неправильно объяснил, итак все попорядку мои действия Создаем в Delphi7 File- New – other – ActiveX - выбираем ActiveForm Выбираю ThreadingModel = Apartment Опции включены На форму кладем Edit1, Button1 и TserverSocket ( ServerType = stThreadBlocking, Port=666)
unit AF_Impl1;
{$WARN SYMBOL_PLATFORM OFF} interface ------- вырезано ----------------------------------- type TAF_X = class(TActiveForm, IAF_X) Button1: TButton; Edit1: TEdit; ServerS: TServerSocket; ------- вырезано ----------------------------------- public { Public declarations } procedure Initialize; override; procedure vviv(tt:string); end; var ff: TAF_X; implementation uses ComObj, ComServ, About1;
//Дальше создаем потомока от TServerClientThread type EServerThread = class( Exception ); TD_ServerThread = class(TServerClientThread) private Stream : TWinSocketStream; strCommand: string; public procedure ClientExecute; override; procedure Log; end;
{ TD_ServerThread }
procedure TD_ServerThread.ClientExecute; var RcvBuf : array[0..255] of Byte; Buffer, s1,c_ctroka,strIn: string; nRead: Integer; vv:boolean;
begin
// inherited FreeOnTerminate := true; <- ЭТОТ бред убери и никому больше не показывай убрал
StrCommand:='запуск'; Synchronize(Log);
try Stream := TWinSocketStream.Create(ClientSocket, 100000);
try while ( not Terminated ) and ( ClientSocket.Connected ) do try repeat vv:=false;
nRead := Stream.Read(Buffer[1],256 ); if nRead = 0 then begin ClientSocket.Close; Break; end;
SetLength (Buffer, nRead); s1:= Buffer;
if (Pos(#10#13'.'#10#13, Buffer) > 0) then begin c_ctroka:= c_ctroka + Copy (Buffer, 1, Pos (#10#13'.'#10#13, Buffer) -1); vv:=true;//выход из цикла end else c_ctroka:= c_ctroka + Buffer;
until vv;
StrCommand:=c_ctroka; Synchronize(Log); //3 показывает что принято сервером StrCommand
//отправить клиенту результаты обратно strIn := 'OK!'; Stream.Write( strIn[1], Length (strIn));
except on e:exception do begin // Если произошла ошибка, то закрываем сокет и выходим ClientSocket.Close; Terminate; end; end; finally Stream.Free; end; except on e:exception do begin // Если произошла ошибка, то закрываем сокет и выходим ClientSocket.Close; Terminate; end; end;
// показывает что принято сервером StrCommand Synchronize(Log);
end;
procedure TD_ServerThread.Log; begin ff.vviv( strCommand);
end;
Также добавил procedure TActiveFormX.ServerSGetThread(Sender: TObject; ClientSocket: TServerClientWinSocket; var SocketThread: TServerClientThread); Begin SocketThread := TD_ServerThread.Create(False, ClientSocket); Edit1.Text:= ' GetThread: RemoteHost '+ ' (' + ClientSocket.RemoteAddress + ')'; End;
procedure TAF_X.vviv(tt: string); begin Edit1.Text:=tt; end;
procedure TAF_X.Button1Click(Sender: TObject); begin ServerS.Active:=true; end; дальше компилируем регисрируем AF_Proj1.ocx в реестре (Register Activex Server) создаем html страницу <HTML> <H1> ACTIVEX </H1> <OBJECT classid="clsid:C917F481-4B84-4F2A-A59B-74DEC32A8C28" width=350 height=250 align=center hspace=0 vspace=0
</OBJECT>
</HTML> открываем в Internet Explorer Сервер запускается Отображается ‘GetThread: RemoteHost 1.1.1.1’ т. е. Клиент подключился, а дальше без изменений
<<На чем же основаны эти умозаключения ? Исключительно на "видимости" ? <<В таком случае тебе в чукчи ("что вижу, то и пою"), а не в программисты. Я бы с выводами не спешил на твоем месте , а если есть желание то помог бы
> begin <- СЮДА ставишь брейкпойнт и убеждаешься в необоснованности >своего "полагаю" Поток не передает данные на Форму Помочь советом можеш как лучше поступить в этой ситуации P.S. Сейчас читаю статью “Понимание потоковых моделей в COM при программировании на Delphi”
-
2 vav ©
Synchronize выкинь нахвиг, замени на че-нить типа Sendmessage
-
> Сейчас читаю статью “Понимание потоковых моделей в COM
Какие тебе нафих "потоковые модели", еслим ты не умеешь пользоваться встроенным в средк Делфи отладчиком..
Ты полез в дебри не зная элементарных основ отладки программ, созданных в среде, которую ты выбрал для разработки.
> ServerSGetThread(
> Edit1.Text:=
Уж сколько раз твердили миру - НЕЛЬЗЯ обращаться в визуальным VCL-контролам в дополнительном потоке процесса приложения, использующего VCL !
> Я бы с выводами не спешил на твоем месте
Я их сделал вовремя, и ты подтвердил это.
> Поток не передает данные на Форму
Да ? А куда поток, по-твоему, тычет ЭТО
> Edit1.Text:= ' GetThread: RemoteHost '+ ' (' + ClientSocket. > RemoteAddress + ')';
? На луну ?
-
Если ты не понимаешь, как работает synchronize, то и нечего было тыкать его вызов куда ни попадя.
-
Я вообщето не программист но работа обязывает. Большое спасибо что вы не промолчали Все ваши ответы мне помогли Synchronize(Log); Оставил в конце нити все проверки в потоке убрал оставил одну finally Stream.Free; end; Принятые данные с потока передаются на форме через synchronize данные не отображаются пошел другим путем через таймер
В Итоге на рабочем столе Серером данные принимаются и отображаются через ативеХ и могут находится под иконкой что и хотел :)
|