Farbauswahl innerhalb eines Formulars



  • Hallo,

    ich habe bislang nur Konsolenanwendungen programmiert und möchte nun Windowsanwendungen erstellen.

    Mein erstes Projekt soll ein Farbauswähler sein.
    Der Farbauswähler sollte später in etwa so aussehen:
    http://www.vb-gera.de/images/ColorPicker.png
    Die ausgewählte Farbe soll später als HTML-Hexwert angezeigt werden.

    -----------------------------------

    Nun zu meinem ersten Problem.
    Per

    this->colorDialog1->ShowDialog();
    

    wird ein hässliches Windowsstandardfarbauswahltool geöffnet. Ich möchte es aber direkt in der Form1 des Programms ohne Popup haben(d.h. ohne vorher einen Button betätigen zu müssen). Und auch nicht dieses Standarddings.

    Wie muss ich da vorgehen? Was ist zu beachten?

    Ich verwende Visual C++ 2008 Express Edition.
    Mein Zielframework ist .NET Framework 2.0

    Ich danke schonmal für alle die mir helfen wollen.



  • Da Du hier einen ColorDialog aufrufst, kannst Du das nicht direkt in die Form einbinden. Erstelle doch die ColorPalette selber. Und ermittel über die Koordinaten des Mauszeigers, welche Farbmischung ausgewählt wurde...
    So würde ich das machen.

    Nicht ganz leicht, aber vielleicht kann Dir ja der C++/CLI Guru Michael E. helfen, der Herr Oberschlau kennt da bestimmt eine Antwort.
    Er muss nur mal in sein C++/CLI Labor gehen und schon hat er die Antwort....



  • In meinem Programm hab ich das auch selbst geregelt:

    http://www.homebasement.de/index.php?page=ocs

    Scroll einfach da weiter runter, dann siehst wie es aussehen kann...

    EDIT: Wenn du hilfe brauchst kann ich dir´s erklären...



  • Hallo,

    danke für eure Antworten!

    denjo303 das sieht bei dir sehr gut aus 🙂
    Wie lautet denn der Fachbegriff des Schiebereglers? In der Toolbox vom Visual C++ finde ich nichts dergleichen.



  • Sieht wirklich gut aus.
    Vielleicht kannst Du mir da auch helfen?



  • Hallo,

    ich habe den Fachbegriff gefunden. Es lautet "Trackbar".

    Gleich mal testen was man damit so alles machen kann *g*

    Noch eine kleine Frage. Ist bei dir die Farbpalette da unten ein Bild?
    Oder wie lässt du dies generieren?

    Danke!



  • Ist kein bild...

    Ich hab das Control Selbst geschrieben:

    using namespace System;
    using namespace System::Drawing;
    using namespace System::Windows::Forms;
    
    ref class ColorPalette : Control
    {
    	Int32 cVal;
    	Color nColor;
    	Boolean rUp;
    	Boolean gUp;
    	Boolean bUp;
    	Color FontColor;
    public: ColorPalette(){
    		rUp=true;
    		gUp=false;
    		bUp=true;
    		this->Size = Drawing::Size(210,20);
    		cVal=0;
    
    		this->SetStyle(ControlStyles::DoubleBuffer | ControlStyles::UserPaint | ControlStyles::AllPaintingInWmPaint, true);
    	}
    protected: ~ColorPalette(){
    
    	}
    
    public: virtual System::Void OnPaint(PaintEventArgs ^e)override{
    			Int32 xL=0 , r=255 , g=0 , b=0 ; 
    			for(Int32 a=0; a<255; a++){
    				DrawLines(e,xL, r, g, b);
    				g++;
    				if(a%10==0) xL++;	
    			}
    			for(Int32 a=0; a<255; a++){
    				DrawLines(e,xL, r, g, b);
    				r--;
    				if(a%10==0) xL++;
    			}
    			for(Int32 a=0; a<255; a++){
    				DrawLines(e,xL, r, g, b);
    				b++;
    				if(a%10==0) xL++;
    			}
    			for(Int32 a=0; a<255; a++){
    				DrawLines(e,xL, r, g, b);
    				g--;
    				if(a%10==0) xL++;
    			}
    			for(Int32 a=0; a<255; a++){
    				DrawLines(e,xL, r, g, b);
    				r++;
    				if(a%10==0) xL++;
    			}
    			for(Int32 a=0; a<255; a++){
    				DrawLines(e,xL, r, g, b);
    				b--;
    				if(a%10==0) xL++;
    			}
    			for(Int32 a=0; a<255; a++){
    				DrawLines(e,xL, r, g, b);
    				r--;
    				if(a%10==0) xL++;
    			}
    			for(Int32 a=0; a<255; a++){
    				DrawLines(e,xL, r, g, b);
    				r++;
    				g++;
    				b++;
    				if(a%10==0) xL++;
    			}
    			Pen ^p3 = gcnew Pen(Color::FromArgb(10,200,200,200));
    			Pen ^p2 = gcnew Pen(Color::FromArgb(100,100,100));
    			Pen ^p1 = gcnew Pen(Color::FromArgb(50,50,50));
    			e->Graphics->DrawRectangle(p3, cVal-4,0,7,20);
    			e->Graphics->DrawRectangle(p2, cVal-3,0,5,20);
    			e->Graphics->DrawRectangle(p1, cVal-2,0,3,20);
    			e->Graphics->DrawRectangle(Pens::Black, 0,0,209,19);
    	   }
    public: System::Void DrawLines(PaintEventArgs ^e, Int32 x, Int32 r, Int32 g, Int32 b){
    			Pen ^p = gcnew Pen(Color::FromArgb(r,g,b));e->Graphics->DrawLine(p, x,0,x,20);
    		}
    public: System::Void SetValue(Int32 v1){
    			cVal = v1;
    			Invalidate();
    		}
    public: Int32 GetColorValue(){
    			return cVal;
    		}
    public: Bitmap^ Ca_Screen() {
    		Bitmap^ b = gcnew Bitmap(1, 1);
    		Graphics^ g = Graphics::FromImage(b);
    		g->CopyFromScreen(Cursor->Position.X, Cursor->Position.Y, 0, 0, b->Size);
    		delete g;
    		return b;
    		} 
    };
    

    Du erzeugst das Control wie gewohnt auf deiner form mit Event und Methode:

    //Attribut der Form
    ColorPalette ^CP;
    Color FontColor;
    
    //Im Konstruktor
    CP = gcnew ColorPalette();
    CP->Location = Point(100,100);
    CP->Click += gcnew EventHandler(this, &OptionForm::SetTextColor);
    this->Controls->Add(CP);
    
    //Die Methode
    public: void SetTextColor(Object ^sender, EventArgs ^e){
    			SetChange();
    			CP->SetValue(CP->Cursor->Current->Position.X - this->Left - 37);
    			Bitmap^ b = CP->Ca_Screen();
    			FontColor = b->GetPixel(0,0);
    			//Mit diesem Colorobject kannst du ja jetzt machen was du willst
    		}
    

    Das geht mit allen erdenklichen auflösungen...



  • Hallo,

    das hilft mir sehr weiter. Finde ich sehr nett von dir! 👍

    Vielen Dank, ich werde mein bestes versuchen.

    ----------------

    Hmmm du kannst mir nicht zufällig sagen, wie ich den Farbverlauf(nicht den Rest) hier implemetieren kann?
    Die Schieberegler usw. habe ich schon zusammengebastelt.
    Das ist der Standard-Code (mein aktuelles sieht anders aus, wäre aber glaub ich zu lang):

    #pragma once
    
    namespace testomat {
    
    	using namespace System;
    	using namespace System::ComponentModel;
    	using namespace System::Collections;
    	using namespace System::Windows::Forms;
    	using namespace System::Data;
    	using namespace System::Drawing;
    
    	/// <summary>
    	/// Zusammenfassung für Form1
    	///
    	/// Warnung: Wenn Sie den Namen dieser Klasse ändern, müssen Sie auch
    	///          die Ressourcendateiname-Eigenschaft für das Tool zur Kompilierung verwalteter Ressourcen ändern,
    	///          das allen RESX-Dateien zugewiesen ist, von denen diese Klasse abhängt.
    	///          Anderenfalls können die Designer nicht korrekt mit den lokalisierten Ressourcen
    	///          arbeiten, die diesem Formular zugewiesen sind.
    	/// </summary>
    	public ref class Form1 : public System::Windows::Forms::Form
    	{
    	public:
    		Form1(void)
    		{
    			InitializeComponent();
    			//
    			//TODO: Konstruktorcode hier hinzufügen.
    			//
    		}
    
    	protected:
    		/// <summary>
    		/// Verwendete Ressourcen bereinigen.
    		/// </summary>
    		~Form1()
    		{
    			if (components)
    			{
    				delete components;
    			}
    		}
    
    	private:
    		/// <summary>
    		/// Erforderliche Designervariable.
    		/// </summary>
    		System::ComponentModel::Container ^components;
    
    #pragma region Windows Form Designer generated code
    		/// <summary>
    		/// Erforderliche Methode für die Designerunterstützung.
    		/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
    		/// </summary>
    		void InitializeComponent(void)
    		{
    			this->components = gcnew System::ComponentModel::Container();
    			this->Size = System::Drawing::Size(300,300);
    			this->Text = L"Form1";
    			this->Padding = System::Windows::Forms::Padding(0);
    			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
    		}
    #pragma endregion
    	};
    }
    

    Wenn das zuviel verlangt ist, dann macht das nichts. Bin dann nicht traurig oder sowas in der Art 😃



  • Ich habe die Stellen mit

    //*********************    Hier
    

    Markiert

    #pragma once
    
    namespace testomat {
    
        using namespace System;
        using namespace System::ComponentModel;
        using namespace System::Collections;
        using namespace System::Windows::Forms;
        using namespace System::Data;
        using namespace System::Drawing;
    
        /// <summary>
        /// Zusammenfassung für Form1
        ///
        /// Warnung: Wenn Sie den Namen dieser Klasse ändern, müssen Sie auch
        ///          die Ressourcendateiname-Eigenschaft für das Tool zur Kompilierung verwalteter Ressourcen ändern,
        ///          das allen RESX-Dateien zugewiesen ist, von denen diese Klasse abhängt.
        ///          Anderenfalls können die Designer nicht korrekt mit den lokalisierten Ressourcen
        ///          arbeiten, die diesem Formular zugewiesen sind.
        /// </summary>
        public ref class Form1 : public System::Windows::Forms::Form
        {
        ColorPalette ^CP;//*********************    Hier
        Color FontColor;//*********************    Hier
    
        public:
            Form1(void)
            {
                InitializeComponent();
                //
                //TODO: Konstruktorcode hier hinzufügen.
                //
                CP = gcnew ColorPalette();//*********************    Hier
                CP->Location = Point(100,100);//*********************    Hier
                CP->Click += gcnew EventHandler(this, &OptionForm::SetTextColor);//*********************    Hier
                this->Controls->Add(CP);//*********************    Hier
    
            }
    
        protected:
            /// <summary>
            /// Verwendete Ressourcen bereinigen.
            /// </summary>
            ~Form1()
            {
                if (components)
                {
                    delete components;
                }
            }
    
        private:
            /// <summary>
            /// Erforderliche Designervariable.
            /// </summary>
            System::ComponentModel::Container ^components;
    
    #pragma region Windows Form Designer generated code
            /// <summary>
            /// Erforderliche Methode für die Designerunterstützung.
            /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
            /// </summary>
            void InitializeComponent(void)
            {
                this->components = gcnew System::ComponentModel::Container();
                this->Size = System::Drawing::Size(300,300);
                this->Text = L"Form1";
                this->Padding = System::Windows::Forms::Padding(0);
                this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
            }
    #pragma endregion
            //**********************************  Und hier die Methode
            public: void SetTextColor(Object ^sender, EventArgs ^e){
                SetChange();
                CP->SetValue(CP->Cursor->Current->Position.X - this->Left - 37);
                Bitmap^ b = CP->Ca_Screen();
                FontColor = b->GetPixel(0,0);
                //Mit diesem Colorobject kannst du ja jetzt machen was du willst
            } 
        };
    }
    


  • Hallo,

    ach doch so einfach - ich dachte das wäre weitaus komplizierter *g*

    Danke!

    -----------------------------

    Wie lautet denn die verwendete Klasse von

    &OptionForm::SetTextColor
    

    ?

    Und bei

    SetChange();
    

    findet der Compiler keinen Bezeichner.

    -----------------------------

    Wenn ich die beiden Zeilen auskommentiere, funktioniert es auch - die Frage ist nur, ob es so richtig ist 😉

    -----------------------------

    Noch eine Frage.
    Wie kann ich die Farbskala in der Breite ändern?
    Wenn ich die Werte in der Datei ändere, dann wird zwar der schwarze Rahmen vergrößert, aber die Farben bleiben immer gleichbreit.
    Ist auch irgendwie logisch wenn die Linien mit 1px gezeichnet werden.

    Kann man vom gezeichneten intern ein Screenshot erstellen und es dann ebenfalls intern in die Breite skalieren?



  • Peterle schrieb:

    Hallo,

    Wie lautet denn die verwendete Klasse von

    &OptionForm::SetTextColor
    

    Sorry es ist hier natürlich :

    &Form1::SetTextColor
    

    und "SetChange()" ist nur ne Methode von meiner Form das eine änderung passiert ist, das kannst löschen

    Ich habs einfach bei mir rauskopiert....lol


Anmelden zum Antworten