Einzelnen Beitrag anzeigen

DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#1

Eigene Tray-Benachrichtigungen anzeigen statt TTrayIcon

  Alt 5. Jan 2024, 18:58
Auch wenn ein paar Dinge dagegen sprechen TTrayIcon abzuschaffen, würde ich das dennoch gerne tun.

Als Ersatz dafür war meine Grundidee, dass bei jeder Meldung im Systembereich ein eigenes, kleines Form ohne Titelzeile angezeigt wird.
Jetzt ist nur die Frage, wie geht man mit mehreren Meldungen im Systembereich um.

Idee 1: ein Formular mit mehreren Seiten? Die Seiten werden dynamisch erzeugt, eine pro Meldung?
Idee 2: mehrere Formulare dynamisch erzeugt? Wenn aktuell bereits eine Meldung angezeigt wird, zeige die nächste über dieser Meldung an. Sobald die erste Meldung verschwunden ist, lasse die zweite Meldung "mitwandern" (ausfaden oder das Formular einfach kleiner werden lassen und Top-Position ändern).
Meldung 1 verschwindet beispielsweise nacht unten, raus aus dem Bildschirm und Meldung 2, die oberhalb von Meldung 1 ist, soll dann mitwandern und an die Position gehen wo Meldung 1 war.

Wie geht man sowas am besten an? Es geht mir um das Management der Fenster und der Animation/Bewegung der Fenster, sollte es zu Idee 2 kommen.

Falls es der ein oder andere kennt: Steam hat das früher so gemacht oder macht es noch immer. Ich möchte nicht den Stil übernehmen, sondern die Funktionalität.

Meine ersten echt unschönen Gehversuche sehen so aus. Noch nichts wirklich in Units aufgeteilt, einfach in ein leeres Projekt geschrieben.
Delphi-Quellcode:
// Mainform
uses Toast;

// Button
TToast.Create(Self).Show('Titel 1', 'Dies ist eine Toast-Meldung 1.');
TToast.Create(Self).Show('Titel 2', 'Dies ist eine Toast-Meldung 2.');
Delphi-Quellcode:
unit Toast;

interface

uses
 Windows, ShellAPI, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;

type
 TToast = class(TObject)
 private const
  FMaxTimeDisplayed = 6000;

 var
  FForm: TForm;
  FTimer: TTimer;
  FDisplayTime: Integer;
  procedure FadeOutWindow(N: Integer);
  procedure Timer1Timer(Sender: TObject);
  procedure FFormClose(Sender: TObject; var Action: TCloseAction);
 public
  constructor Create(AParent: TComponent);
  procedure Show(ACaption: string; AMessage: string);
 end;

implementation

uses
 ToastList;

{TToast}

type
 TTaskBarPos = (_TOP, _BOTTOM, _LEFT, _RIGHT, _NONE);

function GetTaskBarPos(Handle: THandle): TTaskBarPos;
var
 tabd: TAppBarData;
begin
 Result := _BOTTOM;

 FillChar(tabd, SizeOf(TAppBarData), 0);
 tabd.cbSize := SizeOf(TAppBarData);
 if SHAppBarMessage(ABM_GETTASKBARPOS, tabd) = 0 then
  Exit;

 case tabd.uEdge of
  ABE_LEFT:
   Result := _LEFT;
  ABE_TOP:
   Result := _TOP;
  ABE_RIGHT:
   Result := _RIGHT;
  ABE_BOTTOM:
   Result := _BOTTOM;
 end;
end;

function GetTaskBarDimension(Handle: THandle): Integer;
var
 CurrentScreen: TMonitor;
begin
 CurrentScreen := Screen.MonitorFromWindow(Handle);
 Result := (CurrentScreen.Width - CurrentScreen.WorkAreaRect.Width) + (CurrentScreen.Height - CurrentScreen.WorkAreaRect.Height);
end;

constructor TToast.Create(AParent: TComponent);
begin
 inherited Create;
 FForm := TForm.Create(AParent);
 FForm.OnClose := FFormClose;
end;

procedure TToast.Show(ACaption: string; AMessage: string);
var
 TaskbarPos: TTaskBarPos;
 TaskBarHeight: Integer;
 CurrentScreen: TMonitor;
begin
 FForm.Position := poDesigned;
 FForm.Height := 100;
 FForm.Width := 250;

 CurrentScreen := Screen.MonitorFromWindow(FForm.Handle);
 TaskbarPos := GetTaskBarPos(FForm.Handle);
 TaskBarHeight := GetTaskBarDimension(FForm.Handle);

 case TaskbarPos of
  _TOP:
   begin
    FForm.Top := CurrentScreen.Top + TaskBarHeight;
    FForm.Left := CurrentScreen.Left + CurrentScreen.Width - FForm.Width;
   end;
  _BOTTOM:
   begin
    FForm.Top := CurrentScreen.Top + CurrentScreen.Height - TaskBarHeight - FForm.Height;
    FForm.Left := CurrentScreen.Left + CurrentScreen.Width - FForm.Width;
   end;
  _LEFT:
   begin
    FForm.Top := CurrentScreen.Top + CurrentScreen.Height - FForm.Height;
    FForm.Left := CurrentScreen.Left + TaskBarHeight;
   end;
  _RIGHT:
   begin
    FForm.Top := CurrentScreen.Top + CurrentScreen.Height - FForm.Height;
    FForm.Left := CurrentScreen.Left + CurrentScreen.Width - FForm.Width - TaskBarHeight;
   end;
 end;

 FForm.Left := Screen.WorkAreaWidth - FForm.Width;
 FForm.Top := Screen.WorkAreaHeight - FForm.Height;

 FForm.AlphaBlend := True;
 FForm.Show;
 FDisplayTime := 0;
 FTimer := TTimer.Create(FForm);
 FTimer.Interval := 1000;
 FTimer.Enabled := True;
 FTimer.OnTimer := Timer1Timer;
end;

procedure TToast.FadeOutWindow(N: Integer);
begin
 //
end;

procedure TToast.Timer1Timer(Sender: TObject);
begin
 FDisplayTime := FDisplayTime + FTimer.Interval;
 FForm.Caption := FDisplayTime.ToString;

 if FDisplayTime >= FMaxTimeDisplayed then
  begin
   FTimer.Enabled := False;
   FForm.Close;
  end;
end;

procedure TToast.FFormClose(Sender: TObject; var Action: TCloseAction);
begin

end;

end.

Geändert von DieDolly ( 5. Jan 2024 um 21:27 Uhr)
  Mit Zitat antworten Zitat