| Autor |
Beitrag |
Tetsuya1
      
Beiträge: 21
|
Verfasst: So 08.03.09 16:36
Also ich habe vor ein Sudoku Ersteller über ein StringGrid zu realisieren.
Die Struktur ansich passt, nur würde ich die kleinen Spalten/Zeilen gerne blocken, damit die Unterquadrate hervorgehoben werden.
Ansich läuft das ja über:
form1.Feld.FixedCols:=(4);
bzw.
form1.Feld.FixedRows:=(4);
Einzige Problem was ich habe, dass alle Zeilen/spalten bis zur 4. Spalte (1-4) blockiert werden und nicht nur die 4. Spalte.
Dann ging ich davon aus, dass ich evtl erst zu Zelle springen muss (ansich sinnlos), jedoch brachte dies ebenfalls nichts,
Hat jemand eine Idee, wie man dies realisiert?
Einloggen, um Attachments anzusehen!
|
|
Jakob_Ullmann
      
Beiträge: 1747
Erhaltene Danke: 15
Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
|
Verfasst: So 08.03.09 17:09
Benutze einfach den StringGrid.Canvas und male ein paar Rechtecke (-> OnDraw), denn das was du vor hast, geht AFAIK nicht.
|
|
Tetsuya1 
      
Beiträge: 21
|
Verfasst: So 08.03.09 17:30
Gäbe es ansonsten die Möglichkeit bestimmte Striche zu verdeutlichen?
Also dass man statt diesem Zwischenraum, einfach die Striche an dieser Stelle dicker macht?
Habe es nebenbei mit der Canvas Variante versucht:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TForm1.FormCreate(Sender: TObject); begin form1.Feld.Canvas.Pen.Color:=RGB(0,255,0); form1.Feld.Canvas.Pen.Width:=5; form1.Feld.Canvas.MoveTo(0,87); form1.Feld.Canvas.LineTo(200,87);
end; |
Leider wird vom ausgewählten Punkt keine Linie innerhalb des StrinGrids (Feld) gezeichnet.
Edit:
Mein Fehler. Benutzte statt dem OnDraw Ereignis ein OnCreate.
Hab es nun mit OnDraw. Leider flackert der gemalte Strich jetzt. Theoretisch wird das Ereignis nun die ganze Zeit ausgeführt.
Wie stell ich es um, dass es nur einmal gemalt wird?
Ein OnCreate Ereignis, welches das onDraw Ereignis aufrufen soll?
|
|
Keldorn
      
Beiträge: 2266
Erhaltene Danke: 4
Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
|
Verfasst: So 08.03.09 18:06
Du mußt dein ondraw so schreiben, daß du die Striche nicht immer komplett über das ganze Grid zeichnest. Du darfst immer nur die aktuell zu zeichnende Zelle zeichnen, dann flackert auch nicht.
im ondraw hast du das rect und damit die Eckpunkte, mit denenen du die Linie nur innerhalb der Zelle zeichnen kannst.
_________________ Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
|
|
Tetsuya1 
      
Beiträge: 21
|
Verfasst: So 08.03.09 18:14
Wieso ist es nicht möglich die vorgefertigten Feld (bei denen habe ich ja auch gleich die Koordinaten für Spalte/Zeile [z.b. 1,4]).
Wenn ich es male, kann es dich sein, dass der User nicht in die Zellen klickt sondern daneben und dies ist nicht das Ziel.
Oder wird jedes Rectangle als einzelne Zelle anerkannt bzw. erkennt Delphi dies als weiterlaufende Spalten/Zeilen?
Außerdem, wenn ich die Zahl zwar reinschreibe per Canvas, geht das Blinken weg, nur kann ich dann leider nicht mehr über die Koordinatenform ala Zeile/Spalte arbeiten und die Eingabe der Zahlen erschwert sich.
|
|
Jakob_Ullmann
      
