AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Positionierung einer Form in Multimonitorumgebung
Thema durchsuchen
Ansicht
Themen-Optionen

Positionierung einer Form in Multimonitorumgebung

Ein Thema von Dalai · begonnen am 8. Aug 2015 · letzter Beitrag vom 16. Nov 2015
Antwort Antwort
Seite 3 von 3     123   
delnu
(Gast)

n/a Beiträge
 
#21

AW: Positionierung einer Form in Multimonitorumgebung

  Alt 16. Nov 2015, 03:55
Zitat:
Na dann viel Erfolg dafür!
Danke, das kann ich brauchen.

Zitat:
Dann lass mal hören. Vor allem würde mich interessieren, wie du das bei ShowModal machen würdest.
Mit ShowModal habe ich sowas noch nie probiert. Aber weil Du wissen wolltest, wie die Umschaltung auch ohne viele Verrenkungen möglich ist, habe ich mal ein altes Delphi 1-Projekt (wie sich vielleicht erkennen läßt) abgespeckt. Wahrscheinlich sind noch Reste von Teilen drin, die für das Beispiel nicht mehr benutzt werden.

Das eigentliche Umschalten ist sehr simpel. Was das angehängte Beispiel aufbläht ist nur der Rest.

Hier zum Verständnis paar Auszüge:
Delphi-Quellcode:
...
    f_left, f_top : integer;
    MyMonitor : TMonitor;
    DefaultMonitor : integer;
    procedure GetMonitors;
...
procedure TBaseForm.GetMonitors;
VAR
 cnt : INTEGER;
BEGIN
 RadioGroup1.Items.Clear;

  FOR cnt:=0 TO Screen.MonitorCount-1 DO
  WITH Screen.Monitors[cnt]
  DO BEGIN
   RadioGroup1.Items.Add(
             ' Monitor '+IntToStr(MonitorNum)+' : '+
                IntToStr(width)+' *'+IntToStr(Height));
  END;

END; { procedure TBaseForm.GetMonitors }

procedure TBaseForm.FormCreate(Sender: TObject);
begin
  f_left := left;
  f_top := top;
  DefaultMonitor:=0; { sicherheitshalber }
end;

procedure TBaseForm.FormShow(Sender: TObject);
begin
 MyMonitor:=TMonitor.Create;
 GetMonitors;
   RadioGroup1.ItemIndex:=0; // sicherheitshalber erster Monitor ?
// RadioGroup1.ItemIndex:=Screen.MonitorCount-1; //letzter Monitor
   IF Screen.MonitorCount>1 THEN if askuser // global
   THEN Start_Mon; // = Benutzer wählen lassen !
   RadioGroup2.visible:=Screen.MonitorCount>1;
   Caption:=IntToStr(Screen.MonitorCount)+' Monitore';
   Form2.Show;
end;

procedure TBaseForm.FormDestroy(Sender: TObject);
begin
 MyMonitor.Free;
end;
Im innerhalb von "FormShow" (na gut, das könnte vielleicht woanders geschehen) dynamisch erzeugten und in "FormDestroy" freigebenen "MyMonitor" des Typs "TMonitor" wird alles Wesentliche erfaßt. Je nach Anzahl vorhandener Monitore wird in "GetMonitors" für jeden dynamisch ein Eintrag in "RadioGroup1" erzeugt.

Das Umschalten, wo Form1 ("BaseForm") gezeigt werden soll (mit mehr als 2 Monitoren habe ich es auf die Schnelle nicht umgesetzt) erfolgt über "RadioGroup1", entsprechend für "Form2" über "RadioGroup2". Wie Du siehst, besteht in meinem Beispiel der Hauptaufwand woanders.

Nun ja, wenn Du TC-Plugins schreibst (wäre nett, wenn Du an anderer Stelle mal ein Tutorial dafür erstellen könntest) wäre in dem Fall natürlich das Hauptformular der TC selbst. Aber trotzdem wird der von Dir betriebene Aufwand unnötig sein.

Vielleicht bringt Dir das angehängte Beispiel neue Denkanstöße.

So, jetzt bin ich aber wirklich mal für eine Weile weg.

EDIT: Die Hardware für die Netzwerke ist noch nicht vollständig angekommen. Darum hatte ich Zeit, das Beispiel etwas zu optimieren. Jetzt werden (DESKTEST-NEU.ZIP) für beide Forms alle vorhandenen Monitore (bis zur erlaubten Maximalzahl) möglich. Außerdem eine dritte Radiogroup, mit der beide Forms synchron auf jeden der vorhandenen Monitore gesetzt werden können. Die Auswertung habe ich vereinfacht. Hier nur das Wesentliche. Alles andere im angehängten kompletten Source.
Delphi-Quellcode:
procedure TBaseForm.GetMonitors;
VAR
 cnt : INTEGER;
