Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Positionierung einer Form in Multimonitorumgebung (https://www.delphipraxis.net/186156-positionierung-einer-form-multimonitorumgebung.html)

delnu 13. Nov 2015 00:04

AW: Positionierung einer Form in Multimonitorumgebung
 
Liste der Anhänge anzeigen (Anzahl: 1)
zunächst fehlt hinter TfmSvcProperties = class(TTotalCmdWfxForm)ein Semikolon.:lol:

Unit "TotalCmdGUI" : {$Include Compiler.inc} habe ich keine ...

procedure PluginShowForm :

Delphi-Quellcode:
procedure PluginShowForm(const AhParent: HWND);
var fmSvcProperties: TfmSvcProperties;
    Lmon: TFormMonitor;
begin
    fmSvcProperties:= TfmSvcProperties.Create(nil, AhParent);
    try
        case IniFile.Monitor of
        // -> Undefinierter Bezeichner: 'IniFile'
        // -> ',' oder ':' erwartet, aber 'OF' gefunden
          0..4: Lmon:= TFormMonitor(IniFile.Monitor); // -> ')' erwartet, aber Bezeichner 'Monitor' gefunden
          else Lmon:= fmActive;
        end; // EXCEPT oder FINALLY erwartet
        fmSvcProperties.ShowModal(Lmon);
    finally // 'END' erwartet, aber 'FINALLY' gefunden
        FreeAndNil(fmSvcProperties);
    end; // '.' erwartet, aber ';' gefunden
end;
:shock:

Aber mal noch was anderes:
Betrifft die Sache auch das Starten von Progs vom TC aus oder ist das nur speziell für TC-Plugins ?

Gehst Du in der Unit "TotalCmdGUI" von 4 Monitoren aus ? Soviel ich weiß, sind bis zu 9 möglich.

Die vorhandene Menge findet man über "Screen.MonitorCount"

Vor weit mehr als 10 Jahren hatte ich sogar mal was mit Delphi 1 gemacht, das immerhin schon 2 Monitore verwalten konnte. Dazu hatte ich wesentliche Teile der Unit "Multimon" in eine eigene Unit "MMM" gepackt. Der eigentliche Anlaß dazu war aber dies:

Die ab Delphi 4 standardmäßig vorhandene Multimonitor-Erkennung
wird nur beim Programmstart vorgenommen und verläßt sich später
fälschlich auf gültige "Handles", die nicht mehr stimmen, wenn
die Zahl der aktivierten Monitore während des Programm-Ablaufs
geändert wird. Werden Monitore abgeschaltet, so ist das weniger
dramatisch. Neu hinzukommende werden allerdings nicht erkannt !

Ich habe mal meine damalige Unit und ein einfachen Testprogramm kurz getestet, neu gespeichert und hier (nur Sourcen, keine EXE) angehängt. Vielleicht ist manches davon brauchbar, zumal es auch teilweise ab Delphi 1 funktioniert. Das Problem, auf welchem Monitor gestartet wird, hatte ich aber damit NICHT gelöst.

Könntest Du bitte mal ein KOMPLETTES und FUNKTIONIERENDES Beispiel Deiner Lösung bringen ?

Dalai 13. Nov 2015 01:19

AW: Positionierung einer Form in Multimonitorumgebung
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von delnu (Beitrag 1321371)
zunächst fehlt hinter TfmSvcProperties = class(TTotalCmdWfxForm)ein Semikolon.:lol:

Nicht wirklich. Die Zeile darunter ist eine Platzhalterzeile, die noch mehr Sachen innerhalb der Klasse andeutet und durch das nachfolgende
Delphi-Quellcode:
end;
erst abgeschlossen wird.

Zitat:

Unit "TotalCmdGUI" : {$Include Compiler.inc} habe ich keine ...
Die kannst du dir notfalls selber bauen. Darin sind nur die verschiedenen Compiler-Versionen vermerkt mit entsprechenden
Delphi-Quellcode:
$DEFINE
s, damit der Compiler eine bedingte Kompilierung machen kann.

Zitat:

Delphi-Quellcode:
procedure PluginShowForm(const AhParent: HWND);
var fmSvcProperties: TfmSvcProperties;
    Lmon: TFormMonitor;
begin
    fmSvcProperties:= TfmSvcProperties.Create(nil, AhParent);
    try
        case IniFile.Monitor of
        // -> Undefinierter Bezeichner: 'IniFile'
        // -> ',' oder ':' erwartet, aber 'OF' gefunden
          0..4: Lmon:= TFormMonitor(IniFile.Monitor); // -> ')' erwartet, aber Bezeichner 'Monitor' gefunden
          else Lmon:= fmActive;
        end; // EXCEPT oder FINALLY erwartet
        fmSvcProperties.ShowModal(Lmon);
    finally // 'END' erwartet, aber 'FINALLY' gefunden
        FreeAndNil(fmSvcProperties);
    end; // '.' erwartet, aber ';' gefunden
end;
:shock:
Alles Folgefehler des einen, kein Grund schockiert zu sein. Ein bisschen mitdenken musst du schon. IniFile.Monitor ist ein simpler Integer, wie man leicht an der Case-Bedingung erkennen kann. Einfach dort deine eigene Variable einfügen. Oder den Integer komplett weglassen und ShowModal direkt mit TFormMonitor.irgendwas als Parameter aufrufen.

Zitat:

Aber mal noch was anderes:
Betrifft die Sache auch das Starten von Progs vom TC aus oder ist das nur speziell für TC-Plugins ?
Mir geht es ausschließlich um TC-Plugins, konkret um Dateisystemplugins. Prinzipiell kann man diese Unit aber auch für andere, ganz normale Delphi-Programme benutzen, sofern man die Form nur auf einen bestimmten Monitor bringen und dort zentrieren will. In dem Bereich ist der Nutzen aber eh etwas eingeschränkt, weil es ja noch TForm.DefaultMonitor gibt, auch wenn das auch nicht alles kann.

Wobei es bei eigenständigen Programmen eh schwieriger wird, an den Parent zu kommen, denn der existiert ja erstmal nicht. Im momentanen Zustand ist die Unit für solche Programme nicht wirklich zu gebrauchen, denn dafür müsste man CreateParams entfernen (was den Parent des erzeugten Forms setzt). Naja, dafür müsste man wohl die Unit noch etwas umbauen :). Da es mir darum aber nicht ging, überlasse ich das anderen, Quellcode ist ja offen :wink:.

