Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Infofenster im Systembereich erzeugen, einblenden und ausblenden (https://www.delphipraxis.net/197237-infofenster-im-systembereich-erzeugen-einblenden-und-ausblenden.html)

DieDolly 23. Jul 2018 19:52


Infofenster im Systembereich erzeugen, einblenden und ausblenden
 
Ich arbeite gerade an einer Idee, die ich noch nicht in die Tat umsetzen kann.
Ich hätte gerne die Möglichkeit ein Informationsfenster im Systembereich einblenden zu können.
Es gibt mittlerweile aber schon 2 verschiedene Forms dafür mit unterschiedlichen Inhalten und aktuell ist es so, dass Form 2 mit der Anzeige warten muss, bis Form 1 geschlossen wurde.

Wie würdet ihr das lösen, sodass es auch eine Anfängerin wie ich versteht? Meine Idee ist, dass wenn schon ein Fenster angezeigt wird, das zweite einfach oben draufzupacken (hier als Beispiel wenn die Taskleiste unten ist).
Meine Anwendung ist zweisprachig und in einer anderen Unit setze ich die Label-Captions dieser Informationsfenster. Das kann ich aber auch gerne in die Forms selber auslagern.

dummzeuch 23. Jul 2018 20:05

AW: Infofenster dynamisch erzeugen und einblenden
 
Ich verstehe nur Bahnhof. Kannst Du mal ein Bild posten, wie Du Dir das vorstellst?

KodeZwerg 23. Jul 2018 20:22

AW: Infofenster dynamisch erzeugen und einblenden
 
Info1 wird angezeigt, kommt Info2 hinzu, plaziere es über Nummer 1, wenn Nummer 1 geschlossen wird muss Info2 runterrutschen.

So würde ich vorgehen falls ich das richtig entziffert habe was Du da schreibst.

Ps: Das was ich meine kann man sich mit dem Tool JDownloader anschauen, kommt ein Link hinzu popt ein Fenster auf, kommt ein weiterer Link hinzu, popt nächstes Fenster über dem alten auf, ist altes weg rutscht das neue runter. Da wird es über Timer gesteuert.

DieDolly 23. Jul 2018 20:27

AW: Infofenster dynamisch erzeugen und einblenden
 
Das ist richtig aber die Frage ist, wie es technisch gemacht würde.

Zitat:

Zitat von dummzeuch (Beitrag 1408446)
Ich verstehe nur Bahnhof. Kannst Du mal ein Bild posten, wie Du Dir das vorstellst?

Ich poste generell keine Bilder von dem was ich mache.

Das Bild ist nicht von mir aber das was man im Bild sieht meine ich mit Infofenster.
https://www.codeproject.com/KB/cs/Di...screenshot.JPG
Und bevor der Vorschlag kommt die windowseigenen Mittel zu nutzen: nein.

KodeZwergs Erklärung ist im Prinzip das, was ich erklären wollte.
Das aber technisch korrekt und wiederverwendbar umzusetzen ist die (sehr) große Herausforderung.

Hier ist meine Idee was einen Teil der Umsetzung angeht:
eine einzige leere aber kleine randlose Form, die dynamisch erzeugt wird, wenn man sie braucht.
Der Inhalt könnte dann aus einem Frame kommen den man bei Erzeugung der Form-Instanz zugibt.


Ich habe hier mal ein sehr simples Beispiel erstellt
Delphi-Quellcode:
type
 TTaskBarPos = (_TOP, _BOTTOM, _LEFT, _RIGHT, _NONE);



function GetTaskBarPos(Handle: THandle): TTaskBarPos;
var
 hTaskbar: HWND;
 T: TRect;
 scrW, scrH: Integer;
 CurrentScreen: TMonitor;
begin
 Result := _BOTTOM;

 hTaskbar := FindWindow('Shell_TrayWnd', nil);

 if hTaskbar <> 0 then
  begin
   CurrentScreen := Screen.MonitorFromWindow(Handle);

   GetWindowRect(hTaskbar, T);
   scrW := CurrentScreen.Width;
   scrH := CurrentScreen.Height;
   if (T.Top > scrH div 2) and (T.Right >= scrW) then
    Result := _BOTTOM
   else if (T.Top < scrH div 2) and (T.Bottom <= scrW div 2) then
    Result := _TOP
   else if (T.Left < scrW div 2) and (T.Top <= 0) then
    Result := _LEFT
   else

    if T.Left >= scrW div 2 then
    Result := _RIGHT;
  end;
end;

function GetTaskBarDimension(Handle: THandle): Integer;
var
 SysTray: Winapi.Windows.HWND;
 Rect: TRect;
begin
 Result := -1;
 SysTray := FindWindow('Shell_TrayWnd', nil);

 if SysTray <> INVALID_HANDLE_VALUE then
  begin
   if GetWindowRect(SysTray, Rect) then
    begin
     case GetTaskBarPos(Handle) of
      _LEFT, _RIGHT:
       if GetWindowRect(SysTray, Rect) then
        Result := Rect.Right - Rect.Left;

      _TOP:
       if GetWindowRect(SysTray, Rect) then
        Result := Rect.Bottom;

      _BOTTOM:
       if GetWindowRect(SysTray, Rect) then
        begin
         Result := Screen.MonitorFromWindow(Handle).Height - Rect.Top;
        end;
     end;
    end;
  end;
end;

procedure TForm1.Button5Click(Sender: TObject);
var
 Form: TForm;
 TaskbarPos: TTaskBarPos;
 CurrentScreen: TMonitor;
 TaskBarHeight: Integer;
begin
 Form := TForm.Create(Self);
 Form.BorderStyle := bsNone;
 Form.Caption := '';
 Form.Width := 345;
 Form.Height := 145;

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

 case TaskbarPos of
  _TOP:
   begin
    Form.Top := TaskBarHeight;

    Form.Left := CurrentScreen.Width - Form.Width;
   end;
  _BOTTOM:
   begin
    Form.Top := CurrentScreen.Height - TaskBarHeight - Form.Height;

    Form.Left := CurrentScreen.Width - Form.Width;
   end;
  _LEFT:
   begin
    Form.Top := CurrentScreen.Height - Form.Height;

    Form.Left := TaskBarHeight;
   end;
  _RIGHT:
   begin
    Form.Top := CurrentScreen.Height - Form.Height;

    Form.Left := CurrentScreen.Width - Form.Width - TaskBarHeight;
   end;
 end;

 Form.Show;
end;

ConnorMcLeod 24. Jul 2018 06:39

AW: Infofenster im Systembereich erzeugen, einblenden und ausblenden
 
Mein Ansatz wäre mit grundsätzlich zwei Klassen:
  • Fensterklasse, die die Verhaltensweisen beim Anzeigen, Verschwinden und Rutschen implementiert
  • Fensterverwaltungsklasse mit einer Fensterliste, die über alle Fenster Bescheid weiß und Anweisungen zum Anzeigen, Verschwinden und Rutschen gibt.

DieDolly 24. Jul 2018 08:07

AW: Infofenster im Systembereich erzeugen, einblenden und ausblenden
 
Könntest du dafür ein kleines Beispiel liefern? Das hört sich für mich sehr gut und schlüssig an.

MEissing 24. Jul 2018 08:18

AW: Infofenster im Systembereich erzeugen, einblenden und ausblenden
 
Wenn nur und ausschliesslich Windows 10 (auf dem Zielsystem), dann würd ich die Windows 10 Notifications dafür nehmen:
http://docwiki.embarcadero.com/CodeE...cations_Sample
http://docwiki.embarcadero.com/RADSt...n_Mitteilungen

DieDolly 24. Jul 2018 08:23

AW: Infofenster im Systembereich erzeugen, einblenden und ausblenden
 
Wie oben schon geschrieben möchte ich diese nicht verwenden. Ein Grund ist, da nicht nur Windows 10 verwendet wird (XP bis 10).

ConnorMcLeod's Ansatz gefällt mir wirklich sehr gut. Das mit dem Einblenden, Ausblenden und Rutschen würde ich rechnerisch hinbekommen. Ich habe ja Zeit genug.
Aber das Umsetzen der Klassenstrukturen und die Liste die ja vermutlich die Fenster halten und löschen können soll würde ich nicht ansatzweise realisieren können.

dummzeuch 24. Jul 2018 08:27

AW: Infofenster dynamisch erzeugen und einblenden
 
Zitat:

Zitat von DieDolly (Beitrag 1408448)
Zitat:

Zitat von dummzeuch (Beitrag 1408446)
Ich verstehe nur Bahnhof. Kannst Du mal ein Bild posten, wie Du Dir das vorstellst?

Ich poste generell keine Bilder von dem was ich mache.

shrug

Schokohase 24. Jul 2018 08:27

AW: Infofenster im Systembereich erzeugen, einblenden und ausblenden
 
Zitat:

Zitat von MEissing (Beitrag 1408455)
Wenn nur und ausschliesslich Windows 10 (auf dem Zielsystem), dann würd ich die Windows 10 Notifications dafür nehmen:
http://docwiki.embarcadero.com/CodeE...cations_Sample
http://docwiki.embarcadero.com/RADSt...n_Mitteilungen

Dazu sollte man diesen Thread ( https://www.delphipraxis.net/197041-...-center-2.html ) noch lesen

KodeZwerg 24. Jul 2018 08:37

AW: Infofenster im Systembereich erzeugen, einblenden und ausblenden
 
Vor Jahrzehnten hatte ich mir mal so etwas ähnliches gebastelt.
Ich bin dabei etwas anders vorgegangen da bei mir nur ein Fenster-Typ dargestellt werden sollte.
In der IDE habe ich mir ein mini-Fenter gebastelt, im großen und ganzen war es nur ein Label und ein Panel.
Diese leere Form habe ich als proto-Form in Resource abgelegt.
Wie ConnorMcLeod bereits schrieb braucht man dafür eine Verwaltung.
Die Position "unten rechts über Taskbar" war das einzige was ich zum berechnen brauchte.
In der Verwaltung habe ich den Bildschirm in "Max Höhe / Fensterhöhe" unterteilt um Positionen für die einzelnen Fenster zu erhalten.
Nun lediglich proto-Form in eine dynamische umwandeln, Label und Panel beschreiben, Verwaltung abfragen an welcher Position was frei ist und anzeigen lassen.
Was ich damals noch nicht drinnen hatte war das runterrutschen, wäre über die Verwaltung aber auch nicht so extrem schwer umzusetzen da die immer weiß welche Fensterpositionen belegt sind.
Problematisch wurde es bei mir in dem Sonderfall "was soll passieren wenn ein neues Fenster nicht mehr auf Screen passt"....
....da meine Art der Verwaltung nur "Max Screen Höhe / Fensterhöhe" als valide Ziele kannte.

Hobbycoder 24. Jul 2018 08:47

AW: Infofenster im Systembereich erzeugen, einblenden und ausblenden
 
Ich werfe mal JvDesktopAlert und JvDesktopAlertStack in den Raum. Das Funktioniert bei mir seit Jahren perfekt (XP bis Win10) und du hast einiges an Designmöglichkeiten.

Solltest du das aber unter allen Umständen selber machen wollen, so kannst du dir ggf. bei den Jedi's was abgucken.

DieDolly 24. Jul 2018 08:49

AW: Infofenster im Systembereich erzeugen, einblenden und ausblenden
 
Die Jedis benutze ich seit Jahren schon nicht mehr, da sich da scheinbar nichts mehr tut (zumindestes bei GitHub).
Der Code ist auch viel zu kompliziert finde ich, speziell für Anfänger.

Am liebsten wäre es mir, wenn mir ConnorMcLeod und KodeZwerg mit ihren Ideen zur Umsetzung verhelfen könnten.

ConnorMcLeod 24. Jul 2018 09:24

AW: Infofenster im Systembereich erzeugen, einblenden und ausblenden
 
Tut mir leid, wenn ich nicht allzuviel Zeit investieren kann (berufstätig ...), aber als Starthilfe/Diskussionsgrundlage:
Delphi-Quellcode:
type
  TFormPosition = record
    ... x, y, Breite, Höhe, Status (maximiert, normal, minimiert) etc ...
  end;

  TRutschForm = class(TCustomForm)
  private
    FCurrentPosition: TFormPosition;
  public
    procedure ZeigDich;
    procedure VersteckDich;
    procedure ZerstoerDich;
    procedure RutschVonNach(AVon: TFormPosition; ANach: TFormPosition);

    property MessageText: ...
  end;

  TRutschFormList = {delphiversionsabhängig} TList<TRutschForm>
    ... gewünschte Verhaltensweisen ...
  end;

DieDolly 7. Okt 2018 14:35

AW: Infofenster im Systembereich erzeugen, einblenden und ausblenden
 
Ich hab mich mal dran versucht aber bekomme es nicht hin.
Viel weiter komme ich mit deinem Konstrukt auch nicht. Genau gesagt komme ich nicht eine einzige Zeile weiter w eil mir das Verständnis fehlt.

KodeZwerg 7. Okt 2018 16:06

AW: Infofenster im Systembereich erzeugen, einblenden und ausblenden
 
Du kannst mal hier rein schauen, bei Interesse sag was.

DieDolly 7. Okt 2018 16:28

AW: Infofenster im Systembereich erzeugen, einblenden und ausblenden
 
Genau soetwas meine ich. Das ein- und ausblenden habe ich schon. Die entsprechenden Forms dafür ich (ich habe verschiedene).
Nur das mit der Liste kapier ich nicht, sodass wenn ein Fenster sichtbar ist, das neue oben drüber angezeigt wird und zusätzlich wenn eins sich ausblendet das obere runterrutscht.

KodeZwerg 7. Okt 2018 16:38

AW: Infofenster im Systembereich erzeugen, einblenden und ausblenden
 
Ich erzeuge den ganzen kram per Laufzeit, (da wollte ich Wissen ob es das ist was der TE dort wollte, aber blieb unbeantwortet) eine kleine Fensterverwaltung rein, sollte nicht so arg problematisch sein, ich weiß nicht wie Du es momentan machst, aber wenn es sowas in der Art ist wie ich da per Demo zeigte, kann ich das versuchen in ne Klasse zu quetschen, threads draus zu machen, ne kleine verwaltung rein, und es sollte so was wie bei jdownloader rauskommen, bei mir halt ne transparente mini-form blau mit nem Label drauf.
Womit ich gerade probleme habe wäre wie die Fenster reagieren wenn ein OnTop über nen anderes OnTop flutscht, bei mir wirds halt in ner loop ausgeführt bis fenster das sichtbare bild verlassen hat.
Gerne würde ich das runterflutschen auch beschränken das ab Taskbar abgeschnitten wird und nicht rübergemalt wird, so wie es jetzt der Fall ist.

Zeige doch mal ne Demo von dem was Du hast ;)

DieDolly 7. Okt 2018 16:42

AW: Infofenster im Systembereich erzeugen, einblenden und ausblenden
 
Mehr als das was auf Seite 1 steht habe ich nicht.
Mit dem was ich da stehen habe könntest du dir die Taskbarhöhe ausrechnen und dann die Form Height in einer Schleife + Delay immer um 1 verringern. Dann wärst du das Problem mit dem unter der Taskleiste los.

Wir könnten das eventuell zusammen machen. Du das mit den Klassen, da du dich damit scheinbar gut auskennst, und ich gehe das Problem mit der Taskleistenhöhe und -position an und stelle alles danach hier rein.

KodeZwerg 7. Okt 2018 17:28

AW: Infofenster im Systembereich erzeugen, einblenden und ausblenden
 
Delphi-Quellcode:
procedure ShowTrayMessage(const TheMessage: String);
var
 H: HWND;
 Rec: TRect;
 NeededTop: Integer;
 HintForm: TForm;
 HintLabel: TLabel;
 aw: hwnd;
begin
 H := FindWindow('Shell_TrayWnd', nil);
 if h <> 0 then
 begin
  GetWindowRect(h, Rec);
  HintForm := TForm.Create(nil);
  with HintForm do
  begin
   Width := 245;
   Height := 100;
   Color := clSkyBlue;
   BorderStyle := bsNone;
   FormStyle := fsStayOnTop;
   HintLabel := TLabel.Create(nil);
   with HintLabel do
   begin
    Parent := HintForm;
    WordWrap := true;
    Font.Name := 'Fixedsys';
    Font.Style := [fsBold];
    Font.Pitch := fpFixed;
    Font.Size := 9;
    Caption := ' ' + Trim(TheMessage) + ' ';
    Align := alClient;
    Layout := tlCenter;
    Alignment := taCenter;
   end;
   AlphaBlend := true;
   AlphaBlendValue:=220;
   aw := GetActiveWindow;
   ShowWindow(handle, SW_SHOWNOACTIVATE);
   SetActiveWindow(aw);
   Left := Screen.Width - Width;
   Top := Screen.Height - 20;
   NeededTop := Rec.Top - Height;
   while Top > NeededTop do
   begin
    Top:=Top - 2;
    Repaint;
    Sleep(10);
   end;
    Sleep(3000);
   NeededTop := Screen.Width - 20;
   while Top < NeededTop do
   begin
    Top:=Top + 2;
    Repaint;
    Sleep(10);
   end;
   HintLabel.Free;
   Free;
  end;
 end;
end;
So sieht das ganze momentan aus, ja Du magst kein "with", das ist dennoch erstmal meine Ausgangsbasis um daraus ne Threaded Klasse zu erschaffen.
Es gibt viel zu tun, also fangen wir was an :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:30 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