BEGIN
 RadioGroup1.Items.Clear;
 RadioGroup2.Items.Clear;
 RadioGroup3.Items.Clear;

  FOR cnt:=0 TO Screen.MonitorCount-1 DO
  WITH Screen.Monitors[cnt]
  DO BEGIN
   RadioGroup1.Items.Add(
             ' Monitor '+IntToStr(MonitorNum)+' : '+
                IntToStr(width)+' *'+IntToStr(Height));
   RadioGroup2.Items.Add(
             ' Monitor '+IntToStr(MonitorNum)+' : '+
                IntToStr(width)+' *'+IntToStr(Height));
   RadioGroup3.Items.Add(
             ' Monitor '+IntToStr(MonitorNum)+' : '+
                IntToStr(width)+' *'+IntToStr(Height));
  END;

END; { procedure TBaseForm.GetMonitors }
...
procedure TBaseForm.RadioGroup3Click(Sender: TObject);
var
 m: integer;
begin
 m:= RadioGroup3.ItemIndex;
 BaseForm.left:= Screen.Monitors[m].left+f_left;
 BaseForm.top := Screen.Monitors[m].top+f_top;
 Form2.left:= Screen.Monitors[m].left+Form2.baseleft;
 Form2.top := Screen.Monitors[m].top+Form2.basetop;
end;
Angehängte Dateien
Dateityp: zip DESKTEST.ZIP (3,4 KB, 4x aufgerufen)
Dateityp: zip DESKTEST-NEU.ZIP (3,4 KB, 8x aufgerufen)

Geändert von delnu (16. Nov 2015 um 12:42 Uhr) Grund: Überarbeitung/Verbesserung des Beispiels
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.682 Beiträge
 
Delphi 5 Professional
 
#22

AW: Positionierung einer Form in Multimonitorumgebung

  Alt 16. Nov 2015, 15:47
Der Gag an meiner Variante ist die Kapselung in einer Klasse, die für sich den Kram macht und nur anhand der im Show/ShowModal übergebenen Parameter entscheidet, wo sie angezeigt werden soll. Dieser Code kann einfach wiederverwendet werden: Unit einbinden, Variable der Klasse deklarieren und lost geht's (vorausgesetzt, es existiert ein passendes DFM, denn sonst bekommt man nur die Fehlermeldung "Ressource nicht gefunden", wie ich erfahren musste ). Und die Klasse funktioniert auch für modale Aufrufe.

Deine Variante greift viel zu viel auf globale Variablen zurück (ja, ich weiß, alter Code und so ) und wird für ShowModal nicht funktionieren; das ist eben ein blockierender Funktionsaufruf.

Die Geschichte mit dem Anzeigen des Hauptformulars auf einem bestimmten Monitor hast du nicht mit drin, oder? Ich hab zwar testweise askuser:= True; gesetzt, das führt aber nicht zum Anzeigen des Hauptformulars auf dem zweiten Monitor.

MfG Dalai
  Mit Zitat antworten Zitat
delnu
(Gast)

n/a Beiträge
 
#23

AW: Positionierung einer Form in Multimonitorumgebung

  Alt 16. Nov 2015, 17:34
Klar kann man das auch in einer Unit kapseln, aber im Grunde würde sogar eine INCLUDE-Datei reichen. Das basiert ja alles auf Werten der Unit "Forms". Weil dafür bei Delphi 1 die Unit "Multimon" fehlt, hatte ich dann daraus die weiter vorne in einem Beispiel enthaltene Unit "MMM" gebastelt, die auch mit Delphi 1 funktioniert. Wenn man also die Direktzugriffe in eine eigene Unit kapseln will, reicht es, die Initalisierung und Freigabe von "MyMonitor" (das ist vom Typ "TMonitor" der Unit "Forms") vorzunehmen und die in meinen Beispielen direkt auf die RadioGroups gesetzten Ergebnisse eben entsprechend der eigenen Bedürfnisse anzupassen. Das sind doch nur reine Abfragen dessen, was "Forms" schon selbst automatisch zur Verfügung stellt.

Was "askuser" betrifft, so gibt es da jetzt tatsächlich einen Fehler. Das liegt an der Reihenfolge der Zuweisungen hinsichtlich der neuen RadioGroup3.

Ändere "FormShow" mal so:
Delphi-Quellcode:
procedure TBaseForm.FormShow(Sender: TObject);
var
 s: string;
 m: integer;
