Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2009.06.14;
Скачать: [xml.tar.bz2];

Вниз

Это баг в формах?   Найти похожие ветки 

 
Internal Tracking   (2009-04-02 22:17) [0]

Запостил тут бяку одну на саппорт. Форма не закрывается при вызове Close. Я уверен что это баг, но возможно я ошибаюсь? Посмотрите pls
http://qc.embarcadero.com/wc/qcmain.aspx?d=72693


 
Internal Tracking   (2009-04-02 22:18) [1]

D2009


 
boa_kaa ©   (2009-04-02 22:44) [2]

верни свою бяку обратно и не трепли нервы саппорту по причине неумения работать с хелпом


 
KilkennyCat ©   (2009-04-02 22:47) [3]


> верни свою бяку обратно

любопытно, с точки зрения копрофагии...


 
Internal Tracking   (2009-04-02 23:29) [4]


> верни свою бяку обратно и не трепли нервы саппорту по причине
> неумения работать с хелпом


А почему это я не могу юзать подобную конструкцию?
Я работаю в главном потоке.
Я запускаю вторую форму, в ней в OnShow отображаю Processing и вызываю свою функцию..  После окончания функции, я опять выхожу в OnShow и  вызываю Close формы. что тут не правильного? А как тогда правильно?


 
Internal Tracking   (2009-04-02 23:36) [5]

Далее, смотрим в хелп OnShow - написано:

