powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Отображение Application.Icon
6 сообщений из 6, страница 1 из 1
Отображение Application.Icon
    #39982011
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В OnCreate главной формы создаются дочерние формы, которые докаются на TabSheet. Код примерно такой
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TMainForm.FormCreate(Sender: TObject);
begin
  ..........
  ChildForm := TChildForm.Create(Self);
  ChildForm.ManualDock(TabSheet1);
  ChildForm.Show;
  .........
end;



Проблема: при создании формы в Vcl.Forms вызывается такой код
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
constructor TCustomForm.Create(AOwner: TComponent);
begin
    ............
    InitializeNewForm;
    ............
end;

procedure TCustomForm.InitializeNewForm;
begin
  ............
  Screen.AddForm(Self);
  ............
end;

procedure TScreen.AddForm(AForm: TCustomForm);
begin
  FCustomForms.Add(AForm);
  if AForm is TForm then
  begin
    FForms.Add(AForm);
    Application.UpdateVisible;
  end;
end;

procedure TApplication.UpdateVisible;

  procedure SetVisible(Value: Boolean);
  const
    ShowFlags: array[Boolean] of Word = (
      SWP_NOSIZE + SWP_NOMOVE + SWP_NOZORDER + SWP_NOACTIVATE + SWP_HIDEWINDOW,
      SWP_NOSIZE + SWP_NOMOVE + SWP_NOZORDER + SWP_NOACTIVATE + SWP_SHOWWINDOW);
  begin
    // Dont auto-update visibility if somebody else has hidden app window
    if (IsWindowVisible(Handle) = AppVisible) and (AppVisible <> Value) then
    begin
      if MainFormOnTaskBar and not AppVisible then
        SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_NOACTIVATE);
      SetWindowPos(Handle, 0, 0, 0, 0, 0, ShowFlags[Value]);
      AppVisible := Value;
    end;
  end;

var
  I: Integer;
  Form: TForm;
begin
  if Handle <> 0 then
  begin
    for I := 0 to Screen.FormCount - 1 do
    begin
      Form := Screen.Forms[I];
      if Form.Visible and ((Form.ParentWindow = 0) or not Form.HandleAllocated or
        not IsChild(Form.Handle, Form.ParentWindow)) then
      begin
        SetVisible(True);
        Exit;
      end;
    end;
    SetVisible(False);
  end;
end;

Теперь что получается: при создании очередной формы Application.UpdateVisible обнаруживает созданную раннее форму, у которой уже установлено Visible := True и показывает окно Applacation на таскбаре. Но без иконки.

Проблема решается одним из трех способов

1. Установка в дизайнере MainForm.Visible := True;
2. Установка Application.MainFormOnTaskBar := True;
3. Вызов перед Application.Run
Код: pascal
1.
2.
ShowWindow(Application.Handle, SW_HIDE);
ShowWindow(Application.Handle, SW_SHOW);


Delphi 10.3.1, Windows 10 1909

К сожалению не зафиксировал момент, когда проблема появилась. Точно уверен, что на XE3, Windows 8 такой проблемы не было.

Вопрос: куда девается иконка и какие есть цивилизованные способы решения проблемы?

Сейчас решаю передергиванием ShowWindow

С уважением, Vasilisk
...
Рейтинг: 0 / 0
Отображение Application.Icon
    #39982347
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот тестовый пример
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
procedure TForm1.FormCreate(Sender: TObject);
var
  LForm: TForm;
begin
  LForm := TForm2.Create(Self);
  LForm.ManualDock(PageControl1);
  LForm.Show;
  //
  LForm := TForm2.Create(Self);
  LForm.ManualDock(PageControl1);
  LForm.Show;
  //
  Sleep(1000);
end;


dpr
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
program TestIcon;

uses
  Vcl.Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

наличие слипа обязательно. В реальной программе слип заменен долгой загрузкой из базы
...
Рейтинг: 0 / 0
Отображение Application.Icon
    #39982374
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

А если вынести вызов .Show в событие OnShow или OnActivate? Или вообще на короткий таймер (100мс), запускаемый из OnActivate?
И вообще разве для таких вещей не фреймы были придуманы?
...
Рейтинг: 0 / 0
Отображение Application.Icon
    #39982401
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp
И вообще разве для таких вещей не фреймы были придуманы?
вот не надо тут про фреймы.
оно задумано было хорошо, но реализовано было как обычно - криво.
а вообще, речь не об этом.
...
Рейтинг: 0 / 0
Отображение Application.Icon
    #39982407
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий
но реализовано было как обычно - криво.

... поэтому будет делать ещё кривее на формах?..
...
Рейтинг: 0 / 0
Отображение Application.Icon
    #39982752
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp
А если вынести вызов .Show в событие OnShow или OnActivate?
Да костылей можно много придумать.

Тут хочется понять почему Windows так себя ведет. С точки зрения Delphi вызов Application.UpdateVisible на создание формы конечно лишний. Да и проверка Form.ParentWindow = 0 для докнутых формах неверна. Но на ранних версиях Windows все работало

alekcvp
И вообще разве для таких вещей не фреймы были придуманы?
Вообще-то не совсем. Некоторые формы могут потом андокиться и превращаться в обычные окна.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Отображение Application.Icon
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]