AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Vollständige Sichtbarkeit eines Forms

Vollständige Sichtbarkeit eines Forms

Ein Thema von taaktaak · begonnen am 4. Apr 2008 · letzter Beitrag vom 8. Sep 2009
Antwort Antwort
Seite 1 von 2  1 2   
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#1

Vollständige Sichtbarkeit eines Forms

  Alt 4. Apr 2008, 22:46
Moin, Moin.

Ich arbeite abwechselnd mit einem Notebook und einem PC(mit 2 Monitoren). Da hat es genervt, dass die Wiederherstellung der letzten Fensterposition beim Wechsel von PC auf Notebook immer problematisch war - das hat ja nun mal leider keine 2 Bildschirme eingebaut

Nun habe ich mich mal an einer endgültige Problemlösung versucht. Das Ergebnis sorgt nach erstem Test dafür, dass das Programmfenster vollständig sichtbar angezeigt wird, auch wenn aus der INI-Datei Koordinaten zur Positionierung gelesen wurden, mit der das Fenster in der aktuellen Monitorumgebung eigentlich nicht oder nicht vollständig sichtbar dargestellt werden könnte.

1 - Auf welchem Monitor wird Form dargestellt?

Ermittelt, auf welchem Monitor das Form angezeigt wird. Bildet das Form auf Multi-Monitorsystemen Schnittflächen mit mehreren Monitoren, wird derjenige Monitor zurückgeliefert, der die größte Schnittfläche mit dem Form hat. Ist das Form aufgrund einer völlig abweichenden Monitorkonfiguration auf keinem aktuell verfügbaren Monitor sichtbar, wird als Ergebnis der Primärmonitor zurückgeliefert.

Delphi-Quellcode:
function GetCurrentMonitor(Form:TForm):Integer;
var Rect : TRect;
    i,A,maxA : Integer;
begin
  Result:=0;
  maxA :=0;
  for i:=0 to Screen.MonitorCount-1 do
    if IntersectRect(Rect,Screen.Monitors[i].BoundsRect,Form.BoundsRect) then begin
      A:=(Rect.Right-Rect.Left)*(Rect.Bottom-Rect.Top);
      if A>maxA then begin maxA :=A;
                           Result:=i;
                           end
      end
end;
2 - Ist Form auf Monitor vollständig sichtbar?

Die Funktion prüft, ob das übergebene Form aktuell vollständig angezeigt wird.

Delphi-Quellcode:
function FormFullInView(Form:TForm):Boolean;
var MonNo,
    MonL,MonW,
    MonT,MonH : Integer;
begin

  MonNo:=GetCurrentMonitor(Form);
 
  MonL :=Screen.Monitors[MonNo].Left;
  MonW :=Screen.Monitors[MonNo].Width;
  MonT :=Screen.Monitors[MonNo].Top;
  MonH :=Screen.Monitors[MonNo].Height;

  Result:=(Form.Left >=MonL) and
          (Form.Top >=MonT) and
          (Form.Left+Form.Width <=MonL+MonW) and
          (Form.Top +Form.Height<=MonT+MonH)
end;
3 - Vollständige Anzeige des Forms erzwingen

Die Prozedur erzwingt die vollständige Anzeige (zentriert) des Forms auf dem Monitor der mit dem Formular die größte Schnittfläche besitzt. Hat das Form in der aktuellen Konfiguration mit keinem vorhandenen Monitor eine Schnittfläche, wird der primäre Monitor verwendet. Der Aufruf kann (natürlich) erst erfolgen, nachdem Left, Top, Width und Height des Forms festgelegt wurden.

Delphi-Quellcode:
procedure FitFormFullInView(Form:TForm);
var MonNo,
    MonL,MonW,
    MonT,MonH : Integer;
