Как сделать так, чтобы кнопка закрытия программы [ x ] выполняла другое (нужное мне) действие?
Я придумал следующий фэйк (и он в частном случае работает):
1. Выключаем переключатель:
var
Form1: TForm1;
a: boolean = false;
2. Делаем новый батон для закрытия проги:
procedure TForm1.Button1Click(Sender: TObject);
begin
a:=true;
Сlose;
end;
3. ...и далее:
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if a then CanClose:=true else
begin
CanClose:=false;
// ...а сюда пишем новое действие для кнопки [x]
beep;
end;
end;
Но эта уловка не всегда применима. А как поиметь реальный доступ к красной кнопке?
Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
03-03-2007 17:33
К сожалению, Вам, вероятно, придется купить эту библиотеку на сайте производителя или поискать в магазинах диск с нею. Мне она досталась вместе с диском, содержащим, кроме всего прочего, еще и Дельфи 7. В ней довольно много оригинальных компонентов и при ее установки немного улучшается GDI. Подробнее на сайте www.raize.com. Рад был помочь. Удачи.
procedure TForm1.WMSysCommand;
begin
if (Msg.CmdType = SC_CLOSE) then
begin
// <--------
end
else inherited;
end;
Все другие приведенные здесь примеры, как и мой собственный тоже работают, но не могут быть использованы в частных случаях, когда лучше не трогать Close и CloseQuery.
Кстати меня заинтересовала ваша информация о RzTrayIcon из библиотеки Raize. Что еше включает эта библиотека и где ее можно скачать? Желательно не trial, т.к. далеко не все наборы компонентов излечиваются от триальности также легко и охотно как, например, SUIPack или DynamicSkinForm.
In WM_SYSCOMMAND messages, the four low-order bits of the wParam parameter are used internally by the system. To obtain the correct result when testing the value of wParam, an application must combine the value 0xFFF0 with the wParam value by using the bitwise AND operator.
Господа, благодарю за щедрую реакцию на мой вопрос. Но прозвучало: "Зачем это нужно?" вернее "Что именно нужно?". Поясню что именно: мне нужно, чтобы в моей программе (1 форма) кнопка [x] выполняла дкйствие не Close, а Hide. Такое встречается сплошь и рядом: жмете [x], а окно прыгает в трей, закрывается же, например, только из меню.
Приведенный мной в начале пример осуществляет это, но всё-таки, можно ли не кастрируя FormClose и FormCloseQuery получить доступ к [x]? Как узнает система, что нажата именно ЭТА кнопка?
Судя по всему автор - новичек и просто еще не наработал методик обработки закрытия окна.
Поскольку автор не поленился отформатировать свой код (что, к сожалению, редкость), проявив, тем самым уважение к читающим его вопрос, я не счел большим трудом нагенерить различные варианты этой самой обработки. В качестве идей.
Делаем 6 автосоздаваемых форм, на одной - 5 кнопок для открытия других форм, на остальных - по две кнопки, вроде Ok и Cancel.
procedure TForm0.Button1Click(Sender: TObject);
begin
Form1.ModalResult := mrNone; // если форма не уничтожается, то для повторного запуска
Form1.Show; // Немодальное окно
end;
procedure TForm0.Button2Click(Sender: TObject);
begin
Form2.ShowModal;
end;
procedure TForm0.Button3Click(Sender: TObject);
begin
Form3.ShowModal;
end;
procedure TForm0.Button4Click(Sender: TObject);
begin
case Form4.ShowModal of
mrYes: ShowMessage('Закрылись по OK');
mrNo: ShowMessage('Закрылись по Cancel');
else
ShowMessage('Прям даже и не знаю, как это получилось');
end;
end;
procedure TForm0.Button5Click(Sender: TObject);
begin
Form5.ShowModal;
end;
// Немодальное окно
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('Закрываемся по OK');
ModalResult := mrYes;
Close;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ShowMessage('Закрываемся по Cancel');
ModalResult := mrNo;
Close;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if (ModalResult = mrNone) then
begin
ShowMessage('А вот и не закроемся! Нажимайте Ok или Cancel');
Action := caNone;
end;
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
ShowMessage('Закрываемся по OK');
ModalResult := mrYes;
end;
procedure TForm2.Button2Click(Sender: TObject);
begin
ShowMessage('Закрываемся по Cancel');
ModalResult := mrNo;
end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if (ModalResult = mrCancel) then
begin
ShowMessage('А вот и не закроемся! Нажимайте Ok или Cancel');
Action := caNone;
end;
end;
// В инспекторе объектов назначаем:
// Button1.ModalResult := mrYes
// Button2.ModalResult := mrNo
procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
begin
case ModalResult of
mrYes: ShowMessage('Закрываемся по OK');
mrNo: ShowMessage('Закрываемся по Cancel');
else
ShowMessage('А вот и не закроемся! Нажимайте Ok или Cancel');
Action := caNone;
end;
end;
// В инспекторе объектов назначаем:
// Button1.ModalResult := mrYes
// Button2.ModalResult := mrNo
procedure TForm4.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if (ModalResult = mrCancel) then
begin
ShowMessage('А вот и не закроемся! Нажимайте Ok или Cancel');
Action := caNone;
end;
end;
// В инспекторе объектов назначаем:
// Button1.ModalResult := mrOk
// Button2.ModalResult := mrCancel
procedure TForm5.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if ModalResult = mrOk then
begin
ShowMessage('Закрываемся по OK');
Exit;
end;
if ModalResult = mrCancel then
begin
ShowMessage('Закрываемся по Cancel, кнопке Close или Alt-F4');
Exit;
end;
// еще что-нибудь
end;
01-03-2007 02:20 | Комментарий к предыдущим ответам
>>> я так понял, автора интересует именно нажатие по этой кнопке
Я понял тоже так. Поэтому и предложил попытаться перехватывать обработку клика мышки в неклиентской области окна (благо Винда такие возможности предоставляет). Это несколько проще, чем самому изображать ту самую неклиентскую область.
>>> Создайте форму без заголовка, нарисуйте заголовок, прилепите к нему подобную кнопку, в обработчик которой впишите любой свой код
Хм... А если попробовать повесить обработчик на WM_NCHITTEST. Тогда можно оставить стандартную кнопку. К тому же Винда сама расскажет про то, что мы сейчас на кнопкt Close.
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caNone;
Label1.Caption:='НЕ ЗАКРОЮСЬ НИКОГДА!!!'; //Вместо этой строки впишите свой код
end;
И не забудьте про "батон" из пункта 2 Вашего вопроса, убрав из него лишнее.
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.