Сворачивание в трэй

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Сворачивание в трэй

Сообщение А.Н. » 21.07.2010 21:47:50

Как сделать по-человечески? Особенно, когда есть окна, кроме главного.
Не прокатывает:
Код: Выделить всё
      Application.Restore;
      //Application.Minimize;
      Hide();


С минимайзом глючит. Когда есть ещё окна - остаются видимыми.
Как, вообще, правильно делается, с использованием TTrayIcon?
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Сворачивание в трэй

Сообщение Maxizar » 21.07.2010 23:57:44

Скрытие побочных форм, твоя задача как программиста этого никто делать не будет за тебя.
Вот привожу код, в котором есть главная и побочная формы обе открываются разом см исходник, при нажатии на кнопку идет сварачивание в трэй.
Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  StdCtrls,Unit2;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    TrayIcon1: TTrayIcon;
    procedure Button1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure TrayIcon1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.TrayIcon1Click(Sender: TObject);
begin
  Show; //показ формы
  TrayIcon1.Visible:=False;//скрытие иконки, хотя можешь и не скрывать...
end;

procedure TForm1.Button1Click(Sender: TObject);
begin   //короче при клике идет сворачивание в трей
  Hide;
  Unit2.Form2.Hide;//это должен сделать для каждой формы сам кто знает какие они у тебя :)
  TrayIcon1.Visible:=True;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  Unit2.Form2.Show; //ну просто при создании видно еще одну форму для примера
end;

end.



вот код второй формы, у нее тоже есть кнопка при нажатии которой идет вызов процедуры из главной формы, как оформить это дело твое. если нужно сварачивать при минимизации, то необходимо будет отлавливать сообщения, но это для винды.
Код: Выделить всё
unit Unit2;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm2 }

  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form2: TForm2;

implementation
Uses Unit1;
{$R *.lfm}

{ TForm2 }

procedure TForm2.Button1Click(Sender: TObject);
begin
  Unit1.Form1.Button1.Click; //вызов процедуры сварачивания в трэй
end;

end.

Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: Сворачивание в трэй

Сообщение А.Н. » 22.07.2010 06:55:21

Скрытие побочных форм, твоя задача как программиста этого никто делать не будет за тебя.

Как лениво-то. :-(
Если через Screen.Forms делать, придётся заводить список форм бывших видимыми?

если нужно сварачивать при минимизации, то необходимо будет отлавливать сообщения, но это для винды.

Application.OnMinimize подойдёт или нет?
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Сворачивание в трэй

Сообщение alex_rain » 22.07.2010 09:33:40

Если через Screen.Forms делать, придётся заводить список форм бывших видимыми?

Проверка видимости через Screen.Forms[x].Visible или IsWindowVisible не устроит?

Application.OnMinimize подойдёт или нет?

Подойдет.

Lazarus 0.9.29 FPC 2.5.1 Win32
alex_rain
новенький
 
Сообщения: 26
Зарегистрирован: 12.02.2010 06:56:32
Откуда: Russia

Re: Сворачивание в трэй

Сообщение hinst » 22.07.2010 10:51:56

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

или вот ещё мой вариант: отнаследуйте все ваши формы от некой такой, которая наследуется от TForm и добавляет к ней свойство wasVisible, и тогда перед сокрытием будете ставить ей wasVisible. а когда надо будет разворачивать, опять же проверять, была ли она раньше видима по этому свойству. и не придётся заводить список
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Сворачивание в трэй

Сообщение Maxizar » 22.07.2010 11:41:44

Я не согласен с hinst, Зачем использовать ООП и т.п можно поступить намного рпоще, мы же имеем свойство Tag почему бы его нам не использовать, а логика которую я вижу это: Договоримся считать что если мы показали форму то присвоить Tag значение 1 (ну можно и другое значение), скрыли форму сбросили до нуля.
И потом делаем что то типа:
Код: Выделить всё
  Show; //показ  главной формы

  For I:=0 to Screen.FormCount-1 do      //пробегаем остальные формы
          if  Screen.Forms[I].Tag=1 then   //если Tag=1 то форма была видна
              Screen.Forms[I].Show;          //собственно востанавливаем видимость..

Для этого привожу пример приложения, в котором 3 формы одна главная две побочных, одна из побочных создается при старте программы, вторая при необходимости.
Смотрите вложенный файл.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: Сворачивание в трэй

Сообщение А.Н. » 22.07.2010 12:01:40

hinst писал(а):или вот ещё мой вариант: отнаследуйте все ваши формы от некой такой, которая наследуется от TForm и добавляет к ней свойство wasVisible, и тогда перед сокрытием будете ставить ей wasVisible. а когда надо будет разворачивать, опять же проверять, была ли она раньше видима по этому свойству. и не придётся заводить список

Ох, лениво делать наследование. У всех форм придётся переписывать предка. Список - проще.

Maxizar писал(а):Смотрите вложенный файл.

Почему-то не скомпилировалось... Но смысл ясен. Тэги я не использую, потому что неизвестно что в них может быть. Со списком более централизованно. И меньше форм надо будет пробегать, при показе.
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Сворачивание в трэй

Сообщение hinst » 22.07.2010 12:03:40

мне интересно, сколько же у вас классов форм в вашем проекте. двадцать, тридцать? или, может быть, все сто??
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Сворачивание в трэй

Сообщение А.Н. » 22.07.2010 12:06:00

Нет, мало. :-) Штук 15. Но просто со списком проще.