Zitat:

Gehst Du in der Unit "TotalCmdGUI" von 4 Monitoren aus ?
Ja, warum nicht? Reicht das nicht?

Zitat:

Soviel ich weiß, sind bis zu 9 möglich.
Das mag sein, interessiert in der Praxis, in der ich mich bewege, aber nicht. Ich selbst habe nur einen Monitor, in der Firma haben einige Rechner zwei Monitore, mehr existieren in meiner Praxis nicht. Hinzu kommt noch, dass die Definition zwar nur bis zum vierten (expliziten) Monitor erlaubt (nebenbei ja ganz simpel auf mehr Monitore erweiterbar), das Benutzen des aktiven Monitors aber völlig frei ist und auch bei hundert Monitoren funktionieren würde.

Zitat:

Die vorhandene Menge findet man über "Screen.MonitorCount"
Ja, genau das benutze ich doch. Aber was bringt mir das für die Definition eines Enum? OK, man könnte jetzt anbringen, da in der Unit letztlich Integer benutzt werden und der Beispiel-Code oben in Form von IniFile.Monitor auch nur Integer, könnte man auf den Enum verzichten. Hatte ich überlegt, aber momentan spielt das für mich keine Rolle. Die Unit tut ihren Dienst und darum ging es letztlich.

Zitat:

Könntest Du bitte mal ein KOMPLETTES und FUNKTIONIERENDES Beispiel Deiner Lösung bringen ?
Ersetze IniFile.Monitor durch einen Integer deiner Wahl, der dem Enum entspricht, binde die angehängte Compiler.inc ein und das müsste genügen.

MfG Dalai

delnu 13. Nov 2015 10:54

AW: Positionierung einer Form in Multimonitorumgebung
 
Liste der Anhänge anzeigen (Anzahl: 1)
Die Compiler-Optionen sind insofern interessant, daß ich dadurch jetzt erstmals einen Überblick über die Definitionen der Versionen nach Delphi 7 habe. :lol:

Klar, daß IniFile.Monitor ein integer sein müßte, ist logisch. Aber der Name läßt vermuten, daß Du dessen Wert aus einer (mir unbekannten) Ini-Datei liest. Darum meine Bitte nach einem kompletten Quellcode. Tatsächlich ging ich davon aus, das wäre NICHT NUR für Plugins geeignet. Weil ich nicht weiß, wie man die schreibt, hat sich das dann wohl leider für mich erledigt. Also müßte ich einen Weg finden, auf andere Weise erstmal zu prüfen, auf welchem Monitor sich der TC (bzw. das aufrufende Programm) befindet und dann das aufgerufene Programm auf diesen setzen. Aber das ist mir momentan dann doch zu viel, zumal meine aktiven Jahre mit Delphi schon länger zurückliegen und ich mich erst wieder einarbeiten muß.

