Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Странно но факт


Автор: THenry 13.11.2005, 14:04
Суть проблемы в следующем:

Моё приложение имеет несколько форм и висит в трее, главная форма служит как бы контейнером для компонент (иконка в трее, меню для иконки таймера и т.д.) и форма эта невидимая. Выход приложения осуществляется через popup menu и только так.

А теперь собственно говоря проблемма:
Когда я хочу выключить винду все другие запушенные приложения закрываются, а моё нет и винда как следствие не вырубается

Такое событие в дебагере отследить не представляю даже как (тока если из какого нить другого приложения посылать моему WM_CLOSE) но я пошел другим путем и расставил в событии onClose диалоговые сообщения чтоб отследить что выполнятеся а что нет.

Получил вывод: Винда либо не шлет WM_CLOSE моему приложению либо оно не доходит.
Может кто что подскажет?

Автор: Poseidon 13.11.2005, 14:52
Цитата(THenry @ 13.11.2005, 14:04)
Винда либо не шлет WM_CLOSE моему приложению либо оно не доходит.
При завершении работы Винда и не шлет WM_CLOSE. При выключении вначале рассылается WM_QUERYENDSESSION. И если хоть одно приложение вернуло 0 на это сообщение, то рассылается WM_ENDSESSION. В общем отлавливай WM_QUERYENDSESSION и делай Application.Terminate Должно пройти.

Автор: Slayers 13.11.2005, 15:43
THenry Был у меня такой прикол . Я тогда в OnCloseQuery писал CanClose := false и это не давало вырубить камп , и тогда я прописал в OnClose Abort(); И всё заработало smile smile smile

Если не поможет то покажи как ты там делаеш !!! smile

Автор: THenry 13.11.2005, 17:53
Slayers РАзговор не идет о том что написано в onClose. Я говорю о том что при попытке выключить винду до этого самого onClose дело то и не доходит (Я просто вставил первой сторокой MessageDlg, при выходе в ручную всё нормально т.е. появляется сообщение выполняются все необходимые действия, а когда я нажимаю на кнопочку Power чтоб выключить винду то тишина) Вот об этом я и говорю. Естественно onCloseQuery тоже не выполняется (это на тот случай если будет предложение типа CanClose:=true)

Цитата(Poseidon)
В общем отлавливай WM_QUERYENDSESSION и делай Application.Terminate Должно пройти.
А подробней? Где отлавливать?

Автор: Albinos_x 13.11.2005, 18:34
ну написал же ты, что у тебя есть формы, у формы есть событие OnCloseQuery - оно и ловит это сообщение... и вернуть оно должно CanClose:=true или винда не выключится...

Автор: Poseidon 14.11.2005, 00:35
Цитата(THenry @ 13.11.2005, 17:53)
А подробней? Где отлавливать?
Процедуру "отлова" мы должны описать в классе того окна, которое будет принимать данное сообщение т.е. формы. Примерно так:

Код
type
  TForm1 = class(TForm)
  private
    { Private declarations }
      procedure WMQueryEndSession (var Msg : TWMQueryEndSession); message WM_QueryEndSession; 
  public
    { Public declarations }
  end;

Implementation 

procedure TForm1.WMQueryEndSession (var Msg : TWMQueryEndSession); 
begin 
ShowMessage('Windows mast die');
Msg.Result := 1; 
end;


Для реализации твоей задачи нужно сделать что-то вроде:

Код
type
  TForm1 = class(TForm)
  private
    { Private declarations }
      procedure WMQueryEndSession (var Msg : TWMQueryEndSession); message WM_QueryEndSession; 
  public
    { Public declarations }
  end;

Implementation 

procedure TForm1.WMQueryEndSession (var Msg : TWMQueryEndSession); 
begin 
Application.Terminate;
Msg.Result := 1; // главное что бы не 0
end;


Автор: THenry 19.11.2005, 14:46
Только сейчас руки дошли до делфи, сел попробовал то что посоветовал
Poseidon отчасти помогло, но только от части. Теперь приложение завершает свою работу, а винда все равно не выключается smile

Автор: Poseidon 19.11.2005, 16:35
Цитата(THenry @ 19.11.2005, 14:46)
а винда все равно не выключается
Т.е? Что пишет, что происходит?

Автор: THenry 19.11.2005, 17:00
Ничего не пишет и ничего не происходит. Просто приложение завершает свою работу и всё

Автор: Poseidon 19.11.2005, 17:14
Цитата(THenry @ 19.11.2005, 14:46)
а винда все равно не выключается

smile smile smile

Автор: THenry 19.11.2005, 18:30
И что значат эти смайлики? Почему не выключается? Ну так вот за этим я и создал тему чтоб разобраться с аномалией по выключению

Автор: Poseidon 19.11.2005, 18:51
Ё..... smile
Что значит "винда все равно не выключается"? Что при этом происходит (с Виндой а не прогой), какие сообщения появляются (Виндовые а не проги). Что вообще творится?

