Форум: "Прочее";
Текущий архив: 2009.06.14;
Скачать: [xml.tar.bz2];
ВнизЭто баг в формах? Найти похожие ветки
← →
Кто б сомневался © (2009-04-03 15:46) [40]
> Зачем тогда SendMessage(Handle, CM_ACTIVATE, 0, 0), вход
> в цикл, Application.HandleMessage ?
Для того чтобы гарантированно отработали другие события - типа OnActivate и то что в очереди сообщений итп.
← →
clickmaker © (2009-04-03 15:52) [41]> чтобы гарантированно отработали другие события - типа OnActivate
а не кажется, что логика хромает? форма практически одной ногой в могиле, а мы вызываем событие активации
← →
Кто б сомневался © (2009-04-03 16:01) [42]
> а не кажется, что логика хромает? форма практически одной
> ногой в могиле, а мы вызываем событие активации
нет, все вполне логично, вариант, который есть правильный - в [22] работает.
Тогда в оригинальном коде, по вашей логике давайте уберем и эту строку:
ModalResult := 0;
repeat
Application.HandleMessage; << "ведь может быть уже в могиле форма"
if Application.Terminated then ModalResult := mrCancel
else
if ModalResult <> 0 then CloseModal;
until ModalResult <> 0;
Result := ModalResult;
Не пойму почему вас так смущает изменение ModalResult в OnShow?
← →
clickmaker © (2009-04-03 16:05) [43]> Не пойму почему вас так смущает изменение ModalResult в
> OnShow?
потому что нарушается жизненный цикл формы, на котором может быть построена логика другого кода.
Форма должна пройти Oncreate-OnShow-OnActivate-OnPaint
а вот потом - все что угодно
Вообще проблема высосана из пальца. Есть более изящные решения, в т.ч. и с отдельным потоком.
← →
Кто б сомневался © (2009-04-03 16:09) [44]
> Есть более изящные решения, в т.ч. и с отдельным потоком.
Ну приведите мне, хоть одно. Только с одним потоком. И модальной формой (чтобы с другой формой нельзя было работать.).
> потому что нарушается жизненный цикл формы, на котором может
> быть построена логика другого кода.
С чего вы взяли, ничего не нарушается.
← →
clickmaker © (2009-04-03 16:23) [45]с кодом [16] мы вообще рискуем увидеть мелькающую форму на мгновение. И не успеем даже прочитать, что у нас там Processing. И ModalResult особого смысла там не имеет вообще.
А все из-за того, что вторглись в жизненный цикл формы, и не дав ей до конца появиться, запустили некую модальную задачу.
← →
Кто б сомневался © (2009-04-03 16:36) [46]
> с кодом [16] мы вообще рискуем увидеть мелькающую форму
> на мгновение. И не успеем даже прочитать, что у нас там
> Processing.
Слушайте, вы уже начинаете выдумывать.
Причем здесь длительность Processing?
Мигнет она, при условии что операция обработки будет недолгая, а если она будет секунд 10-50? - Ведь это все будет крутиться в OnShow. И только по окончании обработки мы выходим с OnShow.
Ксати, форма также мелькнет и в оригинальном варианте, если ее сразу закрыть.. Тут все зависит от того, сколько времени занимает обработка.
← →
Anatoly Podgoretsky © (2009-04-03 16:42) [47]> Кто б сомневался (03.04.2009 16:36:46) [46]
Зачем нужна форма?
← →
clickmaker © (2009-04-03 16:47) [48]> Мигнет она, при условии что операция обработки будет недолгая,
> а если она будет секунд 10-50?
10-50 секунд юзер будет тупо втыкать в как бы зависшую программу, потом на мгновение мелькнет форма с надписью Processing.
Если у юзера орлинный глаз - таки да, может, он и успеет прочитать о том, что оказывается что-то там было Processing
← →
Кто б сомневался © (2009-04-03 16:58) [49]
> 10-50 секунд юзер будет тупо втыкать в как бы зависшую программу,
> потом на мгновение мелькнет форма с надписью Processing.
>
Application.processmessages там будет, ясен пень...
> Зачем нужна форма?
Это уже к ТЗ.
Но это часто бывает нужно. К примеру если обработка небольшая, к примеру секунд 10-30. и нужно написать "Подождите" или Processing... Wait x. Форма конечно без заголовка - bsNone.
← →
clickmaker © (2009-04-03 17:04) [50]> Application.processmessages там будет, ясен пень...
ага. Открываются новые подробности. То есть какой-то метод некоего класса (причем, может быть, из чужой DLL, да еще написанной на С, к примеру) должен еще знать, что ему периодически надо пинать какую-то форму путем Application.processmessages...
← →
clickmaker © (2009-04-03 17:15) [51]> путем Application.processmessages...
которая, кстати, и не поможет
Потому что мы вызовом модального метода именно в OnShow перекрыли поток остальных сообщений.
Нечего будет processmessages
← →
Кто б сомневался © (2009-04-03 17:17) [52]
> ага. Открываются новые подробности. То есть какой-то метод
> некоего класса (причем, может быть, из чужой DLL, да еще
> написанной на С, к примеру) должен еще знать, что ему периодически
> надо пинать какую-то форму путем Application.processmessages.
> ..
Если закончились аргументы, лучше молчите. А лучше ответьте на [44].
Во первых всегда идет какое то событие прогресса, - изменение прогресса, изменение текущего элемента итп. Если же нет (кстати это уже корректно), то можно просто раз вызвать processmessages до вызова обработки. Тогда обработка должна быть короткой, до 10 сек.
Я еще раз повторяю, это не для длительного процесса.
Для длительного прогресс бар, и поток.
← →
clickmaker © (2009-04-03 17:19) [53]> А лучше ответьте
procedure TForm2.FormActivate(Sender: TObject);
begin
Label1.Caption := "Processing...";
Update;
OtherClass.ProcessSomth;
PostMessage(Handle, WM_SYSCOMMAND, SC_CLOSE, 0);
end;
что-то более красивое недосуг писать. Я бы в потоке сделал
← →
Кто б сомневался © (2009-04-03 17:20) [54]
> Если же нет (кстати это уже корректно), то можно просто
> раз вызвать processmessages до вызова обработки
Опять же здесь лучше второй поток. Условия разные понимаете? Я про Фому, а мне опять про Ярему.
← →
Кто б сомневался © (2009-04-03 17:26) [55]
> clickmaker © (03.04.09 17:19) [53]
>
> > А лучше ответьте
>
> procedure TForm2.FormActivate(Sender: TObject);
> begin
> Label1.Caption := "Processing...";
> Update;
> OtherClass.ProcessSomth;
> PostMessage(Handle, WM_SYSCOMMAND, SC_CLOSE, 0);
> end;
>
> что-то более красивое недосуг писать. Я бы в потоке сделал
ну вот вы и подвердили то что надо было.
Обошли баг отсылкой сообщения.
В потоке - ну вот например мне надо было запустить 3-5 программ, я пишу "подождите" и запускаю их. Я знаю что это займет около 3-5 секунд. Ну не серьезно это переносить на второй поток. Не серьезно и не практично.
← →
Кто б сомневался © (2009-04-03 17:28) [56]
> [55]
Кстати, опять же здесь лучше OnShow, а не OnActivate по понятной причине.
← →
clickmaker © (2009-04-03 17:32) [57]> опять же здесь лучше OnShow
не заработает. Форма не отобразится, хоть 10 Application.processmessages вставь
← →
Кто б сомневался © (2009-04-03 17:32) [58]В [52] ошибка. Отметил жирным.
Если же нет (кстати это уже не корректно- т.е. не отдавать текущий прогерсс), то можно просто раз вызвать processmessages до вызова обработки.
← →
clickmaker © (2009-04-03 17:39) [59]можно еще метод вызвать по таймеру.
Можно в обработчике своего WM_CALL_SOME_METHOD, посланного путем PostMessage
можно просто панель положить невидимую, если заголовок не нужен, и показывать на время работы
можно в заголовке или в статус-баре основной формы писать Processing. Если прогресс нафиг не нужен, то так часто делают
варианты есть, поэтому я упорно продолжаю считать, что проблема, которой автор напряг QC, высосана из пальца )
← →
Кто б сомневался © (2009-04-03 17:48) [60]
> не заработает. Форма не отобразится, хоть 10 Application.
> processmessages вставь
Я думал что по OnShow ее уже видно.
Суть не меняется. OnActivate и close по тому варианту не выполнишь также, т.к. обнуляется уже после активации. Корректный вариант методами VCL - это только второй поток. ИМХО баг остается.
← →
Кто б сомневался © (2009-04-03 17:53) [61]
> можно еще метод вызвать по таймеру.
>>WM_CALL_SOME_METHOD
Можно, но это все варианты обхода официального метода - close, который здесь не работает. C таймером - это мудреж, честно говоря,.
← →
Кто б сомневался © (2009-04-03 18:01) [62]
> варианты есть, поэтому я упорно продолжаю считать, что проблема,
> которой автор напряг QC, высосана из пальца )
Слушайте, какие варианты? вы предлагаете варианта обхода этого бага.
Цель - закрыть форму processing как только закончиться обработка.
Вы ее и закрываете теми самыми вариантами, вместо корректного close
решение - второй поток. Но он здесь не нужен, т.к. обработка в пределах нескольких секунд. Вариант отображать где то на главной форме, не удачный, т.к. юзер должен сразу увидеть что начался процесс обработки.
← →
clickmaker © (2009-04-03 18:18) [63]procedure CallMethodWithSimpleProgressForm(AOwnerForm: TForm);
var
PrForm: TSimpleProgressForm;
p: pointer;
begin
p := DisableTaskWindows(0);
PrForm := TSimpleProgressForm.Create(AOwnerForm);
try
PrForm.Show;
PrForm.Update;
DoSomething;
finally
PrForm.Free;
EnableTaskWindows(p);
BringToFront;
end;
end;
сильно упрощенная имитация ShowModal для однопоточного вызова метода. Для 3-5 секунд вполне подойдет )
← →
clickmaker © (2009-04-03 18:21) [64]> Вариант отображать где то на главной форме, не удачный,
> т.к. юзер должен сразу увидеть что начался процесс обработки.
эээ... а какая связь?
← →
clickmaker © (2009-04-03 18:22) [65]> BringToFront;
вернее, SetActiveWindow(AOwnerForm.Handle);
← →
Кто б сомневался © (2009-04-03 18:31) [66]
> [63]
Короче напомню, - мы спорим о том баг это или не баг.
Вы говорите что это не баг, но предлагаете все время варианты обхода этого бага. Понимаете?
То таймер, то отсылка сообщения, теперь вот иммитация ShowModal.
Так просто согласитесь что это баг, да и все!
Должна быть возможность изменения ModalResult во время активации формы (и соответственно закрытие формы там же). Ладно уже OnShow пропустим, т.к. форма не отображается там.
← →
clickmaker © (2009-04-03 19:11) [67]> Так просто согласитесь что это баг
да можете считать это багом.
Мне лично это не мешает -)
← →
Кто б сомневался © (2009-04-03 19:21) [68]
> да можете считать это багом.
> Мне лично это не мешает -)
Мне то это тоже не мешает, взять отправить WM_CLOSE не сложно.
Кстати, имхо его никто не исправит. Т.к. там проблема глубже.
procedure TCustomForm.CMShowingChanged(var Message: TMessage);
if not (csDesigning in ComponentState) and (fsShowing in FFormState)
raise EInvalidOperation.Create(SVisibleChanged);
← →
Кто б сомневался © (2009-04-03 19:22) [69]
> if not (csDesigning in ComponentState) and (fsShowing in
> FFormState)
Хм, и это в OnActivate когда OnShow уже прошел..
← →
clickmaker © (2009-04-03 19:29) [70]так много можно подобных "багов" найти.
Авторы VCL не могли угодить всем, желающим странного
← →
Кто б сомневался © (2009-04-03 21:21) [71]
> так много можно подобных "багов" найти.
> Авторы VCL не могли угодить всем, желающим странного
Здесь ничего нет странного. Простешая форма, простешее ТЗ из 5 строк.
Но я все таки думаю что это баг. В OnActivate должны были сделать возможность менять ModalResult.
← →
Игорь Шевченко © (2009-04-03 21:25) [72]
> В OnActivate должны были сделать возможность менять ModalResult.
это как ? Активировал форму (допустим мышью), а она mrCancel вернула и закрылась ?
Ты извини, я всю ветку не читал, потому не могу понять, чего тебе надо :)
← →
Кто б сомневался © (2009-04-03 21:39) [73]
> это как ? Активировал форму (допустим мышью), а она mrCancel
> вернула и закрылась ?
Именно.
← →
clickmaker © (2009-04-03 23:36) [74]> не могу понять, чего тебе надо :)
ему надо странного. За что в древнем Китае отрубали руки o)
← →
Игорь Шевченко © (2009-04-03 23:58) [75]
> За что в древнем Китае отрубали руки o)
Вообще-то голову. Желают странного именно головой.
Я просто никак не могу понять, зачем может понадобиться такое поведение формы, которая показывается себе где-то на десктопе. А потом при ее активации закрывается, возвращая (или не возвращая) некий результат.
Я могу понять желание закрыть форму в обработчике события OnCreate, если при ее создании обнаружилось нечто несовместимое с жизнью формы, а вот зачем закрывать на OnActivate - не могу понять.
← →
Кто б сомневался © (2009-04-04 12:13) [76]
> а вот зачем закрывать на OnActivate - не могу понять.
Модальная форма без заголовка - bsNone, служит для того, чтобы отобразить юзеру - текст "подождите" (ну знаете как в инсталляторах). Все работает в одном потоке, т.к. задача на несколько секунд (3-5) поэтому стартуем в OnActivate, делаем все и закрываемся (возможно может быть кнопка "стоп"). Так вот в этом случае мы не закроемся легальным методом Close и кнопка не сработает - т.к. ModalResult обнуляется - причины почему он должен обнуляться, как сейчас, именно после Activate нет.
Поэтому я и считаю это багом, - т.к. это простешее ТЗ, которое довольно часто встречается, и которое нельзя выполнить методами VCL.
← →
Кто б сомневался © (2009-04-04 12:14) [77]
> методами VCL.
Скажем так:
Соответствующими методами VCL
← →
clickmaker © (2009-04-04 16:04) [78]> которое нельзя выполнить методами VCL.
не надо впадать в крайности.
Если есть некая задача, которую нельзя выполнить методами некоего фреймворка, то зачем сразу впадать в ступор и писать гневные письма в саппорт?
Есть API, есть OC - все вполне доступно.
Извините, конечно, но плохому танцору - знаете, что мешает
← →
Кто б сомневался © (2009-04-04 17:29) [79]
> Есть API, есть OC - все вполне доступно.
Вот елки. Который раз уже говорю что это обход официального метода. Close должен работать корректно в OnActivate.
← →
turbouser © (2009-04-04 17:31) [80]
> Кто б сомневался © (04.04.09 17:29) [79]
> Close должен работать корректно в OnActivate.
Он так и работает. Корректно.
Страницы: 1 2 3 вся ветка
Форум: "Прочее";
Текущий архив: 2009.06.14;
Скачать: [xml.tar.bz2];
Память: 0.63 MB
Время: 0.008 c