Occurs when the form is shown (that is, when its Visible property is set to true).
Use OnShow to perform special processing when the form is shown (that is, when the form"s Visible property is set to true).  

Где тут написано подобное про Close или ModalResult ?
Если вы правы, тогда объясните, чтобы не быть голословным.
Вторая форма в данном случае, без заголовка, на ней только Label для отображения текста "Processing".


 
Internal Tracking   (2009-04-02 23:40) [6]


> по причине неумения работать с хелпом


Так, также посмотрел хелп по ModalResult и Close. Ничего подобного не написано.


 
wicked ©   (2009-04-02 23:51) [7]

это баг в твоем коде - так делать нельзя
ембаркадеры не обязаны править баги в коде пользователя


 
turbouser ©   (2009-04-02 23:58) [8]


> Internal Tracking   (02.04.09 23:40) [6]

Попробуй закрыть закрытую дверь.


 
жж   (2009-04-03 00:00) [9]

как сделать правильно:
после того, как в OnShow сделал что надо, отправляй сам себе сообщение "закройся", на Self.Handle, тока обязательно с помощью PostMessage.
а вообще паттер дурной весьма - закрывать в OnShow


 
Internal Tracking   (2009-04-03 00:07) [10]


> после того, как в OnShow сделал что надо, отправляй сам
> себе сообщение "закройся", на Self.Handle, тока обязательно
> с помощью PostMessage.
> а вообще паттер дурной весьма - закрывать в OnShow


Да почему ж дурной!? Почему? Ведь фактически я ведь ставлю ModalResult. Разве его (ModalResult) нельзя менять в OnShow?
Т.е. отправлять WM_CLOSE я могу, а вот менять ModalResult нет . Ну не глупо ли?


>
> > wicked ©   (02.04.09 23:51) [7]
>

> это баг в твоем коде - так делать нельзя


Елки палки, дык объясните почему!


 
Internal Tracking   (2009-04-03 00:21) [11]


> wicked ©   (02.04.09 23:51) [7]


Просто объясните почему.
1. В техническом плане - это не опасно (Ни AV, ни ошибок синхронизации итп). и даже не предсказывается, при работе с основным потоком.
2. Этические соображения (грязный или непонятный код, путанница, итп)  - также не не то.. Здесь все на ладони.

Расскажите тогда, в чем проблема этого кода, и почему это не баг?


 
жж   (2009-04-03 00:25) [12]


>
> Т.е. отправлять WM_CLOSE я могу, а вот менять ModalResult
> нет . Ну не глупо ли?
>


Нет, и то, и то - дурной тон, просто в одном случае работает, а в другом нет


 
жж   (2009-04-03 00:28) [13]


> Да почему ж дурной!? Почему?


потому, что "форма прогресса" должна показывать результаты какого -  то процесса, а не выполнять сам процесс.
А что касается того, почему борланд не сделал - вопрос философский. Не сделал, это данность. И не сделает


 
Кто б сомневался ©   (2009-04-03 00:42) [14]

C точки зренимя правильности - это явный баг.
ModalResult программист действительно может изменить в OnShow, мало ли.
Я еще понимаю в OnCreate это делать нельзя, - можно понять, но в OnShow..


>  Не сделал, это данность. И не сделает


Кстати, там всего то нужно перетащить "ModalResult := 0" на 4 строчки вверх, до вызова Show.  Не знаю как в других Delphi, сейчас посмотреть не могу, у меня тоже 2009.


> что "форма прогресса" должна показывать результаты какого
> -  то процесса


Да ну? Серьезно? Это что конструктор форм, или а-ля скрипт в Word"e?


 
Германн ©   (2009-04-03 00:51) [15]


> Кто б сомневался ©   (03.04.09 00:42) [14]
>
> C точки зренимя правильности - это явный баг.
> ModalResult программист действительно может изменить в OnShow,
>  мало ли.

Нормальный программист понимает, что модальное окно - суть диалог с пользователем. И не станет "сваливать" на "мало ли что".
А пример с использованием Splash поставляется ещё со времен Д1.


 
Internal Tracking   (2009-04-03 00:53) [16]


> потому, что "форма прогресса" должна показывать результаты
> какого -  то процесса, а не выполнять сам процесс.


Форма ничего не выполняет.
Я ж объяснил. В OnShow формы вызывается метод другого класса.
Но т.к. это все выполняется в одном потоке, - т.е. главном, - по окончании этого метода, опять возвращаемся в OnShow,

N/е.

procedure TForm2.FormShow(Sender: TObject);
begin
  MyLabel.Caption := "Processing"
  OtherClass.ProcessSomth; // около 3-8 сек
 
  ModalResult := mrOk. // ну или другое, - это для примера    
end;


 
turbouser ©   (2009-04-03 01:04) [17]


> Internal Tracking   (03.04.09 00:53) [16]


> Форма ничего не выполняет.

На кой она вообще тогда нужна?

> odalResult := mrOk. // ну или другое, - это для примера
>    

См.

> turbouser ©   (02.04.09 23:58) [8]


> Кто б сомневался ©   (03.04.09 00:42) [14]
>
> C точки зренимя правильности - это явный баг.

Баг заключается в том, что иде не ругается на Close и ModalResult := ... etc


 
Кто б сомневался ©   (2009-04-03 01:18) [18]


> Нормальный программист понимает, что модальное окно - суть
> диалог с пользователем. И не станет "сваливать" на "мало
> ли что".


Да ну ладно рассказывать.
Допустим есть варианты  - т.е. отображается текст мол "работаю..." и там пару кнопок. И все делается в одном потоке (бывает что операция не занимает много времени). Юзер может нажать на копку, а может и не нажать. Что ж сваливать весь код на главную форму со всеми событиями и оттуда выставлять Caption второй формы? Туповато как-то.
ИМХО логичнее разгруппировать - меньше путанницы. Второй форме передать нужный класс и вперед. Я пойму еще если там нужно только отображать текст Processing - как у автора, но если там больше действий.

Кстати, причину почему так нельзя делать, кроме как "так сказал Аллах Всевышний (мир ему и благословение)", так никто и не назвал.


 
Германн ©   (2009-04-03 01:26) [19]


> Кто б сомневался ©   (03.04.09 01:18) [18]
>
>
> > Нормальный программист понимает, что модальное окно -
> суть
> > диалог с пользователем. И не станет "сваливать" на "мало
> > ли что".
>
>
> Да ну ладно рассказывать.
> Допустим есть варианты  - т.е. отображается текст мол "работаю.
> .." и там пару кнопок. И все делается в одном потоке (бывает
> что операция не занимает много времени). Юзер может нажать
> на копку, а может и не нажать.

