Warum geht das nicht ? Schriftfarbe in einer ListBox ändern



  • Hallo,

    also ich habe eine Klasse CColorListBox abgeleitet von der Klasse CListBox.
    In dieser Klasse habe ich die Methode AddString ein wenig überladen, nämlich dass sie zum einen den Text und die Farbe mitbekommt.
    Also wie folgt

    class CColorListBox : public CListBox
    {
        int AddString(LPCTSTR lpszItem, COLORREF rgb);			
    }
    
    int CColorListBox::AddString(LPCTSTR lpszItem, COLORREF rgb)
    {
        int nItem = AddString(lpszItem);
        if (nItem >= 0)
    	SetItemData(nItem, rgb);
        return nItem;
    }
    

    So und im Programm sieht das ganze dann wie folgt aus :

    CColorListBox ListBox;
        ListBox.m_hWnd = GetDlgItem(hwndDlg,IDC_LIST1);
        string Hilf = InputDatei_DLL + " nicht gefunden ";
        ListBox.AddString(Hilf.c_str(),RGB(255,0,0));
    

    Aber irgendwie bleibt der Text dennoch schwarz, hat jemand ne Idee ??



  • Aloha,

    mit

    SetItemData();
    

    machst Du nichts anderes, als einen DWORD Wert hinter jeden Eintrag zu speichern, den Du mit GetItemData() wieder auslesen kannst, wenn Du das möchtest.
    Das kann alles sein, ne Struktur, nen Int-Wert, eigentlich alles, was auf dem Speicher liegt oder auch wie in Deinem Fall ein RGB-Wert.

    Damit setzt Du aber keine Text-Farbe.

    Möchtest Du eine einzige Textfarbe für alle Einträge haben, dann einfachsten über

    OnCtlClr()
    

    ansonsten mit Hilfe dieser Klasse kannst Du unterschiedliche Textfarben parallel erzeugen:

    [url]
    http://www.codeguru.com/listbox/colorlb.shtml
    [/url]

    Grüße

    BOA



  • Hallo,

    danke, aber das habe ich ja auch schon gefunden, doch das Problem ist einfach, sein Beispiel da läuft und ein einfügen in mein Projekt geht nicht ? Könnte das vielleicht daran liegen, dass ich das ganze in einer ListBox in einem TabControl machen möchte. Und bei mir sollen ja auch nicht alle Einträge die gleiche Farbe haben, sondern nur gelegentlich welche.
    Wo könnte mein Problem sein ?



  • Hi

    Tantor schrieb:

    das Problem ist einfach, sein Beispiel da läuft und ein einfügen in mein Projekt geht nicht

    Wieso kannst du seine Klasse nicht bei dir einfügen?

    Tantor schrieb:

    Könnte das vielleicht daran liegen, dass ich das ganze in einer ListBox in einem TabControl machen möchte.

    Wohl eher nicht

    Tantor schrieb:

    Und bei mir sollen ja auch nicht alle Einträge die gleiche Farbe haben, sondern nur gelegentlich welche.

    Genau das macht doch die Klasse, die BOA vorgeschlagen hat.

    Grüße Rapha



  • Hallo,

    ja ich habe doch seine Klasse bei mir im Projekt eingefügt. Seine CColorListBox-Klasse verwende ich ja in meinem Projekt... nur irgendwie gehts da nicht



  • Aloha,

    was genau funzt net ?

    Grüße

    BOA



  • Achso sorry, habs übersehen...

    Das Problem ist, dass dein Steuerelement nicht gesubclassed ist.

    Mein Vorschlag:
    Leg für die Liste eine Membervariable vom Typ CListBox an und ändere dann den Typ der Membervariable von CListBox auf CColorListBox.

    Grüße Rapha



  • So sieht es momentan aus :

    void DateiSuchen(HWND hwndDlg)
    {
    	string PATH_Var = getenv("PATH");
    	string Verzeichnis = "";
    	string InputDatei_DLL = "";
    	ifstream InputFile_DLL ("dll.txt");
    	bool gefunden = false;
    
    //***** Anlegen eines Objektes der Klasse *********////
    	CColorListBox ListBox;
    
    	ListBox.m_hWnd = GetDlgItem(hwndDlg,IDC_LIST1);
    
    	if ( InputFile_DLL.good() )
    	{
    		// Einmal vorweglesen
    		getline (InputFile_DLL,InputDatei_DLL);
    
    		// Solange nicht Ende der Datei
    		while (!InputFile_DLL.eof())
    		{
    			// Solange Verzeichnisse im PATH angegeben
    			while ( PATH_Var != "" && gefunden == false)
    			{
    				// Wenn nicht letztes Verzeichnis im Pfad
    				if ( PATH_Var.find(';',0) != string::npos )
    				{
    					// Auslesen des Verzeichnisses im Pfad in dem gesucht werden soll
    					Verzeichnis = PATH_Var.substr(0,PATH_Var.find(';',0));
    
    					// "Abschneiden" des gerade zu durhcsuchenden Pfades aus dem Gesamtpfad
    					PATH_Var.erase(0,PATH_Var.find(';',0)+1);
    
    					// Zusammenbau der Datei nach der gesucht werden soll
    					string Hilf= Verzeichnis + '\\' + InputDatei_DLL;
    
    					// Wenn Datei existiert
    					if ( PathFileExists(Hilf.c_str()) )
    					{
    						gefunden = true;
    					}
    					// Zu durchsuchendes Verzeichnis wieder zuruecksetzen
    					Verzeichnis = "";
    				}
    				// wenn letztes Verzeichnis im PATH
    				else
    				{
    					// Zusammenbau der Datei nach der gesucht werden soll
    					string Hilf = PATH_Var + '\\' + InputDatei_DLL;
    
    					// wenn Datei existiert
    					if ( PathFileExists(Hilf.c_str()) )
    					{
    						gefunden = true;
    					}
    
    					PATH_Var = "";
    				}	
    			}
    
    			// Wenn Datei nicht gefunden
    			if ( gefunden == false )
    			{
    				string Hilf = InputDatei_DLL + " nicht gefunden ";
    //*********** Hier soll farbig ausgegeben werden *************//////
    				ListBox.AddString(Hilf.c_str(),RGB(255,0,0));
    
    			}
    			// wenn gefunden
    			else
    			{
    				string Hilf = InputDatei_DLL + " gefunden ";
    	// ********************** hier ebenfalls **************//
    							ListBox.AddString(Hilf.c_str(),RGB(0,255,0));
    			}
    
    			// Nachlesen fuer naechste DLL
    			getline (InputFile_DLL,InputDatei_DLL);
    			// PATH neu einlesen
    			PATH_Var = getenv("PATH");
    		}
    	}
    	else
    	{
    		MessageBox (hwndDlg,"Fehler beim Öffnen der Datei 'dll.txt'","Fehler Eingabedatei",MB_OK);
    	}
    
    	ListBox.m_hWnd=0;
    }
    


  • Hi
    Allgemeiner Hinweis:
    Ich würde ein Objekt immer mit CWnd::FromHandle erzeugen lassen, also

    CColorListBox *pDlg = CColorListBox::FromHandle(GetDlgItem(...));
    

    Zu meinem Vorschlag:
    Versuche es einmal so, wie ich es gesagt habe. Die 2. Möglichkeit wäre die CWnd::SubclassWindow Methode.

    Grüße Rapha



  • @Rapha:

    Zu Versuch Nr.1 :

    CColorListBox *pDlg = CColorListBox::FromHandle(GetDlgItem(hwndDlg,IDC_LIST1));
    
    c:\WINNT\Personal\Cpp\MFC5\MFC5Dlg.cpp(335): error C2440: 'initializing' : cannot convert from 'CWnd *' to 'CColorListBox *'
    

    Zu Versuch Nr.2 :
    Weiß nicht so genau was du damit meinst 😕

    Ich versteh das einfach nicht ????????



  • Aloha,

    zu Deinem ersten Prob, caste das ganze mal...

    CColorListBox *pDlg = (CColorListBox*)CColorListBox::FromHandle(GetDlgItem(hwndDlg,IDC_LIST1));
    

    das zweite :

    #include "colorlistbox.h" ist klar.
    

    Membervariable anlegen

    CColorListBox m_list1;
    

    Dann im Init

    m_list1.SubclassDlgItem(IDC_LISTE,this);
    

    dann wo Du willst :

    m_list1.AddString("Text_1",RED);
    m_list1.AddString("Text_2",GREEN);
    

    Vorher ganz wichtig, Deine Listbox muß folgende Häkchen haben :

    Besitzerzeichnung fixiert und
    Mit Zeichenfolgen ein Häkchen machen

    Und alles wird gut....

    Grüße

    BOA



  • Hi

    Ich glaube du hast mich missverstanden 🙄
    Versuch Nummer 1 wird nicht funktionieren, da dein List-Control nicht gesublclassed wurde. Wenn du es dann mal gesubclassed hast, ist dies ein Weg, um einen Zeiger auf das Control zu bekommen. Ich geb zu, dass ich noch ein (CColorListBox*) vergessen hab und du deshalb einen Compilerfehler erhältst 😉
    Hier der "richtige" Code

    CColorListBox *pDlg = (CColorListBox*) CColorListBox::FromHandle(GetDlgItem(hwndDlg,IDC_LIST1));
    

    Aber du musst jetzt erst mal das Control subclassen:
    Hier finst du einen ausführlichen Bericht über Subbclassing: http://www.codeproject.com/miscctrl/subclassdemo.asp

    Du kannst dir es aber auch sparen ihn durchzulesen und machst folgendes 😉 :
    Erstelle in deiner DialogKlasse - z.b. CProjektnameDlg - (du hast doch eine dialogbasierende Anwendung? wenn nicht, dann halt in deiner Fensterklasse :D) über den Klassenassistent eine Membervariable vom Typ CListBox.
    Dann gehst du in die Headerdatei deiner Dialogklasse (bzw. Fensterklasse) und änderst den Typ der vorher angelegten Membervariable per Hand von CListBox in CColorListBox (nicht vergessen vor der Klasse ColorListBox.h zu #includieren).

    Jetzt ist das Control gesubclassed (was du auch per SubclassWindow hättest tun können: wird in dem Link, den ich oben angegeben hab, beschrieben).

    Grüße Rapha



  • Hab etwas länger zum Tippen gebraucht :p
    BOA hat die 2. Methode (mit SubclassWindow) beschrieben.
    Jetzt kannst dus dir raussuchen 😃



  • Hallo,

    also der Code sieht nun wie folgt aus :

    void DateiSuchen(HWND hwndDlg)
    {
    	string PATH_Var = getenv("PATH");
    	string Verzeichnis = "";
    	string InputDatei_DLL = "";
    	ifstream InputFile_DLL ("dll.txt");
    	bool gefunden = false;
    
    //	CColorListBox ListBox;
    
    	CColorListBox *pDlg = (CColorListBox*)CColorListBox::FromHandle(GetDlgItem(hwndDlg,IDC_LIST1));
    
    //	MessageBox(hwndDlg,PATH_Var.c_str(),"PATH",MB_OK);
    
    //	ListBox.m_hWnd = GetDlgItem(hwndDlg,IDC_LIST1);
    //	ListBox.SubclassDlgItem(IDC_LIST1,&CTest);
    
    	if ( InputFile_DLL.good() )
    	{
    		// Einmal vorweglesen
    		getline (InputFile_DLL,InputDatei_DLL);
    
    		// Solange nicht Ende der Datei
    		while (!InputFile_DLL.eof())
    		{
    			// Solange Verzeichnisse im PATH angegeben
    			while ( PATH_Var != "" && gefunden == false)
    			{
    				// Wenn nicht letztes Verzeichnis im Pfad
    				if ( PATH_Var.find(';',0) != string::npos )
    				{
    					// Auslesen des Verzeichnisses im Pfad in dem gesucht werden soll
    					Verzeichnis = PATH_Var.substr(0,PATH_Var.find(';',0));
    
    					// "Abschneiden" des gerade zu durhcsuchenden Pfades aus dem Gesamtpfad
    					PATH_Var.erase(0,PATH_Var.find(';',0)+1);
    
    					// Zusammenbau der Datei nach der gesucht werden soll
    					string Hilf= Verzeichnis + '\\' + InputDatei_DLL;
    
    					// Wenn Datei existiert
    					if ( PathFileExists(Hilf.c_str()) )
    					{
    						gefunden = true;
    					}
    					// Zu durchsuchendes Verzeichnis wieder zuruecksetzen
    					Verzeichnis = "";
    				}
    				// wenn letztes Verzeichnis im PATH
    				else
    				{
    					// Zusammenbau der Datei nach der gesucht werden soll
    					string Hilf = PATH_Var + '\\' + InputDatei_DLL;
    
    					// wenn Datei existiert
    					if ( PathFileExists(Hilf.c_str()) )
    					{
    						gefunden = true;
    					}
    
    					PATH_Var = "";
    				}	
    			}
    
    			// Wenn Datei nicht gefunden
    			if ( gefunden == false )
    			{
    				string Hilf = InputDatei_DLL + " nicht gefunden ";
    				pDlg->AddString(Hilf.c_str(),RGB(255,0,0));
    				//ListBox.AddString(Hilf.c_str(),RGB(0,0,255));
    				//ListBox.InsertItem(1,Hilf.c_str(),0);	
    
    			}
    			// wenn gefunden
    			else
    			{
    				string Hilf = InputDatei_DLL + " gefunden ";
    				pDlg->AddString(Hilf.c_str(),RGB(0,255,0));
    				//ListBox.InsertItem(1,Hilf.c_str(),1);
    				//ListBox.AddString(Hilf.c_str(),RGB(0,255,0));
    			}
    
    			// Nachlesen fuer naechste DLL
    			getline (InputFile_DLL,InputDatei_DLL);
    			// PATH neu einlesen
    			PATH_Var = getenv("PATH");
    		}
    	}
    	else
    	{
    		MessageBox (hwndDlg,"Fehler beim Öffnen der Datei 'dll.txt'","Fehler Eingabedatei",MB_OK);
    	}
    
    //	ListBox.m_hWnd=0;
    
    }
    

    und dennoch keine Chance eine andere Farbe als schwarz zu bekommen



  • Aloha,

    naja, so ein freundliches schwarz ist doch schön... 😉

    Du hast ja, wie es aussieht beide Varianten probiert ( schäm Dich, meine hast Du ausgeklammert ).

    Ich sehe allerdings nirgendwo bei der Variante von Rapha gesubclassed...

    Ich denke Du mußt noch folgenden Code einfügen :

    pDlg->SubClassWindow((GetDlgItem(IDC_DEINE_LISTE))->GetSafeHwnd());
    

    Wichtig, die Häkchen nicht vergessen in den Eigenschaften der Listbox !!!!

    Grüße

    BOA


Anmelden zum Antworten