Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.03.19;
Скачать: CL | DM;

Вниз

Delphi: ActiveX Form+TThread=Проблема   Найти похожие ветки 

 
Sany81 ©   (2006-03-02 09:01) [0]

Есть  ActiveX компанента, пытаюсь в потоке вызвать Synchronize(Моя_процедура) - при этом ничего не происходит, если вызвать так Мой_Поток.Моя_Процедура процедура выполняется, но не могу из процедуры вызвать событие самой компаненты.

Пошел по пути который смог придумать, но этот путь неверный(ИМХО), когда в цикле потока происходит чтение данных, я стартую таймер, который в свою очередь запускает событие основной компаненты и после этого отключается. При этом все работает, но мне этот метод не нравится и не совсем понятно почему в ЭктивИкс в потоке я не могу вызвать метод Synchronize и почему не могу вызвать событие самой компаненты.

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

unit AlexZ_ClientSKImpl1;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 ActiveX, AxCtrls, AlexZ_ClientSKProj1_TLB, StdVcl, StdCtrls,
 IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, ExtCtrls;
type
 TCommBlock = record
   Command,
   MyUserName,
   ReceiverName: string[100];
   Msg:string[255];
 end;
 TAlexZ_ClientSK = class;
   TClientHandleThread = class(TThread)
   private
     CB: TCommBlock;
     procedure HandleInput;
   protected
     procedure Execute; override;
   public
   end;
 TAlexZ_ClientSK = class(TActiveForm, IAlexZ_ClientSK)
   Label1: TLabel;
   Client: TIdTCPClient;
   Timer1: TTimer;
   procedure Timer1Timer(Sender: TObject);
   procedure ActiveFormCreate(Sender: TObject);
 private
   FEvents: IAlexZ_ClientSKEvents;
   procedure ActivateEvent(Sender: TObject);
 protected
   procedure EventSinkChanged(const EventSink: IUnknown); override;
   function Get_Active: WordBool; safecall;
   procedure EnabledSK(Enable: WordBool); safecall;
 public
   procedure Initialize; override;
 end;
var
 ClientHandleThread: TClientHandleThread;
 FForm: TAlexZ_ClientSK;
implementation

uses ComObj, ComServ;

{$R *.DFM}

procedure TAlexZ_ClientSK.EventSinkChanged(const EventSink: IUnknown);
begin
 FEvents := EventSink as IAlexZ_ClientSKEvents;
 inherited EventSinkChanged(EventSink);
end;

procedure TAlexZ_ClientSK.Initialize;
begin
 inherited Initialize;
 OnActivate := ActivateEvent;
end;

function TAlexZ_ClientSK.Get_Active: WordBool;
begin
 Result := Active;
end;

procedure TAlexZ_ClientSK.ActivateEvent(Sender: TObject);
begin
 if FEvents <> nil then FEvents.OnActivate;
end;

procedure TClientHandleThread.HandleInput;
begin
 if FForm.FEvents<>nil then begin
   MessageDlg ("OK"+#13+CB.Msg,mtInformation, [mbOk], 0);// эта строка проходит
   FForm.FEvents.OnDataRead(CB.Msg);//на этой строке поток обрывается и начинается опять чтение данных, при этом событие OnDataRead не вызывается
 end
 else
   MessageDlg ("Err"+#13+CB.Msg,mtInformation, [mbOk], 0);
end;

procedure TClientHandleThread.Execute;
begin
 while not Terminated do
 begin
   if not Fform.Client.Connected then
     Terminate
   else
   try
     Fform.Client.ReadBuffer(CB, SizeOf (CB));
//      Fform.Timer1.Enabled:=True;// если пойти этим путем то все работает замечательно но я не считаю это правильным решением
//      Synchronize(HandleInput);// вот эта строка не проходит
     ClientHandleThread.HandleInput;// эта проходит
   except
   end;
 end;
end;

procedure TAlexZ_ClientSK.EnabledSK(Enable: WordBool);
begin
 if Enable then try
   Client.Connect(10000);
   ClientHandleThread := TClientHandleThread.Create(True);
   ClientHandleThread.FreeOnTerminate:=False;
   ClientHandleThread.Resume;
 except
   on E: Exception do MessageDlg("Error while connecting:"+#13+E.Message,
                                 mtError, [mbOk], 0);
 end else begin
   ClientHandleThread.Terminate;
   Client.Disconnect;
 end;
end;

procedure TAlexZ_ClientSK.Timer1Timer(Sender: TObject);
begin
// Изначально Enabled=False
// при получении данных от компаненты я запукаю таймер и таймер уже запускает событие OnDataRead
 FForm.FEvents.OnDataRead(ClientHandleThread.CB.Msg);
 Timer1.Enabled:=False;
end;

procedure TAlexZ_ClientSK.ActiveFormCreate(Sender: TObject);
begin
FForm:=Self;
end;

initialization
 TActiveFormFactory.Create(
   ComServer,
   TActiveFormControl,
   TAlexZ_ClientSK,
   Class_AlexZ_ClientSK,
   1,
   "",
   OLEMISC_SIMPLEFRAME or OLEMISC_ACTSLIKELABEL,
   tmApartment);
end.


 
Сергей М. ©   (2006-03-02 09:54) [1]

> FForm.FEvents.OnDataRead(CB.Msg);//на этой строке поток обрывается

Для начала убедись, что в момент выполнения этой строчки выполняется условие FForm.FEvents <> nil


 
Sany81 ©   (2006-03-02 11:54) [2]


> Для начала убедись, что в момент выполнения этой строчки
> выполняется условие FForm.FEvents <> nil

так у меня и так идет сначала проверка
if FForm.FEvents<>nil then begin//вот она проверка, пробовал даже убирать MessageDlg, думал из за нее все так плохо, но нет, хоть она есть хоть ее нету все равно на строке FForm.FEvents.OnDataRead поток как будто заканчивает свою работу и продолжает дальше цикл
  MessageDlg ("OK"+#13+CB.Msg,mtInformation, [mbOk], 0);// эта строка проходит
  FForm.FEvents.OnDataRead(CB.Msg);//на этой строке поток обрывается и начинается опять чтение данных, при этом событие OnDataRead не вызывается
end


 
Сергей М. ©   (2006-03-02 11:58) [3]

Выполнение условия FForm.FEvents <> nil еще не означает, что поле FEvents содержит корректную интерфейсную ссылку.


 
Sany81 ©   (2006-03-02 13:17) [4]

ОК. Понял, сейчас проверим FEvents



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

Текущий архив: 2006.03.19;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.041 c
15-1140625915
Desdechado
2006-02-22 19:31
2006.03.19
Ресурсы-файлокачалки


1-1140011439
Spieler
2006-02-15 16:50
2006.03.19
Служба + форма


15-1141029035
syte_ser78
2006-02-27 11:30
2006.03.19
Как стать провайдером?


15-1140374277
splr
2006-02-19 21:37
2006.03.19
Интернет...


3-1138366105
diz22
2006-01-27 15:48
2006.03.19
Кол-во записей в DBF. Критично ли 600 000?