Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Отображение Application.Icon / 6 сообщений из 6, страница 1 из 1
20.07.2020, 20:26
    #39982011
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отображение Application.Icon
В 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
21.07.2020, 18:05
    #39982347
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отображение Application.Icon
Вот тестовый пример
Код: 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
21.07.2020, 19:41
    #39982374
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отображение Application.Icon
_Vasilisk_,

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

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

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

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


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