Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 945

/ вопрос открыт /

Доброго времени суток, уважаемые эксперты!

Продолжаю мучаться с формами. Уже полгода как перешел на Delphi 2007. Однако, недавно сталкнулся с одним существенным отличием от Delphi 7.

Как известно, разработчики CodeGear в совместисть с .Net ввели новый элемент в языке, а именно - помошники классов. И первым они это нововведение реализовали в модуле Forms. В модуле они дописали два помошника класса: TCustomFormHelper и TApplicationHelper. Первый помошник значительной роли не играет, а вот второй изменяет логику класса TApplication. Этот помошник создан для управлением свойства главной формы, а именно флагом - показа иконки на панели задач.

Раньше было все просто, иконка на панели задач соответствовала главному окну (Application) и всем прилигающим формам. Теперь же только главной форме.

Вот если создать простую программку (в прилож.) с двумя формами. То на Delphi 7 можно перейти на вторую форму и ее спокойно сворачивать и разворачивать в панель задач. А вот на Delphi 2007 если свернуть вторую форму то на панели задач она будет с пустым текстом и обратно вторая форма при разворачивании уже не появиться.

Уже многое перепробовал, в том числе и переписывать код модуля Forms с Delphi 7 - не помогает.

Ув. эксперты, что же сделать в даной ситуции, чтобы все работало как в Delphi 7?

К вопросу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки вопроса)

Приложение:
  1. unit1;
  2. ...
  3. procedure TForm1.Button1Click(Sender: TObject);
  4. begin
  5. form2.Show;
  6. hide;
  7. end;
  8.  
  9. unit2;
  10. ...
  11. procedure TForm2.Button1Click(Sender: TObject);
  12. begin
  13. form1.show;
  14. hide;
  15. end;


SMaks Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: 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

SMaks (статус: 1-ый класс), 30 сентября 2007, 15:22 [#3]:

2) Вот три различных примера, http://ifolder.ru/3544243.
3) В программе может быть несколько главных форм, тогда как быть, если не прямо их подменивать?
SMaks

SMaks (статус: 1-ый класс), 30 сентября 2007, 15:41 [#4]:

1) Признаю, здесь я был не прав.
Вадим К

Вадим К (статус: Академик), 30 сентября 2007, 22:36 [#5]:

Указанный глюк наблюдался только в втором примере, но после перекомпиляции он пропал.
Галочка "подтверждения прочтения" - вселенское зло.
SMaks

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

SMaks (статус: 1-ый класс), 1 октября 2007, 18:03 [#10]:

Могу и еще странность сказать, если перед Application.CreateForm(TForm1, Form1); поставить Application.MainFormOnTaskBar := true; то вторая форма начинает вести себя странно (обратите внимание на сворачивание и разврачивание). Вот это и стало главной причиной, почему я задал этот вопрос_#945.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:51
Выполнено за 0.03 сек.