Добавлено спустя 4 часа 7 минут 9 секунд:
А как узнать модально показана форма или нет?

Добавлено спустя 2 минуты 37 секунд:
И формы нужны в опр. порядке, в таком, в каком они показаны на экране. Forms это отражает?

Добавлено спустя 1 час 5 минут 47 секунд:
Вообще, по ходу, не такая и тривиальная задачка.
Постоянно какие-то ошибки, при восстановлении вылетают:
osago_new [2010-07-22 17:12:34.843 Error] NO DEBUG INFO (class: EInvalidOperation [addr: 41709C]): [TCustomForm.SetFocus] frmInfoManager:TfrmInfoManager Can not focus)
osago_new [2010-07-22 17:12:45.390 Error] NO DEBUG INFO (class: EInvalidOperation [addr: 41B046]): TCustomForm.ShowModal impossible )


Что делать? Как быть с модальными формами?
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Сворачивание в трэй

Сообщение А.Н. » 01.08.2010 18:16:46

Сегодня вернулся к этой фигне. Дописал функцию. Вроде, даже работает.
Правда, в finalization модуля надо делать очистку памяти. Но, пофиг.
Нормальное сворачивание в трэй, с учётом модальности:
Код: Выделить всё
procedure MinInTray();
type
  TFormState = record
    form: TForm;
    is_modal: boolean;
    tb_show: TShowInTaskbar;
  end;
  PFormState = ^TFormState;

var i: integer;
    fs: PFormState;

begin
  if (vis_forms_list = nil) then vis_forms_list := TList.Create;

  if (Application.MainForm.Visible) then
    begin
      for i := 0 to vis_forms_list.Count - 1 do
        Dispose(PFormState(vis_forms_list[i]));
      vis_forms_list.Clear();
      // Скрываю.
      for i := 0 to Screen.FormCount - 1 do
        begin
          if (not Screen.Forms[i].Visible) then continue;

          new(fs);
          with fs^ do
            begin
              try
                form := Screen.Forms[i];
                if (form <> nil) then
                with form do
                  begin
                    is_modal      := fsModal in FormState;
                    tb_show       := ShowInTaskBar;
                  end;
              except
              end;
            end;
          vis_forms_list.Add(fs);
          //Application.ProcessMessages();
      end;

      for i := vis_forms_list.Count - 1 downto 0 do
        with PFormState(vis_forms_list[i])^ do
          begin
            try
              if (form = nil) then continue;
              form.ShowInTaskBar := stNever;
              form.Hide();
            except
            end;
          end;
    end
  else
    begin
      // Показываю.
      if (vis_forms_list = nil) then Application.MainForm.ShowModal()
      else
        begin
          for i := vis_forms_list.Count - 1 downto 0 do
            if (vis_forms_list[i] <> nil) then
              with PFormState(vis_forms_list[i])^ do
                try
                  if (form = nil) then continue;
                  if (is_modal) then form.ShowModal()
                  else form.Show();
                  form.ShowInTaskBar := tb_show;
                  // Application.ProcessMessages;
                except
                end;
        end;
    end;
end;


Если есть замечания и предложения, напишите. Может, я даже здесь умудрился где-то напортачить. :-

Добавлено спустя 4 часа 36 минут 27 секунд:
И, всё-равно, глючит, с двумя модальными окнами. :-( Что же делать?
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Сворачивание в трэй

Сообщение dunin » 22.01.2014 11:07:51

Коллеги, подскажите, что-то я затупил....

Вот так из меню прикрученному к трэйиконке все работает
Код: Выделить всё
procedure TMainForm.MenuSetupClick(Sender: TObject);
begin
  if (MainForm.Tag = 1)
    then MainForm.Hide
    else MainForm.show;

  MainForm.Tag:= abs(MainForm.Tag - 1);
end;


Но стоит спрятать форму на старте приложения (дописать это)
Код: Выделить всё
procedure TMainForm.FormShow(Sender: TObject);
begin
  //Application.MainForm.Hide; //или
  //Hide; // или
  MainForm.Hide;
end;

то форме через меню отказывает показываться.

Собственно вопрос: как правильно спрятать/убрать главную форму приложения при старте программы, чтобы не было лишних мельканий на экране. Спасибо.
Аватара пользователя
dunin
энтузиаст
 
Сообщения: 634
Зарегистрирован: 02.05.2007 13:18:11
Откуда: Тољя††и


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 240

Рейтинг@Mail.ru