Das grundsätzliche Problem sind "DefaultMonitor" und "Position", die durch ihre Festlegung in der Unit "Forms" eher ein Hindernis darstellen. Ausserdem sind deren Original-Berechnungen falsch. Wird "Position" auf "poDesktopCenter" gesetzt, erscheint das Compilat am rechten Rand meines Default-Monitors. Den zweiten habe ich nämlich links und eben nicht rechts davon. Die in Unit "Forms" benutzte Berechnung
Delphi-Quellcode:
        else if FPosition = poDesktopCenter then
        begin
          if FormStyle = fsMDIChild then
          begin
            X := (Application.MainForm.ClientWidth - Width) div 2;
            Y := (Application.MainForm.ClientHeight - Height) div 2;
          end else
          begin
            X := (Screen.DesktopWidth - Width) div 2;
            Y := (Screen.DesktopHeight - Height) div 2;
          end;
          if X < 0 then X := 0;
          if Y < 0 then Y := 0;
          SetBounds(X, Y, Width, Height);
        end;
berücksichtigt nur Höhe und Breite des Desktops, aber nicht links und oben. Zur korrekten Auswertung müssen die einbezogen werden. Leider lassen sich Standardunits nicht problemlos durch eigene ersetzen, sonst sähe nicht nur "Forms" bei mir anders aus.

Momentan nutze ich an den meisten meiner Computer auch nur 2 Monitore, aber an einem 3 und da sollen es auch maximal 4 werden. Nur aus Gründen der Universalität bzw. Vollständigkeit wäre meiner Meinung nach besser, dem Anwender die maximal nutzbare Menge zu ermöglichen. Das kann durchaus auch durch dynamische statt statische Zuweisung erfolgen.

Anbei ein Screenshot eines Screenshot-Programms, das (statisch) von maximal 9 möglichen Monitoren ausgeht. Die nicht vorhandenen sind ausgegraut und es ist möglich, den gesamten Desktop zu snappen. Den Quelltext kann ich momentan nicht liefern, weil für die diversen möglichen Grafikformate Fremdunits benutzt werden und ich die zum einen suchen müßte und zum anderen nicht aus dem Kopf weiß, welche davon nicht direkt nutzbar sind, sondern evtl. installiert werden müssen.

Dalai 13. Nov 2015 12:24

AW: Positionierung einer Form in Multimonitorumgebung
 
Zitat:

Zitat von delnu (Beitrag 1321409)
Die Compiler-Optionen sind insofern interessant, daß ich dadurch jetzt erstmals einen Überblick über die Definitionen der Versionen nach Delphi 7 habe. :lol:

Da ich für mein Plugin ein unicodefähiges Delphi brauchte, aber die Tests im alten Delphi einfach schneller gehen, hab ich irgendwann mal diese Include-Datei zusammengezimmert (IIRC hab ich dafür die Vorlage von jemand anders benutzt). Schwierig ist immer, herauszufinden, welches Delphi man im
Delphi-Quellcode:
$IFDEF
nun setzen muss, seit wann es ein Feature gibt oder ein Fehler korrigiert wurde...

Zitat:

Tatsächlich ging ich davon aus, das wäre NICHT NUR für Plugins geeignet.
Ich werde die Abhängigkeit von CreateParams mal versuchen zu entfernen, kann aber nichts versprechend, weil mir ohne Tests die Reihenfolge der Aufrufe von Create und CreateParams der abgeleiteten und der Basisklasse nicht klar sind. Ist eben doof, wenn man zwei verschiedene Dinge in einer Klasse vermengt, die aber beide auf das Handle des Parent zurückgreifen. Mal sehen.

Zitat:

Also müßte ich einen Weg finden, auf andere Weise erstmal zu prüfen, auf welchem Monitor sich der TC (bzw. das aufrufende Programm) befindet und dann das aufgerufene Programm auf diesen setzen.
Das musst du sowieso. Aber mit MSDN-Library durchsuchenGetActiveWindow oder MSDN-Library durchsuchenGetForegroundWindow liegt man wahrscheinlich nicht ganz falsch.

Zitat:

Das grundsätzliche Problem sind "DefaultMonitor" und "Position", die durch ihre Festlegung in der Unit "Forms" eher ein Hindernis darstellen.
Ja und nein. Einerseits stimmt das, aber die von mir gewählte Variante über CM_SHOWINGCHANGED springt ja erst nach der Positionierung der Form durch die Klasse TForm ein. Insofern überstimme ich jede Positionierung, die Delphi vorher macht.

Zitat:

