![]() |
AW: Mehrere Formulare an Stringgridgröße anpassen
Zitat:
|
AW: Mehrere Formulare an Stringgridgröße anpassen
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. |
AW: Mehrere Formulare an Stringgridgröße anpassen
Hallo,
was macht ihr da, und warum.....?:shock: Warum nicht einfach so:
Delphi-Quellcode:
und dann im FormShow oder wo es passieren soll
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
Delphi-Quellcode:
OOP und Objektablage geht natürlich auch.
procedure TForm1.FormShow(Sender: TObject);
begin AdjustFormSize(StringGrid1, Self); end; Grüße, blauweiss |
AW: Mehrere Formulare an Stringgridgröße anpassen
Mann, mann, Bummi :shock: OT ist das hier bei weitem nicht.
Das hier ist Spass oder nicht ? Zitat:
|
AW: Mehrere Formulare an Stringgridgröße anpassen
Hallo hoika / Heiko, es könnte soo einfach sein, wie Du andeutetest:
Zitat:
Delphi-Quellcode:
Es funktioniert - aber leider nur beim Formular "Form1". Bei den anderen Formularen bleibt der Code hängen, und zwar in der Zeile (unter "Horizontalkorrektur")
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.
Delphi-Quellcode:
,
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. |
AW: Mehrere Formulare an Stringgridgröße anpassen
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... 8-) Grüße, blauweiss |
AW: Mehrere Formulare an Stringgridgröße anpassen
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). |
AW: Mehrere Formulare an Stringgridgröße anpassen
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. |
AW: Mehrere Formulare an Stringgridgröße anpassen
Zitat:
Die "definierte Schnittstelle" ist ganz einfach eine Procedure mit Übergabeparameter.
Delphi-Quellcode:
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
Delphi-Quellcode:
eigentlich drei Dinge tut:
procedure Form_Skalieren(Form:TForm;StringGrid:TStringGrid)
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. |
AW: Mehrere Formulare an Stringgridgröße anpassen
Hallo,
wenn es läuft, ist es doch schon mal besser als nichts ... ;)
Delphi-Quellcode:
Der Grund für das +6 würde mich mal interessieren.
ColWidths[x] := biggestwidth + 6;
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 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:13 Uhr. |
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