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 aufrufen
    

    Problem: 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 kopieren
    

    So 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 aufrufen
    

    Und 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 aufrufen
    

    Das 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 anzusprechen
    

    Danke für alle Tips und Hinweise, Stefan


Anmelden zum Antworten