Ausserdem sind deren Original-Berechnungen falsch. Wird "Position" auf "poDesktopCenter" gesetzt, erscheint das Compilat am rechten Rand meines Default-Monitors.
Das wurde irgendwann zwischen Delphi 5 und XE2 behoben, denn dort ist die Berechnung an den Monitor der Form gekoppelt, wenn ich das richtig verstanden habe.

Zitat:

Nur aus Gründen der Universalität bzw. Vollständigkeit wäre meiner Meinung nach besser, dem Anwender die maximal nutzbare Menge zu ermöglichen.
Ja, aber wer sagt, welches die maximal nutzbare/mögliche Anzahl von Monitoren ist? Hängt vielleicht auch von der jeweiligen Windows-Version oder irgendwelchen anderen Faktoren ab, und da wird's dann nämlich wieder kompliziert.

MfG Dalai

delnu 13. Nov 2015 13:10

AW: Positionierung einer Form in Multimonitorumgebung
 
zur maximalen Monitormenge:

Als Maximum gilt (ab Windows 98) 9. Ich habe auch keine Informationen, daß es irgendwann mal mehr geworden wären, aber das würde dann wahrscheinlich über übliche Standards hinausgehen. Bei den von mir benutzten Windows-Versionen 98 SE und XP sind jedenfalls 9 das Maximum. Anhand des benutzten Betriebssystems läßt sich ggf. auswerten, wieviel tatsächlich möglich sind - falls mit neueren Versionen (oder durch Zusatztreiber oder wodurch auch immer) mehr als 9 erlaubt wären.

Vielleicht sind hier mehr Informationen versteckt : https://msdn.microsoft.com/de-de/lib...=vs.85%29.aspx, aber ich kann kein "C" ...

Das wirkliche Problem sind wohl in der Regel eher die verfügbaren Steckplätze. Im Zuge der Sparsamkeit am falschen Platz gibt es kaum noch IBM-kompatible Boards mit der üblichen Maximalzahl von 8 Steckplätzen. Mir waren bisher als Maximum integrierter Grafikprozessoren pro Karte 4 bekannt, und diese Karten sind (neu) ziemlich teuer.

In der Wikipedia heißt es allerdings
Zitat:

Während Karten für einen bis zwei Monitore heute Standard sind, sind im höheren Preissegment einzelne Grafikkarten für bis zu 16 Monitore erhältlich. Es lassen sich prinzipiell auch mehrere Standard-Grafikkarten in einem PC betreiben, wodurch problemlos auch mehr als zwei Monitore an einem Computer betrieben werden können. Grundsätzlich ist bei all diesen Lösungen mit Einschränkungen in Bezug auf die 3D-Funktionen zu rechnen.
Dazu fand ich z.B. diese Links:
http://www.chip.de/news/Shuttle-H7-5..._52500408.html
http://www.pcwelt.de/forum/showthrea...nen-PC-steuern

Dalai 13. Nov 2015 16:40

AW: Positionierung einer Form in Multimonitorumgebung
 
Liste der Anhänge anzeigen (Anzahl: 1)
So, ich hab die Klassen TTotalCmdWfxForm und TFormEx nun besser voneinander getrennt, so dass man auch direkt von TFormEx ableiten kann, ohne dass WndParent durch den Aufruf von CreateParams gesetzt wird. Das heißt, die Klasse TFormEx ist nun prinzipiell auch für eigenständige Programme nutzbar. Ich kann aber keinerlei Aussage darüber treffen, ob das in dem Bereich auch für das erste/primäre Formular der Anwendung funktioniert, denn das wird ja in der .dpr mittels
Delphi-Quellcode:
Application.CreateForm()
erzeugt...

Im Anhang findet sich ein komplettes Demo-Projekt (nur Source) mit allen benötigten Dateien (hoffentlich), also auch eine aktualisierte Unit TotalCmdGUI. Dabei sind zwei Formulare, von der das zweite beim Klick auf das erste erzeugt und dann nacheinander auf verschiedenen Monitoren (primär, sekundär, aktiv) angezeigt wird.

Ich hoffe, es funktioniert alles :cyclops:.

MfG Dalai

delnu 15. Nov 2015 13:43

AW: Positionierung einer Form in Multimonitorumgebung
 
Hallo ! Ich kam erst heute dazu, mir das runterzuladen. Seltsam, daß sich die Zahl der Downloads dadurch nicht erhöht hat. :roll:

Gewohnheitsmäßig starte ich Beispiele erstmal sowie sie sind. Erst als ich dann lediglich ein leeres Formular vorfand, guckte ich in den Quelltext und habe den fehlenden Button ergänzt.

Leider ergibt sich nicht die erwünscht Funktionalität. Gestartet und geendet wird immer auf dem primären Monitor. Zwischendurch geht es dann auf den zweiten.

Wahrscheinlich werde ich es nun so machen, Programme, von denen ich weiß, daß ich sie über den TC starte, grundsätzlich auf dem zweiten Monitor erscheinen lasse (falls einer da ist) ...

Obwohl: Wenn der nicht angeschaltet ist (was sich wohl nicht softwaremäßig prüfen läßt) wird das nix und es bringts auch nicht, wenn man den TC selbst auf demm zweiten Monitor startet.

Trotzdem danke ich Dir für Deine Mühe :thumb: und werde mir mal irgendwann (wenn ich dafür mehr Zeit finde) Deine Quelltexte sorgfältig durchsehen und prüfen, ob ich es damit doch irgendwie hinbekomme, das aufgerufene Programm auf dem jeweils anderen Bildschirm starten zu lassen.

Dalai 15. Nov 2015 14:46

AW: Positionierung einer Form in Multimonitorumgebung
 
Zitat:

Zitat von delnu (Beitrag 1321515)
Gewohnheitsmäßig starte ich Beispiele erstmal sowie sie sind. Erst als ich dann lediglich ein leeres Formular vorfand, guckte ich in den Quelltext und habe den fehlenden Button ergänzt.

Nein, da fehlt kein Button. Ich hatte zwar mal einen drin, aber später dachte ich mir, dass der gar nicht nötig ist, denn auch TForm kennt ein OnClick-Ereignis - und genau bei diesem wird die Routine aktiv (eben beim Klick auf das leere Formular).

Zitat:

Leider ergibt sich nicht die erwünscht Funktionalität. Gestartet und geendet wird immer auf dem primären Monitor. Zwischendurch geht es dann auf den zweiten.
Na also macht es doch das, was es soll, denn ich schrieb ja: nacheinander wird das zweite Formular auf verschiedenen Monitoren angezeigt, ganz so, wie es in der Ereignisbehandlungsroutine steht. Die paar Zeilen sind ja nun wirklich nicht schwer zu verstehen.

Zitat:

Wahrscheinlich werde ich es nun so machen, Programme, von denen ich weiß, daß ich sie über den TC starte, grundsätzlich auf dem zweiten Monitor erscheinen lasse (falls einer da ist) ...
Da musst du aber selber rumprobieren, denn zum ersten/primänre Formular hab ich mich ja bereits ausgelassen.

MfG Dalai

delnu 15. Nov 2015 18:34

AW: Positionierung einer Form in Multimonitorumgebung
 
Zitat:

Na also macht es doch das, was es soll, denn ich schrieb ja: nacheinander wird das zweite Formular auf verschiedenen Monitoren angezeigt, ganz so, wie es in der Ereignisbehandlungsroutine steht. Die paar Zeilen sind ja nun wirklich nicht schwer zu verstehen.
Weitere Formulare auf beliebige Bildschirme zu setzen, ist erheblich einfacher möglich als mit solchem Aufwand.
Ging es nicht eigentlich um das Haupt-Formular ? Aber lassen wir das, weil weitere Diskussionen nichts bringen.

Ich bin jetzt erstmal eine Weile raus aus dem Forum, weil ich paar neue Netzwerke einrichten muß.

Dalai 15. Nov 2015 18:42

AW: Positionierung einer Form in Multimonitorumgebung
 
Zitat:

Zitat von delnu (Beitrag 1321522)
Weitere Formulare auf beliebige Bildschirme zu setzen, ist erheblich einfacher möglich als mit solchem Aufwand.

Dann lass mal hören. Vor allem würde mich interessieren, wie du das bei ShowModal machen würdest.

Zitat:

Ging es nicht eigentlich um das Haupt-Formular ?
Nein, mir ging es in erster Linie um TC-Plugins, oder allgemeiner formuliert: in DLLs gelagerte VCL-Forms, die kein Application.Handle und vor allem kein Application.MainForm haben. Dass ich das später auch für reguläre Delphi-Anwendungen umgeschrieben habe, war mehr oder weniger nur Beiwerk. Hauptformulare habe ich ganz bewusst ausgeklammert, weil die mich nicht interessieren, und es dafür auch andere Möglichkeiten gibt (z.B. Position beim Beenden speichern und beim Laden wiederherstellen).

Zitat:

Ich bin jetzt erstmal eine Weile raus aus dem Forum, weil ich paar neue Netzwerke einrichten muß.
Na dann viel Erfolg dafür!

MfG Dalai


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:07 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz