AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Application.MainFormOnTaskbar wird ignoriert (10.4)

Application.MainFormOnTaskbar wird ignoriert (10.4)

Ein Thema von himitsu · begonnen am 9. Aug 2020 · letzter Beitrag vom 27. Sep 2021
Antwort Antwort
Seite 1 von 2  1 2   
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.017 Beiträge
 
Delphi 12 Athens
 
#1

Application.MainFormOnTaskbar wird ignoriert (10.4)

  Alt 9. Aug 2020, 11:29
Moin,

kann es sein, dass Application.MainFormOnTaskbar := False; seit jetzt/länger einfach ignoriert wird?

Es wird immer die MainForm in der Taskleiste angezeigt.
Leere Testanwendung, nur mit := False; geändert.

In TApplication.SetMainFormOnTaskBar ist zwar noch ein Code drin, aber ich seh in der Taskleiste dennoch immer nur die MainForm.


Aufgefallen war es, weil ich endlich mal versuchen wollte einen generellen Bug der VCL zu beheben,
unter dem leider auch die Delphi-IDE leidet.

Beim Programmstart, wenn es ewig dauert und z.B. ein SpalshScrenn angezeigt wird, der beschissender Weise ohne WS_EX_APPWINDOW erstelltt wurde,
oder wenn da eine MessageBox angezeigt wird, z.B. durch eine Exception oder UpdateMeldung,
dann hängt das Programm unsichtbar im Hintergrund, weil es ja noch nicht aktiv war und auch nicht in der Taskleiste angezeigt wird.

Aktueller Versuch, der nicht geht, weil MainFormOnTaskBar:=False keine Wirkung hat.
Delphi-Quellcode:
program Project2;

uses
  Winapi.Windows,
  Vcl.Forms,
  Unit1 in 'Unit1.pas{Form1};

{$R *.res}

type
  THiddenHelper = class
    class procedure ActiveFormChange(Sender: TObject);
  end;

class procedure THiddenHelper.ActiveFormChange(Sender: TObject);
var
  B: Boolean;
begin
  B := True;
  if (Application.MainFormHandle <> 0) and IsWindowVisible(Application.MainFormHandle)
      and (GetWindowLong(Application.MainFormHandle, GWL_EXSTYLE) and WS_EX_APPWINDOW <> 0) then
    B := False;
  if not B and Assigned(Screen.ActiveCustomForm)
      and Screen.ActiveCustomForm.HandleAllocated and IsWindowVisible(Screen.ActiveCustomForm.Handle)
      and (GetWindowLong(Screen.ActiveCustomForm.Handle, GWL_EXSTYLE) and WS_EX_APPWINDOW <> 0) then
    B := False;
  for var i := Screen.CustomFormCount - 1 downto 0 do
    if not B and Screen.CustomForms[i].HandleAllocated and IsWindowVisible(Screen.CustomForms[i].Handle)
        and (GetWindowLong(Screen.CustomForms[i].Handle, GWL_EXSTYLE) and WS_EX_APPWINDOW <> 0) then
      B := False;
  Application.MainFormOnTaskBar := B;
end;

begin
  Application.Initialize;

  Application.MainFormOnTaskbar := False;
  Screen.OnActiveFormChange := THiddenHelper.ActiveFormChange;

  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
Ja, idealder wäre wohl OnMessage ein Message-Hook und dort auf Fenster WM_SHOW/WM_HIDE der Fenster zu reagieren. (aller Fenster, auch welche nicht zur VCL gehören)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 9. Aug 2020 um 11:41 Uhr)
  Mit Zitat antworten Zitat
ghubi01

Registriert seit: 18. Nov 2017
121 Beiträge
 
Delphi 12 Athens
 
#2

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)

  Alt 9. Aug 2020, 18:23
Hallo,
vielleicht hilft folgendes:
Delphi-Quellcode:
program Project1;

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

{$R *.res}

begin
  Application.Initialize;
  //Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
und Unit:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows,
  System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    BtnBeenden: TButton;
    procedure BtnBeendenClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
var
  MyOwner: HWnd;
begin
  MyOwner:=GetWindow(Handle,GW_OWNER);
  ShowWindow(MyOwner,SW_HIDE);
end;

procedure TForm1.BtnBeendenClick(Sender: TObject);
begin
  Close;
end;

end.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.017 Beiträge
 
Delphi 12 Athens
 
#3

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)

  Alt 9. Aug 2020, 20:12
Das mit dem ShowWindow hatte ich vorhin auch schon probiert.
Delphi-Quellcode:
Application.MainFormOnTaskbar := True;
SetWindowLong(Application.Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
ShowWindow(Application.Handle, SW_SHOWMINNOACTIVE);
Aber mit dem Nebeneffekt, dass ich dann das Fenster, also die Titelleiste, unten links auf dem Desktop sehen konnte, aber nicht in der Taskleiste.

Eigentlich wollte ich eine Lösung, die global ist und nicht in den Forms liegt, aber geht wohl nicht,
denn ich sah gerade eben, dass im Application.CreateForm die VCL nochmal an den Eigenschaften dem Applicaton-Form rumpfuscht.


Zum Testen einfach ein Sleep(10000) ins OnCreate der Form (MainForm).
Bis zum Anzeigen würde ich gern die Application-HWND (oder irgendwas) in der Taskleiste sehen wollen und danach (ab OnShow) dann die MainForm.

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  Sleep(10000); // oder irgendwas Langwirigere
end;

{ --------------------- }

Application.Initialize;
Application.MainFormOnTaskbar := False;
//SetWindowLong(Application.Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
//ShowWindow(Application.Handle, SW_SHOWMINNOACTIVE);
//Application.ProcessMessages;

Application.CreateForm(TForm1, Form1);

Application.MainFormOnTaskbar := True;
Application.Run;
Mit ShowWindow oder gar mehr seh ich maximal das Fenster/Titelleiste, aber niemals den Button in der Statusleiste.

Einmal hatte ich es geschafft die Application-Form in die Taskleiste zu bekommen, aber weiß grad nicht mehr wie. (am Ende blieb die drin, auch wenn sie nach Durchlauf ja mit der MainForm wechseln sollte)


Aber egal ob True oder False, erst wenn/nachdem OnCreate fertig ist, wird etwas in der Taskleiste angezeigt und das ist immer nur die MainForm,
wie die Button-Caption und AeroPeak bestätigen -> Vorschau einer leeren Form oder der MainForm, wo ein Memo drauf ist.
Delphi-Quellcode:
Application.Initialize;
Application.MainFormOnTaskbar := False;
Application.CreateForm(TForm1, Form1);
Application.Run;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 9. Aug 2020 um 20:14 Uhr)
  Mit Zitat antworten Zitat
Renate Schaaf

Registriert seit: 25. Jun 2020
Ort: Lippe
114 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)

  Alt 9. Aug 2020, 21:39
Hallo Himitsu,

Bei mir (Delphi 10.3) funktioniert Application.MainformOnTaskbar:=false. Es wird der Titel der Anwendung gezeigt.

Hast Du das in Emba-Help gelesen?

The MainFormOnTaskBar setting is intended to persist for the life of the application; later run-time changes of this property could result in unexpected behavior.

Aber vielleicht kannst du ja expected behavior daraus machen.

Renate
Renate

Geändert von Renate Schaaf ( 9. Aug 2020 um 21:50 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.017 Beiträge
 
Delphi 12 Athens
 
#5

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)

  Alt 9. Aug 2020, 22:03
Delphi-Quellcode:
Application.Initialize;
Application.MainFormOnTaskbar := False;
Application.CreateForm(TForm1, Form1);
Application.Run;
Wie gesagt, alleine das funktioniert schon garnicht.


Wenn man nur den ExStyle und Visible ändert, sollte es keine Probleme geben, aber im SetMainFormOnTaskbar wird auch ein Recreate der HWND der MainForm angestoßen.
Totaler Schwachsinn (kein Wunder, wenn es da Probleme geben kann), außerdem wird im TApplication.CreateForm nochmals dran rumgepfuscht.

Drum sieht es aktuell so aus,
aber so lange ich nicht rausbekomm, wie man eine unsichtbare Form/HWND dazu bringt dennoch ihren TaskButton darzustellen, hab ich ein kleines Problemchen.
Delphi-Quellcode:
program Project2;

