| 
| 
 | Вопрос # 945/ вопрос открыт / | 
 |  Доброго времени суток, уважаемые эксперты!
 Продолжаю мучаться с формами. Уже полгода как перешел на Delphi 2007. Однако, недавно сталкнулся с одним существенным отличием от Delphi 7.
 
 Как известно, разработчики CodeGear в совместисть с .Net ввели новый элемент в языке, а именно - помошники классов. И первым они это нововведение реализовали в модуле Forms. В модуле они дописали два помошника класса: TCustomFormHelper и TApplicationHelper. Первый помошник значительной роли не играет, а вот второй изменяет логику класса TApplication. Этот помошник создан для управлением свойства главной формы, а именно флагом - показа иконки на панели задач.
 
 Раньше было все просто, иконка на панели задач соответствовала главному окну (Application) и всем прилигающим формам. Теперь же только главной форме.
 
 Вот если создать простую программку (в прилож.) с двумя формами. То на Delphi 7 можно перейти на вторую форму и ее спокойно сворачивать и разворачивать в панель задач. А вот на Delphi 2007 если свернуть вторую форму то на панели задач она будет с пустым текстом и обратно вторая форма при разворачивании уже не появиться.
 
 Уже многое перепробовал, в том числе и переписывать код модуля Forms с Delphi 7 - не помогает.
 
 Ув. эксперты, что же сделать в даной ситуции, чтобы все работало как в Delphi 7?
 К вопросу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки вопроса) Приложение:Переключить в обычный режим unit1;...procedure TForm1.Button1Click(Sender: TObject);begin  form2.Show;  hide;end; unit2;...procedure TForm2.Button1Click(Sender: TObject);begin  form1.show;  hide;end;
|  |   Вопрос задал: SMaks (статус: 1-ый класс)Вопрос отправлен: 29 сентября 2007, 22:01
 Состояние вопроса: открыт, ответов: 1.
 |  Ответ #1. Отвечает эксперт: Вадим К Здравствуйте, SMaks!Вообще-то, код, который вы привели спроектирован неверно. за такое в многих фирмах "бьют по пальца"
 Этот шаблон кода называется циклическими ссылками.
 Хотя вам такое поведение кажеться неверним, на самом деле оно упрощает много вещей и я не понимаю, почему сразу не сделали так как надо. Теперь кнопка на таксбаре соответствует форме (главной) и работа с "сворачиванием в трей" и подобные манипуляции заметно упроститься. Но человеческий разум хитёр и постоянно выдумывает ухищения для своих слабостей. Вот так и в этом случае я придлагаю "пилюлю" для лечения, но настоятельно рекомендую задуматься и переделать архитектуру приложения.
 
 итак, в второй форме добавляем в секцию protected процедуру и нажав Ctrl+Shift+C дописываем её реализацию
 
  protected
     procedure CreateParams(var Params: TCreateParams); override;
////
////
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle   := Params.ExStyle or WS_EX_APPWINDOW;
  Params.WndParent := GetDesktopWindow;
end;Теперь вторая форма имеет свою кнопку и по идее должна корректно отрабатывать под Вистой. Но проверить не могу - нет её у меня.Правда появился маленький глюк - кнопка на панели пропадает и появляется снова.
 
 P.S. Чуть подумал и придумал ещё одно решение. Ставим на форму PageControl, делаем две вкладки. Корешки вкладок скрываем (свойство TabVisible вкладки, правда переключаться между ними буден немного неудобно - правой по вкладке, а там всё есть). Потом сам контрол разворачиваем на всю форму (align = alClient)
 для кнопок код будет прост = PageControl1.ActivePageIndex := 1 для перехода на вторую вкладку.
 можно и по именам к вкладкам обращаться - так даже лучше, PageControl1.ActivePage := TabSheet1;
 
|  | Ответ отправил: Вадим К (статус: Академик)Время отправки: 30 сентября 2007, 00:50
 Оценка за ответ: 4
 Комментарий к оценке: 1) Присваивать родителя форме рабочий стол не лучшее решение. Вдруг произойдет сбой в работе рабочего стола, тогда второе окно полетит вмести с ним.2) В вашем варианте опять же остается на панели задач главная форма с пустым заголовком.
 3) Я нашел более лучшее решение: перед показом другой формы делать ее главной.
 
 procedure SetAsMainForm(aForm: TForm);
 var
 P: Pointer;
 begin
 P := @Application.Mainform;
 Pointer(P^) := aForm;
 end;
 
 Кстати, delphi 2007 у меня стоит под Windows XPSP2.
 |  
 Мини-форум вопросаВсего сообщений: 10; последнее сообщение — 1 октября 2007, 18:03; участников в обсуждении: 2. 
