StringGrid in Image - ClientRect?
-
Hallo, zeichne in ein TStringGrid mittels DrawCell eine grafische Oberfläche über viele Spalten und Zeilen (z.B. 12 Spalten, 80 Zeilen). Ich bekomme nicht alle Spalten und Zeilen im StringGrid angezeigt, muss also über die Regler scrollen. Jetzt möchte ich aber das Gesamtbild des TStringGrid (also alle Spalten und Zeilen) an ein externes Grafikprogramm übergeben:
AnsiString z1,z2; // Vars definieren Graphics::TBitmap *bmp = new Graphics::TBitmap(); // BMP Image anlegen TStringGrid *Grid; // TStringGrid vorbereiten Grid=frm14_grd6_Schrank; // StringGrid übergeben //TRect RectA=Rect(0,0,Grid->Width,Grid->Height); // nur aktuelle Fenstergrösse vom TStringGrid TRect RectA=Grid->ClientRect; // kompletter TStringGrid-Bereich? bmp->Height=RectA.Width(); // Breite Image einstellen bmp->Width =RectA.Height(); // Höhe Image einstellen bmp->Canvas->CopyRect(RectA,Grid->Canvas,RectA); // und Grid in Image kopieren z1=Form1->PrgPfad+"\\Ablage\\Grafik_"+frm14_lblSchrank->Caption+".bmp"; // Dateiname bilden bmp->SaveToFile(z1); // Grafik sichern delete bmp; // Image löschen if(FileExists(Form1->PrgGrafEx)==false) { Form1->PrgGrafEx="mspaint.exe"; } // externes Prg. ggfs. korrigieren z2=Form1->PrgGrafEx+" \""+z1+"\""; // ergänzen WinExec(z2.c_str(),SW_NORMAL); // Malprogramm aufrufenProblem: Er übergibt mir nur den sichtbaren Bereich des TStringGrid; alles verdeckte bleibt bei der Übergabe weiss. Frage: Wie kann ich auch den verdeckten Teil übergeben?
Vorher alle Spalten und Zeilen auf den sichtbaren Bereich zoomen habe ich als Funktion zwar, wird aber teilweise zu klein und daher nicht praktikabel.
Danke für jeden Tip...
Gruss Stefan
-
Hallo
benutzt TStringGrid::PaintTo auf ein ausreichend großes TCanvas.
bis bald
akari
-
Hallo, Akari
bmp->Height=RectA.Width(); // Breite Image einstellen bmp->Width =RectA.Height(); // Höhe Image einstellen Grid->PaintTo(bmp->Canvas,0,0); //bmp->Canvas->CopyRect(RectA,Grid->Canvas,RectA); // und Grid in Image kopierenSo zeichnet er auch nur den sichtbaren Bereich (einschl. Fensterrahmen).
Muss ich die Zellen einzeln umlenken mit PaintTo?Gruss Stefan
-
Hallo
hm... ja PaintTo liefert auch nur das gewohnte, hab irgendwie noch geschlafen.
Es wird dir wohl nichts anders übrigbleiben als alle Zellen selber zu zeichnen.
bis bald
akari
-
Hatte auch schon mal das Problem,
und habe es so gelößt, das ich die Breite/Höhe des StringGrids vor dem PaintTo auf die komplette gewünschte Druckgröße geändert habe.StringGrid1->Align = alNone; StringGrid1->Width = StringGrid1->ColCount * StringGrid1->DefaultColWidth; StringGrid1->Height = StringGrid1->RowCount * StringGrid1->DefaultRowHeight; TImage *myImage = new TImage(this); if (myImage) { myImage->Picture->Bitmap->Height = StringGrid1->Height; myImage->Picture->Bitmap->Width = StringGrid1->Width; StringGrid1->PaintTo(myImage->Canvas->Handle, 0, 0); .... delete myImage; myImage=NULL; } StringGrid1->Align = alClient;
-
Hei, Akari
also wenn ich es so mache:
Integer iCol,iRow,iB,iH; AnsiString z1,z2; // Vars definieren TStringGrid *Grid; // TStringGrid vorbereiten Grid=frm14_grd6_Schrank; // StringGrid übergeben iCol=Grid->ColCount; // Anzahl Spalten iRow=Grid->RowCount; // Anzahl Zeilen iB=0; for(int i1=0;i1<iCol;i1++) { iB=iB+Grid->ColWidths[i1]; } // Breite aller Spalten? iH=0; for(int i1=0;i1<iRow;i1++) { iH=iH+Grid->RowHeights[i1]; } // Höhe aller Zeilen? Form1->ExtPrgBmp->Width =iB; // Breite Image einstellen Form1->ExtPrgBmp->Height=iH; // Höhe Image einstellen if(Form1->PrgComp==true) { ShowMessage("BxH = "+IntToStr(iB)+" x "+IntToStr(iB)); } // nur im IDE zeigen TRect RectA; // Rect vorbereiten TGridDrawState State; // State vorbereiten for(int i1=0;i1<iRow;i1++) { // alle Zeilen for(int i0=0;i0<iCol;i0++) { // alle Spalten RectA=Grid->CellRect(i0,i1); // Rect der Zelle ermitteln GridZeichnen(99,i0,i1,RectA,State,frm14_grd6_Schrank); // und Zelle einzeln zeichnen (mit 99 in Grafik kopieren) } // ende } z1=Form1->PrgPfad+"\\Ablage\\Grafik_"+frm14_lblSchrank->Caption+".bmp"; // Dateiname bilden Form1->ExtPrgBmp->SaveToFile(z1); // Grafik sichern if(FileExists(Form1->PrgGrafEx)==false) { Form1->PrgGrafEx="mspaint.exe"; } // externes Prg. ggfs. korrigieren z2=Form1->PrgGrafEx+" \""+z1+"\""; // ergänzen WinExec(z2.c_str(),SW_NORMAL); // Malprogramm aufrufenUnd in der Funktion GridZeichnen(...) unten das anhänge, dann
bekomme ich auch nur den sichtbaren Bereich...?if(p1==99) { // Bitmap für externes Programm wird erzeugt Form1->ExtPrgBmp->Canvas->CopyRect(ARect, Grid->Canvas, ARect); //Grid->PaintTo(Form1->ExtPrgBmp->Canvas->Handle,ARect.Left,ARect.Top); }Liegt das an den Rect Strukturen?
Wenn ich statt der Schleifen oben nur ein Grid->Repaint(); nehme, dann flackert sich das StringGrid tot (und ich beim Zuschauen auch)...Bin etwas ratlos...

Gruss Stefan
-
Hallo, VergissEs
das geht aber auch nur mit dem möglichen sichtbaren Bereich.
Mein Problem: Das StringGrid kann eigentlich z.B. doppelte Bildschirm-
höhe haben. Daher dachte ich es muss doch möglich sein, das zeichnen
so umzulenken, daß es direkt in ein Image gezeichnet wird.Dummerweise scheinen die Koords aber nicht übergeben zu werden,
wenn die Zellen nicht mehr sichtbar sind... ?Gruss Stefan
-
Wenn du doch sowieso DrawCell für alle Zellen zum Zeichnen benutzt, dann brauchst du doch nur eine doppelte Schleife verwenden und das Rechteck selber bestimmen.
Also erstmal ein genügend großes Canvas (Spalten * Spaltenbreite, Zeilen*Zeilenbreite) bereitstellen und dann einfach jede Zelle darauf zeichnen...
for(int i=0; i<Spalten; i++) for(int j=0; j<Zeilen; j++) { Rect r(i*Spaltenbreite, j*Zeilenbreite, (i+1)*Spaltenbreite, (j+1)*Zeilenbreite); DrawCell(canvas, i, j, r, TGridDrawState()); }wobei DrawCell deine eigene Zeichenroutine ist, so daß im Ereignis für OnDrawCell einfach DrawCell(this->Canvas, Col, Row, Rect, State) aufgerufen wird.
-
Hallo zusammen,
so kann das StringGrid beliebig viele Zellen beliebiger Grösse haben;
leicht unschön anzuschauen aber es funktioniert.Integer ix,iy,iCol,iRow,iB,iH,iAktC,iAktR; AnsiString z1,z2; // Vars definieren TStringGrid *Grid; // TStringGrid vorbereiten Graphics::TBitmap *bmp = new Graphics::TBitmap(); // BMP Image anlegen Grid =frm14_grd6_Schrank; // StringGrid übergeben iCol =Grid->ColCount; // Anzahl Spalten iRow =Grid->RowCount; // Anzahl Zeilen iAktC=Grid->LeftCol; // aktuelle linke Spalte? iAktR=Grid->TopRow; // aktuelle obere Zeile? iB=0; for(int i1=0;i1<iCol;i1++) { iB=iB+Grid->ColWidths[i1]; } // Breite aller Spalten? iH=0; for(int i1=0;i1<iRow;i1++) { iH=iH+Grid->RowHeights[i1]; } // Höhe aller Zeilen? bmp->Width =iB; // Breite Image einstellen bmp->Height=iH; // Höhe Image einstellen //if(Form1->PrgComp==true) { ShowMessage("BxH = "+IntToStr(iB)+" x "+IntToStr(iB)); } // nur im IDE zeigen TRect RectA,RectB; // Rects vorbereiten TGridDrawState State; // State vorbereiten iy=0; // Start Koordinate Y for(int i1=0;i1<iRow;i1++) { // alle Zeilen Grid->TopRow=i1; ix=0; // Zeile for(int i0=0;i0<iCol;i0++) { // alle Spalten Grid->LeftCol=i0; // Spalte neu einstellen RectA=Grid->CellRect(i0,i1); // Rect der aktuellen Zelle ermitteln GridZeichnen(1,i0,i1,RectA,State,frm14_grd6_Schrank); // und Zelle direkt einzeln zeichnen RectB=Rect(ix,iy,ix+RectA.Width(),iy+RectA.Height()); // Rect für Image ermitteln bmp->Canvas->CopyRect(RectB, Grid->Canvas, RectA); // und Zelle in Image kopieren ix=ix+Grid->ColWidths[i0]; // Breite dazuaddieren } // ende for(i0 iy=iy+Grid->RowHeights[i1]; // Höhe dazuaddieren } // ende for(i1 Grid->LeftCol=iAktC; // aktuelle Spalte wieder einstellen Grid->TopRow =iAktR; // aktuelle Höhe wieder einstellen z1=Form1->PrgPfad+"\\Ablage\\Grafik_"+frm14_lblSchrank->Caption+".bmp"; // Dateiname bilden bmp->SaveToFile(z1); // Grafik sichern delete bmp; // und freigeben if(FileExists(Form1->PrgGrafEx)==false) { Form1->PrgGrafEx="mspaint.exe"; } // externes Prg. ggfs. korrigieren z2=Form1->PrgGrafEx+" \""+z1+"\""; // ergänzen WinExec(z2.c_str(),SW_NORMAL); // Malprogramm aufrufenDas Grid=frm14_grd6_Schrank; kann ersetzt werden mit einer Funktion und
dann Übergabe des StringGrid als TObject:TStringGrid *Grid = dynamic_cast<TStringGrid *> (Sender); // Versuchen, Sender als StringGrid anzusprechenDanke für alle Tips und Hinweise, Stefan