begin
  if not(FormFullInView(Form)) then begin

    MonNo:=GetCurrentMonitor(Form);
    MonL :=Screen.Monitors[MonNo].Left;
    MonW :=Screen.Monitors[MonNo].Width;
    MonT :=Screen.Monitors[MonNo].Top;
    MonH :=Screen.Monitors[MonNo].Height;

    with Form do begin
      Left:=MonL+(MonW-Width ) div 2;
      Top :=MonT+(MonH-Height) div 2;
      end

   end
end;
Nach Setzen der in der INI-Datei gespeicherten letzten Fensterkoordinaten wird die zuletzt gezeigte Prozedur aufgerufen. Damit wird dann sichergestellt, dass das Form unter jeder Monitorkonfiguration immer vollständig angezeigt wird - hoffe ich jedenfalls

Warum poste ich das Ganze nun?

Ich würde das gern noch mal von einer weiteren Person testen lassen.
Vielleicht gibt es sogar in der DP-Gemeinde ein Mitglied mit 3, 4 oder noch mehr Monitoren.

// edit : Rechtschreibfehler beseitigt
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von OldGrumpy
OldGrumpy

Registriert seit: 28. Sep 2006
Ort: Sandhausen
941 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Vollständige Sichtbarkeit eines Forms

  Alt 4. Apr 2008, 23:14
Oh das werde ich gleich morgen früh mal ausprobieren, ich hab nämlich gerade das Phänomen dass meine App mit XP-Manifest zwar im Modus "maximiert" auf dem Bildschirm erscheint, aber trotzdem deutlich kleiner als der Bildschirm ist. Erst zweimaliges Klicken aufs Border Icon maximiert die Applikation dann korrekt (grummel!) - ohne XP-Manifest klappts. Mal sehen ob Dein Ansatz da Abhilfe schafft

[edit=Phoenix]Text wiedergeholt.. Mfg, Phoenix[/edit]
"Tja ja, das Ausrufezeichen... Der virtuelle Spoiler des 21. Jahrhunderts, der Breitreifen für die Datenautobahn, die k3wle Sonnenbrille fürs Usenet. " (Henning Richter)
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#3

Re: Vollständige Sichtbarkeit eines Forms

  Alt 6. Apr 2008, 16:53
Moin, Moin.
Gibt's hier im Forum kein Mitglied, das mehr als zwei Monitore hat und das mal testen kann?
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#4

Re: Vollständige Sichtbarkeit eines Forms

  Alt 6. Apr 2008, 19:34
Also ich hab leider keinen 2. Monitor, aber ich hab deine Funktionen im Kopf überprüft und würde sagen: Daumen hoch, sieht sehr gut aus.
GetCurrentMonitor ist piffig gelöst.

Vielleicht statt TForm die Klasse TCustomForm verwenden.
FitFormFullInView könnte man vielleicht besser lösen.
Sobald ein Form die Monitorfläche um ein Pixel verlässt, wird es in x- und y-Richtung zentriert.
Es würde aber reichen, das Form nur soweit zu verschieben, bis es nirgends mehr übersteht.
Also 1.) GetCurrentMonitor aufrufen 2.) ermitteln, um wieviele Pixel das Form in x- und/oder y-Richtung übersteht 3.) Form um genau diese x/y-Beträge so verschieben, dass es vollständig im Monitor ist.
Ich würde dazu nicht FormFullInView aufrufen, sondern gleich in die Rechnung einsteigen.
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#5

Re: Vollständige Sichtbarkeit eines Forms

  Alt 6. Apr 2008, 21:01
Vielen Dank für den Check
- TCustomForm werde ich ändern,
- den zweiten Punkt erst einmal mal in der Praxis austesten. Hatte das Zentrieren gewählt, damit besonders deutlich wird, dass das Form vom Programm abweichend von der letzten Position neu positioniert wurde
Ralph
  Mit Zitat antworten Zitat
Assertor

Registriert seit: 4. Feb 2006
Ort: Hamburg
1.296 Beiträge
 
Turbo C++
 
#6

Re: Vollständige Sichtbarkeit eines Forms

  Alt 21. Jun 2008, 20:09