|   | Вадим К (статус: Академик), 30 сентября 2007, 14:32 [#1]:>>Присваивать родителя форме рабочий стол не лучшее решение. Вдруг произойдет сбой в работе рабочего стола, тогда второе окно полетит вмести с ним. Не понял коментарий. Я не делал подобного да и хотелось бы узнать "как это оно "полетит""
 >>В вашем варианте опять же остается на панели задач главная форма с пустым заголовком.
 Ничего не остаётся.
 Может вместо того, что бы сбрасывать файл form.pas из дистрибутива вы сбросили минимальный пример, который воспроизводит ошибку и, что было бы очень неплохо,  скриншот с указанием, что именно не нравиться.
 >> Я нашел более лучшее решение
 Вы вправе решать так как вам кажеться удобно
 Но ваш код "обманывает компилятор". Но как говориться в программерском мире "не обманывай компилятор -потом хуже будет".
 такое "преобразование кода" может вылезте боком - ведь остальной код надеется, что MainForm не поменяется в течении работы программы. Посмотрели бы для начал в код forms.pas и поняли, что Mainform свойство только для чтения. Нет никакой гарантии, что ваш код не перестанет работать с новой версией компилятора.
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Вадим К (статус: Академик), 30 сентября 2007, 14:51 [#2]:>>Вдруг произойдет сбой в работе рабочего стола, тогда второе окно полетит вмести с ним. Специально попробывал прибить "рабочий стол" с диспетчера задач во время работы программы. Программа работает нормально. запускаю explorer снова, что бы восстановился рабочий стол - всё как положено
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | SMaks (статус: 1-ый класс), 30 сентября 2007, 15:22 [#3]:2) Вот три различных примера, http://ifolder.ru/3544243. 3) В программе может быть несколько главных форм, тогда как быть, если не прямо их подменивать?
 |  
|   | SMaks (статус: 1-ый класс), 30 сентября 2007, 15:41 [#4]:1) Признаю, здесь я был не прав. |  
|   | Вадим К (статус: Академик), 30 сентября 2007, 22:36 [#5]:Указанный глюк наблюдался только в втором примере, но после перекомпиляции он пропал. Галочка "подтверждения прочтения" - вселенское зло. |  
|   | SMaks (статус: 1-ый класс), 1 октября 2007, 14:09 [#6]:Вот именно, что во втором примере. Я пробовал перекомпилировать его и на Delphi 7 и на Delphi 2007, все равно глюк не исчез. А вот при "не правильном" подходе все достаточно хорошо работает. И вообще назвать какую-ту визуальную форму главной сложно, т.к. каждая имеет свою специфику. |  
|   | Вадим К (статус: Академик), 1 октября 2007, 15:23 [#7]:Не знаю, у меня глюк после перекомпиляции перестал наблюдаться. странно, но в uses он использует unit3, который не был приложен. Хотя и ссылок на него нет. Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Вадим К (статус: Академик), 1 октября 2007, 15:37 [#8]:да, под 7 код ведёт себя интересней. Но это связано с тем, что там кнопка на таксбаре принадлежит Application, а не форме Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Вадим К (статус: Академик), 1 октября 2007, 16:10 [#9]:Заметил, если убрать Application.MainFormOnTaskBar := true; с файла проекта, то прога ведёт себя как и под 7 делфи, не смотря на то, что компилированна в 2007 Но вот не могу понять. Почему то приложение подвисает и продолжает висеть в задачах. как под 7 так и 2007. не всегда, найти зависимость пока не могу
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | SMaks (статус: 1-ый класс), 1 октября 2007, 18:03 [#10]:Могу и еще странность сказать, если перед Application.CreateForm(TForm1, Form1); поставить Application.MainFormOnTaskBar := true; то вторая форма начинает вести себя странно (обратите внимание на сворачивание и разврачивание). Вот это и стало главной причиной, почему я задал этот вопрос_#945. |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |