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

Вниз

Как из Thread обращ. к объектам на активной MDI-дочерней форме?   Найти похожие ветки 

 
Billis   (2006-06-15 15:40) [0]

Помогите, пож. Есть дочерняя MDI-приложения, на каждой дочерней форме есть кнопка, запускающая процесс. Эти процессы должны заполнять дочернюю форму. Однако, любой из этих процессов заполняет последнюю открытую дочернюю форму, а не ту, с которой был запущен. Как быть?
Процедура процесса:

procedure TMyThread.FullGrid;
VAR i: integer;        
begin

CashCardForm.ADOQuery1.Active:=false;
CashCardForm.ADOQuery1.SQL.Text:=""+
"SELECT DISTINCT Children.ID, Children.Family, Children.Name, Children.HomeID, Home.Title "+
"FROM Home INNER JOIN (Children INNER JOIN (Cash INNER JOIN CashForChildren ON Cash.ID = CashForChildren.IDCash) ON Children.ID = CashForChildren.IDChildren) ON Home.ID=Children.HomeID "+
"WHERE Children.ID NOT IN "+
"(SELECT Children.ID "+
"FROM Home INNER JOIN (Children INNER JOIN (Cash INNER JOIN CashForChildren ON Cash.ID = CashForChildren.IDCash) ON Children.ID = CashForChildren.IDChildren) ON Home.ID=Children.HomeID "+
"WHERE YearCash="+MyMDIForm.cxTextEdit06.Text+") "+
"UNION "+
"SELECT Children.ID, Children.Family, Children.Name, Children.HomeID, Home.Title "+
"FROM Home INNER JOIN Children ON Home.ID=Children.HomeID "+
"WHERE Children.ID NOT IN "+
"(SELECT DISTINCT CashForChildren.IDChildren "+
"FROM CashForChildren)";
CashCardForm.ADOQuery1.Active:=true;
CashCardForm.ProgressBar1.Position:=10;
If CashCardForm.ADOQuery1.RecordCount>0 then
  begin
  CashCardForm.ADOQuery1.First;
  CashCardForm.ADOQuery1.Sort:="ID";
  For i:=1 to CashCardForm.ADOQuery1.RecordCount do
      begin
      CashCardForm.StringGrid1.Cells[0,i]:=CashCardForm.ADOQuery1.FieldValues["ID"];
      CashCardForm.StringGrid1.Cells[1,i]:=CashCardForm.ADOQuery1.FieldValues["Family" ];
      CashCardForm.StringGrid1.Cells[2,i]:=CashCardForm.ADOQuery1.FieldValues["Name"];
      CashCardForm.StringGrid1.Cells[3,i]:=CashCardForm.ADOQuery1.FieldValues["HomeID" ];
      CashCardForm.StringGrid1.Cells[4,i]:=CashCardForm.ADOQuery1.FieldValues["Title"] ;
      CashCardForm.ADOQuery1.Next;
      If i<CashCardForm.ADOQuery1.RecordCount then CashCardForm.StringGrid1.RowCount:=CashCardForm.StringGrid1.RowCount+1;
      CashCardForm.ProgressBar1.Position:=10+(90 div CashCardForm.ADOQuery1.RecordCount)*i;
      end;
  end;
T1.Terminate;
end;


 
Сергей М. ©   (2006-06-15 15:47) [1]


> кнопка, запускающая процесс


Разницу между "процесс" и "thread" осюсяешь ?


 
Billis   (2006-06-15 15:56) [2]

в спысле thread-поток он же нить


 
Сергей М. ©   (2006-06-15 15:57) [3]

Ну тады следует самым серьезным образом отнестись к тому, что обращение в визуальным (и не только) VCL-объектам в контексте доп.потоков НЕдопустимо.


 
evvcom ©   (2006-06-15 15:59) [4]

> Однако, любой из этих процессов заполняет последнюю открытую
> дочернюю форму

Ты ж используешь глобальную переменную CashCardForm! Ясен пень. И эту переменную наверняка переписываешь всякий раз, когда создаешь новую MDI-форму. А теперь подумай, что у тебя происходит, и что же (как же) тебе надо бы сделать.


 
Billis   (2006-06-15 16:00) [5]

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


 
evvcom ©   (2006-06-15 16:01) [6]

> [3] Сергей М. ©

А может он его (TMyThread.FullGrid) через Synchronize вызывает?


 
Сергей М. ©   (2006-06-15 16:02) [7]


> Billis   (15.06.06 16:00) [5]


На то есть демо-проект threads.dpr.

Разберись как он работает и поймешь, что все гениальное проще пареной репы.


 
Сергей М. ©   (2006-06-15 16:03) [8]


> evvcom ©   (15.06.06 16:01) [6]


Судя по изложению проблемы - не похоже.


 
Billis   (2006-06-15 16:03) [9]

для evvcom
необходимо передать в поток номер активной дочернейформы, чтобы обращаться к ней MDIChildren[i]  , но как это сделать?


 
Сергей М. ©   (2006-06-15 16:05) [10]


> необходимо передать в поток номер активной дочернейформы


Не забывай, что пока поток работает, активной может стать другая форма.


 
evvcom ©   (2006-06-15 16:08) [11]

> CashCardForm.ADOQuery1.Sort:="ID";

Почему бы это в SQL не вынести?
Нафига строить динамический запрос, если гораздо нагляднее он в статике в design-time?
Нафига StringGrid заполнять, если можно DBGrid использовать?

> CashCardForm.ADOQuery1.RecordCount

Пока не выполнен метод Last, значению RecordCount доверять нельзя.


 
Billis   (2006-06-15 16:10) [12]

да нет же,
перед запуском потока (по нажатию кнопки на дочерней форме)
необходимо определить номер активной дочерней формы, записать его в глобальную i и обращаться в потоке именно к нужной дочерней так  MainForm.MDIChildren[i].
Так наверное нужно сделать?


 
evvcom ©   (2006-06-15 16:14) [13]

> [8] Сергей М. ©

Да. Надо было смайлик поставить.

> [9] Billis

например в конструкторе. Только передавать тогда уж не номер, а сразу указатель на объект. Воспользуйся лучше советом [7]

> [12] Billis

нет, не так. Использование глобальных переменных для передачи локальных параметров чревато.


 
Джо ©   (2006-06-15 16:16) [14]

> [12] Billis   (15.06.06 16:10)
> да нет же,
> перед запуском потока (по нажатию кнопки на дочерней форме)
>
> необходимо определить номер активной дочерней формы, записать
> его в глобальную i и обращаться в потоке именно к нужной
> дочерней так  MainForm.MDIChildren[i].
> Так наверное нужно сделать?

Зачем в глобальную? Заведи у своего потока свойство, в него и записывай ту форму, которая активна на момент создания экз. потока.


 
Billis   (2006-06-15 16:21) [15]

А как определить какой номер у активной дочерней?


 
Billis   (2006-06-15 16:31) [16]

Спасибо


 
Джо ©   (2006-06-15 16:33) [17]

> [15] Billis   (15.06.06 16:21)
> А как определить какой номер у активной дочерней?

А не лучше ли, как уже, кажется, советовали, запоминать не номер, а ссылку на сам экземпляр формы? Зачем вводить лишние сущности и условности?


 
Billis   (2006-06-15 16:37) [18]

Как ввести ссылку на экземпля формы и передать ее?


 
Джо ©   (2006-06-15 16:49) [19]

> [18] Billis   (15.06.06 16:37)
> Как ввести ссылку на экземпля формы и передать ее?

Например, так:

// Твой потомок TThread
// со свойством
 TMyThread = class (TThread)
 private
   FMyForm: TMyMDIForm;
 public
   property MyForm: TMyMDIForm read FMyForm write FMyForm;
 end;


// Ну, и создание и запуск потока в таком роде:
 with TMyThread.Create(True) do
 begin
   FreeOnTerminate := True
   MyForm := <ссылка на активную MDI-форму>
   ....
   Resume
 end;


 
evvcom ©   (2006-06-15 16:49) [20]

procedure TMyMDIForm.FormCreate(Sender: TObject);
begin
 FMyThread := TMyThread.Create(Self);
end;

constructor TMyThread.Create(AOwner: TMyMDIForm);
begin
 FMyMDIForm := AOwner;
 inherited Create(False);
end;


 
Billis   (2006-06-15 17:05) [21]

по [19] сделал - таже ерунда, заполняется только последняя дочерняя форма


 
Сергей М. ©   (2006-06-15 17:07) [22]

Отладчик тебе в руки.



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

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

Наверх




Память: 0.52 MB
Время: 0.029 c
3-1148455210
Бульбаш
2006-05-24 11:20
2006.07.30
Проблемы с цветом в гриде под Win98


2-1152258098
alexal
2006-07-07 11:41
2006.07.30
формула разложения 16 битного числа на 2 байта


2-1152173712
Ламот
2006-07-06 12:15
2006.07.30
Работа с текстовым файлом


6-1142861596
RomanH
2006-03-20 16:33
2006.07.30
Параметры SocketConnection во время выполнения программы


2-1152543830
Blackcrazzy
2006-07-10 19:03
2006.07.30
Frame