Beiträge: 1747
Erhaltene Danke: 15
Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
|
Verfasst: So 08.03.09 18:47
Sorry, nicht OnDraw sondern OnDrawCell. Du musst also abfragen, ob du eine bestimmte Zelle hast und dementsprechend die Linien zeichnen. Natürlich gehts auch ohne, aber dann dauert es ewig. Alternativ kannst du auch mit einem TImage arbeiten und dich selbst um die Eingabe kümmern (es geht ja nur um eine Zahl von 1 bis 9 und hoch / runter / links / rechts). So würde ich es wahrscheinlich machen.
|
|
Tetsuya1 
      
Beiträge: 21
|
Verfasst: So 08.03.09 18:56
Hatte es auch über OnDrawCell gemacht, aber wie realisierst du dann die Abfrage?
Bezüglich der TImage Komponente. Dies dient ja dazu ein Bild einzufügen. Dies wäre aber theoretisch das selbe in Grün.
Ich habe zwar den Hintergrund, muss aber dennoch die einzelnen Bereiche über Arrays abfragen und der User kann seine Zahlen einfügen wo er will.
Oder wird das Image sozusagen über die Spalten "gemalt" und die Spalten-, Zeilenstruktur bleibt dann gleich?
Habe mit jener Variante bisher noch nicht gearbeitet.
Habe nebenbei das erstmal bei dem OnDrawCell Ereignis belassen. Dabei habe ich nun 9 Radio Buttons (mit den Zahlen 1-9) erstellt und hatte vor, beim klicken auf ein Feld, jene Zahl einzugeben.
Wie wird jedoch die Abfrage realisiert, auf wessen Feld geklickt wurde? Es müssten dazu ja Koordinaten rauskommen.
Oder habt ihr eine leichtere Variante, da meine doch recht schreiblastig ist.
|
|
Keldorn
      
Beiträge: 2266
Erhaltene Danke: 4
Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
|
Verfasst: So 08.03.09 19:58
Tetsuya1 hat folgendes geschrieben : | Hatte es auch über OnDrawCell gemacht, aber wie realisierst du dann die Abfrage?
|
im ondrawcell werden acol und arow übergeben = die Zelle, die gezeichnet werden muß.
Zeig am besten mal deine komplette ondrawcell-routine
| Zitat: |
Ich hätte nun vor eine 9 Radio Buttons (von 1-9) die Ziffern einzutragen über anklicken des jeweiligen Feldes.
|
würde auch direkt übers Grid gehen, wenn du nur die Eingabe von den Zahlen erlaubst
| Zitat: |
Wie wird jedoch die Abfrage realisiert, auf wessen Feld geklickt wurde?
|
meinst du im Grid oder Radiobutton?
wenn du die klicks im Radiobutton auswerten willst, kannst Du dir z.B. die Tag-Eigenschaft zu nutze mache. jedes Radiobutton erhält als Tag die Zahl 1-9. einem Radiobutton im onclick zuweisen
Delphi-Quelltext 1:
| Stringgrid.cells[stringgrid.col,stringgrid.row]:=inttostr(((Sender as Tradiobutton).Tag)); |
und dieses onclick weißt du den anderen 8 auch zu, damit hast nur eine Routine für alle.
obwohl ich mir jetzt nicht ganz sicher wäre, ob 9 normale Buttons da etrwas schöner aussehen würden.
_________________ Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
|
|
Jakob_Ullmann
      
Beiträge: 1747
Erhaltene Danke: 15
Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
|
Verfasst: So 08.03.09 20:09
Zu dem Image: Du musst es nicht einmal abfragen, du kannst es berechnen.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| uses ..., Math;
spalte := floor(x / spaltenbreite); zeile := floor(y / zeilenhoehe); |
|
|
Tetsuya1 
      
