Форум: "Прочее";
Текущий архив: 2009.06.21;
Скачать: [xml.tar.bz2];
Внизвопрос по CloseQuery Найти похожие ветки
← →
Кто б сомневался © (2009-04-09 13:37) [40]
> А то что программист не отреагировал на эту ситуацию и выдал
> подобный запрос плохо говорит об его квалификации, это же
> не запрос на сохранение файлов.
По меркам VCL скрытая форма- это уже закрытая форма (caHidden).
Какие могут быть события перед закрытием - OnCloseQuery если форма уже закрыта?
← →
Игорь Шевченко © (2009-04-09 13:48) [41]Кто б сомневался © (09.04.09 13:31) [39]
> OnCloseQuery должна получать видимая форма по очевидным
> и логичным причинам
Ты ошибаешься. VCL не знает, что происходило в форме до момента прихода сообщения WM_QUERYENDSESSION и возлагает принятие решения о необходимых действиях на программиста, пишущего обработчик события OnCloseQuery.
← →
Кто б сомневался © (2009-04-09 15:08) [42]
> Ты ошибаешься. VCL не знает, что происходило в форме до
> момента прихода сообщения WM_QUERYENDSESSION и возлагает
> принятие решения о необходимых действиях на программиста,
> пишущего обработчик события OnCloseQuery.
Это ты ошибаешся, и причем не хочешь признавать ошибку, чтобы казаться правым (ну я же гуру).
VCL и не должна знать что происходило на форме, она должна проверять видимая ли форма или нет (т.к. [40]). Программист, который писал тот код просто забыл (не учел) это сделать.
← →
Кто б сомневался © (2009-04-09 15:10) [43]Смысла уже спорить я не вижу, т.к. баг уже открыт и признан саппортом (иначе он был бы Reported или Closed или Pending).
← →
Игорь Шевченко © (2009-04-09 15:15) [44]
> Это ты ошибаешся
Я не ошибаюсь. Я бы сделал точно также, как сделано в VCL, почему - я уже писал, не вижу смысла повторяться. Невидимая и закрытая форма - это две разные вещи, проще понять эту простую истину и не спорить
> По меркам VCL скрытая форма- это уже закрытая форма (caHidden).
Это неверное утверждение
← →
Cobalt © (2009-04-09 15:24) [45]
> Кто б сомневался © (09.04.09 03:24) [29]
Для того, чтобы спрашивать пользователя о сохранении изменений, эти изменения должны случиться.
Обычно для этого используется один или несколько флагов, которые взводятся при изменении данных на форме пользователем
← →
Кто б сомневался © (2009-04-09 15:25) [46]
> Я бы сделал точно также, как сделано в VCL, почему - я уже
> писал, не вижу смысла повторяться
Ага, потому что на уровне API рассылается сообщение окнам. хороший аргумент. VCL это не API. Формы это не окна - у них своя логика, которая в данном случае нарушается.
Короче [43]
← →
Anatoly Podgoretsky © (2009-04-09 15:28) [47]> Кто б сомневался (09.04.2009 13:37:40) [40]
Hidden переводится как невидимая, но никак не закрытая.
← →
Игорь Шевченко © (2009-04-09 15:28) [48]
> Формы это не окна - у них своя логика, которая в данном
> случае нарушается.
Не вижу какой-то "своей логики" у форм VCL при обработке оконных сообщений.
Если ты полагаешь, что невидимая форма не должна обрабатывать оконных сообщений, то ты глубоко ошибаешься.
← →
Кто б сомневался © (2009-04-09 15:48) [49]
> Не вижу какой-то "своей логики" у форм VCL при обработке
> оконных сообщений.
Нарушение логики форм 1:
OnCloseQuery должен срабатывает перед OnClose - я переведу:
Событие ЗапросНаЗакрытие формы должен срабатывать перед событием ПриЗакрытии формы.
Если OnCloseQuery произошел, должен произойти OnClose. чего не происходит в данном случае.
Нарушение логики форм 2:
Help:
> You can use an OnCloseQuery event handler to ask users if
> they are sure they really want the form closed immediately.
> For example, you can use the handler to display a message
> box that prompts the user to save a file before closing
> the form.
Т.е. если форма видима, и юзер нажал кнопочку, мы решаем, следует ли закрывать (скрывать) форму или нет. Здесь же формы невидима (скрыта) - поэтому все что там делалось на форме, сделано или еще не делалось. Это не надо переводить? Данные которые вводились на форму уже были введены или еще не вводились, т.к. форма не показывалась.
Нарушение логики форм 3:
Если OnCloseQuery на невидимых окнах возбуждается при LogOff (те. при закрытии программы ), то это должно и происходить при простом закрытии программы. чего не происходит.
← →
Кто б сомневался © (2009-04-09 15:55) [50]Нарушение логики форм 4:
При вызове метода Close - форма по умолчанию скрывается.
переведу:
При вызове метода ЗакрытьФорму, форма по умолчанию скрывается.
при вызове ЗапросНаЗакрытие форма уже закрыта (скрыта по идиологии VCL).
← →
AndreyV © (2009-04-09 15:59) [51]> [23] Игорь Шевченко © (09.04.09 02:37)
На каждый свой пук - писать гневные письма в саппорт, о выявленных багах.:)
← →
MsGuns © (2009-04-09 17:43) [52]>Кто б сомневался © (09.04.09 13:31) [39]
>OnCloseQuery должна получать видимая форма
Да ? А что делать с многодокументным интерфейсом (например вордом) в случае когда открыто n документов (каждый в "своей" форме) и в каждое внесено изменение, но видна в момент закрытия приложения только одна ?
Капец всем изменениям ?
← →
Кто б сомневался © (2009-04-13 15:57) [53]
> Да ? А что делать с многодокументным интерфейсом
> но видна в момент закрытия приложения только одна ?
Прежде чем писать подобные речи, следовало бы прочитать пару веток этой темы.
Там черным по русскому написано:
OnCloseQuery НЕ срабатывает при закрытии программы, если форма не видима. Он срабатывает только при LogOff.
кстати, MDI - это уже другая история, которая работает корректно.
Или вы собрались делать ворд без MDI?
← →
Игорь Шевченко © (2009-04-13 16:32) [54]
> Или вы собрались делать ворд без MDI?
а нефиг делать
← →
Eraser © (2009-04-13 16:42) [55]> [53] Кто б сомневался © (13.04.09 15:57)
ну криво сделано что поделать то, никто ж не заставляет насильно использовать это событие и не запрещает вручную обрабатывать сообщения.
← →
Игорь Шевченко © (2009-04-13 17:06) [56]Eraser © (13.04.09 16:42) [55]
А почему криво ? :) Когда при перезагрузке тебя Notepad спрашивает, сохранить ли данные, это тоже криво ? Пусть данные пропадают ?
← →
Eraser © (2009-04-13 17:14) [57]> [56] Игорь Шевченко © (13.04.09 17:06)
> [53] Кто б сомневался © (13.04.09 15:57)
> OnCloseQuery НЕ срабатывает при закрытии программы, если
> форма не видима. Он срабатывает только при LogOff.
в этом кривость. Кто б сомневался не првый новичок, кто наступает на грабли с OnCloseQuery. сплошь и рядом такое.
все таки думаю надо было им сделать отдельное понятное событие OnQueryEndSession (в т.ч. добавить такое же событие для Application), заодно и доп. флаги, передаваемые в WM_QUERYENDSESSION можно было бы предоставлять. А отменить штатное закрытие формы или вывести запрос можно и в OnClose.
← →
Игорь Шевченко © (2009-04-13 17:19) [58]Eraser © (13.04.09 17:14) [57]
>
> > OnCloseQuery НЕ срабатывает при закрытии программы, если
>
> > форма не видима. Он срабатывает только при LogOff.
А это ерунда
← →
Игорь Шевченко © (2009-04-13 17:26) [59]Eraser © (13.04.09 17:14) [57]
В дополнение к [58] - OnCloseQuery не срабатывает даже при закрытии программы, если форма видима.
Собстна, код:
main.pasunit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
uses
f2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
form2.Close;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
PostMessage(Form2.Handle, WM_CLOSE, 0, 0);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Form2.Show;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
Form2.Hide;
end;
end.
f2.pasunit f2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm2 = class(TForm)
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
ShowMessage("Form2Close");
end;
end.
.dprprogram AutoCreate;
uses
Forms,
main in "main.pas" {Form1},
f2 in "f2.pas" {Form2};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.Run;
end.
Можешь понажимать на кнопки и убедиться сам.
← →
Eraser © (2009-04-13 17:48) [60]> [59] Игорь Шевченко © (13.04.09 17:26)
> OnCloseQuery не срабатывает даже при закрытии программы,
> если форма видима.
так о том то и речь, хотя я думал, что если уж видима - то сработает, хотя каюсь сам не проверил. в вашем примере срабатывало при нажатии на кнопки 1, 2 (не зависимо от того видима форма или нет!) и при закрытии 2 формы вручную.
но это еще усугубляет ситуацию. помню лет 9 назад, когда, как раз, занимался батонокидательством не мог понять логики работы OnCloseQuery, то срабатывает, то не срабатывает. о том, что существуют какие-то там сообщения вообще только подозревал. тяжело это для не окрепших умов новичков (да и, как оказалось, не новичков тоже)).
тем более непонятна такая архитектура, если учесть, что все это было придумано во времена 9х, когда с пом. OnCloseQuery можно было легко заблокировать систему так, что помогал только ресет. а если добавить такую программку в автозапуск, можно было достичь интересных эффектов ;-)
именно от не пониманя того, что OnCloseQuery может заблокировать не только закрытие программы, но и завершение работы ОС, до сих пор попадается софт, который сильно тормозит завершение работы системы.
← →
Игорь Шевченко © (2009-04-13 18:04) [61]Eraser © (13.04.09 17:48) [60]
Собственно, событие срабатывает согласно VCL - если выполняется метод Close для немодальной формы, если выполняется метод CloseModal для модальной формы и если происходит завершение сеанса пользователя, цель одна - дать возможность перехватить момент и отменить закрытие формы/завершение сеанса пользователя.
Иначе пришлось бы вводить событие OnQueryEndSession, что по всей вероятности посчитали излишним.
Кстати, с каким-то компонентами была проблема, то ли с Indy какой-то версии, то ли еще с какими - они обрабатывали это сообщение и запрещали завершение сеанса.
> но это еще усугубляет ситуацию. помню лет 9 назад, когда,
> как раз, занимался батонокидательством не мог понять логики
> работы OnCloseQuery, то срабатывает, то не срабатывает.
> о том, что существуют какие-то там сообщения вообще только
> подозревал. тяжело это для не окрепших умов новичков (да
> и, как оказалось, не новичков тоже)).
Странно, не испытывал проблем
← →
Eraser © (2009-04-13 18:39) [62]> [61] Игорь Шевченко © (13.04.09 18:04)
> цель одна - дать возможность перехватить момент и отменить
> закрытие формы/завершение сеанса пользователя.
цель то понятна, но без изучения исходников VCL наступить на грабли с OnCloseQuery проще простого. как-то оно не очень дружественно к пользователям выглядит. в справке тоже почти ничего.
у меня вот в Д2009 все описание события выглядит такOccurs when close is attempted.
есть еще описание TCloseQueryEventTCloseQueryEvent is used for event handlers that are called when a window is about to close.
← →
Игорь Шевченко © (2009-04-13 18:46) [63]
> цель то понятна, но без изучения исходников VCL наступить
> на грабли с OnCloseQuery проще простого
А собственно, в чем состоят грабли ? VCL рассчитана, что пользователь знает, когда вызывается обработчик (как написано в справке, при попытке закрытия формы)и что он, пользователь, сам определит, нужно ли закрывать форму на основе логики работы своего приложения. А если пользователь будет писать обработчик, как в примере в этой ветке, он получит то, что получает - определит моменты вызова обработчика :)
Граблей не вижу в упор
> как-то оно не очень дружественно к пользователям выглядит
какой ужас
← →
Eraser © (2009-04-13 19:07) [64]> [63] Игорь Шевченко © (13.04.09 18:46)
> А собственно, в чем состоят грабли ? VCL рассчитана, что
> пользователь знает, когда вызывается обработчик (как написано
> в справке, при попытке закрытия формы)и что он, пользователь,
> сам определит, нужно ли закрывать форму на основе логики
> работы своего приложения. А если пользователь будет писать
> обработчик, как в примере в этой ветке, он получит то, что
> получает - определит моменты вызова обработчика :)
так то оно так, только непонятно, почему обработчик не вызывается при закрытии приложения (кстати, даже если форма2 видима). у меня в 95% случаев формы создаются/уничтожаются динамически или же в них не требуется интерактивное взаимодействие с пользователем при закрытии. но зато именно новички (те кто не использует динамическое создание форм, т.к. не знает как) часто наступают на эти грабли. поэтому масса многоформенных программок тех же студентов грешит багами при закрытии, а еще чаще, при завершении работы системы. я за то, чтобы для обработки завершения работы системы использовать отдельное событие, а не мешать мух с котлетами.
← →
Игорь Шевченко © (2009-04-13 19:22) [65]Eraser © (13.04.09 19:07) [64]
> так то оно так, только непонятно, почему обработчик не вызывается
> при закрытии приложения
У тебя исходники VCL есть ? :) Посмотри, почему не вызывается.
> но зато именно новички (те кто не использует динамическое
> создание форм, т.к. не знает как) часто наступают на эти
> грабли. поэтому масса многоформенных программок тех же студентов
> грешит багами при закрытии, а еще чаще, при завершении работы
> системы. я за то, чтобы для обработки завершения работы
> системы использовать отдельное событие, а не мешать мух
> с котлетами.
Новички - это отдельный вопрос. Новичкам надо учить матчасть до полного и окончательного просветления, прежде чем кнопки кидать - мое такое мнение.
Насчет события - тебе никто не мешает сделать это так, как ты считаешь - достаточно написать наследника формы с отдельной обработкой сообщения WM_QUERYENDSESSION и все свои формы наследовать от него.
Чем хороша Delphi и VCL - она не запрещает менять тебе ее поведение. А если ты хочешь, чтобы за тебя кто-то исполнил твои же желания, тогда тебе лучше искать золотую рыбку - это по ее части, а вовсе не по части VCL :)
← →
Eraser © (2009-04-13 19:37) [66]> [65] Игорь Шевченко © (13.04.09 19:22)
> Новичкам надо учить матчасть до полного и окончательного
> просветления, прежде чем кнопки кидать - мое такое мнение.
это правильно, но делфи позиционируется вроде как RAD, т.е. среда не только для профессионалов, но и для, к примеру, рядовых инженеров, которым на скорую руку нужно сколотить приложенице для подсчета чего-то там. ну да ладно, эта тема - отдельный разговор, который сведется в к обсуждению сборщиков муссора :)
> Насчет события - тебе никто не мешает сделать это так, как
> ты считаешь - достаточно написать наследника формы с отдельной
> обработкой сообщения WM_QUERYENDSESSION и все свои формы
> наследовать от него.
так и приходится делать (или почти так - напрямую обрабатывать WM_QUERYENDSESSION, не добавляя новых событий, т.к. чаще всего в приложении достаточно только одного места для обработки WM_QUERYENDSESSION). беда OnCloseQuery именно в половинчатости решения. не нашим не вашим. т.е. событие запроса на заврешение системы и запрос на закрытие окна конечно чем-то схожи, но различий у них больше )
← →
MsGuns © (2009-04-13 20:08) [67]Блин, купил чувак коньки, где НЕ написано "для льда !" и давай на них вышивать по асфальту. После двух-трех чебуряхов шавло в три монитора на производителей, дескать надули, гады, туфту гонят.
← →
b z (2009-04-13 20:18) [68]
> шавло
А что это? :)
← →
Игорь Шевченко © (2009-04-13 20:25) [69]Eraser © (13.04.09 19:37) [66]
> это правильно, но делфи позиционируется вроде как RAD, т.
> е. среда не только для профессионалов, но и для, к примеру,
> рядовых инженеров, которым на скорую руку нужно сколотить
> приложенице для подсчета чего-то там
Нет, для этих она не позиционируется. Для этих позиционируется Excel. А delphi позиционируется как продвинутый Visual Basic, скорее. Его тоже надо изучать, прежде чем писать на нем что-то.
> т.е. событие запроса на заврешение системы и запрос на закрытие
> окна конечно чем-то схожи, но различий у них больше )
Еще раз - VCL не знает, что происходило с приложением и может ли оно благополучно завершиться при завершении сеанса, поэтому оно дает шанс каждой форме верхнего уровня обработать запрос на завершение сеанса, как бы "закрывая" форму, в надежде на то, что та знает, можно ли ее закрыть.
> т.к. чаще всего в приложении достаточно только одного места
> для обработки WM_QUERYENDSESSION
Далеко не для всех приложений, потому неприемлемо в общем случае.
← →
Городской Шаман (2009-04-13 20:28) [70]
> Кто б сомневался © (09.04.09 03:24) [29]
А что вам мешает вставить такой код
if not Visible then Exit;
Ну или вставить его в обработчик сообщения. А далее наследовать все свои формы от данной.
Я в проекте стараюсь вводить одну глобальную форму от которой наследуются все остальные в которой и переопределяю обработку на ту которая мне нравится.
← →
Городской Шаман (2009-04-13 20:40) [71]
> MsGuns © (13.04.09 20:08) [67]
>
> Блин, купил чувак коньки, где НЕ написано "для льда !" и
> давай на них вышивать по асфальту. После двух-трех чебуряхов
> шавло в три монитора на производителей, дескать надули,
> гады, туфту гонят.
Угу
Стою на асфальте я в лыжи обутый,
То ли лыжи не те,
То ли я ...ый
← →
Кто б сомневался © (2009-04-13 20:55) [72]To all:
Причем здесь новички.
Повторюсь, это не корректная (не логичная) работа с точки зрения VCL форм. C точки зрения окон здесь все логично. Вот эту разницу Игорь и еще некоторые и не могут схватить, хотя уже все подробно расписал в [49] и [50]. В саппорте этот баг не стоит в очереди, а уже открыт (это значит что над ним работают) - а это значит что это баг, хоть с этим фактом любители поспорить не будут спорить?
Еще раз, прочитайте посты 49 и 50 может дойдет.
← →
Игорь Шевченко © (2009-04-13 21:13) [73]Кто б сомневался © (13.04.09 20:55) [72]
ссылку на QC дай
← →
Кто б сомневался © (2009-04-13 21:17) [74]
> ссылку на QC дай
А что, так не верится?
http://qc.embarcadero.com/wc/qcmain.aspx?d=72862
← →
Игорь Шевченко © (2009-04-13 21:19) [75]Кто б сомневался © (13.04.09 20:55) [72]
Кстати, обрати внимание на то, что OnCloseQiery не срабатывает у открытой формы при завершении приложения. Код приведен в посте [59]
← →
Игорь Шевченко © (2009-04-13 21:20) [76]Кто б сомневался © (13.04.09 21:17) [74]
> А что, так не верится?
мы же не в церкви, это там вопросы веры обсуждают.
← →
Игорь Шевченко © (2009-04-13 21:27) [77]теперь там поспорим
← →
Eraser © (2009-04-13 21:28) [78]> [72] Кто б сомневался © (13.04.09 20:55)
а там как не меняй поведение - правильного решения не будет (то одних будет не устраивать, то других, что и демонстрирует данная ветка). По-хорошему, нужно разделять OnCloseQuery на два отдельных события. Но этого не будет из-за соображений об обратной совместимости :(
← →
Игорь Шевченко © (2009-04-13 21:42) [79]Eraser © (13.04.09 21:28) [78]
Может, я чего не понимаю, но я не вижу причины разделения на два события. Цель вроде в обоих случаях одна - дать возможность не закрыться втихую, возложить на пользователя решение о том, закрываться или нет, а отчего происходит закрытие - от явного вызова Close, от нажатия на кнопку "Закрыть" в области заголовка, от явной посылки сообщения WM_CLOSE или от завершения сеанса пользователя - а какая разница-то ?
← →
Кто б сомневался © (2009-04-13 21:46) [80]
> теперь там поспорим
Нет уж, мусорку туда переносить не хочу. Тем более и так все сказано..
Страницы: 1 2 3 вся ветка
Форум: "Прочее";
Текущий архив: 2009.06.21;
Скачать: [xml.tar.bz2];
Память: 0.65 MB
Время: 0.012 c