Farbverlauf



  • Hallo,

    in Windows XP gibt es häufig (z.B. Suchfunktion im Explorer linke Seite) einen Farbverlauf von z.B. dunkelgrau nach hellgrau. Kennt ihr eine Möglichkeit soetwas mit dem Borland Builder hinzubekommen?



  • versuchs mal mit GradientFill oder machs halt selber, ist doch nun nicht so schwer ein paar farbige linien zu zeichnen oder?!



  • GradientFill jkingt ja gut. Ich habe in den Hilfen folgendes gefunden:

    Betrifft

    TCanvas3D-Komponente

    Deklaration

    procedure GradientFill ( Const Rect:TRect; StartColor,EndColor:TColor; Direction:TGradientDirection); virtual; abstract;

    Beschreibung

    Die Methode GradientFill wird zum Ausfüllen eines Bildschirmbereichs mit mehrfarbigen Linien verwendet. Dadurch wird ein schöner Schattiereffekt und ein farbiger Hintergrund erzeugt. Diese Methode wird intern von der Komponente Chart.Gradient verwendet.

    Beispiel:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    Chart1.Canvas.GradientFill( Canvas, ClientRect, clYellow, clBlue, True);
    end;

    Canvas hat aber keine Methode GradientFill. Führe ich sie wie folgt aus:

    TRect * rect;
    
      rect->left = Form1->Left;
      rect->top = Form1->Top;
      rect->right = Form1->Width;
      rect->Bottom = Form1->Height;
    
      GradientFill(Form1->Canvas, rect, clYellow, clBlue, true);
    

    bekomme ich Fehlermeldungen mit denen ich nicht allzuviel anfangen kann 😞

    [C++ Fehler] Unit1.cpp(22): E2034 Konvertierung von 'TRect *' nach '_TRIVERTEX *' nicht möglich
    [C++ Fehler] Unit1.cpp(22): E2340 Keine Übereinstimmung des Typs beim Parameter 2 ('_TRIVERTEX *' erwartet, 'TRect *' erhalten)
    [C++ Fehler] Unit1.cpp(22): E2034 Konvertierung von 'const TColor' nach 'void *' nicht möglich
    [C++ Fehler] Unit1.cpp(22): E2340 Keine Übereinstimmung des Typs beim Parameter 4 ('void *' erwartet, 'TColor' erhalten)
    [C++ Fehler] Unit1.cpp(22): E2193 Zu wenige Parameter im Aufruf von '__stdcall GradientFill(void *,_TRIVERTEX *,unsigned long,void *,unsigned long,unsigned long)'

    Was ist denn bitte "_TRIVERTEX" ??



  • Hallo,

    Du bringst hier ein bischen was durcheinander. Der Hilfetext den du gepostet hast bezieht sich auf TCanvas3D::GradientFill von TChart und kann auch nur da angwendet werden. Die Methode GradientFill die du aufgerufen hast ist aus der WinAPI (eigentlich GDI) und erfordert andere Parameter
    siehe GradientFill

    Ciao



  • Grundsätzlich liegen die Farbwert im RGB Format vor. Du hast also 3 Werte als Startwerte der Zielfarbe und hast 3 Werte die die Zielfarbe ergeben. Nun kommt es darauf an, in wievielen Schritten du die Zielwerte erreichen willst. Ein Farbschritt ist dann die Differenz zwischen Start- und Zielwert dividiert durch die Anzahl der Schritte.

    Kannst den Quellcode von

    http://www.marquardtnet.info/cecke/programme.4/4_farbrechner.html

    gerne haben. Schick ggf. eine Mail



  • Wobei das Ergebnis nicht sonderlich gut aussieht wenn man es direkt auf die RGB-Werte anwendet (wird bei deinem Farbrechner wahrscheinlich auch nicht gemacht). Ich konvertiere die Farben normalerweise erst nach HLS und erzeuge dann die Palette. Die muß dann nur noch wieder zurück konvertiert werden. Genauer gesagt konvertiere ich immer zwischen TColor und HLS. Die Ergebnisse gefallen mir eigentlich ganz gut. Wem es interessiert dem kann ich ja mal die entsprechenden Routinen schicken.



  • Danke Christian211, ich schicke dir de PM.

    Ichhabe jetzt:

    TRIVERTEX * myTRIVERTEX;
      GRADIENT_TRIANGLE * myGRADIENT_TRIANGLE;
    
      myTRIVERTEX->x = Form1->Top;
      myTRIVERTEX->y = Form1->Left;
      myTRIVERTEX->Red = 0x0000;// to 0xff00
      myTRIVERTEX->Green = 0x050;
      myTRIVERTEX->Blue = 0x1AF;
      myTRIVERTEX->Alpha = 0xff00;
    
      myGRADIENT_TRIANGLE->Vertex1 = 0;
      myGRADIENT_TRIANGLE->Vertex2 = 50;
      myGRADIENT_TRIANGLE->Vertex3 = 100;
    
      GradientFill(Form1->Canvas, myTRIVERTEX, 100, myGRADIENT_TRIANGLE, 1, GRADIENT_FILL_TRIANGLE);
    

    und bekomme einen Linker Fehler:

    [Linker Fehler] Unresolved external 'GradientFill' referenced from C:\PROGRAMME\BORLAND\CBUILDER6\PROJECTS\TMP\UNIT1.OBJ

    Da muss ich doch bestimmt die Funktion mit einer KLssenspezifikation aufrufen, oder? Aber welche?

    ???:GradientFill()
    Oder ises ganz was anderes?



  • header (wingdi.h) eingebunden? benötigt aber mind. win2000, winxp.



  • Ein unresolved external deutet eigentlich eher auf eine fehlende lib oder dll hin (Msimg32.dll). Außerdem ist die WinGDI.h schon über die windows.h mit drin. Da die Parameterliste erkannt wurde nehme ich mal an das die schon dabei ist.



  • Hallo,

    ich habe mich an einem gradientfill versucht. klappt ja auch ganz gut, jedoch möchte ich nicht nur die rgb werte erhöhen, sondern einen gradient von einer farbe zur anderen bekommen, wie gehe ich da am besten vor?

    keinen plan im moment.

    hier mein bisheriges beispiel für ein ListView:

    void __fastcall TForm1::ListView1AdvancedCustomDraw(
          TCustomListView *Sender, const TRect &ARect, TCustomDrawStage Stage,
          bool &DefaultDraw)
    {
        int myRow = 0;
        int myHeight = 0 ;
        myHeight = 1;
        for (myRow = 0; myRow < 255; myRow++)
    	{
    		Sender->Canvas->Brush->Color = (TColor) RGB(myRow / 4,myRow / 2,myRow);
    		Sender->Canvas->FillRect(Rect(0,myRow * myHeight, Sender->ClientWidth,ARect.Bottom));
    	}
    }
    

    kann mir da jemand helfen?

    nachtrag:
    mir fiel gerade auf, dass wenn man die listview scrollt, die flächen, die raus und dann wieder reinrollen nicht neu gezeichnet werden, wie kann man denn das auch noch lösen?

    gruß und dank gerd



  • Farbverläufe mache ich immer so:

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    int Hoehe=Height;
    int Breite=Width;
    int Farbe=0;
    for(int Nr=0;Nr<Hoehe;Nr++)
    {
    
    Farbe=255*Nr/Hoehe;
    
    Canvas->Pen->Color=RGB(0,0,Farbe);
    
    Canvas->MoveTo(0,Nr);
    Canvas->LineTo(Breite,Nr);
    }
    }
    


  • Hallo,

    Damit machst du aber nur einen Farbverlauf innerhalb einer Farbe (also dunkelblau nach hellblau oder so).
    Wie ich in diesen Thread schon einmal gesagt habe eignet sich meiner Meinung nach RGB nicht unbedingt für schöne Farbverläufe. Eine Konvertierung in ein anderes Farbmodell (wie z.Bsp. HLS) ist für meine Begriffe da geeigneter. Man kann in diesen Modell leicht einen Hell nach Dunkel-Verlauf innerhalb einer Farbe machen, indem man H und L konstant läßt und nur S ändert. Wenn man andererseits L und S konstant läßt und nur H ändert, erhält man einen Farbverlauf über mehrer Farben bei gleichbleibender Helligkeit.
    Ich find das so besser.



  • Und wie konvertiert man zu HLS?
    Und wie wendet man das an?



  • Ich hatte mal eine Quelle im Web gefunden, finde sie aber gerade nicht wieder.
    Hier ist mal eine Quelle von RGB zu HLS (aber kein C++)
    http://www.aboutvb.de/khw/artikel/khwrgbhlshsv.htm
    Falls ich meine Orginalquelle noch finde stelle ich sie hier auch noch rein.
    Meine Konvertierungsroutinen kommen jetzt

    struct THLSColor
    {
        double Hue, Sat, Lum;
    } ;
    
    void TColorToHLS(const TColor Color, THLSColor &hls)
    {
        // Konvertierung
        int rgbcol = ColorToRGB(Color);
        int rcol = (rgbcol & 0xFF0000) >> 16;
        int gcol = (rgbcol & 0x00FF00) >> 8;
        int bcol = rgbcol & 0x0000FF;
        double minval = min(rcol, min(gcol, bcol));
        double maxval = max(rcol, max(gcol, bcol));
        double mdiff  = maxval - minval;
        double msum   = maxval + minval;
    
        hls.Lum = msum / 510.0;
    
        if (maxval == minval)
        {
          hls.Sat = 0.0;
          hls.Hue = 0.0;
        }
        else
        {
          double rnorm = (maxval - rcol)*1.0 / mdiff;
          double gnorm = (maxval - gcol)*1.0 / mdiff;
          double bnorm = (maxval - bcol)*1.0 / mdiff;
    
          hls.Sat = (hls.Lum <= 0.5) ? (mdiff*1.0 / msum) : (mdiff / (510.0 - msum));
    
          if (rcol   == maxval) hls.Hue = 60.0 * (6.0 + bnorm - gnorm);
          if (gcol == maxval) hls.Hue = 60.0 * (2.0 + rnorm - bnorm);
          if (bcol  == maxval) hls.Hue = 60.0 * (4.0 + gnorm - rnorm);
          if (hls.Hue >= 360.0) hls.Hue = hls.Hue - 360.0;
        }
    }
    //---------------------------------------------------------------------------
    
    int HLSToRGB1(double rm1, double rm2, double rh)
    {
      if      (rh > 360.0) rh -= 360.0;
      else if (rh <   0.0) rh += 360.0;
    
      if      (rh <  60.0) rm1 = rm1 + (rm2 - rm1) * rh / 60.0;
      else if (rh < 180.0) rm1 = rm2;
      else if (rh < 240.0) rm1 = rm1 + (rm2 - rm1) * (240.0 - rh) / 60.0;
    
      return int(rm1 * 255);
    }
    //---------------------------------------------------------------------------
    
    TColor HLSToColor(const THLSColor hls)
    {
        int cred, cgreen, cblue;
        if (hls.Sat == 0.0) // Grauton, einfacher Fall
        {
          cred = cgreen = cblue = int(hls.Lum * 255.0);
        }
        else
        {
          double rm1, rm2;
    
          if (hls.Lum <= 0.5) rm2 = hls.Lum + hls.Lum * hls.Sat;
          else                rm2 = hls.Lum + hls.Sat - hls.Lum * hls.Sat;
          rm1 = 2.0 * hls.Lum - rm2;
          cred   = HLSToRGB1(rm1, rm2, hls.Hue + 120.0);
          cgreen = HLSToRGB1(rm1, rm2, hls.Hue);
          cblue  = HLSToRGB1(rm1, rm2, hls.Hue - 120.0);
        }
       return static_cast<TColor>(RGB(cblue,cgreen,cred));
    }
    //---------------------------------------------------------------------------
    


  • hallo,

    eine meiner wichtigsten fragen war unter anderem:

    habe ich einen Farbverlauf unter onCustomDraw eingebunden, funzt es ja auch. nur scrollt man die listview jetzt, und anschließend zurück, dann habe ich als hintergrund nur noch schwarz, wie kann man das hinbekommen, das der teil der neu gezeichnet werden muss dann auch mit farbverlauf (natürlich nur den teil davon) gezeichnet wird?

    gruß gerd



  • Hallo,

    Was passiert denn wenn du das in den OnAdvancedCustomDraw Event packst statt in OnCustomDraw.



  • hallo,

    leider klappt es auch nicht wie erwünscht, er zeichnet zwar neu, doch das mehrmals.

    noch irgendwelche ideen?

    gruß gerd


Anmelden zum Antworten