KGrid Komponente kompilieren



  • Hallo alle zusammen!

    Normalerweise versuche ich meine Problemchen selber zu lösen und nicht die Foren voll zu spammen, aber momentan verzweifel ich hier und brauche einfach Hilfe!

    Ich benötige ein StringGrid, mit mehr Funktionalitäten (z.B. Checkboxen, AutoAusrichtung etc.) als die Standardkomponente bietet. Nach kurzer Suche bin ich auch schon auf KGrid (http://www.tkweb.eu/en/delphicomp/kgrid.html) gestoßen. Sieht nach genau dem aus, was ich benötige. Allerdings bekomme ich es einfach nicht hin, dass Ding unter Delphi so zu kompilieren, dass ich es im Builder einsetzen kann!

    Ich hab schon so mehr oder weniger lib's und hpp's zu der Komponente erzeugen können, allerdings wirft er mir dann beim Kompilieren im C++ Builder wilde Syntaxfehler in den Headerdateien um die Ohren. Wenn ich im Delphi beim Linker "Alle C++ Dateien erzeugen" auswähle, dann bekomme ich auch Fehlermeldungen, dass ungültige Sprachkonstrukte in den Pas-Dateien vorhanden sind (btw habe ich keine Ahnung von Pascal!)...
    Ich kann die Komponente aber stumpf in Delphi kompilieren und installieren, kein Problem.
    Ich dreh durch!

    Hat einer von euch diese Komponente schon im C++ Builder des RAD Studios 2007 erfolgreich zum Laufen gebracht oder kann mir eine andere Komponente mit ähnlicher Funktionalität empfehlen??

    Ich bin für jede Antwort dankbar!
    Schönen Gruß



  • Der FAQ-Eintrag "Delphi-Komponenten im BCB" hilft nicht weiter?



  • Jansen schrieb:

    Der FAQ-Eintrag "Delphi-Komponenten im BCB" hilft nicht weiter?

    Nein, leider nicht, aber vielen Dank!

    Dazu habe ich eh noch eine Frage:
    Ich habe früher mit dem BCB 5 gearbeitet und dann kam lange nichts und jetzt bin ich gerade erst wieder mit dem CodeGear RAD Studio 2007 zugange.
    Warum kann ich Komponenten nicht mehr anhand ihrer cpp / pas Files einfügen?? Ich entsinne mich noch grob, dass ich früher auch einfach die Registrierungs-PAS-Dateien bei "Komponenten hinzufügen" auswählen konnte und die Komponente wurde installiert. Warum geht das in der neuen Version nicht mehr und warum gibt es standardmäßig die Builder-Package-Dateien nicht mehr?

    Ok ok, die letzte Frage ist erstmal nicht so wichtig. Wäre aber schön, wenn ihr mir ansonsten weiterhelfen könntet!
    Vielen Dank schonmal! (warum steht vor_raus auf der Blacklist? Vorraus)

    P.S.: Ich hasse es, dass Software heutzutage nicht mehr mit vernünftigen Handbüchern ausgeliefert wird, sondern nur noch solche Online-Hilfen, die oft mehr Arbeit machen als zu helfen! 😞



  • __yoshi schrieb:

    P.S.: Ich hasse es, dass Software heutzutage nicht mehr mit vernünftigen Handbüchern ausgeliefert wird, sondern nur noch solche Online-Hilfen, die oft mehr Arbeit machen als zu helfen! 😞

    Das stimmt. Ein ordentliches Handbuch zu C++Builder ist z.B. das hier, vereinzelt auch noch günstiger zu finden.



  • audacia schrieb:

    Das stimmt. Ein ordentliches Handbuch zu C++Builder ist z.B. das hier, vereinzelt auch noch günstiger zu finden.

    Vielen Dank. Allerdings kann ich beim besten Willen kein vernünftiges (besser gesagt gar kein) aktuelles Buch finden, dass auch auf die neuen Eigenheiten von der IDE des RAD Studios 2007 eingeht. Es gibt zwar "C++ mit dem C++ Builder" von Richard Kaiser in einer Auflage von 2007, aber da hat mich die erste Auflage schon nicht vom Hocker gehauen, weil es ein Anfängerbuch ist, das mir zu stark auf C++ allgemein eingeht.

    Ich habe zunehmend das Gefühl, dass der C++ Builder dem Aussterben nahe ist.

    Naja, ich glaube ich werde jetzt mal in den sauren Apfel beißen und die kommerziellen Komponenten von Bergsoft kaufen. Die haben zumindest noch einen humanen Suite-Preis und werden mit BCB2006 Packages ausgeliefert.
    Hat jemand Erfahrungen mit den Komponenten?

    Schönen Gruß



  • __yoshi schrieb:

    Vielen Dank. Allerdings kann ich beim besten Willen kein vernünftiges (besser gesagt gar kein) aktuelles Buch finden, dass auch auf die neuen Eigenheiten von der IDE des RAD Studios 2007 eingeht.

    Da ist meist tatsächlich nur die Online-Hilfe hilfreich. Was die VCL-Neuerungen angeht, ist aber vielleicht die einschlägige Delphi-Lektüre für dich von Interesse.

    __yoshi schrieb:

    Ich habe zunehmend das Gefühl, dass der C++ Builder dem Aussterben nahe ist.

    Dem war er schon viel näher, insbesondere in der Zeit zwischen C++Builder 6 und 2006 😉

    Wenn ich nachher noch Zeit habe, kann ich mal versuchen, mir dieses KGrid mit C++Builder 2006 anzusehen.



  • audacia schrieb:

    Da ist meist tatsächlich nur die Online-Hilfe hilfreich. Was die VCL-Neuerungen angeht, ist aber vielleicht die einschlägige Delphi-Lektüre für dich von Interesse.

    Ja, da stöber ich tatsächlich inzwischen meist rum! Für Delphi gibt es nach wie vor eine ganze Menge.
    Mein Problem ist, dass ich überhaupt kein Pascal kann und diese seltsamen Konstrukte von Klassen, Funktionen und Schleifen finde ich durchaus befremdlich.
    Ich hab zwar schonmal eine Komponente mit Delphi entwickelt, weil es unbedingt sein musste, aber ich hab mir nicht wirklich die Mühe gemacht zu verstehen, was ich da so mache 😃

    audacia schrieb:

    Dem war er schon viel näher, insbesondere in der Zeit zwischen C++Builder 6 und 2006 😉

    Die Zeit habe ich (zum Glück?) nicht ernsthaft mitbekommen. Da haben die mich mit so 'nem neumodischen Kram wie Java und Python (*g* jaja, neumodisch... ich weiß schon) geärgert 🙄

    audacia schrieb:

    Wenn ich nachher noch Zeit habe, kann ich mal versuchen, mir dieses KGrid mit C++Builder 2006 anzusehen.

    Oh, dafür wäre ich dir äußerst dankbar!
    Wenn man schon Hilfe bekommt, dann möchte es man dem Gegenüber ja auch möglichst angenehm machen, daher hier nochmal der DL-Link für's KGrid: http://www.tkweb.eu/en/delphicomp/kgrid.html
    und eine schöne heiße Tasse Kaffee dazu! 🙂

    Ich lausche gespannt auf Nachricht von dir!
    Schönen Gruß



  • Liegt es eventuell daran ?

    Necessary packages
    JEDI Code Library (JCL) - Version 1.100+



  • ed_die schrieb:

    Liegt es eventuell daran ?

    Necessary packages
    JEDI Code Library (JCL) - Version 1.100+

    Das hätte ein Grund sein können, aber ich habe die aktuelle JCL und JVCL installiert und im Einsatz, daran liegt es also nicht. Aber Danke!



  • __yoshi schrieb:

    Mein Problem ist, dass ich überhaupt kein Pascal kann und diese seltsamen Konstrukte von Klassen, Funktionen und Schleifen finde ich durchaus befremdlich.

    Dann rate ich dir dringend, Delphi mal näher anzuschauen. Es lohnt sich auf jeden Fall. Gerade wenn du schon eine Weile mit C++Builder arbeitest, wird es dir nicht schwerfallen.

    audacia schrieb:

    Wenn ich nachher noch Zeit habe, kann ich mal versuchen, mir dieses KGrid mit C++Builder 2006 anzusehen.

    Ganz fertig bin ich noch nicht damit, aber folgendes habe ich herausgefunden:
    Die Komponente greift auf mindestens drei Dinge zurück, mit denen C++Builder Probleme hat (weiter hält mich noch ein hartnäckiger Linkerfehler auf, der aber nur im Debug-Mode auftritt). Diese drei lassen sich aber von Hand beheben:

    • Zunächst wird in KFunctions.pas ein enum namens TMsgBoxButtons definiert, das einige Konstanten für die Übergabe an MessageBox definiert:
    //Win32 API message box
    type
      TMsgBoxButtons = (mbAbortRetryIgnore, mbOk, mbOkCancel, mbRetryCancel, mbYesNo, mbYesNoCancel);
    

    Einige dieser Konstanten sind bereits in der VCL-Unit Dialogs.pas als Set-Konstanten definiert:

    const
      mbYesNo = [mbYes, mbNo];
      mbYesNoCancel = [mbYes, mbNo, mbCancel];
      ...
      mbOKCancel = [mbOK, mbCancel];
      mbAbortRetryIgnore = [mbAbort, mbRetry, mbIgnore];
      ...
    

    Unglücklicherweise macht der Delphi-Compiler bei der Header-Generation Makros daraus:

    #define mbYesNo (Set<TMsgDlgBtn, mbYes, mbHelp> () << TMsgDlgBtn(0) << TMsgDlgBtn(1) )
    #define mbYesNoCancel (Set<TMsgDlgBtn, mbYes, mbHelp> () << TMsgDlgBtn(0) << TMsgDlgBtn(1) << TMsgDlgBtn(3) )
    ...
    #define mbOKCancel (Set<TMsgDlgBtn, mbYes, mbHelp> () << TMsgDlgBtn(2) << TMsgDlgBtn(3) )
    #define mbAbortRetryIgnore (Set<TMsgDlgBtn, mbYes, mbHelp> () << TMsgDlgBtn(4) << TMsgDlgBtn(5) << TMsgDlgBtn(6) )
    ...
    

    Und wie man das so gewohnt ist, expandiert der Präprozessor Makros ganz rücksichtslos, auch in diesem Fall, wo der Delphi-Compiler aus obigem enum die ganz harmlose C++-Entsprechung

    #pragma option push -b-
    enum TMsgBoxButtons { mbAbortRetryIgnore, mbOk, mbOkCancel, mbRetryCancel, mbYesNo, mbYesNoCancel };
    #pragma option pop
    

    gemacht hat. Die Folgen sind obskure Compilerfehler.
    Die Lösung ist, die Makrodefinitionen in Dialogs.hpp durch folgendes zu ersetzen:

    static const Set<TMsgDlgBtn, mbYes, mbHelp> mbYesNo = Set<TMsgDlgBtn, mbYes, mbHelp> () << TMsgDlgBtn(0) << TMsgDlgBtn(1);
    static const Set<TMsgDlgBtn, mbYes, mbHelp> mbYesNoCancel = Set<TMsgDlgBtn, mbYes, mbHelp> () << TMsgDlgBtn(0) << TMsgDlgBtn(1) << TMsgDlgBtn(3);
    ...
    static const Set<TMsgDlgBtn, mbYes, mbHelp> mbOKCancel = Set<TMsgDlgBtn, mbYes, mbHelp> () << TMsgDlgBtn(2) << TMsgDlgBtn(3);
    static const Set<TMsgDlgBtn, mbYes, mbHelp> mbAbortRetryIgnore = Set<TMsgDlgBtn, mbYes, mbHelp> () << TMsgDlgBtn(4) << TMsgDlgBtn(5) << TMsgDlgBtn(6);
    ...
    

    (Ich habe mal bei CodeGear angeregt, dies für die nächste Version von C++Builder generell so zu lösen.)

    • Das zweite Problem (das möglicherweise in C++Builder 2007 gar nicht mehr existiert - also erst mal schauen, ob es auch so klappt) hängt damit zusammen, daß die TKGridColors-Klasse einige Properties definiert, die über eine Funktion mit Index-Parameter abgefragt und gesetzt werden. Dabei werden für die Indizes nicht Integerwerte, sondern die Werte der enum-Definition namens TKGridColorIndex benutzt:
    // Grids.pas, Z. ~1487:
        function GetColor(Index: TKGridColorIndex): TColor;
        ...
        ...
        procedure SetColor(Index: TKGridColorIndex; Value: TColor);
    ...
    // Z.1511ff:
        { Background color for non-fixed cells. }
        property CellBkGnd: TColor index ciCellBkGnd read GetColor write SetColor default cCellBkGndDef;
        { Color for lines around non-fixed cells. }
        property CellLines: TColor index ciCellLines read GetColor write SetColor default cCellLinesDef;
    

    In der Headerdatei sieht das ganz korrekt so aus:

    Graphics::TColor __fastcall GetColor(TKGridColorIndex Index);
    	...
    	void __fastcall SetColor(TKGridColorIndex Index, Graphics::TColor Value);
    	...
    
    __published:
    	__property Graphics::TColor CellBkGnd = {read=GetColor, write=SetColor, index=0, default=-16777211};
    	__property Graphics::TColor CellLines = {read=GetColor, write=SetColor, index=1, default=-16777201};
    

    Nun meldet der C++-Compiler aber die Fehler

    BCC32 5.82 schrieb:

    [C++ Fehler] KGrids.hpp(353): E2347 Keine Entsprechung der Parameter in read mit Zugriffsspezifikation der Eigenschaft CellBkGnd
    [C++ Fehler] KGrids.hpp(353): E2347 Keine Entsprechung der Parameter in write mit Zugriffsspezifikation der Eigenschaft CellBkGnd
    [C++ Fehler] KGrids.hpp(354): E2347 Keine Entsprechung der Parameter in read mit Zugriffsspezifikation der Eigenschaft CellLines
    [C++ Fehler] KGrids.hpp(354): E2347 Keine Entsprechung der Parameter in write mit Zugriffsspezifikation der Eigenschaft CellLines
    ...

    Warum er das tut, weiß ich nicht, jedenfalls ist es möglicherweise in C++Builder 2007, mit höchster Wahrscheinlichkeit aber in der kommenden C++Builder-Version behoben. Ein Workaround für die Zwischenzeit wäre, die Funktionen SetColor und GetColor mit einem herkömmlichen Integer-Indexparameter auszustatten:

    // Grids.pas, Z. ~1487:
        function GetColor(Index2: {TKGridColorIndex} Integer): TColor;
        ...
        ...
        procedure SetColor(Index2: {TKGridColorIndex} Integer; Value: TColor);
    

    Entsprechend müssen die Implementationen angepaßt werden: Von

    // KGrids.pas, Z. ~4547:
    function TKGridColors.GetColor(Index: TKGridColorIndex): TColor;
    begin
      case FColorScheme of
        csBright:
        begin
          if FBrightColors[Index] = clNone then
            FBrightColors[Index] := BrightColor(FColors[Index], 0.5, bsOfTop);
          Result := FBrightColors[Index];
        end;
        csGrayed:
          case Index of
            ciCellBkGnd, ciFocusedCellText, ciSelectedCellText: Result := clWindow;
            ciCellText, ciFixedCellText, ciFocusedCellBkGnd: Result := clGrayText;
          else
            Result := FColors[Index];
          end;
      else
        Result := FColors[Index];
      end;
    end;
    
    procedure TKGridColors.SetColor(Index: TKGridColorIndex; Value: TColor);
    begin
      if FColors[Index] <> Value then
      begin
        FColors[Index] := Value;
        FBrightColors[Index] := clNone;
        if not (csLoading in FGrid.ComponentState) and FGrid.HandleAllocated then
          FGrid.Invalidate;
      end;
    end;
    

    zu

    function TKGridColors.GetColor(Index2: {TKGridColorIndex} Integer): TColor;
    var
      Index: TKGridColorIndex;
    begin
      Index := TKGridColorIndex (Index2);
      ... { der ganze Rest}
    end;
    
    ...
    
    procedure TKGridColors.SetColor(Index2: {TKGridColorIndex} Integer; Value: TColor);
    var
      Index: TKGridColorIndex;
    begin
      Index := TKGridColorIndex (Index2);
        ... { der ganze Rest}
    end;
    
    • Der dritte und vorerst letzte Punkt basiert auf der Tatsache, daß gegenwärtige Versionen von C++Builder keine Properties vom Delphi-Typ "array[<bounds>] of <type>" verarbeiten können. Ein Exemplar davon befindet sich in KGrids.pas in Zeile 224:
    { This array serves as storage field for all colors. }
      TKGridColorArray = array[Low(TKGridColorIndex)..High(TKGridColorIndex)] of TColor;
    ...
    // Verwendung Z. ~1500:
        property Colors: TKGridColorArray read FColors write SetColors;
    

    Dies verursacht den von dir anfangs genannten Fehler:

    DCC32 schrieb:

    E1025 Sprach-Feature wird nicht unterstützt: 'Eigenschaft vom Typ Array'

    Abhelfen kann man sich, indem man einen Wrapper-Typ sowie eine Getter- und eine Setter-Funktion definiert:

    // direkt nach der Deklaration von TKGridColorArray einfügen:
      TKGridColorArrayWrapper = record
        Colors : TKGridColorArray; 
      end;
    ...
    // Z. ~1475:
      TKGridColors = class(TPersistent)
      private
        ...
        function GetColors: TKGridColorArrayWrapper; // neu einfügen
        ...
        procedure SetColors(const Value: TKGridColorArray); // in TKGridColorArrayWrapper ändern
        ...
        property Colors: TKGridColorArray read FColors write SetColors;
        // in dieses hier ändern:    
        // property Colors: TKGridColorArrayWrapper read GetColors write SetColors;
        ...
    

    Auch die Implementationen müssen natürlich noch abgeändert werden:

    // Z. ~4595:
    
    procedure TKGridColors.SetColors(const Value: TKGridColorArray); // in TKGridColorArrayWrapper ändern
    begin
      FColors := Value;
      // in das hier ändern:
      // FColors := Value.Colors;
      ClearBrightColors;
    end;
    
    // hinzufügen:
    function TKGridColors.GetColors: TKGridColorArrayWrapper;
    begin
      Result.Colors :=FColors;
    end;
    

    Dieses Problem dürfte mit großer Sicherheit in der kommenden C++Builder-Version behoben sein.

    Nach diesen Korrekturen konnte ich fast ohne weitere Schwierigkeiten ein TKGrid auf meinem Formular plazieren und benutzen. (Du benutzt ja, wenn ich recht gelesen habe, C++Builder 2007, und möglicherweise ist der Linker-Bug da schon behoben, aber im C++Builder 2006 klappt es momentan leider nur im Release Mode.)

    Jetzt schuldest du mir aber nen Kaffee 😉



  • 😮 Audacia, da bin ich platt! Es funktioniert! Bestens sogar!

    audacia schrieb:

    Warum er das tut, weiß ich nicht, jedenfalls ist es möglicherweise in C++Builder 2007, mit höchster Wahrscheinlichkeit aber in der kommenden C++Builder-Version behoben.

    Im BCB 2007 ist das noch. Dein Workaround hat aber wunderbar funktioniert!

    Ich weiß gar nicht, was ich sagen soll. GANZ HERZLICHEN DANK für die viele Mühe, die du dir gemacht hast!

    Ich weiß leider nicht wann ich mal bei dir in der Nähe bin, aber wenn du mal nach Berlin kommst, dann gibt's eine schöne Tasse Kaffee und ein Stück Torte dazu oder alternativ 'nen Bierchen und Bratwurst! 😉

    Nochmals herzlichen Dank und schönen Gruß!

    EDIT:
    Eine (vermutlich ziemlich simple) Frage habe ich:
    ich habe die Komponente (dank Audacia) erfolgreich kompiliert und installiert. Allerdings wird sie nur in der Tool-Palette von Delphi angezeigt. Sie wird im BCB bei den Entwurfszeit-Packages aufgelistet und ich kann sie auch verwenden, aber weder die neue Palettenseite, noch die Komponente werden in der Tool-Palette des BCB angezeigt. Was kann man da machen?



  • __yoshi schrieb:

    ich habe die Komponente (dank Audacia) erfolgreich kompiliert und installiert. Allerdings wird sie nur in der Tool-Palette von Delphi angezeigt. Sie wird im BCB bei den Entwurfszeit-Packages aufgelistet und ich kann sie auch verwenden, aber weder die neue Palettenseite, noch die Komponente werden in der Tool-Palette des BCB angezeigt. Was kann man da machen?

    Versuche mal, im Designtime-Package-Projekt in den Linker-Optionen bei der Linker-Ausgabe "Alle C++Builder-Dateien erzeugen" auszuwählen (dann sollte auch eine .bpi erzeugt werden).



  • Hallo audacia,

    genau das hatte ich auch gemacht und dann habe ich die Komponente nochmal entfernt und im BCB über das bpi importiert. Der Effekt ist allerdings der selbe, das Package wird installiert und ich kann es verwenden, die Komponente wird aber nicht in der Tool-Palette angezeigt. Ich konnte bisher auch nichts finden, ob sich evtl. etwas mit der Registrierungsmethode für Komponenten im BCB 2007 geändert hat...

    Ich kann zwar die C++ Personality und die von Delphi parallel starten und die Komponente dann aus der Tool-Palette von Delphi auf meine Form im BCB ziehen, aber das ist etwas zu umständlich für meinen Geschmack.

    Im BCB kann ich mir ja auch die Icons für importierte Komponenten anzeigen lassen und da bekomme ich das Icon der KGrid Komp. auch angezeigt. Gibt es nicht irgendeine Möglichkeit, wie ich die angezeigten Komponenten der Tool-Palette quasi von Hand bearbeiten kann?



  • Dann wäre noch eine Option, ein neues C++Builder-Package anzulegen und diesem die .pas-Dateien hinzuzufügen. Allerdings läßt es sich dann wahrscheinlich in Delphi-Projekten nicht mehr verwenden.

    Sehr seltsam jedenfalls, daß es nicht mit Delphi-Packages funktioniert (bei mir ebenfalls nicht). In der Installationsroutine der JCL war irgendetwas von "Dual packages" zu lesen - aber wenn ich das recht verstanden habe, bewirkte diese Option auch lediglich die Erzeugung von .bpi-Dateien.



  • Irgendwie gefällt dem BCB die Trennung von Laufzeit- und Entwurfpackage wohl nicht so richtig. Ich habe die KGridDesign.pas jetzt mal mit in das R-Package übernommen und es zu einem Laufzeit- und Entwurfpackage gemacht.
    Danach über die bpl importiert und siehe da, das Grid taucht in der Tool-Palette auf. 🙂



  • Mal ein kleines Update hinsichtlich C++Builder 2009:

    Delphi-Konstanten werden (vermutlich, um nicht dem PCH-Mechanismus in die Quere zu kommen) nach wie vor als #defines übersetzt, daher ist der kleine Eingriff in Dialogs.pas vor der Verwendung des KGrid weiterhin notwendig.

    Auch müssen an der Komponente selbst, um in Delphi 2009 einsetzbar zu sein, ein paar Unicode-bedingte Anpassungen vorgenommen werden (insbesondere sollten alle WideString-Typen durch String ersetzt werden). Wahrscheinlich wird der Autor dies in absehbarer Zeit selbst tun, falls er Delphi 2009 unterstützen will.

    Dann allerdings ist die Komponente ohne weiteres direkt in C++Builder einsetzbar. Beide Probleme, die ich oben angesprochen hatte (enum-Typen als Property-Indizes und Arrays als Rückgabewerte), sind in C++Builder 2009 behoben.


Anmelden zum Antworten