Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  23:50[Войти] | [Зарегистрироваться]
Ответ на вопрос № 49724

28-02-2007 15:33
Как сделать так, чтобы кнопка закрытия программы [ 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;


Но эта уловка не всегда применима. А как поиметь реальный доступ к красной кнопке?

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

03-03-2007 17:33
К сожалению, Вам, вероятно, придется купить эту библиотеку на сайте производителя или поискать в магазинах диск с нею. Мне она досталась вместе с диском, содержащим, кроме всего прочего, еще и Дельфи 7. В ней довольно много оригинальных компонентов и при ее установки немного улучшается GDI. Подробнее на сайте www.raize.com. Рад был помочь. Удачи.

03-03-2007 16:09 | Сообщение от автора вопроса
Да решена. Я применил ваш вариант:

procedure TForm1.WMSysCommand;
begin
  if (Msg.CmdType = SC_CLOSE) then
    begin
      // <--------
    end
  else inherited;
end;


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

Кстати меня заинтересовала ваша информация о RzTrayIcon из библиотеки Raize. Что еше включает эта библиотека и где ее можно скачать? Желательно не trial, т.к. далеко не все наборы компонентов излечиваются от триальности также легко и охотно как, например, SUIPack или DynamicSkinForm.

Благодарю всех.

02-03-2007 19:03
Спасибо, DRON. Теперь буду знать. Вот только были бы еще хелпы по-русски...

И Вам, Green, спасибо, за полезную информацию.

timself, а решена ли проблема? Хотелось бы узнать.

02-03-2007 15:50
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.

02-03-2007 14:57 | Сообщение от автора вопроса
Что обозначает $FFF0? Для чего это?

02-03-2007 02:08
Только проверка должна быть несколько другая:

  if (Msg.CmdType and $FFF0 = SC_CLOSE) then


01-03-2007 23:17
Кажется я решил эту проблему:


  private
    { Private declarations }
    procedure WMSysCommand(var Msg: TWMSysCommand);
    message WM_SYSCOMMAND;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.WMSysCommand;
begin
  if (Msg.CmdType = SC_CLOSE) then
    begin
      RzTrayIcon1.MinimizeApp
    end
  else inherited;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Close;
end;



RzTrayIcon - это компонент из библиотеки Raize. Другие способы отправки окна в трей мне не понравились.

01-03-2007 17:35 | Сообщение от автора вопроса
Господа, благодарю за щедрую реакцию на мой вопрос. Но прозвучало: "Зачем это нужно?" вернее "Что именно нужно?". Поясню что именно: мне нужно, чтобы в моей программе (1 форма) кнопка [x] выполняла дкйствие не Close, а Hide. Такое встречается сплошь и рядом: жмете [x], а окно прыгает в трей, закрывается же, например, только из меню.
Приведенный мной в начале пример осуществляет это, но всё-таки, можно ли не кастрируя FormClose и FormCloseQuery получить доступ к [x]? Как узнает система, что нажата именно ЭТА кнопка?

Видимо WM_SYSCOMMAND ... SC_CLOSE

Спасибо.

01-03-2007 05:30
Судя по всему автор - новичек и просто еще не наработал методик обработки закрытия окна.
Поскольку автор не поленился отформатировать свой код (что, к сожалению, редкость), проявив, тем самым уважение к читающим его вопрос, я не счел большим трудом нагенерить различные варианты этой самой обработки. В качестве идей.
Делаем 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 | Комментарий к предыдущим ответам
>>> я так понял, автора интересует именно нажатие по этой кнопке
Я понял тоже так. Поэтому и предложил попытаться перехватывать обработку клика мышки в неклиентской области окна (благо Винда такие возможности предоставляет). Это несколько проще, чем самому изображать ту самую неклиентскую область.

01-03-2007 02:15 | Комментарий к предыдущим ответам
Geo, я так понял, автора интересует именно нажатие по этой кнопке. Можно нажать и Alt+F4. А это автору, скорее всего, не нужно.

01-03-2007 01:19
>>> Создайте форму без заголовка, нарисуйте заголовок, прилепите к нему подобную кнопку, в обработчик которой впишите любой свой код
Хм... А если попробовать повесить обработчик на WM_NCHITTEST. Тогда можно оставить стандартную кнопку. К тому же Винда сама расскажет про то, что мы сейчас на кнопкt Close.

01-03-2007 00:10
Label1.Caption:='НЕ ЗАКРОЮСЬ НИКОГДА!!!'

Обработчик OnClose вызывается не всегда. Например, он не будет выполнен для дочерних форм при закрытии главной формы приложения.

28-02-2007 23:08
Создайте форму без заголовка, нарисуйте заголовок, прилепите к нему подобную кнопку, в обработчик которой впишите любой свой код.

28-02-2007 20:37
От себя добавлю возглас малыша Билли - "да когда же я смогу перезагрузиться/выключиться, эта ... программулина упорно не хочет закрываться"...

28-02-2007 19:54
Есть другой вариант. Пишем:


procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action:=caNone;
  Label1.Caption:='НЕ ЗАКРОЮСЬ НИКОГДА!!!'; //Вместо этой строки впишите свой код
end;



И не забудьте про "батон" из пункта 2 Вашего вопроса, убрав из него лишнее.

28-02-2007 17:27
Ловите WM_SYSCOMMAND c параметром SC_CLOSE.

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Зимой — белый, летом — серый. Кто?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования