dynamisch erzeugtes StringGrid und OnDrawCell



  • Hallo zusammen,

    ich weiß,dass das Thema schon oft disskutiert worden ist,aber komme mit den FAQ nicht weiter.

    Ziel ist es, eine StringGrid dynamisch auf dem Fenster zu platzieren und die Überschrift der Spalten fett zu schreiben.
    Dazu habe ich zunächst eine Klasse XTabelle von TStringGrid abgeleitet.
    Die zur Laufzeit erzeugte XTabelle wird auch in meinem Fenster angezeigt. Soweit so gut.
    Jetzt weise ich im Konstruktor von XTabelle das Ereigniss OnDrawCell des Fensters meiner Tabelle zu:

    this->OnDrawCell = Form->StringGridDrawCell;
    

    Das Ereignis füge ich jetzt wie folgt im Fenster ein:

    void __fastcall TForm1::StringGridDrawCell(TObject *Sender, int ACol,
          int ARow, TRect &Rect, TGridDrawState State)
    {
        //Canvas->Font->bla bla bla 
    DrawText(Tabelle->Canvas->Handle,
    Tabelle->Cells[ACol][ARow].c_str(),
        -1, &Rect, DT_SINGLELINE | DT_VCENTER | hAlign);
    };
    

    Dann gibt er mir folgende Fehlermeldung aus:
    [C++ Fehler] U_Tabelle.cpp(37): E2034 Konvertierung von 'void (_fastcall * (_closure )(TObject *,int,int,TRect &,TGridDrawState))(TObject *,int,int,TRect &,TGridDrawState)' nach 'void (_fastcall * (_closure )(TObject *,int,int,const TRect &,TGridDrawState))(TObject *,int,int,const TRect &,TGridDrawState)' nicht möglich

    Um das Problem zu umgehen ändere ich also die Parameter von:

    void __fastcall StringGridDrawCell(TObject *Sender, int ACol,
          int ARow, TRect &Rect, TGridDrawState State);
    

    in

    void __fastcall StringGridDrawCell(TObject *Sender, int ACol,
          int ARow, const TRect &Rect, TGridDrawState State);
    

    ==> Ok, Funktioniert. Jetzt funktioniert jedoch der Aufruf von DrawText nicht:
    Fehlermeldung:
    [C++ Fehler] UMain.cpp(285): E2034 Konvertierung von 'const TRect *' nach 'tagRECT *' nicht möglich
    und
    [C++ Fehler] UMain.cpp(285): E2342 Keine Übereinstimmung des Typs beim Parameter 'lpRect' ('tagRECT *' erwartet, 'const TRect *' erhalten)

    Was mach ich nur falsch? Bin ich auf ein Versionskonflikt der VCL gestoßen oder was soll das Ganze. Arbeite mit BCB 6.
    Wäre nett,wenn jemand mein Problem lösen könnte.

    Danke im Vorraus
    Sebastian



  • Hallo

    mach aus dem konstanten Rect-Parameter in dem Event noch eine nicht-konstante Zwischenvariable

    void __fastcall TForm1::StringGridDrawCell(TObject *Sender, int ACol,
          int ARow, const TRect &Rect, TGridDrawState State)
    {
    TRect buffer = Rect;
    ...
    DrawText(Tabelle->Canvas->Handle,
    Tabelle->Cells[ACol][ARow].c_str(),
        -1, &buffer, DT_SINGLELINE | DT_VCENTER | hAlign);
    };
    

    bis bald
    akari



  • Wo kommt hier eigentlich das "const TRect &Rect" her? Bei OnDrawCell ist das normalerweise nicht konstant. Hast du OnDrawCell in deiner Klasse redeklariert?



  • Hallo

    ja das ist ein Fehler der VCL. Wenn du den Event über den OI erstellst, konnt kein const und der Compiler beschwert sich auch nicht.
    Wenn du aber zur Laufzeit den Event zuweisen willst, verlangt der Compiler das const. Ist zumindestens beim BCB5 noch so.

    bis bald
    akari



  • Ok,

    Ich habs grad mal im BCB6 getestet und da ist es auch noch so.



  • Erstmal danke für eure Antworten. Leider ist mir immer noch nicht so wirklich geholfen.

    @ Akari:

    Wenn ich deinen Code implementiere, meckert der Compiler wie folgt:

    [C++ Fehler] UMain.cpp(258): E2034 Konvertierung von 'const TRect *' nach 'tagRECT *' nicht möglich
    und

    [C++ Fehler] UMain.cpp(258): E2342 Keine Übereinstimmung des Typs beim Parameter 'lpRect' ('tagRECT *' erwartet, 'const TRect *' erhalten)

    sowie

    [C++ Fehler] UMain.cpp(261): E2451 Undefiniertes Symbol 'hAlign'

    Ich habe jetzt folgendes gemacht:

    void __fastcall TForm1::StringGridDrawCell(TObject *Sender, int ACol,
          int ARow, const TRect &Rect, TGridDrawState State)
    {
      if(ARow==0)
       Tabelle->Canvas->Font->Style= TFontStyles()<<fsBold;
      else
        Tabelle->Canvas->Font->Style= TFontStyles();
    
      tagRECT* test =new tagRECT;
      test->left=Rect.Left;
      test->top=Rect.Top;
      test->right=Rect.Right;
      test->bottom=Rect.Bottom;
    
      DrawText(Tabelle->Canvas->Handle, Tabelle->Cells[ACol][ARow].c_str(),
        -1, test,DT_SINGLELINE | DT_VCENTER);
    
    };
    

    Leider funktioniert das nicht wirklich, der Text in den Zellen wirkt irgendwie verschwommen. Weiß nit woran es noch liegen kann...

    Hat von euch noch jemand eine Idee? Da ich verschiedene Eigenschaften hinzufügen will,muss ich von TStringGrid ableiten und kann somit die Tabelle nur zur Laufzeit erzeugen.

    Gruß an alle



  • Hallo

    @ Akari:

    Wenn ich deinen Code implementiere, meckert der Compiler wie folgt:

    Das liegt daran, das er nicht TRect sondern einen Pointer auf TRect erwartet.

    Leider funktioniert das nicht wirklich, der Text in den Zellen wirkt irgendwie verschwommen. Weiß nit woran es noch liegen kann...

    Das sind die Überreste der alten Beschriftungen. Du must die noch komplett überzeichnen :

    if(ARow==0)
        Tabelle->Canvas->Font->Style= TFontStyles()<<fsBold;
      else
        Tabelle->Canvas->Font->Style= TFontStyles();
    
      TRect buffer = Rect;
      Tabelle->Canvas->FillRect(buffer);
      DrawText(Tabelle->Canvas->Handle, Tabelle->Cells[ACol][ARow].c_str(),
        -1, &buffer,DT_SINGLELINE | DT_VCENTER);
    

    So mußt du natrülich noch selber den blauen Hintergrund der ausgewählten Zelle einbauen, je nach State

    bis bald
    akari



  • Jo besten Dank,

    funktioniert jetzt fehlerlos. Gebe zu, auf die Geschichte mit dem Zeiger hätte ich selbst kommen können.

    Gruß



  • Hallo

    das &buffer hatte ich aber schon in meinem ersten Post... 😉

    bis bald
    akari


Anmelden zum Antworten