Независимые потоки

Status
Not open for further replies.

tarakan19832

Турист
Есть mdi приложение (программа для работы с УТМ ЕГАИС – если знаете что это) и скажем 2 child формы.
Форма 1.
На форме есть кнопка, по кнопке запускается поток, который обращается к ресурсу http://localhost:8080, загружает документы, обрабатывает их и т.п. и т.д. На форме есть ProgressBar, который отображает ход процесса, т.е. в процедурах synchronize конкретно указана форма и компонент, который надо менять form1. ProgressBar.position := PROGRES.
На форме 2 есть также кнопка, которая запускает тот же самый поток и ProgressBar, который надо менять, но как сделать так,
1. Чтобы в зависимости от того какая форма вызвала поток, на той форме и менялись контролы
2. Идеально было бы, если бы каждый вызов потока работал независимо от другого. И обновлял нужные контролы.
Подскажите как это осуществить.
 

tarakan1983

Турист
Отвечаю сам себе
Code:
TMyThread =class(TThread)
private
  FmyControl: TProgressBar;
public
  constructor Create(suspend: boolean; Eventcontrol: TProgressBar);
protected
  procedure SynchoEvent;
end;

constructor TMyThread.Create((suspend: boolean; Eventcontrol: TProgressBar);
begin
  inherited Create(suspend);
  self.FMycontrol:=EventControl;// мы будем работать вот с ней
end;

procedure TMyThread.SynchoEvent;
begin
  self.Eventcontrol.Position:=.......// и работаем с ней
end;
Направили в правильную сторону на другом формуме
 
Last edited by a moderator:

Keoda

Турист
Передавай в поток не TProgressBar а указатель на форму, захочешь управлять из потока чем-то ещё на форме - пригодится.
 

tarakan1983

Турист
Keoda, а как передать указатель на всю форму не покажете?
Потому что на одной форме надо менять groupbox.caption, на другой label.caption на третей #какойтолевыкомпонент.caption или #какойтолевыкомпонент.color или #какойтолевыкомпонент.#какоетосвойство.
И самое главное как потом обратиться к свойству этого компонента
 
Last edited by a moderator:

StrikerLoner

Турист
Сразу имеется готовый ответ, если имеется разное количество объектов для обработки, то нужно создать один объект прокладку например
Type
TTMYProxyObjectType = (potNone, potProgress, potGroupBOX, pot<ЧтотоТамМного обектов>)
TMYProxyObject = class
private
FAction: TTMYProxyObjectType;
FProgress: TProgressBar;
FGroupBox: TGroubBox;
FLabel: TLabel;
FLabel_Other: TLabel;

public
property Action: TTMYProxyObjectType read FAction write FAction;

// Ниже описываем все типы контролов которые будут использованы
property Progress: TProgressBar read FProgress write FProgress;
property GroupBox: TGroubBox read FGroupBox write FGroupBox;
property Label: TLabel read FLabel write FLabel;
property Label_Other: TLabel read FLabel_Other write FLabel_Other;
end;

и уже в обработке самого потока смотрим свойство данного объекта Action и работаем с соответствующими свойствами
 

oakrom

Турист
а как передать указатель на всю форму не покажете?
ну примерно вот так:

Code:
constructor Create(suspend: boolean; aSomeForm: TForm);
а обращаться можно примерно вот так:

Code:
(aSomeForm.SomeComponent as TLabel).Caption:='блаблабла';
 

Keoda

Турист
Но, лучше форму из потока не менять. Я, как правило, отправляю из потока PostMessage.
Code:
typedef struct {
HWND__*   hWindow;
unsigned int Msg;
} MessageFromThread;

MessageFromThread msge_params;
msge_params.hWindow = this->Handle;
msge_params.Msg = MSGE_THR_YOUR_MESSAGE_MACRO;
CreateThread(NULL, 0, YourProc, &MessageFromThread, 0, NULL);
Только помните о памяти, через которую идет обмен данными, она должна существовать на пртяжении всего вызова
 

keep91

Турист
Извините что наверно не в тему. Но как можно завершить поток из основного тела программы?
 

pornov

Турист
вызвать метод Terminate через указатель на поток
Terminate лишь устанавливает внутреннюю переменную Terminated в true, что завершает основной цикл в Execute:

Code:
procedure TMyThread.Execute;
begin
  while not Terminated do
    begin
      // тело "вечного" цикла
    end;
end;
После завершения потока необходимо освободить ресурсы вызовом Free.
Кстати, судя по исходникам можно вообще просто вызывать Free, т.к. Terminate вызывается из него:

Code:
destructor TThread.Destroy;
begin
  if (FThreadID <> 0) and not FFinished and not FExternalThread then
  begin
    Terminate;
    if FCreateSuspended then
      Resume;
    WaitFor;
  end;
 ...
end;
Я лично также как и Keoda отправляю данные из потока в главную форму через сообщения, благо там можно все что хочешь передать - текст, число, структуру.
 
Status
Not open for further replies.
Top