Beiträge: 21
|
Verfasst: So 08.03.09 20:28
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| procedure TForm1.FeldDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); var nx,ny:byte; begin
form1.Feld.Canvas.Pen.Width:=1; for nx:=0 to 8 do begin for ny:=0 to 8 do begin form1.Feld.Canvas.Rectangle(30*nx,30*ny,30*nx+30,30*ny+30); end; end; |
Ist noch nicht perfekt, da alle 3 Kästchen der Abstand größer werden muss um den Strich dicker zu ziehen. Werde ich wohl über Mod machen.
Wenn ich jedoch über das ankicken des Feldes eine Ziffer eintippe, verschwindet jene sofort wieder.
Habe außerdem im Hintergrund noch das alte gezeichnete StringGrid. Wenn ich jedoch das StringGrid auf eine Zelle minimiere (bekomme sie ja nicht komplett weg), wird das Gitter nicht gemalt und ich kann somit auch nichts eintragen, bis auf in die erste Zelle, ich ich ja nicht wegbekomme.
Keldorn hat folgendes geschrieben : |
| Zitat: |
Wie wird jedoch die Abfrage realisiert, auf wessen Feld geklickt wurde?
|
meinst du im Grid oder Radiobutton? |
Meinte schon im Grid. Radiobuttun Abfrage würde ich über Boolean machen. Ob es aktiviert wurde oder nicht.
|
|
Jakob_Ullmann
      
Beiträge: 1747
Erhaltene Danke: 15
Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
|
Verfasst: So 08.03.09 20:43
Das Teil verschwindet, weil du ja ein Rechteck drüberzeichnest. Lösung dafür: Setze vor Feld.Canvas.Rectangle(...) den Feld.Canvas.Brush.Style := bsClear; Damit zeichnest du nur den Rahmen, ohne eine Füllung. Zurücksetzen wäre dann mit Feld.Canvas.Brush.Style := bsSolid; möglich.
|
|
Keldorn
      