begin
 MyMonitor:=TMonitor.Create;
 s:=' Monitor';
 GetMonitors;
 m:=Screen.MonitorCount;
   RadioGroup3.visible:=m>1;
   RadioGroup3.ItemIndex:=0; // sicherheitshalber erster Monitor ?
   RadioGroup1.ItemIndex:=0; // sicherheitshalber erster Monitor ?
// RadioGroup1.ItemIndex:=m-1; //letzter Monitor
   IF m>1 THEN if askuser // global
   THEN Start_Mon; // = Benutzer wählen lassen !
   RadioGroup2.visible:=m>1;
   RadioGroup2.ItemIndex:=0; // sicherheitshalber erster Monitor ?
   if m>1 then s:=s+'e';
   Caption:=IntToStr(m)+s;
   Form2.Show;
end;
Dann wird der ItemIndex für RadioGroup3 vor dem für RadioGroup1 gesetzt. Wenn die Zuweisungen für Form2 auch vorgezogen werden, würde Form2 bereits vor der Abfrage (also auch vor der Sichtbarkeit der Hauptform) gezeigt.

In ein paar Tagen habe ich hoffentlich verbesserte Möglichkeiten und mehr Zeit, das zu verfeinern. Beispielsweise habe ich ja auch keine dynamische Höhenanpassung der Radiogroups drin, die entsprechend der Monitoranzahl nötig wäre. Bei der momentanen fest eingestellten Höhe könnte man schon ab ca. 4 oder 5 Monitoren nichts mehr lesen, weil alles zusammen gequetscht wäre.

Außerdem müßte man noch berücksichtigen, daß der Anwender natürlich die Forms auch unabhängig vom jeweiligen Monitor manuell verschieben können will. Die geänderten Relativpositionen müßten dann natürlich angepaßt werden. Wenn die Monitore unterschiedliche Grafikauflösungen haben, muß dafür gesorgt werden, daß die Forms nicht im Nirvana verschwinden, sondern dann zumindest in den noch sichtbaren Bereich verschoben werden. Aber das sind alles Ausgestaltungen und haben mit der reinen Funktionalität, etwas auf einem bestimmten Monitor zu platzieren, nichts mehr zu tun.

Im Grunde steht doch alles Wesentliche im Typ "TMonitor" drin. Es kommt also allenfalls darauf an, Schnittstellen bereitzustellen, mit denen das Hauptprogramm dann kommunizieren kann. In meinem Beispiel sind das die Radiogroups, weil dadurch die Umschaltung erfolgt. Natürlich kann man die Zuweisung auch in Prozeduren kapseln, vielleicht sogar besser in Funktionen (wegen der Möglichkeit z.B. eines Rückgabewerts "FALSE") ...

Aber erzähl doch mal, was Du gekapselt haben willst, bzw. auch wie.

Die Sache mit nicht gefundenen Resourcen läßt sich in der Regel per Übergabeparameter regeln. Das mit "ShowModal" läßt sich wohl auch noch rausfinden, aber ich würde sowas eher mit FormStyle "fsStayOnTop" und BorderStyle "bsToolWindow" machen, wie z.B. bei diversen Grafikprogrammen.

Mir ging es ja mit dem Beispiel nur drum, zu zeigen, daß die eigentliche Umschaltung auch sehr einfach erfolgen kann. Wirklich komplexe Multimonitoranwendungen mit echter Funktionalität könnten auch gut als Gemeinschaftprojekte mehrere Beteiligter zustandekommen.

Geändert von delnu (16. Nov 2015 um 17:40 Uhr) Grund: ein paar Textergänzungen
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.682 Beiträge
 
Delphi 5 Professional
 
#24

AW: Positionierung einer Form in Multimonitorumgebung

  Alt 16. Nov 2015, 18:51
Klar kann man das auch in einer Unit kapseln, aber im Grunde würde sogar eine INCLUDE-Datei reichen.
Ich meine nicht Unit sondern Klasse. Dass die Klasse in einer eigenen Unit steht, bietet sich logischerwese an, heißt aber erstmal nicht viel und könnte auch anders geregelt sein.

Zitat:
Das basiert ja alles auf Werten der Unit "Forms".
Ja klar, deswegen hab ich ja meine Klasse von TForm abgeleitet.

Zitat:
Im Grunde steht doch alles Wesentliche im Typ "TMonitor" drin. Es kommt also allenfalls darauf an, Schnittstellen bereitzustellen, mit denen das Hauptprogramm dann kommunizieren kann.
Ja, eben. Und dafür sind globale Variablen ungeeignet.

