Форум: "Начинающим";
Текущий архив: 2006.03.19;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.014 c