Beiträge: 2266
Erhaltene Danke: 4
Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
|
Verfasst: So 08.03.09 21:02
| Zitat: |
Werde ich wohl über Mod machen.
|
das ist ne gute idee.
| Zitat: |
form1.Feld.Canvas.Pen.Width:=1;
|
nimm bitte immer das form1 weg, das brauchst du hier nicht
| Zitat: |
Rectangle(30*nx,30*ny,30*nx+30,30*ny+30);
|
würde ich nicht machen, besser, du würdest hier nicht mit festen Werten arbeiten, sondern mit defaultcolwidth und defaultrowheight. (colsizing und rowsizing hast du ja in deinem Fall sicher aus. Damit würdest Du auch bei einer evtl späteren Größenänderung keine Probleme bekommen.
Aber wie gesagt: ondrawcell ist für eine Zelle und nicht für alle. Du zeichnest immer das komplette Grid neu und das führt zu Problemen. Du solltest in ondrawcell immer nur in dem Bereich (das übergebene Rect) zeichnen, der zu der Zelle gehört.
in etwa so:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46:
| procedure TForm1.StringGrid2DrawCell(Sender: TObject; ACol, ARow: Integer;Rect: TRect; State: TGridDrawState); Var nx,ny:integer; s:string; begin with sender as TStringGrid do begin if gdselected in state then begin canvas.Brush.Color := clHighlight; canvas.font.color := clHighlightText; end else begin canvas.Brush.Color := clwindow; canvas.font.color := clWindowText; end;
canvas.FillRect(rect);
s:=cells[acol,arow]; DrawText(canvas.Handle,PChar(s), StrLen(PChar(s)),Rect,DT_CENTER or DT_VCENTER or DT_SINGLELINE);
if ((acol+1) mod 3)=0 then begin canvas.Pen.Color := clblack; Canvas.Pen.Width:=3; canvas.moveto(Rect.Right,rect.top); canvas.LineTo(Rect.Right,rect.bottom); end; if ((arow+1) mod 3)=0 then begin canvas.Pen.Color := clblack; Canvas.Pen.Width:=3; canvas.moveto(Rect.left,rect.Bottom); canvas.LineTo(Rect.Right,rect.bottom); end; end; end; |
| Zitat: |
Meinte schon im Grid
|
-> on click-Ereignis und dann enthalten stringgrid.col und stringrid.row deine selektierte Zelle.
_________________ Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
|
|
Tetsuya1 
      
Beiträge: 21
|
Verfasst: So 08.03.09 21:48
Also schon mal danke an alle die bisher geholfen haben. Ist ne schwere Geburt ^^"
Keldorn hat folgendes geschrieben : |
Aber wie gesagt: ondrawcell ist für eine Zelle und nicht für alle. Du zeichnest immer das komplette Grid neu und das führt zu Problemen. Du solltest in ondrawcell immer nur in dem Bereich (das übergebene Rect) zeichnen, der zu der Zelle gehört. |
Kann mir das grade nicht vorstellen. Wenn immer nur eine Zelle gezeichnet wird, muss ich doch so oder so über eine for-do Schleife die restlichen noch hinzufügen.
Habe dies auch noch nicht 100% verstanden, da ich bisher immer in die vorgegeben Zellen die Zahl hinschreibe und über Rect nur das flimmern entfernte.
Zu dem Quelltest hätte ich ebenfalls ein paar Fragen (seit 2 Jahren erst Schul-Delphi).
Delphi-Quelltext 1:
| if gdselected in state then |
Was ist jeweils gdselectet und state und welche Werte werden in State von gdselectet übergeben?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| begin canvas.Brush.Color := clHighlight; canvas.font.color := clHighlightText; end else begin canvas.Brush.Color := clwindow; canvas.font.color := clWindowText; end; |
Wenn die gdselectet in state drinnen ist, wird die Farbe hervorgehoben, ansonsten normale Farbe?
Was für ein Farbton ist in dem Fall window? Die Hintergrundfarbe?
Delphi-Quelltext 1: 2:
| DrawText(canvas.Handle,PChar(s), StrLen(PChar(s)),Rect,DT_CENTER or DT_VCENTER or DT_SINGLELINE); |
Leider überfordert damit.
Warum soll der Zelltext vertikal und horizontal ausgegeben werden?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| if ((acol+1) mod 3)=0 then begin canvas.Pen.Color := clblack; Canvas.Pen.Width:=3; canvas.moveto(Rect.Right,rect.top); canvas.LineTo(Rect.Right,rect.bottom); end; if ((arow+1) mod 3)=0 then begin canvas.Pen.Color := clblack; Canvas.Pen.Width:=3; canvas.moveto(Rect.left,rect.Bottom); canvas.LineTo(Rect.Right,rect.bottom); end; |
Wenn ich das jetzt richtig lese, wird nur ein dicker Strich rechts oben bis rechts Mitte gezeichnet und ein Strich von Links unten bis Rechts unten.
Nur müssen es insgesamt 2 dicke Vertikale/Horizontale Striche sein, welche jeweils bei 33% /66% des Bildes bis zum anderem Ende des Bildes gezeichnet werden.
Ich denke es hängt damit zusammen, dass jeweils nur eine Zelle gezeichnet werden soll.
Wo kommen aber dann die restlichen 80 hinzu?
Mein Weg war ja eher suboptimal.
| Zitat: | | Zitat: |
Meinte schon im Grid
|
-> on click-Ereignis und dann enthalten stringgrid.col und stringrid.row deine selektierte Zelle. |
Konnte ich nicht auslesen. Evtl. auch falscher Code dafür.
Soll ich das Programm als ganzes hochladen?
Ich habe irgendwie das Gefühl, dass das erstellen des eigentlichen Sudoku leichter ist, als die Grafik...
Mag auch daran liegen, dass ich die Grafikmöglichkeiten Delphis so noch nie benutzt habe ^^"
|
|
Keldorn
      
Beiträge: 2266
Erhaltene Danke: 4
Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
|
Verfasst: So 08.03.09 22:10
| Zitat: |
Kann mir das grade nicht vorstellen. Wenn immer nur eine Zelle gezeichnet wird, muss ich doch so oder so über eine for-do Schleife die restlichen noch hinzufügen.
Habe dies auch noch nicht 100% verstanden, da ich bisher immer in die vorgegeben Zellen die Zahl hinschreibe und über Rect nur das flimmern entfernte.
|
nein. du bekommst ein Ereignis ausgelöst, das Zelle(x,y) neugezeichnet werden muß und reagierst drauf. wenn z.B. das komplette Grid neugezeichnet werden muß, wird es halt für jede Zelle einzeln ausgelöst.
Du übernimmst mit ondrawcell das komplette Zeichnen der Zelle selbst (Hintergrund + Text)
| Zitat: | | Was ist jeweils gdselectet und state und welche Werte werden in State von gdselectet übergeben? |
onlinehilfe unter TGridDrawState bzw Cursor in Delphi drauf+F1 drücken
gdselectet=Zelle ist ausgewählt
clwindow etc sind Farbkonstanten. im Normalfall ist clwindow=clwhite=weiß. Wenn Du in Windowsa aber ein anderes Farbschema auswählst, ist das aber u.U. nicht mehr weiß.
wenn Du Farbkonstanten wie clwindow etc verwendest, ist das anwenderfreundlicher, weil die Anwendung dann farblich so aussieht, wie es sich der Nutzer eingestellt hat.
| Zitat: |
Leider überfordert damit.
Warum soll der Zelltext vertikal und horizontal ausgegeben werden?
|
weil es wahrscheinlich schöner aussieht
| Zitat: |
Wenn ich das jetzt richtig lese, wird nur ein dicker Strich rechts oben bis rechts Mitte gezeichnet und ein Strich von Links unten bis Rechts unten. ] |
nein. z.B. horizontal
1. bei jeder 3. Spalte (((acol+1) mod 3)=0)
wird in der Zelle rechts ein Strich von Zelle oben bis Zelle unten gemalt.
da es für jede Zelle gemalt wird erhälst Du so einen Strich im Grid von oben nach unten.
| Zitat: |
Nur müssen es insgesamt 2 dicke Vertikale/Horizontale Striche sein, welche jeweils bei 33% /66% des Bildes bis zum anderem Ende des Bildes gezeichnet werden. |
genau das amcht der Code.
für die anderen Zellen hast Du ja schon die normale Zellumrandung vom Grid
der Zeichen code ist universell, Du kannst ihn auch komplett kopieren und in deine ondrawcell-routine einfügen.
| Zitat: | Konnte ich nicht auslesen. Evtl. auch falscher Code dafür.
|
Stringgrid mußt Du natürlich durch den Namen deines Grids ersetzen 
_________________ Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
|
|
Tetsuya1 
      