Да ну ладно придумывать всякую чушь оправдывающую "криворукость".


 
Германн ©   (2009-04-03 01:29) [20]


> Кто б сомневался ©   (03.04.09 01:18) [18]
>
> Кстати, причину почему так нельзя делать, кроме как "так
> сказал Аллах Всевышний (мир ему и благословение)", так никто
> и не назвал.
>

Тогда я назову.
Потому что нормальные люди думают нормально. А все бредовые идеи предусмотреть просто не реально.


 
Германн ©   (2009-04-03 01:41) [21]

Кстати.
А о чём тут спор?
Обратите внимание на то, как автор описал Reproduce:
procedure TForm1.FormShow(Sender: TObject);
begin
 form2 := TForm2.Create(Application);
 Form2.ShowModal;
end;

И не упомянул при этом, что TForm2 он убрал из списка "Автосоздание"!


 
Кто б сомневался ©   (2009-04-03 02:10) [22]


Германн ©
> Да ну ладно придумывать всякую чушь оправдывающую "криворукость".


Ну какие же они бредовые еклм?

Берем вариант афтара, - форма с label, но добавляем туда кнопку.
Все крутится в одном потоке. Обновляется через Application.ProcessMesages.
В OnShow стартуем. Жмем на кнопку, и опа, а закрыться то мы не можем легально, т.к. ModalResult не работает корректно - он обнуляется после выхода в OnShow.

Прежде чем кричать, предожите не бредовый вариант, я посмотрю..
Один поток конечно, - основной, не забывайте.


 
Кто б сомневался ©   (2009-04-03 02:14) [23]


> И не упомянул при этом, что TForm2 он убрал из списка "Автосоздание"!


Боже, да причем здесь автосоздание. Ведь ModalResult обнуляется после выхода с OnShow, что с автосозданием, что без него.


 
AndreyV ©   (2009-04-03 08:26) [24]

> [18] Кто б сомневался ©   (03.04.09 01:18)
> ИМХО логичнее разгруппировать - меньше путанницы. Второй
> форме передать нужный класс и вперед.

Создать экземпляр нужного класса вызваеть его метод, а уж он, если ему надо, создаёт вторую форму "Прогресс", показывает её немодально и занимается с ней. По нажатию кномки вторая форма не закрывается сама, а выставляет флаг КнопкаБылаНажата, который проверяется создавшим её и форма закрывается им же.


 
KSergey ©   (2009-04-03 10:00) [25]

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

Для решения задачи автора есть другие методы, упирать на этот - совершенно нет смысла. Данный обработчик вовсе не про то. И так было всегда в дельфи, из ShowModal вызывать Close нельзя. И аллах тут ни при чем, есть интерфейс.


 
KSergey ©   (2009-04-03 10:03) [26]

Я, кстати, сильно пдозреваю, что борланды данный код написали не от балды. Наверняка соотв. сообщение Windows (от которого в итоге этот обработчк и растёт) другого просто не допускает, так что тем, кто предлагает патчи к генофонду есть смысл попробовать сработает ли такое решение. Это не сложно. (может и сработает, конечно, я не проверял)


 
clickmaker ©   (2009-04-03 11:42) [27]

> procedure TForm2.FormShow(Sender: TObject);
> begin
>  MyLabel.Caption := "Processing"
>  OtherClass.ProcessSomth; // около 3-8 сек
>  
>  ModalResult := mrOk. // ну или другое, - это для примера
>  
> end;


Form2 := TForm2.Create(Application);
try
 Form2.MyLabel.Caption := "Processing";
 Form2.Show;
 OtherClass.ProcessSomth;
finally
 Form2.Free;
end;

почему бы не быть проще? чтоб к тебе потянулись люди


 
Кто б сомневался ©   (2009-04-03 14:13) [28]


> Создать экземпляр нужного класса вызваеть его метод, а уж
> он, если ему надо, создаёт вторую форму "Прогресс", показывает
> её немодально и занимается с ней.