Zitat:
Aber erzähl doch mal, was Du gekapselt haben willst, bzw. auch wie.
Ich kann meine Unit nehmen und - so wie sie ist - wiederverwenden. Beispiel: Ich erstelle ein neues Projekt, binde diese Unit ein, erstelle ein weiteres Formular, ändere dort die Ableitung von TForm auf TFormEx und benutze dann simpel z.B. den Aufruf neueForm.Show(fmActive, Self.Handle) . Fertig. Ich brauche keine weiteren Variablen (vor allem keine globalen), ich muss nichts mehr an der Form rumschieben (auch wenn das natürlich weiterhin möglich ist) oder mich in irgendeiner Weise mit der Ermittlung von Monitoren rumschlagen, weil das alles die Klasse TFormEx bereits macht. Oder ich geb die Unit weiter an jemand anders, und der kann sie ohne viel Gefummel einbinden. Wiederverwendung von Code eben.

Zitat:
Die Sache mit nicht gefundenen Resourcen läßt sich in der Regel per Übergabeparameter regeln.
Nein, tut es nicht. Jedes Formular einer von TForm abgeleiteten Klasse braucht eine passende DFM(-Ressource).

Zitat:
Das mit "ShowModal" läßt sich wohl auch noch rausfinden, aber ich würde sowas eher mit FormStyle "fsStayOnTop" und BorderStyle "bsToolWindow" machen, wie z.B. bei diversen Grafikprogrammen.
Ein modales Fenster hat nichts mit einem immer im Vordergrund befindlichen Fenster zu tun. Das sind zwei völlig verschiedene Dinge.

MfG Dalai

Geändert von Dalai (16. Nov 2015 um 18:54 Uhr)
  Mit Zitat antworten Zitat
delnu
(Gast)

n/a Beiträge
 
#25

AW: Positionierung einer Form in Multimonitorumgebung

  Alt 16. Nov 2015, 19:45
Zitat:
ändere dort die Ableitung von TForm auf TFormEx
Wieso so umständlich ? Es ist doch schon alles von Anfang an in der Unit Forms vorhanden. Man muß es nur abfragen, kann es allenfalls ergänzen. Im Grunde machst Du nichts anderes, als ein neues Formular zu erzeugen, das unnötig aufgebläht ist. Was Du als "globale Variablen" bemängelst, sind bei Dir dafür die vielen zusätzlichen, verkomplizierenden Vorgänge. Das halte ich für viel undurchschaubarer.

Zitat:
Ja, eben. Und dafür sind globale Variablen ungeeignet.
Wozu sind sie denn dann schon VON HAUS AUS vorhanden? Man muß sie doch einfach nur benutzen. Aber klar: Wieso einfach, wenn's auch umständlich geht. Sind viele Zusatzprozeduren einfacher? Meiner Meinung ist es eher gegenteilig.

Zitat:
Jedes Formular einer von TForm abgeleiteten Klasse braucht eine passende DFM(-Ressource).
Wovon ich ausging, waren Prozeduren und Funktionen.

Zitat:
Ein modales Fenster hat nichts mit einem immer im Vordergrund befindlichen Fenster zu tun. Das sind zwei völlig verschiedene Dinge.
Ich habe mir lediglich einen möglichen Grund vorgestellt, wieso Du unbedingt ein modales Fenster haben willst. Sowas käme für mich nur in Betracht, wenn es dauernd offen sein soll, um es besser wiederfinden zu können. Dann würde ich es aber so machen, wie erwähnt. Darum mein Vorschlag. Es gibt schon viel zu viele Anwendungen, die einen mit modalen Fenstern nerven, beispielsweise störende Abfragen, die sich nicht einfach wegklicken lassen.

Aber egal. Weil Du unbedingt Deine komplizierte Methode beibehalten willst, statt auf das zugreifen zu wollen, was die Unit Forms von Haus aus bietet, wird das mit der möglichen Entwicklung gemeinsamer Multimonitor-Projekte wohl nichts.

Damit bin ich aus dem Thema raus, weil Du meine Anregungen offenbar nicht verstehst.

Nachtrag:
Die von mir benutzte Variable "MyMonitor" des Typs "TMonitor" ist unnötiges Überbleibsel.

Alle nötigen Informationen stehen VON HAUS AUS bereits in "Screen.Monitors" !

Geändert von delnu (16. Nov 2015 um 20:32 Uhr) Grund: Nachtrag
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.682 Beiträge
 
Delphi 5 Professional
 
#26

