![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
DLL и форма [D7, XP]
Yegorchic © (2006-07-12 09:29:00)Здравствуйте!
Во время выполнения в DLL'ке одного кода мне надо создавать там форму и потом после того как она закроется её уничтожать. Создаю форму я так:
if newform = nil then newform:=Tnewform.Create(Application);
Далее у меня идёт код работы с формой, а точнее я присваиваю переменной LV (TTreeView) свой TreeView с NewForm.
LV:=newform.TreeView;
И потом идёт одиц цикл и после его выполнения делается
newform.ShowModal;
А сразу поле этого я пишу
newform.Free;
Если запустить этот код, то сразу будет какая-то ошибка (vialation access, т.к. Delphi ни на какую строчку не показыват).
Если же, сразу после создания формы постаить вот такой небольшой код
repeat
Application.ProcessMessages;
sleep(100);
until not (newform = nil);
то уже становится лучше: ошибка вылезает не постоянно, а только иногда, но всё же вылезает.
Как правильно создавать и удалять форму? Что я делаю тут не так?
И ещё, код с созданием формы у меня находится в кнопке, и пользователь эту кнопку может нажимать сколько угодно раз во время работы программы, но когда уже второй раз жмёшь на эту кнопку, то сразу же, вылезает ошибка та же.
Что делать? Как исправить глюк?
Yegorchic (2006-07-13 09:35:00) [1]Всё заработало!
Сделал я всё так:
я создал новую переменную nform: TForm;
Перед запуском потока я создаю эту форму так: nform:=Tnewform.create(nil);
Потом дальше я работал с nform только, и всё было хорошо! Т.к. я работаю с единственным компонентом на форме той - TListView'ов, то я просто нашёл его так (var LV: TListView;):
for i:=0 to nform.ComponentCount-1 do
if (nform.Components[i] is TListView) then
LV:=TListView(nform.Components[i]);
И всё, дальше всё делал также как и с той формой: nform.ShowModal; nform.free; nform:=nil; и всё!
parovoZZ (2006-07-12 19:53:00) [2]Я бы сделал так - жмём кнопку - запускаем модальное окно - в OnCreate создаём нить и делаем всё, что нам хочется.
Yegorchic (2006-07-12 17:41:00) [3]Что-то я совсем запутался...
Ладно, наврное надо придумать, как можно сделать это всё по-другому.
Desdechado (2006-07-12 17:34:00) [4]Издеваешься?
В 47 я спрашивал о потоке, который должен что-то делать, не зная о форме вообще. И его можно создать уже после того, как нажата кнопка на форме. И в нем нет смысла пытаться показывать форму, да еще и модально.
Yegorchic (2006-07-12 17:29:00) [5]
> Нельзя что ли создать поток при нажатии кнопки в форме?
А он так и создаётся.
Я так пытался (выше писал):
Создаётся newform в OnCreate mainform'ы > жмём на кнопку, которая на MainForm > создаётся поток, в середине которого только показывается форма > закончился поток, закрываем программу и всё вроде бы хорошо прошло, как вдруг в OnDestroy MainForm'ы выполняется newform.Free и вылезает ошибка про неверный дескриптор окна.
Desdechado (2006-07-12 17:23:00) [6]> А в потоке тогда я только newform.showModal делал
И зачем?
Нельзя что ли создать поток при нажатии кнопки в форме?
Yegorchic (2006-07-12 17:18:00) [7]
> Очень полохо поступаешь. А то, что все работает, то это
> просто повезло.
А почему, кстати, когда я написал synchronize(myProc) - поток как бы "заело" (я выше писад об этом)?
Amoeba (2006-07-12 17:15:00) [8]
> надо делать этот Synchronize, но я делаю всё и без него
> и с компонентами работаю - всё хорошо работает.
Очень полохо поступаешь. А то, что все работает, то это просто повезло.
Yegorchic (2006-07-12 17:14:00) [9]
> Desdechado © (12.07.06 17:02) [41]
Да, я так пытался сделать. Когда я создавал newform в OnCreate MainForm'ы и делал newform.free в OnDestroy MainForm'ы, то тогда мне прога выдавала ошибку, что "неверный дескриптор окна" при OnDestroy'е (т.е. выполнялся newform.Free). А в потоке тогда я только newform.showModal делал, т.е. его уже не вынести из потока.
Yegorchic (2006-07-12 17:14:00) [10]
> Desdechado © (12.07.06 17:02) [41]
Да, я так пытался сделать. Когда я создавал newform в OnCreate MainForm'ы и делал newform.free в OnDestroy MainForm'ы, то тогда мне прога выдавала ошибку, что "неверный дескриптор окна" при OnDestroy'е (т.е. выполнялся newform.Free). А в потоке тогда я только newform.showModal делал, т.е. его уже не вынести из потока.
Yegorchic (2006-07-12 17:09:00) [11]
> Amoeba © (12.07.06 16:54) [38]
Когда сделал ка вы сказали, всё стало только хуже: поток как бы вообще не запусклся. Ну MyProc не выполнялась, как бы.
Да, с потоками я недавно работаю, и вы сказали, что надо делать этот Synchronize, но я делаю всё и без него и с компонентами работаю - всё хорошо работает. В этом потоке ещё есть некоторые функции (напримерmainForm.iLabel.Caption:='тест';- и всё появляется, но когда поставил этот Synchronize - перестало всё работать, как я уже сказал)
Desdechado (2006-07-12 17:02:00) [12]Yegorchic © (12.07.06 16:57) [39]
Так и вынеси в потокдействия, а не создание формы и работу из нее.
Amoeba (2006-07-12 16:59:00) [13]
> repeat
> Application.ProcessMessages;
> sleep(100);
> until not (newform = nil);
И нафига здесь Sleep?
Yegorchic (2006-07-12 16:57:00) [14]
> Desdechado © (12.07.06 16:52) [37]
Дык дело то не в форме. Просто действия, которые в том потоке достаточно долго выполняются, поэтому что бы программа "не зависала", я сделал поток такой.
Amoeba (2006-07-12 16:54:00) [15]
> В потоке запускается одна функция:
> procedure TMyThread.Execute;
> begin
> MyProc;
> end;
Вот и грабли! Поскольку в MyProc имеем дело с компонетами, то не надо забывать про Synchronize:
procedure TMyThread.Execute;
begin
Synchronize(MyProc);
end;
Desdechado (2006-07-12 16:52:00) [16]Если у тебя форма модальная, зачем тебе отдельная нить?
Yegorchic (2006-07-12 16:45:00) [17]
> Вообщем, если кнопка.
если = есть
> одна функция:
извиняюсь, процедура
Yegorchic (2006-07-12 16:44:00) [18]Вообщем, если кнопка. По её нажатию запускается так поток:
MyThread:=TMyThread.Create;
MyThread.Resume; // поток создаётся приостановленным
В потоке запускается одна функция:
procedure TMyThread.Execute;
begin
MyProc;
end;
Что это за процедура:
procedure TMyThread.MyProc;
var
i: integer;
//.......
begin
//... тут второстепенный код, не имебщий никакого отношения в созданию формы
if newform=nil then begin
newform:=Tmsgform.Create(nil);
repeat
Application.ProcessMessages;
sleep(100);
until not (newform = nil);
end;
// ... тут опять второстепенный код
for i:=1 to .... do
begin
// здесь создаются Item'ы в TListView'е, который на newform находится
end;
newform.ShowModal;
newform.Free; newform:=nil;
// всё, работа с формой закончена, опять второстепенный код
end;
На форме newform нет ничего особенного, только этот ListView и одна кнопка, которая закрывает форму (Close;).
Всё. Столько хватит? Или ещё что-то?
P.S:
> Здесь запросто могут лежать хо-о-о-рошие грабли!
К примеру?
Amoeba (2006-07-12 16:41:00) [19]
> Yegorchic © (12.07.06 16:34) [33]
>
> > Desdechado © (12.07.06 16:30) [30]
>
>
> Что, всё так плохо?
Не просто плох, а хуже некуда!
Yegorchic (2006-07-12 16:34:00) [20]
> Desdechado © (12.07.06 16:30) [30]
Что, всё так плохо?