Hi taaktaak,

Zitat von taaktaak:
Ich würde das gern noch mal von einer weiteren Person testen lassen.
Etwas spät, aber hiermit getan

Ich habe es eben mit 2 Monitoren in unterschiedlicher Anordnung getestet (1,2 / 2,1).

Ich sehe auf Anhieb zwei Probleme:

1) Du berücksichtigest bei einem Resize nicht die Höhe der Taskbar und auf welchem der Monitore diese ist. WorkareaRect wäre hier der richtige Ansatz.

2) Was ist, wenn ein Benutzer wirklich das Form über mehrere Monitore vergrößern will? Es gibt ja auch Multimonitorsysteme ohne Displayrahmen, die zusammen einen großen Desktop ergeben. Dabei würde Deine Lösung immer auf einen einzelnen Monitor verkleinern.

Zitat von taaktaak:
- den zweiten Punkt erst einmal mal in der Praxis austesten. Hatte das Zentrieren gewählt, damit besonders deutlich wird, dass das Form vom Programm abweichend von der letzten Position neu positioniert wurde
Hast Du daran schon etwas verändert? Dieser Ansatz gefällt mir auch besser.

Ich habe gerade genau das gleiche Problem und sitze in Griffweite eines Multimonitorsystems... Ist das für Dich noch aktuell?

Gruß Assertor
Frederik
  Mit Zitat antworten Zitat
Assertor

Registriert seit: 4. Feb 2006
Ort: Hamburg
1.296 Beiträge
 
Turbo C++
 
#7

Re: Vollständige Sichtbarkeit eines Forms

  Alt 21. Jun 2008, 23:42
So,

hier mal ein Lösungsansatz für die angesprochenen Probleme:

Damit erledigt FitFormFullInView zusammen mit seinen Hilfsfunktionen die folgenden Aufgaben (für Einzel- oder Multi-Monitor):
  • Wenn das Fenster in den gesamten Desktop passt, wird es unverändert gelassen (für gewünschte, große Multimonitor-Fenster)
  • Ist das Fenster zum Teil außerhalb des gültigen Gesamtdesktops, wird es auf dem Monitor mit dem größten Anteil zentriert angezeigt
  • Ist das Fenster vollständig außerhalb des gültigen Gesamtdesktops, wird es auf dem Primary-Monitor zentriert angezeigt
  • Ist das Fenster immer noch zu groß für den jeweiligen Monitor, wird es entsprechend in Höhe und Breite angepasst
  • Bei der Anpassung wird die Taskbar berücksichtigt (egal ob Links, Oben, Rechts, Unten)
Delphi-Quellcode:
function GetCurrentMonitor(AForm: TCustomForm): Integer;
var
  Rect: TRect;
  i, A, maxA: Integer;
begin
  {
    man kann sich diese Funktion auch sparen und einfach AForm.Monitor aufrufen,
    wobei diese u.U. nicht so gründlich und schön auf die Maximalnutzung prüft
  }

  Result := 0;
  maxA := 0;
  for i := 0 to Screen.MonitorCount-1 do
    if IntersectRect(Rect, Screen.Monitors[i].BoundsRect, AForm.BoundsRect) then
    begin
      A := (Rect.Right-Rect.Left) * (Rect.Bottom-Rect.Top);
      if A > maxA then
      begin
        maxA := A;
        Result:=i;
      end;
    end;
end;

function FormFullInView(AForm: TCustomForm): Boolean;
var
  MonNo,
  MonL, MonW,
  MonT, MonH: Integer;
