Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Application.MainFormOnTaskbar wird ignoriert (10.4) (https://www.delphipraxis.net/205177-application-mainformontaskbar-wird-ignoriert-10-4-a.html)

himitsu 9. Aug 2020 10:29

Application.MainFormOnTaskbar wird ignoriert (10.4)
 
Moin,

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

Es wird immer die MainForm in der Taskleiste angezeigt.
Leere Testanwendung, nur mit
Delphi-Quellcode:
:= 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)

ghubi01 9. Aug 2020 17:23

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)
 
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.

himitsu 9. Aug 2020 19:12

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)
 
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
Delphi-Quellcode:
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;

Renate Schaaf 9. Aug 2020 20:39

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)
 
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

himitsu 9. Aug 2020 21:03

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)
 
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.

KodeZwerg 10. Aug 2020 07:34

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)
 
Öhhmm... vielleicht übersehe ich ja was aber "WS_EX_TOOLWINDOW" zeichnet nunmal kein Bild auf TaskBar.
ein
Delphi-Quellcode:
SetWindowLong(Application.Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW);
sollte eigentlich Dein Hidden in ein sichtbares verwandeln.

ghubi01 10. Aug 2020 11:25

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)
 
Liste der Anhänge anzeigen (Anzahl: 2)
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:

himitsu 10. Aug 2020 13:19

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)
 
Zitat:

WS_EX_TOOLWINDOW
Ahhhhhhhhh, der blöde Copy&Paste-AutoVervollständigung-BlindHinguck-Fehler :wall:
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.

Sailor 10. Aug 2020 15:34

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)
 
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

himitsu 10. Aug 2020 17:02

AW: Application.MainFormOnTaskbar wird ignoriert (10.4)
 
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;


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:05 Uhr.
Seite 1 von 2  1 2      

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