AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Mehrere Formulare an Stringgridgröße anpassen

Ein Thema von Delphi-Laie · begonnen am 28. Okt 2010 · letzter Beitrag vom 2. Nov 2010
Antwort Antwort
Seite 3 von 4     123 4      
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#21

AW: Mehrere Formulare an Stringgridgröße anpassen

  Alt 30. Okt 2010, 17:57
Wenn ich hierfür die Objektablage verwenden würde wäre diese 1. bis zum Platzen voll und viele Funktionen die erst in einem Projektrahmen zur Verfügung könnten gar nicht erst implementiert werden.
Ne, absolut falsch. Problem ist : in erforderlichen Formularen wird redundant Code eingefügt. Das ist nicht gut. Du musst eine Form-Historie aufbauen. Immer vererben und fertig.
Gruß
Hansa
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#22

AW: Mehrere Formulare an Stringgridgröße anpassen

  Alt 30. Okt 2010, 18:55
Nach rund 300 Projekte mit Aufwänden mit zwischen 2 Wochen und 4 Jahren bin ich sicher, daß Aufgrund der extrem verschiedenen/gegensätzlichen Kundenanforderungen das von Dir beschrieben Vorgehen für mich nicht praxisgerecht ist.
Aber wir solltest daß hier beenden wir sind weit OT.
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
blauweiss

Registriert seit: 19. Jun 2007
142 Beiträge
 
#23

AW: Mehrere Formulare an Stringgridgröße anpassen

  Alt 30. Okt 2010, 21:22
Hallo,

was macht ihr da, und warum.....?

Warum nicht einfach so:
Delphi-Quellcode:
function GetGridWidth(aStringGrid: TStringGrid): integer;
var
  i: integer;
begin
  Result := 0;
  with aStringGrid do
    for i := 0 to ColCount-1 do
      inc(Result, ColWidths[i] + GridLineWidth);
end; // GetGridWidth

function GetGridHeight(aStringGrid: TStringGrid): integer;
var
  i: integer;
begin
  Result := 0;
  with aStringGrid do
    for i := 0 to RowCount-1 do
      inc(Result, RowHeights[i] + GridLineWidth);
end; // GetGridHeight

procedure AdjustFormSize(aStringGrid: TStringGrid; aForm: TForm);
begin
  with aStringGrid do
    begin
      ClientWidth := GetGridWidth(aStringGrid);
      ClientHeight := GetGridHeight(aStringGrid);
    end;
  aForm.AutoSize := true;
end; // AdjustFormSize
und dann im FormShow oder wo es passieren soll
Delphi-Quellcode:
procedure TForm1.FormShow(Sender: TObject);
begin
  AdjustFormSize(StringGrid1, Self);
end;
OOP und Objektablage geht natürlich auch.

Grüße,
blauweiss
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#24

AW: Mehrere Formulare an Stringgridgröße anpassen

  Alt 30. Okt 2010, 21:30
Mann, mann, Bummi OT ist das hier bei weitem nicht.

Das hier ist Spass oder nicht ?

Nach rund 300 Projekte mit Aufwänden mit zwischen 2 Wochen und 4 Jahren bin ich sicher,..
Bei 300 Projekten, wieviele Forms gibt es da ? 3000 ? Und Du schlägst ernsthaft vor, da nicht grundlegende Eigenschaften zu vererben ? Einmal entwickeln und immer wieder verwenden ? Selbst wenn es nur darum geht, eine nicht Windows-konforme, dafüt aber ISO-mässige Funktion einzubauen ? Das kommt in die Standardform und fertig. Guck mal beim DIN-Institut nach.
Gruß
Hansa
  Mit Zitat antworten Zitat
Delphi-Laie

Registriert seit: 25. Nov 2005
1.474 Beiträge
 
Delphi 10.1 Berlin Starter
 
#25

AW: Mehrere Formulare an Stringgridgröße anpassen

  Alt 30. Okt 2010, 23:21
Hallo hoika / Heiko, es könnte soo einfach sein, wie Du andeutetest:

Delphi-Quellcode:
Unit FormTools;

XXX

procedure AdjustForm(theForm: TForm; theStringGrid: TStringGrid);
begin
  dein Code

Heiko
Nun, meine Unit mit dem "tausendmal bewährten Code" (der in den einzelnen Units mit jeweils angepaßten Bezeichnern funktionert) sieht nunmehr so aus:
Delphi-Quellcode:
unit Formtools;

interface;

uses
 Windows
 , Forms
 , Grids
 ;

const Zeilenhoehe=17;Zellenbreitenzuschlag=6;

procedure Form_Skalieren(Form:TForm;StringGrid:TStringGrid);

implementation;

procedure Form_Skalieren(Form:TForm;StringGrid:TStringGrid);
var l,m:word;
begin
Form.Hide;

//Spaltenbreitenskalierung des Grids
for l:=0 to pred(StringGrid.ColCount) do StringGrid.ColWidths[l]:=Zellenbreitenzuschlag+StringGrid.Canvas.TextWidth(StringGrid.Cells[l,0]);//Skalieren nach Tabellenkopf
for l:=0 to pred(StringGrid.ColCount) do for m:=1 to pred(StringGrid.RowCount) do
  if StringGrid.ColWidths[l]<Zellenbreitenzuschlag+StringGrid.Canvas.TextWidth(StringGrid.Cells[l,m])
  then StringGrid.ColWidths[l]:=Zellenbreitenzuschlag+StringGrid.Canvas.TextWidth(StringGrid.Cells[l,m]);

//maximale horizontale Ausdehnung des Fensters ermitteln
Form.Width:=1;
while ((GetWindowlong(StringGrid.Handle,GWL_STYLE) and WS_HSCROLL)<>0) and (Form.width<screen.width) do Form.Width:=succ(Form.Width);

//maximale vertikale Ausdehnung des Fensters ermitteln
Form.Height:=succ(Form.Height-Form.ClientHeight);
while ((GetWindowlong(StringGrid.Handle,GWL_STYLE) and WS_VSCROLL)<>0) and (Form.Height<Screen.Height) do Form.Height:=succ(Form.Height);

//Horizontalkorrektur; es ginge wohl auch umgekehrt: 1. vertikale, 2. horizontale Ausdehnung ermitteln und schließlich Vertikalkorrektur
if ((GetWindowlong(StringGrid.Handle,GWL_STYLE) and WS_HSCROLL)=0) then //Horizontalscrollleiste nicht zu sehen
  begin
  while (GetWindowlong(StringGrid.Handle,GWL_STYLE) and WS_HSCROLL)=0 do Form.Width:=pred(Form.Width);
  Form.Width:=succ(Form.Width)
  end;

Form.Position:=poScreenCenter;
Form.Show

end;
end.
Es funktioniert - aber leider nur beim Formular "Form1". Bei den anderen Formularen bleibt der Code hängen, und zwar in der Zeile (unter "Horizontalkorrektur")

while (GetWindowlong(StringGrid.Handle,GWL_STYLE) and WS_HSCROLL)=0 do Form.Width:=pred(Form.Width) ,

und zwar wird dort die Breite ("Width") aus unerklärlichen Gründen in der While-Schleife nicht mehr verändert (dekrementiert). Was nützt (mir) der eigentlich sehr gute Debugger, wenn er nicht das tut, was im Quelltext angezeigt wird? Nichts!

Daß diese Funktion insgesamt überhaupt funktionieren soll (und es beim Form1 sogar zu meiner Verblüffung tut), ist mir völlig schleierhaft, weil hier doch nur Werteparameter, jedoch keine Variablenparameter übergeben werden (schließlich möchte ich ja das Originalformular verändern, also in seiner Größe anpassen, nicht jedoch irgendeine seiner Kopien). Ich kenne es von Pascal so, daß bei Werteparametern lokale Kopien angelegt werden, deshalb kam mir so etwas einfaches wie Dein obiger Vorschlag gar nicht erst in den Sinn. Doch das Formular und das StringGrid als Variablenparameter übergeben zu wollen/versuchen, war der Beginn meiner ersten und leider abenteuerlich-frustrationsreichen Exkursion in die (Un)Tiefen der objektorientierten Programmierung, die mich schließlich hilfesuchend in dieses Forum trieben. Doch trotz aufoperungsvoller Hilfe aller hier Beteiligen bin ich momentan meinem Ziel kein Quentchen nähergekommen.

Geändert von Delphi-Laie (31. Okt 2010 um 10:41 Uhr)
  Mit Zitat antworten Zitat
blauweiss

Registriert seit: 19. Jun 2007
142 Beiträge
 
#26

AW: Mehrere Formulare an Stringgridgröße anpassen

  Alt 31. Okt 2010, 00:12
Hallo Delphi-Laie,

ruhig Blut, das wird schon....

Du möchtest also nicht nur die Form-Größe minimal setzen, sondern auch die einzelnen Spaltenbreiten so minimieren, daß genau der Zelleninhalt gezeigt wird.
Hier mein Vorschlag:
Delphi-Quellcode:
procedure MinimizeColWidths(aStringGrid: TStringGrid);
var
  x, y: integer;
  onewidth, biggestwidth: integer;
begin
  with aStringGrid do
    for x := 0 to ColCount-1 do
      begin
        biggestwidth := 0;
        for y := 0 to RowCount-1 do
          begin
            onewidth := Canvas.TextWidth(Cells[x, y]);
            if (onewidth > biggestwidth) then
              biggestwidth := onewidth;
          end;
        ColWidths[x] := biggestwidth + 6;
      end;
end; // MinimizeColWidths

Und dann verwende bitte um Gottes Willen Form.AutoSize := true und nicht diese Krücke mit den Scrollbars. Mein Code oben z.B. macht, was Du willst.

Zu Deinen weiteren Fragen:
1. Form und StringGrid sind Instanzen von Klassen, sprich pointer. Hier brauchst Du nur dann mit var-Parametern arbeiten, wenn Du den Verweis auf die Instanz an sich in der Prozedur ändern willst. Du brauchst kein var, wenn Du nur Bestandteile(Properties) der Instanz ändern willst. Es stimmt, das war unter Standard-Pascal logischer.
2. die Ursache dafür, daß Form.Width nicht weiter minimiert werden kann, liegt vermutlich an Constraints, die die Minimalgröße beschränken. Dein Programm würde dann auch stand-alone in einer Endlos-Schleife hängenbleiben. Mit dem Debugger hat das nichts zu tun.

Und Du könntest Dir auch überlegen, wie Dein Code ordentlicher eingerückt werden könnte...

Grüße,
blauweiss
  Mit Zitat antworten Zitat
Delphi-Laie

Registriert seit: 25. Nov 2005
1.474 Beiträge
 
Delphi 10.1 Berlin Starter
 
#27

AW: Mehrere Formulare an Stringgridgröße anpassen

  Alt 31. Okt 2010, 10:39
Hallo blauweiss, besten Dank!

Die Skalierung des Stringgrids, konkret der Minimierung seiner Spaltenbreiten, ist nicht mein Problem; meine Codezeilen dazu funktionieren. Deine sind m.E. auch nicht substantiell anders; mir scheint sogar so, als daß meine sogar ein Quentchen effizienter sind, da ich die Spaltenbreiten anfangs nicht einnull(t)e (so sah man Code früher auch aus), sondern gleich mit der Spaltenbreite der ersten Zeile bestücke.

Mein Problem ist auch nicht, Formulare an die Größe des eingebetteten StringGrids anzupassen, auch der Code funktioniert (bei Delphi 2 & 3) stets (ab Delphi 4 allerdings nicht beim ersten Aufruf des jeweiligen bzw. eines jeden Formulares, das habe ich dann angepaßt) zu meiner Zufriedenheit.

Mein Problem ist, daß ich diese Größenanpassung(en) in eine Routine (Funktion oder Prozedur, egal) packen wollte, um mir Codewiederholungen mit lästigen und fehlerträchtigen Bezeichnerbenennungsanpassungen zu sparen.

Autosize funktioniert dafür nicht (zu meiner Zufriedenheit), das schrieb ich schon.

Das mit dem Constrain stimmt: Das Fenster ist merkwürdigerweise auf 112 Pixel (das Minimum) voreingestellt, so daß die Dekrementierungsschleife natürlich endlos wird. Merkwürdig, wenn die Codezeilen direkt verwende, funktionieren sie tadellos.... Danke auch für diesen Hinweis!

Wie das ganze funktionieren soll, ist in meinem Programm "Prozesse" (auch hier veröffentlicht) zu sehen, was allerdings immer noch Feinschliff benötigt (Fehlerbereinigungen und Codeoptimierung).

Ich werde der Reihe nach alle Hinweise, die mir hier (und auch per PM) zukamen, durcharbeiten (hoikas Idee war die erste).

Aber nun weiß ich wenigstens dank Deiner, daß ich eine weitere Pascal-Altlast, die immer noch in meinem Kopfe umhergeistert, nicht 1:1 in Delph übernehmen kann.

Und Du hast recht: Maximal übersichtlich ist mein Code nicht (Asche auf mein Haupt).

Geändert von Delphi-Laie (31. Okt 2010 um 10:46 Uhr)
  Mit Zitat antworten Zitat
Delphi-Laie

Registriert seit: 25. Nov 2005
1.474 Beiträge
 
Delphi 10.1 Berlin Starter
 
#28

AW: Mehrere Formulare an Stringgridgröße anpassen

  Alt 31. Okt 2010, 11:12
So, ich habe es jetzt anscheinend geschafft. Hoikas Idee war wohl doch richtig, der Fehler lag an einem fehlerhaften Aufruf der Routine: Es müssen natürlich FormX und FormX.StringGrid (X=Nummer des jeweiligen Formulares) übergeben werden, ich übergab jedoch stets nur StringGrid1 und damit das des aktuellen, aufrufenden Formulares.

Dank an alle noch einmal!

Ich werde das beizeiten in mein Prozeßbetrachtungsprogramm einbauen.
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

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

AW: Mehrere Formulare an Stringgridgröße anpassen

  Alt 31. Okt 2010, 11:14
Die Skalierung des Stringgrids, konkret der Minimierung seiner Spaltenbreiten, ist nicht mein Problem; meine Codezeilen dazu funktionieren. Deine sind m.E. auch nicht substantiell anders; mir scheint sogar so, als daß meine sogar ein Quentchen effizienter sind...
Der Code von blauweiss hat Qualität, denn er ist wiederverwendbar durch seine definierte Schnittstelle.
Die "definierte Schnittstelle" ist ganz einfach eine Procedure mit Übergabeparameter.
procedure MinimizeColWidths(aStringGrid: TStringGrid);
Dein Code ist dagegen nicht wiederverwendbar, sondern einfach in eine andere Procedure eingebettet.
Ich weiss nicht ob dir bewusst ist dass deine procedure Form_Skalieren(Form:TForm;StringGrid:TStringGrid) eigentlich drei Dinge tut:
1.) das Stringgrid in der Breite anpassen
2.) Höhe und Breite des Formulars (mehrfach!) ändern
3.) das Formular unsichtbar und wieder sichtbar machen
Also ist der Name "Form_Skalieren" nicht wirklich passend.

Dagegen ist die Procedure "MinimizeColWidths" fast perfekt.
Der Name beschreibt recht gut was passieren soll,
wobei ich eher von Optimieren statt von Minimieren sprechen würde.

Eine Procedure, Funktion oder Methode sollte genau eine Aufgabe durchführen.
Falls mehr als eine Aufgabe durchgeführt wird, müssen die Teilaufgaben
als Unterfunktionen implementiert werden.
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.276 Beiträge
 
Delphi 10.4 Sydney
 
#30

AW: Mehrere Formulare an Stringgridgröße anpassen

  Alt 31. Okt 2010, 12:26
Hallo,

wenn es läuft, ist es doch schon mal besser als nichts ...

ColWidths[x] := biggestwidth + 6; Der Grund für das +6 würde mich mal interessieren.
Ist das die Breite einer Scrollbar ?

Ich würde den Code auch mal mit "large fonts" testen.

Der Code funktioniert übrigens wohl auch nicht im FormCreate,
sondern erst im FormActivate (Canvas ist noch nicht richtig initialisiert)


Heiko
Heiko
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 4     123 4      


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 18:15 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