uses
  Winapi.Windows,
  Vcl.Forms,
  Unit1 in 'Unit1.pas{Form1};

{$R *.res}

type
  THiddenHelper = class
    class procedure ActiveFormChange(Sender: TObject);
  end;

class procedure THiddenHelper.ActiveFormChange(Sender: TObject);
var
  B: Boolean;
begin
  B := True;
  if (Application.MainFormHandle <> 0) and IsWindowVisible(Application.MainFormHandle)
      and (GetWindowLong(Application.MainFormHandle, GWL_EXSTYLE) and WS_EX_APPWINDOW <> 0) then
    B := False;
  if not B and Assigned(Screen.ActiveCustomForm)
      and Screen.ActiveCustomForm.HandleAllocated and IsWindowVisible(Screen.ActiveCustomForm.Handle)
      and (GetWindowLong(Screen.ActiveCustomForm.Handle, GWL_EXSTYLE) and WS_EX_APPWINDOW <> 0) then
    B := False;
  for var i := Screen.CustomFormCount - 1 downto 0 do
    if not B and Screen.CustomForms[i].HandleAllocated and IsWindowVisible(Screen.CustomForms[i].Handle)
        and (GetWindowLong(Screen.CustomForms[i].Handle, GWL_EXSTYLE) and WS_EX_APPWINDOW <> 0) then
      B := False;
  //Application.MainFormOnTaskBar := B; // False entfernt WS_EX_TOOLWINDOW von der MainForm, was nicht erwünscht ist
  if (GetWindowLong(Application.Handle, GWL_EXSTYLE) and WS_EX_TOOLWINDOW <> 0) <> B then begin
    SetWindowLong(Application.Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
    ShowWindow(Application.Handle, SW_SHOWMINNOACTIVE);
  end else begin
    SetWindowLong(Application.Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle, GWL_EXSTYLE) and not WS_EX_TOOLWINDOW);
    ShowWindow(Application.Handle, SW_HIDE);
  end;
end;

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Screen.OnActiveFormChange := THiddenHelper.ActiveFormChange;
  SetWindowLong(Application.Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
  ShowWindow(Application.Handle, SW_SHOWMINNOACTIVE);
  //Application.ProcessMessages;

  Application.CreateForm(TForm1, Form1);
  THiddenHelper.ActiveFormChange(nil);

  //Application.MainFormOnTaskbar := True;
  Application.Run;
end.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 9. Aug 2020 um 23:10 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.685 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)

  Alt 10. Aug 2020, 08:34
Öhhmm... vielleicht übersehe ich ja was aber "WS_EX_TOOLWINDOW" zeichnet nunmal kein Bild auf TaskBar.
ein SetWindowLong(Application.Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW); sollte eigentlich Dein Hidden in ein sichtbares verwandeln.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
ghubi01

Registriert seit: 18. Nov 2017
121 Beiträge
 
Delphi 12 Athens
 
#7

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)

  Alt 10. Aug 2020, 12:25
Hallo,

ich habe das mit einer einfachen VCL-Anwendung getestet und bekomme in der Taskleiste auch zwei verschiedene Fenster angezeigt, wenn ich mit dem Mauszeiger darauf gehe.
siehe Bilder:
Miniaturansicht angehängter Grafiken
ontaskbar-false.jpg   ontaskbar-true.jpg  
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.017 Beiträge
 
Delphi 12 Athens
 
#8

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)

  Alt 10. Aug 2020, 14:19
Zitat:
WS_EX_TOOLWINDOW
Ahhhhhhhhh, der blöde Copy&Paste-AutoVervollständigung-BlindHinguck-Fehler
Ich schieb jetzt einfach Mal die Schukd auf Corona und Hitze.


Aber wenn selbst
Delphi-Quellcode:
Application.Initialize;
Application.MainFormOnTaskbar := False;
Application.CreateForm(TForm1, Form1);
Application.Run;
nicht funktioniert, dann kann der Fehler doch "hier" nicht bei mir liegen?

Siehe auch ghubi01, wo man im ScreenShot das schön sieht, dass da eben immer die MainForm angezeigt wird.
Aber OK, als Überschrift des AeroPeek ist zumindestens die Caption unterschiedlich, aber dennoch immer als Bild die Form.

Und wenn man den Start verzögert, dann ist bis zur Anzeige der MainForm weiterhin kein Button in der Taskleiste.
Aber genau das wollte ich ja eigentlich erreichen, dass so lange die Anwendung läuft, immer was in der Taskleiste ist, egal ob eine Form sichtbar ist, oder nicht.
(Zumindestens beim Starten und Beenden, bis die Anwendung fertig geladen wurde, bzw. bis sie komplett weg ist)


Langsam überkommt mich das Gefühl, es könnte eine "Verbesserung" im DesktopWindowManager vom Windows 10 sein.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (10. Aug 2020 um 14:29 Uhr)
  Mit Zitat antworten Zitat
Sailor

Registriert seit: 20. Jul 2008
Ort: Balaton
112 Beiträge
 
Delphi 2010 Professional
 
#9

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)

  Alt 10. Aug 2020, 16:34
Keine Ahnung, ob das Dein Problem löst, ich mache das seit Olims Zeiten so wie hier beschrieben. Die Hauptanwendung startet eine untergeordnete Anwendung und blendet das Icon aus. Umgekehrt beim Verlassen der Nebenanwendung. Funktioniert auch unter W10, es gibt nur eine kurze Zeitspanne, in der 2 Icons zu sehen sind. Das kann aber auch an dem schwachbrüstigen Rechner liegen, der bei der Hitze keine richtige Lust hat.

Delphi-Quellcode:
  PROCEDURE HideTaskBarButton(CONST app:String; hide:Boolean);
   VAR
    h_wnd: HWnd;
    style: Integer;

   BEGIN
    h_wnd := FindWindow(NIL,PChar(app));
    IF h_wnd <> 0
     THEN BEGIN
           style := GetWindowLong(h_wnd,gwl_ExStyle)
                   OR
                    ws_Ex_ToolWindow;
           IF hide = True
            THEN BEGIN
                  style := style AND NOT(ws_Ex_AppWindow);
                  ShowWindow(h_wnd,sw_Hide)
                 END
            ELSE BEGIN
                  style := style AND ws_Ex_AppWindow;
                  ShowWindow(h_wnd,sw_Show)
                 END;
           SetWindowLong(h_wnd,gwl_ExStyle,style)
          END
   END; //OF PROCEDURE HideTaskBarButton
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.017 Beiträge
 
Delphi 12 Athens
 
#10

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)

  Alt 10. Aug 2020, 18:02
Es liegt nicht am Windows 10.
Delphi 10.3 auf Windows 7, das Gleiche.
Titel ist hier der Application-Title, aber AeroPeek bleibt weiterhin die MainForm (wäre aber egal und eigentlich OK),
aber vor Ablauf der Pause ist weiterhin nichts zu sehn. (die ProcessMessages machen keinen Unterschied)
Delphi-Quellcode:
Application.Initialize;
Application.MainFormOnTaskbar := False;
//Application.ProcessMessages;
Sleep(10000); // eigentlich Berechnung im TForm1.OnCreate, aber für den kurzen Test hier
//Application.ProcessMessages;
Application.CreateForm(TForm1, Form1); // z.B. mit einem TMemo drauf, um den Unterschied zu sehen .... Vorschau/AeroPeek ohne Memo = Application und Mit = MainForm
Application.Run;
@Sailor: Über den Namen suchen ist etwas ungünstig, wenn das Programm mehrmals gestartet wurde,
aber in Application.Handle ist ja eh das gesuchte Fenster drin.
Delphi-Quellcode:
Application.Initialize;
Application.MainFormOnTaskbar := True; // oder False

ShowWindow(Application.Handle, SW_SHOW);
SetWindowLong(Application.Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW);
Application.ProcessMessages;

Sleep(10000);

Application.CreateForm(TForm1, Form1);

ShowWindow(Application.Handle, SW_HIDE);
SetWindowLong(Application.Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle, GWL_EXSTYLE) and not WS_EX_APPWINDOW);

//Application.MainFormOnTaskbar := True;
Application.Run;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (10. Aug 2020 um 18:13 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:08 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz