У меня проблема следующего характера
Прога при отключении питания не может выгрузиться, притом событие FormCloseQuery проходит, а на FormClose уже нет. FormCloseQuery у меня не используется, просто вставлял beep, чтобы понять где пропадает собщение... А при нажатии на "х" все срабатывает... Да и через диспетчер задач снимается.... А вот при выключении компьютера никак не хочет закрываться... В чем может быть проблема? Заранее благодарен...
Компилятор Delphi7
Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
procedure TVSSComm32.CommWndProc( var msg: TMessage );
begin
case msg.msg of
PWM_GOTCOMMDATA:
begin
ReceiveData( PChar(msg.LParam), msg.WParam );
LocalFree( msg.LParam );
end;
PWM_REQUESTHANGUP:
RequestHangup;
else
with msg do
Result := DefWindowProc( FHWnd, Msg, wParam, lParam);
end;
end;
22-11-2007 09:50 | Комментарий к предыдущим ответам
Нашел TVSSComm32.CommWndProc
procedure TVSSComm32.CommWndProc( var msg: TMessage );
begin
case msg.msg of
PWM_GOTCOMMDATA:
begin
ReceiveData( PChar(msg.LParam), msg.WParam );
LocalFree( msg.LParam );
end;
PWM_REQUESTHANGUP:
RequestHangup;
end;
end;
Исправленный вариант:
procedure TVSSComm32.CommWndProc( var msg: TMessage );
begin
case msg.msg of
PWM_GOTCOMMDATA:
begin
ReceiveData( PChar(msg.LParam), msg.WParam );
LocalFree( msg.LParam );
end;
PWM_REQUESTHANGUP:
RequestHangup;
// If next line is not present, the shutdown/logoff on NT will fail,
// since the hidden window/component cannot be shut down
WM_QUERYENDSESSION:
msg.Result := Ord(True);
else
// If the next line is not present, some messages will be discarded, causing
// our app to be non-responsive in some cases.. at least, with my app
with msg do
Result := DefWindowProc( FHWnd, Msg, wParam, lParam);
end;
end;
Когда окно показывается - трей уже освобождается, и его нет. Но даже в этом состоянии прога кочевряжется... Может быть, какие-то другие компоненты мешают закрытию приложения?
function TForm1.CreateTray: Boolean;
begin
Result:=CheckBox4.Checked;
if Result then
begin
IconData.cbSize := sizeof(IconData);
IconData.Wnd := Handle;
IconData.uID := 100;
IconData.uFlags := NIF_MESSAGE + NIF_ICON + NIF_TIP;
IconData.uCallbackMessage := WM_USER + 1;
IconData.hIcon := Application.Icon.Handle;
StrPCopy(IconData.szTip, Application.Title);
Shell_NotifyIcon(NIM_ADD, @IconData);
end
end;
//Обработчики PopupMenu1:
procedure TForm1.Open1Click(Sender: TObject);
begin
Shell_NotifyIcon(NIM_DELETE, @IconData);
Form1.Show;
ShowWindow(Application.Handle, SW_NORMAL);
end;
procedure TForm1.Exit1Click(Sender: TObject);
begin
Shell_NotifyIcon(NIM_DELETE, @IconData);
Application.ProcessMessages;
Application.Terminate;
end;
// переместил в CloseQuery, но без результатов...
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if not CheckBox4.Checked then
Shell_NotifyIcon(NIM_DELETE, @IconData);
SaveIni; // копеешная процедурка для сохранения инишника
end;
// еще конструктор;
constructor TForm1.create(AOwner: TComponent);
begin
inherited Create(AOwner);
v:=Valuts.Create;
LastTim:=LastModify;
TsToV;
if v.SentStart then
Button1.Click;
У меня была однажды такая же проблема. У программы был значок в трее, но завершение работы системы обламывалось - программа не закрывалась и продолжала работать. Тоже думал, что форма не правильно обрабатывает WM_QUERYENDSESSION, но дело оказалось не в этом. Я использовал сторонний компонент для работы с tray-ем, который создавал message-only окошко. Оно также получало сообщение WM_QUERYENDSESSION, будучи окном верхнего уровня. Завершение работы происходит только в том случае, когда все окна обработав сообщение вернули TRUE, (для этого рекомендуется просто вызывать DefWindowProc в оконной функции), а в том компоненте в оконной функции вместо
Забывали просто Message.Result в true выставить... Может у вас подобный случай? Не используете ли вы сторонние компоненты, которые создают Message-only окошки посредством AllocateHwnd?
Ну так а мне как закрыть приложение?
Если можете, перенесите сохранение важных данных из OnClose в OnCloseQuery.
Только не стоит делать там (в OnCloseQuery) что-то длительное.
22-11-2007 07:24 | Вопрос к автору: запрос дополнительной информации
Я писал CanClose:=True
Никакого эффекта, что в принципе и понятно, так как справедливо замечено, что CanClose по умолчанию True
У меня есть еще обработчики событий, но и без них такая же фигня.
destructor TForm1.destroy;
begin
v.Destroy;
inherited;
end;
procedure TForm1.WMSysCommand;
begin
if (Msg.CmdType = SC_MINIMIZE) then
if CreateTray then
begin
Form1.Hide;
ShowWindow(Application.Handle, SW_HIDE);
Exit;
end;
inherited;
end;
procedure TForm1.WndProc(var Msg : TMessage);
var
p : TPoint;
begin
case Msg.Msg of
WM_USER + 1:
case Msg.lParam of
WM_RBUTTONDOWN:
begin
GetCursorPos(p);
PopupMenu1.Popup(p.x, p.y);
end
end;
end;
inherited;
end;
В чем разница между этими запросами
При завершении работы Windows форма вызывает CloseQuery в обработчике сообщения WM_QUERYENDSESSION (OnCloseпри этом не вызывается):
procedure TCustomForm.WMQueryEndSession(var Message: TWMQueryEndSession);
begin
Message.Result := Integer(CloseQuery and CallTerminateProcs);
end;
При "обычном" закрытии формы вызывается метод Close (в нем уже вызываются OnCloseQuery и OnClose).
Что самое противное, я не могу отследить место, где трабла. При выклюсении питания Delphi сразу хочеть сделать Terminate. А при штатном закрытии на "х" все хорошо работает... В чем разница между этими запросами?
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.