Beiträge: 21
|
Verfasst: Mo 09.03.09 20:10
Ich belasse es vorerst bei den vorgefertigten Grid und male selber die Dicken Linien rein. Sieht nur etwas unsauber aus, wenn man die Zeilen reinschreibt, aber nicht weiter tragisch. Evtl. muss ich es früher oder später ändern, aber erstmal generelle Programm aufbauen.
Gibt es die Möglichkeit den Text, welcher über Cells[col,row]:=inttostr(n); eingefügt wird in der jeweiligen Zelle zu zentrieren, sprich Mittig zu schreiben?
Und kann man die Schriftgröße/Farbe jener ändern? Theoretisch ja, nur wie heißt der Befehl dazu?
Man kann ja einstellen, ob man dem User die Möglichkeit bietet etwas in die weißen Kästchen zu schreiben oder nicht. Kann ich einige Zellen blocken, sodass da keine Möglichkeit mehr gibt, da etwas reinzuschreiben?
Feld.Cells.acess[col,row]:=false; (fiktiv)
Basiert aber wohl eher auf meine erste Frage in diesem Topic. Also wohl eher nein.
Wie kann ich die Eingaben des User in einem Feld überwachen?
Da ich wahrscheinlich einige Zellen nicht vorm Zugriff schützen kann, würde ich dann prüfen, ob die Zahlen in den bestimmten Zellen noch vorhanden sind, wenn nicht, schreibt er die wieder hin und löscht die alte Eingabe.
|
|
Keldorn
      
Beiträge: 2266
Erhaltene Danke: 4
Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
|
Verfasst: Mo 09.03.09 21:28
_________________ Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
|
|
Tetsuya1 
      