Автор: THenry 19.11.2005, 20:15
Объясняю еще раз повторяя свои же цитаты:

Цитата(THenry)
Ничего не пишет и ничего не происходит
это я говорил о винде.

Что еще тут добавить?

А теперь во избежание вопросов рассказываю процесс:
1. Нажимаю кнопку Power(или через меню пуск, что не важно), жду..
2. Итог: Все приложения закрываются, никаких сообщений не вылетает ничего нестандартного не происходит(винда продолжает работать)
3. Запускаю "Диспетчер задач" чистейщая винда (как будто только что поставил smile)




Автор: Poseidon 19.11.2005, 20:46
Это у тебя так происходит только тогда, кагда ты запускаешь сваю прогу и потом пытаешься выйтииз Винды или всегда так происходит?

Автор: THenry 20.11.2005, 11:45
Да, всмысле, только при запущенном моем приложении.

Автор: simsmann 17.2.2008, 19:43
Вопрос поставлен давно, но до сих пор на него нет ответа!!!
Этот вопрос ставился на многих форумах, есть статьи но ничего не дает результата!!!
Вот некоторые ссылки

http://valler.narod.ru/master/ShutDown.html
http://www.delphikingdom.com/asp/answer.asp?IDAnswer=57161
http://delphiworld.narod.ru/_app_.html
Как правило трудности у тех программ которые помещают икону в систем трей.
Обработка WMQueryEndSession и WMEndSession ничего не дает, если даже программа на выходе ничего не сохраняет, все равно программа выгружается если обработать WMQueryEndSession и WMEndSession, а винда затормозилась и продолжает работать какбудто команды на выключение не было.

Кто решил данную проблема ОТКЛИКНИТЕСЬ!!!

Автор: simsmann 17.2.2008, 20:07
Заметил следующее после обработки WMQueryEndSession, 
WMEndSession не обрабатывается по какой то причине винда не шлет сообщение.
Т.е. после WMQueryEndSession выключение прекращается.

Автор: bems 18.2.2008, 18:18
попробуй обрабытывать эти сообщения в Application.OnMessage

Автор: simsmann 18.2.2008, 20:56
Слава БОГУ! и Винграду!
Нарыл идею!
Проблема в SC_MINIMIZE при работе с иконой в систем трей.
Замечено, что при обработке WMQueryEndSession хотя программа и выгружается и посылает Винде TRUE или результат <>0 WMEndSession не вызывается и причиной того скорее всего, что программа висит в процессах, и сообщение TRUE от окна ничего недает. Далее выяснилось, что нельзя завершать работу программы CLOSE или Application.Terminate по всей видимости потому, что Винда не получит сообщение именно о завершении процесса от окна получила, а от процесса нет, поэтому Винда и не выгружается. Проблема решается следующим образом использовать для завершения своей программы в WMQueryEndSession - ExitProcess(0);.
Вот держите!!! Опробовано почти во всех ОС, все работает!!!

Код

unit ...

type
...
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);

  private
    { Private declarations }
    procedure WMQueryEndSession(var Msg: TWMQueryEndSession); message WM_QUERYENDSESSION;

  public
    { Public declarations }
  end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
{ЗДЕСЬ ВЫ ОБРАБАТЫВАЕТЕ ЧТО ВАМ НУЖНО СДЕЛАТЬ ПЕРЕД ЗАКРЫТИЕМ ПРОГРАММЫ
так же можете обработать и в DESTROY}
end;

procedure TForm1.WMQueryEndSession(var Msg: TWMQueryEndSession);
begin
    inherited;
    ExitProcess(0);
    Msg.Result := 1;
end;




Модераторы можно закрыть данный вопрос и не мешалобы поместить это в DRBK , чтоб ребята не мучались.

Автор: MetalFan 18.2.2008, 23:18
simsmann, бред полнейший. зачем рубить процесс exitprocess'ом? смысл вызывать inherited и выставлять Msg.Result := 1.
в пустой тестовой программе прекрасно происходит обработка этих сообщений.
проблему заметил в многопоточном приложении...
выход нашел такой: при получении WM_QUERYENDSESSION завершаю потоки и вырубаю приложение.
винда прекрасно выключается
вывод: проблема в вашей программе...

Автор: MetalFan 15.3.2008, 22:00
Внимание! Народ!
Боролся тут с этой проблемой: прога не давала выключиться винде. все процессы завершались, она одна оставалась висеть.
прога сложная, много сторонних компонент, многопоточная... но дело оказалось не в этом.
камень вот в чем:
используется в программе функция AllocateHWND. кто не знает - она позволяет создать "пустое" окно для получения сообщений, и назначает в обработчик сообщений окна переданную процедуру TWndMethod.
так вот, если в назначенном обработчике сообщений не сделать обработку сообщения WM_QUERYENDSESSION, и в Result не возвращать 1, то программа не будет корректно завершаться и давать выключится ОС.
вот такие дела.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)