AW: Positionierung einer Form in Multimonitorumgebung

  Alt 16. Nov 2015, 20:46
Zitat:
ändere dort die Ableitung von TForm auf TFormEx
Wieso so umständlich ? Es ist doch schon alles von Anfang an in der Unit Forms vorhanden.
Wie positionierst du denn ein Formular auf dem zweiten Monitor? Du durchsuchst das Array Screen.Monitor. Ich tue das zwar auch, aber ich biete das durch den Enum TFormMonitor auch nach außen an, so dass man eben ohne zusätzliche Arbeit direkt auf den zweiten Monitor plazieren kann, allein durch den Aufruf von TFormEx.Show(fmSecondary) .

Wo bietet denn die Unit Forms eine solche Funktionalität an, ein Formular auf dem zweiten oder dritten Monitor zu plazieren? Standardmäßig gibt's doch nur die Möglichkeiten von Delphi-Referenz durchsuchenTForm.DefaultMonitor, das aber eben keine weiteren Monitore beinhaltet. Ich sehe daher nichts, nur das Durchackern des Screen.Monitor Arrays. Und genau das habe ich in eine Klasse gepackt, die das gezielte Plazieren erlaubt.

Zitat:
Im Grunde machst Du nichts anderes, als ein neues Formular zu erzeugen, das unnötig aufgebläht ist.
Aufgebläht ist daran gar nichts, es bietet nur erweiterte Funktionalität.

Zitat:
Was Du als "globale Variablen" bemängelst, sind bei Dir dafür die vielen zusätzlichen, verkomplizierenden Vorgänge. Das halte ich für viel undurchschaubarer.
Es mag auf den ersten Blick undurchschaubarer sein, ist es aber nicht wirklich.

Zitat:
Zitat:
Ja, eben. Und dafür sind globale Variablen ungeeignet.
Wozu sind sie denn dann schon VON HAUS AUS vorhanden?
Du meinst die globale Variable Screen? Ja, nun, Delphi hat auch mal klein angefangen, und damals™ hat man noch häufiger globale Variablen benutzt. Das heißt aber nicht, dass man das im eigenen Code fortsetzen muss. Globale Variablen sind böse, auch wenn ich sie ebenfalls hin und wieder verwende.

Zitat:
Zitat:
Jedes Formular einer von TForm abgeleiteten Klasse braucht eine passende DFM(-Ressource).
Wovon ich ausging, waren Prozeduren und Funktionen.
Nun, Funktionen sind nunmal keine Ressourcen. Ressourcen sind das, was im Kompilat landet und man nachträglich auslesen kann, Bilder, Audio, Video, Manifeste etc. pp. - und eben Formulare.

Zitat:
Zitat:
Ein modales Fenster hat nichts mit einem immer im Vordergrund befindlichen Fenster zu tun. Das sind zwei völlig verschiedene Dinge.
Ich habe mir lediglich einen möglichen Grund vorgestellt, wieso Du unbedingt ein modales Fenster haben willst.
Ich benutze fast ausschließlich modale Fenster, weil es bei mir sehr oft darum geht, vom Benutzer Daten abzufragen, ohne die es nicht weitergehen kann, aber auch, um den Codefluss für mich einfacher zu gestalten (ich hab in den allerwenigsten Fällen mehr als drei Formulare in meinen Anwendungen, insofern will ich da auch keinen Aufwand treiben). Und gerade bei den TC-Plugins gibt es überhaupt keinen Grund, nicht-modale Fenster zu verwenden.

Zitat:
Es gibt schon viel zu viele Anwendungen, die einen mit modalen Fenstern nerven, beispielsweise störende Abfragen, die sich nicht einfach wegklicken lassen.
Stimmt. Daher sind Fenster in meinen Anwendungen oft durch ESC schließ-/abbrechbar.

Zitat:
Weil Du unbedingt Deine komplizierte Methode beibehalten willst, statt auf das zugreifen zu wollen, was die Unit Forms von Haus aus bietet
Ne, sie bietet ja eben nicht alles, was ich brauche, daher ja die Ableitung und Erweiterung.

Zitat:
Damit bin ich aus dem Thema raus, weil Du meine Anregungen offenbar nicht verstehst.
Ich glaube schon, dass ich sie verstehe, nur sehe ich nicht, wie ich deine Varianten in meinem Code umsetzen sollte, ohne erheblich mehr Aufwand zu treiben, als das bei meiner Variante der Fall ist.

Wahrscheinlich gehen wir von zu unterschiedlichen Vorstellungen aus, dass wir aneinander vorbei reden/schreiben.

MfG Dalai
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 3     123   


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 21:16 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