Beiträge: 21
|
Verfasst: Mi 11.03.09 10:51
Habe die Erstellung nun über deinen Code absolviert.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36:
| procedure TForm1.FeldDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); var nx,ny,rx,ry:byte; s:string; begin
with sender as TStringGrid do begin canvas.Brush.Color := clwhite; canvas.font.color := clblack; feld.canvas.FillRect(rect); s:=cells[acol,arow]; DrawText(canvas.Handle,PChar(s), StrLen(PChar(s)),Rect,DT_CENTER or DT_VCENTER or DT_SINGLELINE);
canvas.Pen.Color := clblack; Canvas.Pen.Width:=3;
if ((acol+1) mod 3)=0 then begin canvas.moveto(Rect.Right,rect.top); canvas.LineTo(Rect.Right,rect.bottom); end; if ((arow+1) mod 3)=0 then begin canvas.moveto(Rect.left,rect.Bottom); canvas.LineTo(Rect.Right,rect.bottom); end; end; end; |
Das Problem was ich nun habe ist, wenn ich die Zelle ändern will, also etwas reinschreiben möchte, wird der Strich immer durch die marekierung des Feld sozusagen überschrieben, sodass die ganze Zelle Weiß ist und an den Randfeldern den schwarzen Strich übermalen.
Wie kann man dies ändern?
|
|
Keldorn
      
Beiträge: 2266
Erhaltene Danke: 4
Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
|
Verfasst: Mi 11.03.09 21:26
| Zitat: |
Das Problem was ich nun habe ist, wenn ich die Zelle ändern will, also etwas reinschreiben möchte, wird der Strich immer durch die marekierung des Feld sozusagen überschrieben, sodass die ganze Zelle Weiß ist und an den Randfeldern den schwarzen Strich übermalen.
|
das geht leider nicht ohne weiteres. Wenn Du was in einem Grid editierst, erstellt das Grid intern ein eigenes Editfeld (nicht wirklich was anderes als ein normales TEdit, wie du es selber auf die Form ziehen kannst). An den inplaceditor selber kommst du nicht ohne weiteres ran, auch dann wäre ich mir nicht sicher, ob du dann den Editor im richtigen Moment auch verschieben kannst. Auch die Gridlinewith erhöhen oder das grid komplett selber malen bringt keinen Erfolg.
Ich würde es so lösen:
goediting in den options auf false stellen, das Grid kann somit nicht editiert werden.
als Ansatz: ins onkeypress schreibst du dann z.B.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| with sender as TStringGrid do begin if (cells[col,row]='') and (key in ['1'..'9']) then cells[col,row]:=key; ... end; |
daher, wenn eine Taste 1-9 gedrückt wurde, wird der zelltext direkt geändert. Damit wird der Stringgrid eigene Editor nicht aufgerufen und es kommt zu keinen Überschneidungen. Außerdem verhinderst du auch so gleich, das einer z.B. 99 eintragen kann  .
für das vertikale und horizontale Zentrieren: das läßt sich auch canvas.textout lösen, drawtext ist sicher eleganter und bei weiten flexibler und einfacher handhabbar.
Fürs Verständnis geht auch das:
Delphi-Quelltext 1: 2: 3: 4: 5:
| s:=cells[acol,arow]; canvas.TextOut(rect.Left+(rect.Right-Rect.left-canvas.TextWidth(s)) div 2, rect.top+(rect.bottom-Rect.top-canvas.TextHeight(s)) div 2, s ); |
einfach mal einen Zettel nehmen und mal aufmalen, wo elche Punkte genommen und was berechnet wird.
Gruß Frank
_________________ Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
|
|
Tetsuya1 
      