begin
  MonNo := GetCurrentMonitor(AForm);

  MonL := Screen.Monitors[MonNo].WorkareaRect.Left;
  MonW := Screen.Monitors[MonNo].WorkareaRect.Right - Screen.Monitors[MonNo].WorkareaRect.Left;
  MonT := Screen.Monitors[MonNo].WorkareaRect.Top;
  MonH := Screen.Monitors[MonNo].WorkareaRect.Bottom - Screen.Monitors[MonNo].WorkareaRect.Top;

  // handle multi-monitor windows
  if (AForm.Left >= Screen.DesktopLeft) and
     (AForm.Top >= Screen.DesktopTop) and
     ((AForm.Left + AForm.Width) <= (Screen.DesktopWidth + Screen.DesktopLeft)) and
     ((AForm.Top + AForm.Height) <= (Screen.DesktopHeight + Screen.DesktopTop))
  then
    Result := True
  else
    Result:= (AForm.Left >= MonL) and (AForm.Top >= MonT) and
      (AForm.Left + AForm.Width <= MonL + MonW) and
      (AForm.Top + AForm.Height <= MonT + MonH);
end;

procedure FitFormFullInView(AForm: TCustomForm);
var
  MonNo,
  MonL, MonW,
  MonT, MonH: Integer;
begin
  if not (FormFullInView(AForm)) then
  begin
    MonNo := GetCurrentMonitor(AForm);
    MonL := Screen.Monitors[MonNo].WorkareaRect.Left;
    MonW := Screen.Monitors[MonNo].WorkareaRect.Right - Screen.Monitors[MonNo].WorkareaRect.Left;
    MonT := Screen.Monitors[MonNo].WorkareaRect.Top;
    MonH := Screen.Monitors[MonNo].WorkareaRect.Bottom - Screen.Monitors[MonNo].WorkareaRect.Top;
    with AForm do
    begin
      if Height > MonH then
        Height := MonH;
      if Width > MonW then
        Width := MonW;
      Left := MonL + (MonW-Width) div 2;
      Top := MonT + (MonH-Height) div 2;
    end;
  end;
end;
Im Ergebnis finde ich die Zentrierung auch besser.

Nützlich ist die Funktion, wenn z.B. 1) ein Anwender seinen Monitor / seine Grafikkarte durch ein Modell mit anderer Standard-Auflösung ersetzt und ein Programm dann mit diesen neuen Einstellungen klar kommen muß oder 2) eine Anwendung mit Einstellungen für einen Multimonitor-PC z.B. auf einem USB-Stick mobil am Notebook eingesetzt wird.

Gruß Assertor
Frederik
  Mit Zitat antworten Zitat
sirarcher

Registriert seit: 7. Mär 2007
22 Beiträge
 
#8

Re: Vollständige Sichtbarkeit eines Forms

  Alt 9. Sep 2008, 09:28
Hi,

beim From die "Position" auf "poScreenCenter" stellen. Dann wirds auch sauber ausgerichtet.

Gruss
  Mit Zitat antworten Zitat
Assertor

Registriert seit: 4. Feb 2006
Ort: Hamburg
1.296 Beiträge
 
Turbo C++
 
#9

Re: Vollständige Sichtbarkeit eines Forms

  Alt 9. Sep 2008, 09:34
Hi,

Zitat von sirarcher:
beim From die "Position" auf "poScreenCenter" stellen. Dann wirds auch sauber ausgerichtet.
Ein fast 3 Monate alter Thread, den Du da auskramst... Aber Dein Vorschlag hilft nicht, da hier Zentrierung nur bei geänderten Monitorverhältnissen gewünscht ist. Die oben gepostete Lösung funktioniert doch einwandfrei...

Warum also der Post

Gruß Assertor
Frederik
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#10

Re: Vollständige Sichtbarkeit eines Forms

  Alt 9. Sep 2008, 10:14
Moin, Moin.
... weil ich sonst gar nicht mitbekommen hätte, dass Assertor meinen Code verbessert hast. Prima!

Werde allerdings die Funktionalität
Zitat:
Wenn das Fenster in den gesamten Desktop passt, wird es unverändert gelassen (für gewünschte, große Multimonitor-Fenster)
optional gestalten. Noch mal Danke für die Optimierung
Ralph
  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 19:33 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