Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Monitore und dessen Positionen anzeigen (Bildschirmanordnung) (https://www.delphipraxis.net/184002-monitore-und-dessen-positionen-anzeigen-bildschirmanordnung.html)

dGeek 18. Feb 2015 17:51


Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Ich interessiere mich momentan dafür wie man sich seine Monitore, dessen Namen und Positionen anzeigen lassen kann.
Also die Bildschirmanordnung.

Was ich meine ist dieses Fenster welches man sieht wenn man seine Auflösung verändert. Oben werden ja alle Monitore mit einer Nummer markiert und dessen Positionen angezeigt.

Auch hier sieht man das mit einem Monitor schön:
http://www.chip.de/ii/6/4/9/6/8/6/5/...887c2b8862.png

Wie lässt sich so etwas realisieren?

himitsu 18. Feb 2015 18:46

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Delphi-Referenz durchsuchenScreen

BadenPower 18. Feb 2015 18:50

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Schau Dir einmel die Klassen TScreen und TMonitor an.

Wenn Du mehr Informationen zu den einzelnen Moitoren und Grafikeinstellungen benötigst musst Du auf die Windows-Api zurückgreifen.

Siehe dort zum Beispiel unter:
EnumDisplayDevices
EnumDisplaySettings
EnumDisplaySettingsEx
GetDeviceCaps

dGeek 18. Feb 2015 19:01

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Und genau da liegt ja der Hund begraben ;)

Screen und Monitor sagen mir etwas.
Aber wie bekomme ich die Bildschirmanordnung heraus?
Bildschirm 2 ist ja nicht zwangsweise rechts, der kann auch oben, unten oder links sein.

BadenPower 18. Feb 2015 19:10

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Zitat:

Zitat von dGeek (Beitrag 1290460)
Und genau da liegt ja der Hund begraben ;)

Screen und Monitor sagen mir etwas.
Aber wie bekomme ich die Bildschirmanordnung heraus?
Bildschirm 2 ist ja nicht zwangsweise rechts, der kann auch oben, unten oder links sein.

Hast Du Dir einmal die Hilfe zu TMonitor angeschaut???

Da steht bei der Property "Top" zum Beispiel so ein netter Hinweis.

Zitat:

In Anwendungen mit mehreren Bildschirmen kann sich der verfügbare vertikale Anzeigebereich über mehrere Bildschirme erstrecken. Mit Top können Sie feststellen, wo sich der obere Rand des Bildschirms innerhalb des Gesamtbereichs befindet. Der Wert von Top wird relativ zum oberen Rand des Primärbildschirms in Pixel angegeben.
Es lohnt sich auch die anderen Propertys anzuschauen.

dGeek 18. Feb 2015 19:12

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Wenn es eine online-Hilfe gibt, gucke ich mir das gerne an.
Aber nach dem Update 3 für mein XE2 funktioniert meine Hilfe nicht mehr und alles neu zu installieren dauert zu lange :(

Ich sehe gerade dass das alles viel zu komplex für mich ich da blicke ich nicht durch.
Außerdem komme ich mit Monitor gar nicht klar, mit Screen schon.

dGeek 18. Feb 2015 19:31

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Also wie ich die Positionen herausbekomme habe ich jetzt sehr laienhaft herausbekommen.

Aber wie kann ich das umrechnen und auf einem Form anzeigen lassen? Genau damit habe ich eben Probleme.

himitsu 18. Feb 2015 20:07

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Wieso laienhaft?

In Screen findet man die Monitore und in jedem Monitor die pixelgenaue Position und Größe.
Das kann man nun direkt bbenutzen, oder man rechnet es sich entsprechend um, auf die benötigte Größe. (Zoomen -> Prozentrechnung oder der geliebte Dreisatz)

dGeek 18. Feb 2015 21:02

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Ich glaube das wird mit mir heute nichts mehr :P

Das folgende ist nur zum Testen. Aber die Shapes bzw das Shape wird immer oben links in den negativen Bereich gesetzt.
Solche Rechnungen sind zu kompliziert für mich :D

Delphi-Quellcode:
var
  p: TPoint;
  i: Integer;
  aShape: TShape;
begin
  for i := 0 to Screen.MonitorCount - 1 do
  begin
    p := Point(Screen.Monitors[i].Top, Screen.Monitors[i].Left);

    aShape := (FindComponent('Shape' + IntToStr(i + 1)) as TShape);
    aShape.Left := ScreenToClient(p).Y;
    aShape.Top := ScreenToClient(p).X;

    aShape.Width := Screen.Monitors[i].Width;
    aShape.Height := Screen.Monitors[i].Height;

    showmessage(IntToStr(aShape.Left) + ' - ' + IntToStr(aShape.Top));
  end;

Sir Rufo 18. Feb 2015 21:14

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Zitat:

Zitat von dGeek (Beitrag 1290467)
Wenn es eine online-Hilfe gibt, gucke ich mir das gerne an.
Aber nach dem Update 3 für mein XE2 funktioniert meine Hilfe nicht mehr und alles neu zu installieren dauert zu lange :(

Ich sehe gerade dass das alles viel zu komplex für mich ich da blicke ich nicht durch.
Außerdem komme ich mit Monitor gar nicht klar, mit Screen schon.

Hach, so ein Mist aber auch ... wenn es nur sowas wie ein vernetztes Informationsdingen geben würde - man würde es glatt Internet nennen können - wo diese Informationen abrufbar wären ... das wär schön ..

Delphi-Referenz durchsuchenTScreen oder direkt für XE3 auf deutsch
http://docwiki.embarcadero.com/Libra....Forms.TScreen

dGeek 18. Feb 2015 21:15

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Mit TScreen und TMonitor gibt es ja keine Probleme.

Ich habe Probleme mit der Berechnung und der Skalierung ;)

BadenPower 18. Feb 2015 21:17

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Zitat:

Zitat von dGeek (Beitrag 1290494)
Ich glaube das wird mit mir heute nichts mehr :P
Delphi-Quellcode:
    aShape.Left := ScreenToClient(p).Y;
    aShape.Top := ScreenToClient(p).X;

Das Koordinatensystem ist auch nicht gerade Dein Freund?

dGeek 18. Feb 2015 21:18

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Nein, heute nicht :P X und Y vertauscht, wie peinlich.

dGeek 18. Feb 2015 21:34

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
So ich bin jetzt soweit, dass die Shapes sichtbar angezeigt werden.
Aber: wenn sich Monitor 2 links neben Monitor 1 befindet, ist Monitor 2 im negativen Bereich, da Monitor 1 immer an Position 0|0 ist:

Delphi-Quellcode:
procedure TForm2.Button1Click(Sender: TObject);
var
  p: TPoint;
  i: Integer;
  aShape: TShape;
begin
  for i := 0 to Screen.MonitorCount - 1 do
  begin
    p := Point(Screen.Monitors[i].Left, Screen.Monitors[i].Top);

    aShape := (FindComponent('Shape' + IntToStr(i + 1)) as TShape);
    aShape.Left := prozentwert(p.X, 5);
    aShape.Top := prozentwert(p.Y, 5);

    aShape.Width := prozentwert(Screen.Monitors[i].Width, 5);
    aShape.Height := prozentwert(Screen.Monitors[i].Height, 5);

    showmessage(IntToStr(aShape.Left) + ' - ' + IntToStr(aShape.Top));
  end;
end;

Sir Rufo 18. Feb 2015 21:40

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Und was ist daran schlimm, dass da negative Werte sind? Das sagt ja auch die Doku

dGeek 18. Feb 2015 21:43

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Es ist schlimm, weil es dann nicht auf meinem Formular sichtbar ist da Monitor 1 immer an Position 0|0 ist :P

Sir Rufo 18. Feb 2015 21:51

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Zitat:

Zitat von dGeek (Beitrag 1290510)
Es ist schlimm, weil es dann nicht auf meinem Formular sichtbar ist da Monitor 1 immer an Position 0|0 ist :P

Ist aber auch ein schlimmer Finger dein Formular. Kannst du das nicht austricksen indem du zu jedem Wert einen bestimmten Wert addierst. Ein guter Wert wäre ja der Wert, der dann mit dem Left-Wert des 2. Monitors zusammen 0 ergibt. :cyclops:

dGeek 18. Feb 2015 21:59

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Dann müsste ich ja aber auch den ersten Monitor, der sich an Position 0|0 befindet, mit verschieben und alle anderen ebenfalls.

Das kann doch so nicht richtig sein, oder?

Sir Rufo 18. Feb 2015 22:03

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Oder um es technischer zu formulieren:

Du benötigst zur Darstellung einen Zoom-Faktor
Delphi-Quellcode:
Single
und einen Offset
Delphi-Quellcode:
TPoint
.

Oder versuchst du auch die Monitore 1:1 darzustellen (per Wallpainting) :mrgreen:

BadenPower 18. Feb 2015 22:11

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Zitat:

Zitat von dGeek (Beitrag 1290512)
Das kann doch so nicht richtig sein, oder?

Doch, dass hat alles seine Richtigkeit, da der primäre Monitor immer mit 0/0 beginnt, da es der einzige Monitor ist, welchen Du nicht ohne weiteres " abstöpseln kannst.

Die anderen Monitore werden demnach um den primären Monitor herum gebaut und beziehen ihre Positionsangaben immer auf den Primären.



Schau die auch dazu noch:

Screen.Width
Screen.Height
Screen.Display.Top
Screen.Display.Left
Screen.Display.Width
Screen.Display.Height

und die ganzen

Screen.WorkArea...

-Propertys an.

Dann verstehst Du auch die Zusammenhänge.

dGeek 18. Feb 2015 22:12

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Nein. Ich habe nur ein kleines Fenster und da möchte ich kleine Shapes reinpacken welche die Monitore darstellen sollen.
Das mit der Größe habe ich hinbekommen. Das mit dem Minisbereich nicht.

dGeek 18. Feb 2015 22:47

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Ok also ich habe wirklich Eigeninitiative gezeigt und lasse mir nicht alles vorkauen.

Aber nun bin ich am Ende und besser bekomme ich es nicht hin.
(Einfach in eine Form packen die etwa 500px hoch und 400p breit ist).

Wenn mir nun noch jemand helfen könnte die Skalierung richtig hinzubekommen sodass alle Monitore (Shapes) richtig auf der Form angezeigt werden können, wäre ich sehr dankbar.

Delphi-Quellcode:
procedure TForm2.FormShow(Sender: TObject);
const
  aScale = 7;
var
  p: TPoint;
  iMostTop, iPrimaryX, iPrimaryY, iPrimary, i: Integer;
  aShape: TShape;
  aLabel: TLabel;
  procedure drawScreen(iMonCnt: Integer; bPrimary: Boolean = False);
  begin
    p := Point(Screen.Monitors[iMonCnt].Left, Screen.Monitors[iMonCnt].Top);

    if Assigned((FindComponent('aScreen' + IntToStr(iMonCnt + 1)) as TShape)) then
      (FindComponent('aScreen' + IntToStr(iMonCnt + 1)) as TShape).Free;

    aShape := TShape.Create(Self);
    aShape.Parent := Self;
    aShape.Name := 'aScreen' + IntToStr(iMonCnt + 1);
    aShape.Anchors := [];

    aShape.Width := prozentwert(Screen.Monitors[iMonCnt].Width, aScale);
    aShape.Height := prozentwert(Screen.Monitors[iMonCnt].Height, aScale);

    if bPrimary then
    begin
      aShape.Left := (Self.Width div 2) - (aShape.Width div 2);
      aShape.Top := iMostTop; // (Self.Height div 2) - (aShape.Height div 2);
      iPrimaryX := aShape.Left;
      iPrimaryY := aShape.Top;
    end
    else
    begin
      aShape.Left := prozentwert(p.X, aScale) + iPrimaryX;
      aShape.Top := prozentwert(p.Y, aScale) + iPrimaryY;
    end;

    if Assigned((FindComponent('aLabel' + IntToStr(iMonCnt + 1)) as TLabel)) then
      (FindComponent('aLabel' + IntToStr(iMonCnt + 1)) as TLabel).Free;

    aLabel := TLabel.Create(Self);
    aLabel.Parent := Self;
    aLabel.Name := 'aLabel' + IntToStr(iMonCnt + 1);
    aLabel.Anchors := aShape.Anchors;
    aLabel.Font.Size := -13;
    aLabel.Font.Style := [fsBold];
    aLabel.AutoSize := False;
    aLabel.Left := aShape.Left + 1;
    aLabel.Top := aShape.Top + (aShape.Height div 2) - (aLabel.Height div 2);
    aLabel.Width := aShape.Width - 2;
    aLabel.Alignment := taCenter;
    aLabel.Caption := IntToStr(iMonCnt + 1);
    aLabel.Visible := True;
    aLabel.BringToFront;

    Repaint;
  end;

begin
  iMostTop := 0;
  for i := 0 to Screen.MonitorCount - 1 do
  begin
    if Screen.Monitors[i].Top < iMostTop then
      iMostTop := Screen.Monitors[i].Top;
  end;
  iMostTop := iMostTop + 20;

  for i := 0 to Screen.MonitorCount - 1 do
  begin
    if Screen.Monitors[i].Primary then
    begin
      iPrimary := i;
      drawScreen(i, True);
      break;
    end;
  end;

  for i := 0 to Screen.MonitorCount - 1 do
  begin
    if i = iPrimary then
      Continue;

    drawScreen(i);
  end;
end;

BadenPower 18. Feb 2015 23:13

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Die Funktion "prozentwert()" fehlt.

dGeek 19. Feb 2015 02:22

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Delphi-Quellcode:
function prozentwert(i, p: Integer): Integer;
begin
 Result := (i div 100) * p;
end;

himitsu 19. Feb 2015 09:28

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
10% von 290 sind?

20 :roll:

BadenPower 19. Feb 2015 10:43

AW: Monitore und dessen Positionen anzeigen (Bildschirmanordnung)
 
Kleines Quick 'n Dirty:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, Forms, Classes, Controls, ComCtrls, ExtCtrls, StdCtrls, Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure MonitorPanelResize(Sender: TObject);
  private
    procedure ShowMonitors();
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

uses
  SysUtils, Math;


{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  liZ1: Integer;
  lPanel: TPanel;
begin
  Position := poScreenCenter;
  Color := $444444;
  lPanel := TPanel.Create(Self);
  lPanel.Parent := Self;
  lPanel.Name := 'MonitorPanel';
  lPanel.Caption := '';
  lPanel.ParentBackground := true;
  lPanel.BevelOuter := bvNone;
  lPanel.AlignWithMargins := true;
  lPanel.Margins.SetBounds(10,10,10,10);
  lPanel.Align := alClient;
  lPanel.OnResize := MonitorPanelResize;
  ShowMonitors();
end;

procedure TForm1.MonitorPanelResize(Sender: TObject);
begin
  ShowMonitors();
end;

procedure TForm1.ShowMonitors();
var
  liZ1: Integer;
  lScaleFactor: Extended;
  lOffsetX: Integer;
  lOffsetY: Integer;
  lPanel: TPanel;
  lParentPanel: TPanel;
begin
  lParentPanel := TPanel(Self.FindComponent('MonitorPanel'));

  for liZ1 := lParentPanel.ControlCount - 1 downto 0 do
   begin
    lParentPanel.Controls[liZ1].Free;
   end;

  lScaleFactor := Min(lParentPanel.Width / Screen.DesktopWidth,lParentPanel.Height / Screen.DesktopHeight);
  lOffsetX := Round(Screen.DesktopLeft * lScaleFactor);
  lOffsetY := Round(Screen.DesktopTop * lScaleFactor);

  for liZ1 := 0 to Screen.MonitorCount - 1 do
   begin
    lPanel := TPanel.Create(lParentPanel);
    lPanel.Parent := lParentPanel;
    lPanel.ParentBackground := false;
    lPanel.Color := $888888;
    lPanel.BevelInner := bvLowered;
    lPanel.BevelWidth := Max(Round(10 * lScaleFactor),1);
    lPanel.Caption := IntToStr(Screen.Monitors[liZ1].MonitorNum + 1);
    lPanel.Top := Round(Screen.Monitors[liZ1].Top * lScaleFactor) - lOffsetY;
    lPanel.Left := Round(Screen.Monitors[liZ1].Left * lScaleFactor) - lOffsetX;
    lPanel.Height := Round(Screen.Monitors[liZ1].Height * lScaleFactor);
    lPanel.Width := Round(Screen.Monitors[liZ1].Width * lScaleFactor);
    lPanel.Font.Size := Max(lPanel.Height div 2,8);
   end;

end;

end.
EDIT:


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