Beiträge: 21
|
Verfasst: Do 12.03.09 23:30
Vielen Dank für die Hilfe. Echt Top Forum.
Bezüglich des Zentrierens.
Delphi-Quelltext 1: 2: 3:
| s:=cells[acol,arow]; canvas.TextOut(rect.Left+(rect.Right-Rect.left-canvas.TextWidth(s)) div 2,rect.top+(rect.bottom-Rect.top-canvas.TextHeight(s)) div 2,s ); |
Ist doch das gleiche wie das oder?
Delphi-Quelltext 1: 2:
| DrawText(canvas.Handle,PChar(s), StrLen(PChar(s)),Rect,DT_CENTER or DT_VCENTER or DT_SINGLELINE); |
So. Denke, dass ich dies mit StringGrid nun verstanden habe. Hätte nicht gedacht, dass man so detailliert arbeiten kann ^^
Eine Frage bleibt jedoch offen. Im 2. Delphicode schreibt er den Text ja über DrawGrid. Wie sind jedoch die einzelnen Übergaben zu deuten?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| canvas.handle - müsste ansich ja irgendwas reinmalen in den StringGrid. Also reinmal des Buchstaben?
PChar(s) - dürfte wohl die Übergabe des eingelesen Wortes sein.
Rect - hatten wir vorhin benutzt zum ausfüllen des Feldes, dies wäre aber das gleiche wie canvas.handle
DT_Center etc. - Wieso kommt es dort zu mehreren Auswahlmöglichkeiten? Ich denke mal, dass es bedeutet, dass der Text zentriert ausgegeben wird (sagen mir die vordersten Werte. Der 3. Wert "Singleline" sagt mir hier aber nichts. |
--------
Weiß nicht ob ich nen neues Thema öffnen soll oder nicht. Wenns nicht rein passt bzw. nicht erwünscht wird, mach ich gerne neues Topic auf.
Ich habe mir nun überlegt, dass die Prozedur zum erstellen des Sudoku folgendermaßen aufgebaut ist:
Er beginnt mit 1, rasselt diese 9 mal durch, sodass in jedem Unterquadrat eine 1 steht. Sobald eine 1 positioniert wurde, habe ich vor, die Spalte/Zeile zu sperren, sodass es bereits eindeutig wird. Danach werden die Spalten/Zeilen wieder freigestellt und der rattert die 2 9x durch. Bei bereits belegtem Feld wird ein anderes Feld gesucht.
Soviel zur Idee. Umsetzung sieht wieder ganz anders aus.
Ich habe ein Array
Delphi-Quelltext 1:
| var tZelle : array[0..8, 0..8] of Integer; |
In jenem habe ich vor, die Spalte/Zeile zu sperren, indem ich einfach die Zahl rauslösche. Wär dies überhaupt möglich, da ich das Array direkt vorgegeben habe?
Ist es ebenfalls möglich. Angenommen es würde funktionieren mit dem rausstreichen, dass man ein Random Befehl so schreibt, dass er eine ZUufallszahl aus den restlichen Spalten/Zeilen zieht oder muss dies dann über eine case of bzw if-Schleife erledigt werden?
Bitte schlagt mich nicht für den Text ^^"
|
|
Keldorn
      
Beiträge: 2266
Erhaltene Danke: 4
Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
|
Verfasst: Sa 14.03.09 17:25
| Zitat: |
Ist doch das gleiche wie das oder?
|
ja, das Endresultat ist das gleiche.
Aber die Canvas.textout-Variante ist vielleicht für Dich vom Verständnis bzw von der Herleitung her logischer. Drawtext ist eleganter und hat viel mehr einfacherer Möglichkeiten.
Fragen zu Drawtext: einfach mal Cursor drauf und f1 drücken  , da steht auch zu den Parametern alles, was Du wissen willst..
Da steht dann z.B. bei DT_Vcenter:
| Zitat: |
Centers text vertically. This value is used only with the DT_SINGLELINE value.Centers text vertically. This value is used only with the DT_SINGLELINE value.
|
mit drawtext kannst du auch Texte mehrzeilig ausgeben (geht z.B. mit Canvas.textout nicht wirklich). Einen mehrzeiligen Text (DT_Multiline) kannst aber eben nicht vertikal zentriert ausgeben.
einfach auch mal im Forum nach Drawtext und stringgrid suchen, da findest Du viele Beispiele, die du einfach mal ausprobieren solltest.
| Zitat: |
Weiß nicht ob ich nen neues Thema öffnen soll oder nicht.
|
ja 
_________________ Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
|
|
|