Это уже обход ошибки. Кстати, так лучше не делать - не надо перемешивать рабочие классы, с формами. Формы должны вызывать методы классов, а не наоборот.

> clickmaker ©   (03.04.09 11:42) [27]

The same.


> Я, кстати, сильно пдозреваю, что борланды данный код написали
> не от балды.

На деле если перенести ModalResult := 0 выше Show ничего не изменится.
Так что никакой балды здесь я не вижу.
И вообще не пойму почему программист не может менять ModalResult в OnShow?


>
> анный обработчик вовсе не про то. И так было всегда в дельфи,
>  из ShowModal вызывать Close нельзя.


Обычно если нельзя, пишут в хелпе, чего там нет.


 
test ©   (2009-04-03 14:17) [29]

clickmaker ©   (03.04.09 11:42) [27]
Form2.Show; == Form2.ShowModal;?
А то чревато ошибками, пользователь будет за окном гоняться.


 
clickmaker ©   (2009-04-03 14:28) [30]

> И вообще не пойму почему программист не может менять ModalResult
> в OnShow?

загляни в Forms.pas - ShowModal

Show;
try
 SendMessage(Handle, CM_ACTIVATE, 0, 0);
 ModalResult := 0;
 repeat
 ...
 until ModalResult <> 0;


 
AndreyV ©   (2009-04-03 14:38) [31]

> [28] Кто б сомневался ©   (03.04.09 14:13)
>
> > Создать экземпляр нужного класса вызваеть его метод, а уж
> > он, если ему надо, создаёт вторую форму "Прогресс", показывает
> > её немодально и занимается с ней.
>
> Кстати, так лучше не делать - не надо
> перемешивать рабочие классы, с формами. Формы должны вызывать
> методы классов, а не наоборот.

Никакой класс, кроме "рабочего", не знает что и когда отображать на форме, работать с экземплярами класса которой могут и должны все подобные этому. Это о форме типа "Прогресс бар", смене её заколовка, изменении позиции индикатора, через методы типа StepIt() и подобные.


 
Anatoly Podgoretsky ©   (2009-04-03 14:56) [32]

> clickmaker  (03.04.2009 14:28:30)  [30]

Все прекрасно и правильно написано. Все логично.


 
Кто б сомневался ©   (2009-04-03 14:58) [33]


> clickmaker ©   (03.04.09 14:28) [30]
>
> > И вообще не пойму почему программист не может менять ModalResult
>
> > в OnShow?
>
> загляни в Forms.pas - ShowModal


Здрасьте, этот код еще автор в начале написал (в ссылке). в этом то и баг. Проснулся... :)


> AndreyV ©   (03.04.09 14:38) [31]
> Никакой класс, кроме "рабочего", не знает что и когда отображать
> на форме, работать с экземплярами класса которой могут и
> должны все подобные этому. Это о форме типа "Прогресс бар",
>  смене её заколовка, изменении позиции индикатора, через
> методы типа StepIt() и подобные.


Это делается при помощи событий. Т.е. клас возбужает событие, которое перехватывает форма. - типа MyClass.OnChangeItem итп. Так как вы предложили, не делается - по очевидным соображением (путанница, грязный код, класс заточен только под форму итп..).


 
Кто б сомневался ©   (2009-04-03 15:03) [34]


> Anatoly Podgoretsky ©   (03.04.09 14:56) [32]


Кто б сомневался ©   (03.04.09 02:10) [22]  =
не работает - хотя вариант вполне легальный и правильный.

Вобщем я понял. Раз Borland и CodeGear не исправили этот баг, значит он автоматом становиться фичей (мысль стандартного программиста - ну куда уж мне давать советы самому Borland\CodeGear - ведь там сидять киборги которые никогда не ошибаются... Поэтому буду как вся масса говорить - да нету там бага, "Все прекрасно и правильно написано. Все логично.").
И причину никто пока не объяснил, хотя вот уже вторая страница пошла. Зато все говорят  [32]


 
clickmaker ©   (2009-04-03 15:05) [35]

> Здрасьте, этот код еще автор в начале написал (в ссылке)
> .

мне иногда лениво по ссылкам тыцать )
и что, было лучше, если б там так было:

ModalResult := 0;
Show;
if ModalResult <> 0 then CloseModal;
try
if ModalResult = 0 then
  SendMessage(Handle, CM_ACTIVATE, 0, 0);
if ModalResult <> 0 then CloseModal;
while ModalResult = 0 do begin
...

не слишком ли много проверок?


 
AndreyV ©   (2009-04-03 15:05) [36]

> [33] Кто б сомневался ©   (03.04.09 14:58)
> Так как вы предложили, не делается - по очевидным соображением
> (путанница, грязный код, класс заточен только под форму
> итп..).

Наверно, мы говорим о разном.
Класс ПрогрессБар один для всех, все знают о способах работы с ним.


 
Кто б сомневался ©   (2009-04-03 15:34) [37]


> clickmaker ©   (03.04.09 15:05) [35]
> и что, было лучше, если б там так было:


Ох, представляю какой код вы пишите...
Вот оригинальный код:

 
 Show;
 try
    SendMessage(Handle, CM_ACTIVATE, 0, 0);
    ModalResult := 0;
    repeat
      Application.HandleMessage;
      if Application.Terminated then ModalResult := mrCancel
      else
        if ModalResult <> 0 then CloseModal;
    until ModalResult <> 0;
   Result := ModalResult;


Простое перемещение
 
ModalResult := 0;
 Show;
 try
    SendMessage(Handle, CM_ACTIVATE, 0, 0);  
    repeat
      Application.HandleMessage;
      if Application.Terminated then ModalResult := mrCancel
      else
        if ModalResult <> 0 then CloseModal;
    until ModalResult <> 0;
   Result := ModalResult;


Т.е. просто переносим ModalResult и ставим перед Show. Абсолютно никаких побочек, изменений в старых программах, в новых втч. итд. И баг исправлен.


 
clickmaker ©   (2009-04-03 15:41) [38]

> Т.е. просто переносим ModalResult и ставим перед Show

а если мы в OnShow его изменили?
Зачем тогда SendMessage(Handle, CM_ACTIVATE, 0, 0), вход в цикл, Application.HandleMessage ?


 
Кто б сомневался ©   (2009-04-03 15:44) [39]


> AndreyV ©   (03.04.09 15:05) [36]
>
> > [33] Кто б сомневался ©   (03.04.09 14:58)
> > Так как вы предложили, не делается - по очевидным соображением
>
> > (путанница, грязный код, класс заточен только под форму
>
> > итп..).
>
> Наверно, мы говорим о разном.
> Класс ПрогрессБар один для всех, все знают о способах работы
> с ним.

Ну насколько я понял, вы предлагаете из какого то класса, запускать форму и из класса ставить значения форме (а не из формы запускать класс, а затем реагировать на события класса, которые устанавливают значения в форме).
Вот я об этом. А с прогресс баром я работаю как и все - т.е. просто устанавливаю Position и все.


 
Кто б сомневался ©   (2009-04-03 15:46) [40]


> Зачем тогда SendMessage(Handle, CM_ACTIVATE, 0, 0), вход
> в цикл, Application.HandleMessage ?


Для того чтобы гарантированно отработали другие события - типа OnActivate и то что в очереди сообщений итп.



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

Форум: "Прочее";
Текущий архив: 2009.06.14;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.005 c
15-1239379729
Real
2009-04-10 20:08
2009.06.14
Использование компонентов от Delphi 5 в Delphi 6


2-1240844649
Igor2010
2009-04-27 19:04
2009.06.14
Помогите плиз с TWebBrowser


2-1240826671
TNT
2009-04-27 14:04
2009.06.14
Системное меню


2-1240904761
rar
2009-04-28 11:46
2009.06.14
Копирование файла


15-1239292132
CoderM
2009-04-09 19:48
2009.06.14
Реализация Captcha





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский