Einzelnen Beitrag anzeigen

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, 22: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