Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
2-1240783670
Rembo
2009-04-27 02:07
2009.06.14
Проблема с ООП Access Violation


2-1240689147
Ramil
2009-04-25 23:52
2009.06.14
combobox


15-1239376021
мда, серьезные люди...
2009-04-10 19:07
2009.06.14
Почему я не могу попасть на форумы с сохраненных ранее ссылок?


3-1222175692
SergP
2008-09-23 17:14
2009.06.14
Oracle. Insert


6-1203400294
grisme
2008-02-19 08:51
2009.06.14
CONNECT-режим





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский